From ecd8cbe8b6efba23d62ef0f8cbfb986886248b87 Mon Sep 17 00:00:00 2001 From: EvilDeaaaadd Date: Thu, 1 Aug 2019 16:54:11 +0300 Subject: [PATCH] Fix docs --- .gitignore | 6 +- Cargo.toml | 2 +- README.md | 2 +- target/doc/.lock | 0 target/doc/COPYRIGHT.txt | 45 + target/doc/FiraSans-LICENSE.txt | 94 + target/doc/FiraSans-Medium.woff | Bin 0 -> 186824 bytes target/doc/FiraSans-Regular.woff | Bin 0 -> 183268 bytes target/doc/LICENSE-APACHE.txt | 201 + target/doc/LICENSE-MIT.txt | 23 + target/doc/SourceCodePro-LICENSE.txt | 93 + target/doc/SourceCodePro-Regular.woff | Bin 0 -> 55472 bytes target/doc/SourceCodePro-Semibold.woff | Bin 0 -> 55360 bytes target/doc/SourceSerifPro-Bold.ttf.woff | Bin 0 -> 93248 bytes target/doc/SourceSerifPro-It.ttf.woff | Bin 0 -> 36200 bytes target/doc/SourceSerifPro-LICENSE.md | 93 + target/doc/SourceSerifPro-Regular.ttf.woff | Bin 0 -> 88596 bytes .../ahocorasick/enum.MatchKind.html | 10 + .../ahocorasick/struct.AhoCorasick.html | 10 + .../struct.AhoCorasickBuilder.html | 10 + .../ahocorasick/struct.FindIter.html | 10 + .../struct.FindOverlappingIter.html | 10 + .../ahocorasick/struct.StreamFindIter.html | 10 + target/doc/aho_corasick/all.html | 3 + target/doc/aho_corasick/enum.ErrorKind.html | 40 + target/doc/aho_corasick/enum.MatchKind.html | 119 + .../aho_corasick/error/enum.ErrorKind.html | 10 + .../doc/aho_corasick/error/struct.Error.html | 10 + target/doc/aho_corasick/index.html | 166 + target/doc/aho_corasick/sidebar-items.js | 1 + .../aho_corasick/state_id/trait.StateID.html | 10 + .../doc/aho_corasick/struct.AhoCorasick.html | 646 + .../struct.AhoCorasickBuilder.html | 256 + target/doc/aho_corasick/struct.Error.html | 26 + target/doc/aho_corasick/struct.FindIter.html | 89 + .../struct.FindOverlappingIter.html | 88 + target/doc/aho_corasick/struct.Match.html | 49 + .../aho_corasick/struct.StreamFindIter.html | 90 + target/doc/aho_corasick/trait.StateID.html | 43 + target/doc/aliases.js | 17 + target/doc/brush.svg | 1 + target/doc/c2_chacha/all.html | 3 + target/doc/c2_chacha/guts/index.html | 3 + target/doc/c2_chacha/guts/sidebar-items.js | 1 + target/doc/c2_chacha/guts/struct.ChaCha.html | 18 + target/doc/c2_chacha/guts/struct.State.html | 16 + target/doc/c2_chacha/guts/trait.Machine.html | 29 + target/doc/c2_chacha/index.html | 28 + target/doc/c2_chacha/sidebar-items.js | 1 + target/doc/cfg_if/all.html | 3 + target/doc/cfg_if/index.html | 25 + target/doc/cfg_if/macro.cfg_if!.html | 10 + target/doc/cfg_if/macro.cfg_if.html | 20 + target/doc/cfg_if/sidebar-items.js | 1 + target/doc/dark.css | 1 + target/doc/down-arrow.svg | 1 + target/doc/favicon.ico | Bin 0 -> 23229 bytes target/doc/getrandom/all.html | 3 + target/doc/getrandom/error/struct.Error.html | 10 + target/doc/getrandom/fn.getrandom.html | 9 + target/doc/getrandom/index.html | 64 + target/doc/getrandom/sidebar-items.js | 1 + target/doc/getrandom/struct.Error.html | 46 + .../aho_corasick/trait.StateID.js | 10 + .../c2_chacha/guts/trait.Machine.js | 10 + .../implementors/core/clone/trait.Clone.js | 19 + target/doc/implementors/core/cmp/trait.Eq.js | 15 + target/doc/implementors/core/cmp/trait.Ord.js | 10 + .../implementors/core/cmp/trait.PartialEq.js | 15 + .../implementors/core/cmp/trait.PartialOrd.js | 10 + .../implementors/core/convert/trait.AsRef.js | 10 + .../implementors/core/convert/trait.From.js | 15 + .../implementors/core/convert/trait.Into.js | 10 + .../core/default/trait.Default.js | 14 + .../doc/implementors/core/fmt/trait.Debug.js | 18 + .../implementors/core/fmt/trait.Display.js | 15 + .../doc/implementors/core/hash/trait.Hash.js | 10 + .../iter/traits/collect/trait.IntoIterator.js | 12 + .../double_ended/trait.DoubleEndedIterator.js | 11 + .../exact_size/trait.ExactSizeIterator.js | 11 + .../iter/traits/iterator/trait.Iterator.js | 16 + .../iter/traits/marker/trait.FusedIterator.js | 10 + .../implementors/core/marker/trait.Copy.js | 16 + .../implementors/core/marker/trait.Send.js | 21 + .../implementors/core/marker/trait.Sync.js | 21 + .../core/ops/deref/trait.Deref.js | 10 + .../core/ops/deref/trait.DerefMut.js | 10 + .../implementors/core/ops/drop/trait.Drop.js | 11 + .../core/ops/index/trait.Index.js | 10 + .../implementors/core/str/trait.FromStr.js | 10 + .../implementors/owoify/trait.OwOifiable.js | 10 + .../implementors/ppv_lite86/trait.Machine.js | 10 + .../implementors/ppv_lite86/trait.Store.js | 10 + .../doc/implementors/ppv_lite86/trait.VZip.js | 10 + .../rand/distributions/trait.Distribution.js | 10 + .../uniform/trait.SampleBorrow.js | 10 + .../uniform/trait.SampleUniform.js | 10 + .../uniform/trait.UniformSampler.js | 10 + .../weighted/alias_method/trait.Weight.js | 10 + .../rand/seq/trait.IteratorRandom.js | 10 + .../rand/seq/trait.SliceRandom.js | 10 + .../implementors/rand/trait.AsByteSliceMut.js | 10 + .../doc/implementors/rand/trait.CryptoRng.js | 10 + target/doc/implementors/rand/trait.Rng.js | 10 + target/doc/implementors/rand/trait.RngCore.js | 10 + .../implementors/rand/trait.SeedableRng.js | 10 + .../rand_core/block/trait.BlockRngCore.js | 10 + .../implementors/rand_core/trait.CryptoRng.js | 11 + .../implementors/rand_core/trait.RngCore.js | 11 + .../rand_core/trait.SeedableRng.js | 11 + .../regex/bytes/trait.Replacer.js | 10 + .../doc/implementors/regex/trait.Replacer.js | 10 + .../doc/implementors/std/error/trait.Error.js | 15 + target/doc/implementors/std/io/trait.Read.js | 10 + .../std/panic/trait.UnwindSafe.js | 10 + target/doc/lazy_static/all.html | 3 + target/doc/lazy_static/fn.initialize.html | 20 + target/doc/lazy_static/index.html | 77 + .../doc/lazy_static/macro.lazy_static!.html | 10 + target/doc/lazy_static/macro.lazy_static.html | 8 + target/doc/lazy_static/sidebar-items.js | 1 + target/doc/lazy_static/trait.LazyStatic.html | 7 + target/doc/light.css | 1 + target/doc/main.js | 95 + target/doc/memchr/all.html | 3 + target/doc/memchr/fn.memchr.html | 16 + target/doc/memchr/fn.memchr2.html | 2 + target/doc/memchr/fn.memchr2_iter.html | 2 + target/doc/memchr/fn.memchr3.html | 2 + target/doc/memchr/fn.memchr3_iter.html | 2 + target/doc/memchr/fn.memchr_iter.html | 2 + target/doc/memchr/fn.memrchr.html | 16 + target/doc/memchr/fn.memrchr2.html | 2 + target/doc/memchr/fn.memrchr2_iter.html | 2 + target/doc/memchr/fn.memrchr3.html | 2 + target/doc/memchr/fn.memrchr3_iter.html | 2 + target/doc/memchr/fn.memrchr_iter.html | 2 + target/doc/memchr/index.html | 34 + target/doc/memchr/iter/struct.Memchr.html | 10 + target/doc/memchr/iter/struct.Memchr2.html | 10 + target/doc/memchr/iter/struct.Memchr3.html | 10 + target/doc/memchr/sidebar-items.js | 1 + target/doc/memchr/struct.Memchr.html | 84 + target/doc/memchr/struct.Memchr2.html | 84 + target/doc/memchr/struct.Memchr3.html | 84 + target/doc/normalize.css | 2 + target/doc/noscript.css | 1 + target/doc/owoify/all.html | 3 + target/doc/owoify/index.html | 2 + target/doc/owoify/sidebar-items.js | 1 + target/doc/owoify/trait.OwOifiable.html | 14 + target/doc/ppv_lite86/all.html | 3 + target/doc/ppv_lite86/index.html | 20 + target/doc/ppv_lite86/macro.dispatch!.html | 10 + target/doc/ppv_lite86/macro.dispatch.html | 9 + .../ppv_lite86/macro.dispatch_light128!.html | 10 + .../ppv_lite86/macro.dispatch_light128.html | 11 + .../ppv_lite86/macro.dispatch_light256!.html | 10 + .../ppv_lite86/macro.dispatch_light256.html | 11 + target/doc/ppv_lite86/sidebar-items.js | 1 + target/doc/ppv_lite86/trait.AndNot.html | 9 + target/doc/ppv_lite86/trait.ArithOps.html | 5 + target/doc/ppv_lite86/trait.BSwap.html | 7 + target/doc/ppv_lite86/trait.BitOps0.html | 5 + target/doc/ppv_lite86/trait.BitOps128.html | 4 + target/doc/ppv_lite86/trait.BitOps32.html | 4 + target/doc/ppv_lite86/trait.BitOps64.html | 4 + target/doc/ppv_lite86/trait.LaneWords4.html | 10 + target/doc/ppv_lite86/trait.Machine.html | 27 + target/doc/ppv_lite86/trait.MultiLane.html | 11 + .../ppv_lite86/trait.RotateEachWord128.html | 4 + .../ppv_lite86/trait.RotateEachWord32.html | 14 + .../ppv_lite86/trait.RotateEachWord64.html | 7 + target/doc/ppv_lite86/trait.Store.html | 7 + target/doc/ppv_lite86/trait.StoreBytes.html | 10 + target/doc/ppv_lite86/trait.Swap64.html | 14 + target/doc/ppv_lite86/trait.UnsafeFrom.html | 7 + target/doc/ppv_lite86/trait.VZip.html | 8 + target/doc/ppv_lite86/trait.Vec2.html | 9 + target/doc/ppv_lite86/trait.Vec4.html | 9 + target/doc/ppv_lite86/trait.Words4.html | 10 + target/doc/ppv_lite86/trait.u128x1.html | 4 + target/doc/ppv_lite86/trait.u128x2.html | 4 + target/doc/ppv_lite86/trait.u128x4.html | 4 + target/doc/ppv_lite86/trait.u32x4.html | 4 + target/doc/ppv_lite86/trait.u32x4x2.html | 4 + target/doc/ppv_lite86/trait.u32x4x4.html | 4 + target/doc/ppv_lite86/trait.u64x2.html | 4 + target/doc/ppv_lite86/trait.u64x2x2.html | 4 + target/doc/ppv_lite86/trait.u64x2x4.html | 4 + target/doc/ppv_lite86/trait.u64x4.html | 4 + target/doc/ppv_lite86/types/trait.AndNot.html | 10 + .../doc/ppv_lite86/types/trait.ArithOps.html | 10 + target/doc/ppv_lite86/types/trait.BSwap.html | 10 + .../doc/ppv_lite86/types/trait.BitOps0.html | 10 + .../doc/ppv_lite86/types/trait.BitOps128.html | 10 + .../doc/ppv_lite86/types/trait.BitOps32.html | 10 + .../doc/ppv_lite86/types/trait.BitOps64.html | 10 + .../doc/ppv_lite86/types/trait.Machine.html | 10 + .../types/trait.RotateEachWord128.html | 10 + .../types/trait.RotateEachWord32.html | 10 + .../types/trait.RotateEachWord64.html | 10 + target/doc/ppv_lite86/types/trait.Store.html | 10 + .../ppv_lite86/types/trait.StoreBytes.html | 10 + .../types/types/trait.LaneWords4.html | 10 + .../types/types/trait.MultiLane.html | 10 + .../ppv_lite86/types/types/trait.Swap64.html | 10 + .../types/types/trait.UnsafeFrom.html | 10 + .../ppv_lite86/types/types/trait.VZip.html | 10 + .../ppv_lite86/types/types/trait.Vec2.html | 10 + .../ppv_lite86/types/types/trait.Vec4.html | 10 + .../ppv_lite86/types/types/trait.Words4.html | 10 + .../ppv_lite86/types/types/trait.u128x1.html | 10 + .../ppv_lite86/types/types/trait.u128x2.html | 10 + .../ppv_lite86/types/types/trait.u128x4.html | 10 + .../ppv_lite86/types/types/trait.u32x4.html | 10 + .../ppv_lite86/types/types/trait.u32x4x2.html | 10 + .../ppv_lite86/types/types/trait.u32x4x4.html | 10 + .../ppv_lite86/types/types/trait.u64x2.html | 10 + .../ppv_lite86/types/types/trait.u64x2x2.html | 10 + .../ppv_lite86/types/types/trait.u64x2x4.html | 10 + .../ppv_lite86/types/types/trait.u64x4.html | 10 + target/doc/ppv_lite86/x86_64/index.html | 9 + target/doc/ppv_lite86/x86_64/sidebar-items.js | 1 + .../ppv_lite86/x86_64/struct.Avx2Machine.html | 12 + target/doc/ppv_lite86/x86_64/struct.NoA1.html | 12 + target/doc/ppv_lite86/x86_64/struct.NoA2.html | 12 + target/doc/ppv_lite86/x86_64/struct.NoNI.html | 12 + target/doc/ppv_lite86/x86_64/struct.NoS3.html | 12 + target/doc/ppv_lite86/x86_64/struct.NoS4.html | 12 + .../ppv_lite86/x86_64/struct.SseMachine.html | 12 + .../doc/ppv_lite86/x86_64/struct.YesA1.html | 12 + .../doc/ppv_lite86/x86_64/struct.YesA2.html | 12 + .../doc/ppv_lite86/x86_64/struct.YesNI.html | 12 + .../doc/ppv_lite86/x86_64/struct.YesS3.html | 12 + .../doc/ppv_lite86/x86_64/struct.YesS4.html | 12 + target/doc/ppv_lite86/x86_64/type.AVX.html | 3 + target/doc/ppv_lite86/x86_64/type.AVX2.html | 1 + target/doc/ppv_lite86/x86_64/type.SSE2.html | 1 + target/doc/ppv_lite86/x86_64/type.SSE41.html | 1 + target/doc/ppv_lite86/x86_64/type.SSSE3.html | 1 + .../x86_64/union.vec128_storage.html | 23 + .../x86_64/union.vec256_storage.html | 19 + .../x86_64/union.vec512_storage.html | 18 + target/doc/rand/all.html | 3 + .../bernoulli/enum.BernoulliError.html | 10 + .../bernoulli/struct.Bernoulli.html | 10 + .../binomial/struct.Binomial.html | 10 + .../distributions/cauchy/struct.Cauchy.html | 10 + .../dirichlet/struct.Dirichlet.html | 10 + .../distributions/enum.BernoulliError.html | 26 + .../distributions/exponential/struct.Exp.html | 10 + .../exponential/struct.Exp1.html | 10 + .../distributions/float/struct.Open01.html | 10 + .../float/struct.OpenClosed01.html | 10 + .../rand/distributions/gamma/struct.Beta.html | 10 + .../gamma/struct.ChiSquared.html | 10 + .../distributions/gamma/struct.FisherF.html | 10 + .../distributions/gamma/struct.Gamma.html | 10 + .../distributions/gamma/struct.StudentT.html | 10 + target/doc/rand/distributions/index.html | 103 + .../normal/struct.LogNormal.html | 10 + .../distributions/normal/struct.Normal.html | 10 + .../normal/struct.StandardNormal.html | 10 + .../other/struct.Alphanumeric.html | 10 + .../distributions/pareto/struct.Pareto.html | 10 + .../distributions/poisson/struct.Poisson.html | 10 + .../doc/rand/distributions/sidebar-items.js | 1 + .../distributions/struct.Alphanumeric.html | 27 + .../rand/distributions/struct.Bernoulli.html | 44 + .../doc/rand/distributions/struct.Beta.html | 24 + .../rand/distributions/struct.Binomial.html | 26 + .../doc/rand/distributions/struct.Cauchy.html | 26 + .../rand/distributions/struct.ChiSquared.html | 28 + .../rand/distributions/struct.Dirichlet.html | 35 + .../rand/distributions/struct.DistIter.html | 85 + target/doc/rand/distributions/struct.Exp.html | 26 + .../doc/rand/distributions/struct.Exp1.html | 29 + .../rand/distributions/struct.FisherF.html | 25 + .../doc/rand/distributions/struct.Gamma.html | 35 + .../rand/distributions/struct.LogNormal.html | 27 + .../doc/rand/distributions/struct.Normal.html | 29 + .../doc/rand/distributions/struct.Open01.html | 36 + .../distributions/struct.OpenClosed01.html | 37 + .../doc/rand/distributions/struct.Pareto.html | 26 + .../rand/distributions/struct.Poisson.html | 25 + .../rand/distributions/struct.Standard.html | 222 + .../distributions/struct.StandardNormal.html | 27 + .../rand/distributions/struct.StudentT.html | 24 + .../rand/distributions/struct.Triangular.html | 25 + .../rand/distributions/struct.Uniform.html | 55 + .../rand/distributions/struct.UnitCircle.html | 26 + .../struct.UnitSphereSurface.html | 25 + .../rand/distributions/struct.Weibull.html | 24 + .../distributions/trait.Distribution.html | 47 + .../triangular/struct.Triangular.html | 10 + .../doc/rand/distributions/uniform/index.html | 94 + .../distributions/uniform/sidebar-items.js | 1 + .../distributions/uniform/struct.Uniform.html | 55 + .../uniform/struct.UniformDuration.html | 25 + .../uniform/struct.UniformFloat.html | 38 + .../uniform/struct.UniformInt.html | 103 + .../uniform/trait.SampleBorrow.html | 12 + .../uniform/trait.SampleUniform.html | 13 + .../uniform/trait.UniformSampler.html | 37 + .../unit_circle/struct.UnitCircle.html | 10 + .../unit_sphere/struct.UnitSphereSurface.html | 10 + .../distributions/weibull/struct.Weibull.html | 10 + .../weighted/alias_method/index.html | 9 + .../weighted/alias_method/sidebar-items.js | 1 + .../alias_method/struct.WeightedIndex.html | 61 + .../weighted/alias_method/trait.Weight.html | 24 + .../weighted/enum.WeightedError.html | 39 + .../rand/distributions/weighted/index.html | 16 + .../distributions/weighted/sidebar-items.js | 1 + .../weighted/struct.WeightedIndex.html | 66 + target/doc/rand/fn.random.html | 35 + target/doc/rand/fn.thread_rng.html | 7 + target/doc/rand/index.html | 49 + target/doc/rand/prelude/index.html | 9 + target/doc/rand/prelude/sidebar-items.js | 1 + target/doc/rand/rngs/adapter/index.html | 8 + .../rngs/adapter/read/struct.ReadError.html | 10 + .../rngs/adapter/read/struct.ReadRng.html | 10 + .../reseeding/struct.ReseedingRng.html | 10 + target/doc/rand/rngs/adapter/sidebar-items.js | 1 + .../rand/rngs/adapter/struct.ReadError.html | 18 + .../doc/rand/rngs/adapter/struct.ReadRng.html | 42 + .../rngs/adapter/struct.ReseedingRng.html | 81 + .../rand/rngs/entropy/struct.EntropyRng.html | 10 + target/doc/rand/rngs/index.html | 82 + target/doc/rand/rngs/mock/index.html | 4 + target/doc/rand/rngs/mock/sidebar-items.js | 1 + target/doc/rand/rngs/mock/struct.StepRng.html | 43 + target/doc/rand/rngs/os/struct.OsRng.html | 10 + target/doc/rand/rngs/sidebar-items.js | 1 + target/doc/rand/rngs/std/struct.StdRng.html | 10 + target/doc/rand/rngs/struct.EntropyRng.html | 32 + target/doc/rand/rngs/struct.OsRng.html | 57 + target/doc/rand/rngs/struct.StdRng.html | 45 + target/doc/rand/rngs/struct.ThreadRng.html | 41 + .../doc/rand/rngs/thread/fn.thread_rng.html | 10 + .../rand/rngs/thread/struct.ThreadRng.html | 10 + target/doc/rand/seq/index.html | 24 + target/doc/rand/seq/index/enum.IndexVec.html | 33 + .../rand/seq/index/enum.IndexVecIntoIter.html | 92 + .../doc/rand/seq/index/enum.IndexVecIter.html | 86 + target/doc/rand/seq/index/fn.sample.html | 18 + target/doc/rand/seq/index/index.html | 9 + target/doc/rand/seq/index/sidebar-items.js | 1 + target/doc/rand/seq/sidebar-items.js | 1 + .../doc/rand/seq/struct.SliceChooseIter.html | 86 + target/doc/rand/seq/trait.IteratorRandom.html | 57 + target/doc/rand/seq/trait.SliceRandom.html | 115 + target/doc/rand/sidebar-items.js | 1 + target/doc/rand/struct.Error.html | 36 + target/doc/rand/trait.AsByteSliceMut.html | 13 + target/doc/rand/trait.CryptoRng.html | 21 + target/doc/rand/trait.Rng.html | 182 + target/doc/rand/trait.RngCore.html | 114 + target/doc/rand/trait.SeedableRng.html | 116 + target/doc/rand_chacha/all.html | 3 + .../chacha/struct.ChaCha12Core.html | 10 + .../chacha/struct.ChaCha12Rng.html | 10 + .../chacha/struct.ChaCha20Core.html | 10 + .../chacha/struct.ChaCha20Rng.html | 10 + .../chacha/struct.ChaCha8Core.html | 10 + .../rand_chacha/chacha/struct.ChaCha8Rng.html | 10 + target/doc/rand_chacha/index.html | 13 + target/doc/rand_chacha/sidebar-items.js | 1 + .../doc/rand_chacha/struct.ChaCha12Core.html | 27 + .../doc/rand_chacha/struct.ChaCha12Rng.html | 69 + .../doc/rand_chacha/struct.ChaCha20Core.html | 27 + .../doc/rand_chacha/struct.ChaCha20Rng.html | 69 + .../doc/rand_chacha/struct.ChaCha8Core.html | 27 + target/doc/rand_chacha/struct.ChaCha8Rng.html | 69 + target/doc/rand_chacha/type.ChaChaCore.html | 2 + target/doc/rand_chacha/type.ChaChaRng.html | 2 + target/doc/rand_core/all.html | 3 + target/doc/rand_core/block/index.html | 47 + target/doc/rand_core/block/sidebar-items.js | 1 + .../doc/rand_core/block/struct.BlockRng.html | 66 + .../rand_core/block/struct.BlockRng64.html | 55 + .../rand_core/block/trait.BlockRngCore.html | 18 + target/doc/rand_core/error/struct.Error.html | 10 + .../impls/fn.fill_bytes_via_next.html | 6 + .../impls/fn.fill_via_u32_chunks.html | 27 + .../impls/fn.fill_via_u64_chunks.html | 9 + .../rand_core/impls/fn.next_u32_via_fill.html | 2 + .../rand_core/impls/fn.next_u64_via_fill.html | 2 + .../rand_core/impls/fn.next_u64_via_u32.html | 2 + target/doc/rand_core/impls/index.html | 18 + target/doc/rand_core/impls/sidebar-items.js | 1 + target/doc/rand_core/index.html | 24 + target/doc/rand_core/le/fn.read_u32_into.html | 3 + target/doc/rand_core/le/fn.read_u64_into.html | 3 + target/doc/rand_core/le/index.html | 9 + target/doc/rand_core/le/sidebar-items.js | 1 + target/doc/rand_core/sidebar-items.js | 1 + target/doc/rand_core/struct.Error.html | 37 + target/doc/rand_core/trait.CryptoRng.html | 21 + target/doc/rand_core/trait.RngCore.html | 114 + target/doc/rand_core/trait.SeedableRng.html | 114 + target/doc/regex/all.html | 3 + target/doc/regex/bytes/index.html | 98 + target/doc/regex/bytes/sidebar-items.js | 1 + .../regex/bytes/struct.CaptureLocations.html | 36 + .../regex/bytes/struct.CaptureMatches.html | 82 + .../doc/regex/bytes/struct.CaptureNames.html | 81 + target/doc/regex/bytes/struct.Captures.html | 74 + target/doc/regex/bytes/struct.Match.html | 24 + target/doc/regex/bytes/struct.Matches.html | 83 + target/doc/regex/bytes/struct.NoExpand.html | 19 + target/doc/regex/bytes/struct.Regex.html | 296 + .../doc/regex/bytes/struct.RegexBuilder.html | 89 + target/doc/regex/bytes/struct.RegexSet.html | 164 + .../regex/bytes/struct.RegexSetBuilder.html | 73 + .../doc/regex/bytes/struct.ReplacerRef.html | 16 + target/doc/regex/bytes/struct.SetMatches.html | 38 + .../bytes/struct.SetMatchesIntoIter.html | 86 + .../regex/bytes/struct.SetMatchesIter.html | 93 + target/doc/regex/bytes/struct.Split.html | 80 + target/doc/regex/bytes/struct.SplitN.html | 81 + .../regex/bytes/struct.SubCaptureMatches.html | 84 + target/doc/regex/bytes/trait.Replacer.html | 45 + target/doc/regex/enum.Error.html | 35 + target/doc/regex/error/enum.Error.html | 10 + target/doc/regex/fn.escape.html | 4 + target/doc/regex/index.html | 418 + .../re_builder/bytes/struct.RegexBuilder.html | 10 + .../set_bytes/struct.RegexSetBuilder.html | 10 + .../set_unicode/struct.RegexSetBuilder.html | 10 + .../unicode/struct.RegexBuilder.html | 10 + .../re_bytes/struct.CaptureLocations.html | 10 + .../regex/re_bytes/struct.CaptureMatches.html | 10 + .../regex/re_bytes/struct.CaptureNames.html | 10 + .../doc/regex/re_bytes/struct.Captures.html | 10 + target/doc/regex/re_bytes/struct.Match.html | 10 + target/doc/regex/re_bytes/struct.Matches.html | 10 + .../doc/regex/re_bytes/struct.NoExpand.html | 10 + target/doc/regex/re_bytes/struct.Regex.html | 10 + .../regex/re_bytes/struct.ReplacerRef.html | 10 + target/doc/regex/re_bytes/struct.Split.html | 10 + target/doc/regex/re_bytes/struct.SplitN.html | 10 + .../re_bytes/struct.SubCaptureMatches.html | 10 + target/doc/regex/re_bytes/trait.Replacer.html | 10 + .../regex/re_set/bytes/struct.RegexSet.html | 10 + .../regex/re_set/bytes/struct.SetMatches.html | 10 + .../bytes/struct.SetMatchesIntoIter.html | 10 + .../re_set/bytes/struct.SetMatchesIter.html | 10 + .../regex/re_set/unicode/struct.RegexSet.html | 10 + .../re_set/unicode/struct.SetMatches.html | 10 + .../unicode/struct.SetMatchesIntoIter.html | 10 + .../re_set/unicode/struct.SetMatchesIter.html | 10 + target/doc/regex/re_unicode/fn.escape.html | 10 + .../re_unicode/struct.CaptureLocations.html | 10 + .../re_unicode/struct.CaptureMatches.html | 10 + .../regex/re_unicode/struct.CaptureNames.html | 10 + .../doc/regex/re_unicode/struct.Captures.html | 10 + target/doc/regex/re_unicode/struct.Match.html | 10 + .../doc/regex/re_unicode/struct.Matches.html | 10 + .../doc/regex/re_unicode/struct.NoExpand.html | 10 + target/doc/regex/re_unicode/struct.Regex.html | 10 + .../regex/re_unicode/struct.ReplacerRef.html | 10 + target/doc/regex/re_unicode/struct.Split.html | 10 + .../doc/regex/re_unicode/struct.SplitN.html | 10 + .../re_unicode/struct.SubCaptureMatches.html | 10 + .../doc/regex/re_unicode/trait.Replacer.html | 10 + target/doc/regex/sidebar-items.js | 1 + target/doc/regex/struct.CaptureLocations.html | 36 + target/doc/regex/struct.CaptureMatches.html | 82 + target/doc/regex/struct.CaptureNames.html | 81 + target/doc/regex/struct.Captures.html | 74 + target/doc/regex/struct.Match.html | 25 + target/doc/regex/struct.Matches.html | 82 + target/doc/regex/struct.NoExpand.html | 19 + target/doc/regex/struct.Regex.html | 324 + target/doc/regex/struct.RegexBuilder.html | 89 + target/doc/regex/struct.RegexSet.html | 164 + target/doc/regex/struct.RegexSetBuilder.html | 73 + target/doc/regex/struct.ReplacerRef.html | 16 + target/doc/regex/struct.SetMatches.html | 38 + .../doc/regex/struct.SetMatchesIntoIter.html | 86 + target/doc/regex/struct.SetMatchesIter.html | 93 + target/doc/regex/struct.Split.html | 80 + target/doc/regex/struct.SplitN.html | 81 + .../doc/regex/struct.SubCaptureMatches.html | 84 + target/doc/regex/trait.Replacer.html | 44 + target/doc/regex_syntax/all.html | 3 + .../regex_syntax/ast/enum.AssertionKind.html | 36 + target/doc/regex_syntax/ast/enum.Ast.html | 61 + target/doc/regex_syntax/ast/enum.Class.html | 32 + .../regex_syntax/ast/enum.ClassAsciiKind.html | 57 + .../regex_syntax/ast/enum.ClassPerlKind.html | 30 + .../doc/regex_syntax/ast/enum.ClassSet.html | 37 + .../ast/enum.ClassSetBinaryOpKind.html | 35 + .../regex_syntax/ast/enum.ClassSetItem.html | 45 + .../ast/enum.ClassUnicodeKind.html | 37 + .../ast/enum.ClassUnicodeOpKind.html | 32 + .../doc/regex_syntax/ast/enum.ErrorKind.html | 123 + target/doc/regex_syntax/ast/enum.Flag.html | 36 + .../regex_syntax/ast/enum.FlagsItemKind.html | 29 + .../doc/regex_syntax/ast/enum.GroupKind.html | 29 + .../regex_syntax/ast/enum.HexLiteralKind.html | 39 + .../regex_syntax/ast/enum.LiteralKind.html | 41 + .../regex_syntax/ast/enum.RepetitionKind.html | 31 + .../ast/enum.RepetitionRange.html | 32 + .../ast/enum.SpecialLiteralKind.html | 41 + target/doc/regex_syntax/ast/fn.visit.html | 13 + target/doc/regex_syntax/ast/index.html | 55 + target/doc/regex_syntax/ast/parse/index.html | 5 + .../regex_syntax/ast/parse/sidebar-items.js | 1 + .../regex_syntax/ast/parse/struct.Parser.html | 31 + .../ast/parse/struct.ParserBuilder.html | 61 + target/doc/regex_syntax/ast/print/index.html | 4 + .../regex_syntax/ast/print/sidebar-items.js | 1 + .../ast/print/struct.Printer.html | 23 + target/doc/regex_syntax/ast/sidebar-items.js | 1 + .../regex_syntax/ast/struct.Alternation.html | 30 + .../regex_syntax/ast/struct.Assertion.html | 26 + .../regex_syntax/ast/struct.CaptureName.html | 30 + .../regex_syntax/ast/struct.ClassAscii.html | 29 + .../ast/struct.ClassBracketed.html | 30 + .../regex_syntax/ast/struct.ClassPerl.html | 29 + .../ast/struct.ClassSetBinaryOp.html | 30 + .../ast/struct.ClassSetRange.html | 31 + .../ast/struct.ClassSetUnion.html | 40 + .../regex_syntax/ast/struct.ClassUnicode.html | 38 + .../doc/regex_syntax/ast/struct.Comment.html | 29 + .../doc/regex_syntax/ast/struct.Concat.html | 30 + target/doc/regex_syntax/ast/struct.Error.html | 41 + target/doc/regex_syntax/ast/struct.Flags.html | 38 + .../regex_syntax/ast/struct.FlagsItem.html | 26 + target/doc/regex_syntax/ast/struct.Group.html | 37 + .../doc/regex_syntax/ast/struct.Literal.html | 33 + .../doc/regex_syntax/ast/struct.Position.html | 49 + .../regex_syntax/ast/struct.Repetition.html | 30 + .../regex_syntax/ast/struct.RepetitionOp.html | 27 + .../doc/regex_syntax/ast/struct.SetFlags.html | 26 + target/doc/regex_syntax/ast/struct.Span.html | 50 + .../regex_syntax/ast/struct.WithComments.html | 30 + .../doc/regex_syntax/ast/trait.Visitor.html | 61 + .../regex_syntax/ast/visitor/fn.visit.html | 10 + .../ast/visitor/trait.Visitor.html | 10 + target/doc/regex_syntax/enum.Error.html | 38 + target/doc/regex_syntax/error/enum.Error.html | 10 + .../doc/regex_syntax/error/type.Result.html | 10 + target/doc/regex_syntax/fn.escape.html | 4 + target/doc/regex_syntax/fn.escape_into.html | 4 + .../regex_syntax/fn.is_meta_character.html | 8 + target/doc/regex_syntax/fn.is_word_byte.html | 4 + .../regex_syntax/fn.is_word_character.html | 9 + target/doc/regex_syntax/hir/enum.Anchor.html | 39 + target/doc/regex_syntax/hir/enum.Class.html | 59 + .../doc/regex_syntax/hir/enum.ErrorKind.html | 44 + .../doc/regex_syntax/hir/enum.GroupKind.html | 35 + target/doc/regex_syntax/hir/enum.HirKind.html | 57 + target/doc/regex_syntax/hir/enum.Literal.html | 33 + .../regex_syntax/hir/enum.RepetitionKind.html | 31 + .../hir/enum.RepetitionRange.html | 29 + .../regex_syntax/hir/enum.WordBoundary.html | 38 + target/doc/regex_syntax/hir/fn.visit.html | 13 + target/doc/regex_syntax/hir/index.html | 32 + .../doc/regex_syntax/hir/literal/index.html | 5 + .../regex_syntax/hir/literal/sidebar-items.js | 1 + .../hir/literal/struct.Literal.html | 550 + .../hir/literal/struct.Literals.html | 124 + target/doc/regex_syntax/hir/print/index.html | 5 + .../regex_syntax/hir/print/sidebar-items.js | 1 + .../hir/print/struct.Printer.html | 29 + target/doc/regex_syntax/hir/sidebar-items.js | 1 + .../regex_syntax/hir/struct.ClassBytes.html | 50 + .../hir/struct.ClassBytesIter.html | 80 + .../hir/struct.ClassBytesRange.html | 41 + .../regex_syntax/hir/struct.ClassUnicode.html | 46 + .../hir/struct.ClassUnicodeIter.html | 80 + .../hir/struct.ClassUnicodeRange.html | 41 + target/doc/regex_syntax/hir/struct.Error.html | 31 + target/doc/regex_syntax/hir/struct.Group.html | 34 + target/doc/regex_syntax/hir/struct.Hir.html | 142 + .../regex_syntax/hir/struct.Repetition.html | 43 + .../doc/regex_syntax/hir/trait.Visitor.html | 34 + .../doc/regex_syntax/hir/translate/index.html | 6 + .../hir/translate/sidebar-items.js | 1 + .../hir/translate/struct.Translator.html | 31 + .../translate/struct.TranslatorBuilder.html | 36 + .../regex_syntax/hir/visitor/fn.visit.html | 10 + .../hir/visitor/trait.Visitor.html | 10 + target/doc/regex_syntax/index.html | 93 + .../regex_syntax/parser/struct.Parser.html | 10 + .../parser/struct.ParserBuilder.html | 10 + target/doc/regex_syntax/sidebar-items.js | 1 + target/doc/regex_syntax/struct.Parser.html | 36 + .../regex_syntax/struct.ParserBuilder.html | 92 + target/doc/regex_syntax/type.Result.html | 2 + target/doc/rust-logo.png | Bin 0 -> 5758 bytes target/doc/rustdoc.css | 1 + target/doc/search-index.js | 19 + target/doc/settings.css | 1 + target/doc/settings.html | 1 + target/doc/settings.js | 1 + target/doc/source-files.js | 18 + target/doc/source-script.js | 1 + .../doc/src/aho_corasick/ahocorasick.rs.html | 4067 ++++++ target/doc/src/aho_corasick/automaton.rs.html | 805 ++ target/doc/src/aho_corasick/buffer.rs.html | 265 + target/doc/src/aho_corasick/classes.rs.html | 489 + target/doc/src/aho_corasick/dfa.rs.html | 1379 ++ target/doc/src/aho_corasick/error.rs.html | 209 + target/doc/src/aho_corasick/lib.rs.html | 595 + target/doc/src/aho_corasick/nfa.rs.html | 2503 ++++ target/doc/src/aho_corasick/prefilter.rs.html | 505 + target/doc/src/aho_corasick/state_id.rs.html | 335 + target/doc/src/c2_chacha/guts.rs.html | 601 + target/doc/src/c2_chacha/lib.rs.html | 101 + target/doc/src/cfg_if/lib.rs.html | 291 + target/doc/src/getrandom/error.rs.html | 335 + target/doc/src/getrandom/error_impls.rs.html | 73 + target/doc/src/getrandom/lib.rs.html | 515 + target/doc/src/getrandom/util.rs.html | 195 + target/doc/src/getrandom/windows.rs.html | 55 + .../doc/src/lazy_static/inline_lazy.rs.html | 133 + target/doc/src/lazy_static/lib.rs.html | 425 + target/doc/src/memchr/fallback.rs.html | 695 + target/doc/src/memchr/iter.rs.html | 357 + target/doc/src/memchr/lib.rs.html | 627 + target/doc/src/memchr/naive.rs.html | 77 + target/doc/src/memchr/x86/avx.rs.html | 1409 ++ target/doc/src/memchr/x86/mod.rs.html | 213 + target/doc/src/memchr/x86/sse2.rs.html | 1585 +++ target/doc/src/owoify/lib.rs.html | 119 + target/doc/src/ppv_lite86/lib.rs.html | 47 + target/doc/src/ppv_lite86/soft.rs.html | 843 ++ target/doc/src/ppv_lite86/types.rs.html | 561 + target/doc/src/ppv_lite86/x86_64/mod.rs.html | 869 ++ target/doc/src/ppv_lite86/x86_64/sse2.rs.html | 3269 +++++ .../src/rand/distributions/bernoulli.rs.html | 335 + .../src/rand/distributions/binomial.rs.html | 627 + .../doc/src/rand/distributions/cauchy.rs.html | 207 + .../src/rand/distributions/dirichlet.rs.html | 257 + .../rand/distributions/exponential.rs.html | 219 + .../doc/src/rand/distributions/float.rs.html | 525 + .../doc/src/rand/distributions/gamma.rs.html | 745 ++ .../src/rand/distributions/integer.rs.html | 371 + target/doc/src/rand/distributions/mod.rs.html | 765 ++ .../doc/src/rand/distributions/normal.rs.html | 343 + .../doc/src/rand/distributions/other.rs.html | 441 + .../doc/src/rand/distributions/pareto.rs.html | 137 + .../src/rand/distributions/poisson.rs.html | 305 + .../src/rand/distributions/triangular.rs.html | 161 + .../src/rand/distributions/uniform.rs.html | 2543 ++++ .../rand/distributions/unit_circle.rs.html | 203 + .../rand/distributions/unit_sphere.rs.html | 193 + .../doc/src/rand/distributions/utils.rs.html | 1013 ++ .../src/rand/distributions/weibull.rs.html | 131 + .../weighted/alias_method.rs.html | 1001 ++ .../rand/distributions/weighted/mod.rs.html | 499 + .../distributions/ziggurat_tables.rs.html | 561 + target/doc/src/rand/lib.rs.html | 1441 ++ target/doc/src/rand/prelude.rs.html | 59 + target/doc/src/rand/rngs/adapter/mod.rs.html | 33 + target/doc/src/rand/rngs/adapter/read.rs.html | 299 + .../src/rand/rngs/adapter/reseeding.rs.html | 715 + target/doc/src/rand/rngs/entropy.rs.html | 157 + target/doc/src/rand/rngs/mock.rs.html | 129 + target/doc/src/rand/rngs/mod.rs.html | 243 + target/doc/src/rand/rngs/os.rs.html | 193 + target/doc/src/rand/rngs/std.rs.html | 203 + target/doc/src/rand/rngs/thread.rs.html | 251 + target/doc/src/rand/seq/index.rs.html | 785 ++ target/doc/src/rand/seq/mod.rs.html | 1587 +++ target/doc/src/rand_chacha/chacha.rs.html | 907 ++ target/doc/src/rand_chacha/lib.rs.html | 63 + target/doc/src/rand_core/block.rs.html | 869 ++ target/doc/src/rand_core/error.rs.html | 271 + target/doc/src/rand_core/impls.rs.html | 333 + target/doc/src/rand_core/le.rs.html | 139 + target/doc/src/rand_core/lib.rs.html | 989 ++ target/doc/src/regex/backtrack.rs.html | 609 + target/doc/src/regex/compile.rs.html | 2233 ++++ target/doc/src/regex/dfa.rs.html | 3933 ++++++ target/doc/src/regex/error.rs.html | 163 + target/doc/src/regex/exec.rs.html | 2933 +++++ target/doc/src/regex/expand.rs.html | 443 + target/doc/src/regex/freqs.rs.html | 545 + target/doc/src/regex/input.rs.html | 843 ++ target/doc/src/regex/lib.rs.html | 1377 ++ target/doc/src/regex/literal/mod.rs.html | 2295 ++++ .../src/regex/literal/teddy_avx2/imp.rs.html | 967 ++ .../src/regex/literal/teddy_avx2/mod.rs.html | 19 + .../src/regex/literal/teddy_ssse3/imp.rs.html | 1581 +++ .../src/regex/literal/teddy_ssse3/mod.rs.html | 19 + target/doc/src/regex/pikevm.rs.html | 763 ++ target/doc/src/regex/prog.rs.html | 849 ++ target/doc/src/regex/re_builder.rs.html | 779 ++ target/doc/src/regex/re_bytes.rs.html | 2341 ++++ target/doc/src/regex/re_set.rs.html | 927 ++ target/doc/src/regex/re_trait.rs.html | 539 + target/doc/src/regex/re_unicode.rs.html | 2425 ++++ target/doc/src/regex/sparse.rs.html | 153 + target/doc/src/regex/utf8.rs.html | 521 + target/doc/src/regex/vector/avx2.rs.html | 377 + target/doc/src/regex/vector/mod.rs.html | 11 + target/doc/src/regex/vector/ssse3.rs.html | 387 + target/doc/src/regex_syntax/ast/mod.rs.html | 3051 +++++ target/doc/src/regex_syntax/ast/parse.rs.html | 10857 ++++++++++++++++ target/doc/src/regex_syntax/ast/print.rs.html | 1175 ++ .../doc/src/regex_syntax/ast/visitor.rs.html | 1117 ++ target/doc/src/regex_syntax/either.rs.html | 19 + target/doc/src/regex_syntax/error.rs.html | 643 + .../doc/src/regex_syntax/hir/interval.rs.html | 983 ++ .../src/regex_syntax/hir/literal/mod.rs.html | 3105 +++++ target/doc/src/regex_syntax/hir/mod.rs.html | 4387 +++++++ target/doc/src/regex_syntax/hir/print.rs.html | 753 ++ .../src/regex_syntax/hir/translate.rs.html | 5295 ++++++++ .../doc/src/regex_syntax/hir/visitor.rs.html | 447 + target/doc/src/regex_syntax/lib.rs.html | 459 + target/doc/src/regex_syntax/parser.rs.html | 415 + target/doc/src/regex_syntax/unicode.rs.html | 917 ++ .../regex_syntax/unicode_tables/age.rs.html | 1001 ++ .../case_folding_simple.rs.html | 1421 ++ .../unicode_tables/general_category.rs.html | 4071 ++++++ .../grapheme_cluster_break.rs.html | 921 ++ .../regex_syntax/unicode_tables/mod.rs.html | 27 + .../unicode_tables/perl_word.rs.html | 415 + .../unicode_tables/property_bool.rs.html | 6071 +++++++++ .../unicode_tables/property_names.rs.html | 305 + .../unicode_tables/property_values.rs.html | 669 + .../unicode_tables/script.rs.html | 1681 +++ .../unicode_tables/script_extension.rs.html | 1749 +++ .../unicode_tables/sentence_break.rs.html | 1315 ++ .../unicode_tables/word_break.rs.html | 729 ++ target/doc/src/thread_local/lib.rs.html | 1517 +++ target/doc/src/thread_local/thread_id.rs.html | 125 + .../doc/src/thread_local/unreachable.rs.html | 150 + target/doc/src/ucd_util/hangul.rs.html | 213 + target/doc/src/ucd_util/ideograph.rs.html | 169 + target/doc/src/ucd_util/lib.rs.html | 63 + target/doc/src/ucd_util/name.rs.html | 411 + target/doc/src/ucd_util/property.rs.html | 251 + .../unicode_tables/jamo_short_name.rs.html | 47 + .../src/ucd_util/unicode_tables/mod.rs.html | 13 + target/doc/src/utf8_ranges/char_utf8.rs.html | 75 + target/doc/src/utf8_ranges/lib.rs.html | 1071 ++ target/doc/storage.js | 1 + target/doc/theme.js | 39 + target/doc/thread_local/all.html | 3 + target/doc/thread_local/index.html | 61 + target/doc/thread_local/sidebar-items.js | 1 + .../struct.CachedThreadLocal.html | 43 + target/doc/thread_local/struct.IntoIter.html | 80 + target/doc/thread_local/struct.IterMut.html | 80 + .../doc/thread_local/struct.ThreadLocal.html | 42 + .../doc/thread_local/type.CachedIntoIter.html | 2 + .../doc/thread_local/type.CachedIterMut.html | 2 + target/doc/ucd_util/all.html | 3 + .../constant.RANGE_HANGUL_SYLLABLE.html | 4 + .../ucd_util/constant.RANGE_IDEOGRAPH.html | 3 + .../ucd_util/fn.canonical_property_name.html | 5 + .../ucd_util/fn.canonical_property_value.html | 8 + .../ucd_util/fn.character_name_normalize.html | 3 + ...n.hangul_full_canonical_decomposition.html | 8 + target/doc/ucd_util/fn.hangul_name.html | 5 + target/doc/ucd_util/fn.ideograph_name.html | 19 + target/doc/ucd_util/fn.property_values.html | 9 + .../ucd_util/fn.symbolic_name_normalize.html | 6 + .../constant.RANGE_HANGUL_SYLLABLE.html | 10 + ...n.hangul_full_canonical_decomposition.html | 10 + .../doc/ucd_util/hangul/fn.hangul_name.html | 10 + .../ideograph/constant.RANGE_IDEOGRAPH.html | 10 + .../ucd_util/ideograph/fn.ideograph_name.html | 10 + target/doc/ucd_util/index.html | 27 + .../name/fn.character_name_normalize.html | 10 + .../name/fn.symbolic_name_normalize.html | 10 + .../property/fn.canonical_property_name.html | 10 + .../property/fn.canonical_property_value.html | 10 + .../ucd_util/property/fn.property_values.html | 10 + .../ucd_util/property/type.PropertyTable.html | 10 + .../property/type.PropertyValueTable.html | 10 + .../property/type.PropertyValues.html | 10 + target/doc/ucd_util/sidebar-items.js | 1 + target/doc/ucd_util/type.PropertyTable.html | 5 + .../doc/ucd_util/type.PropertyValueTable.html | 11 + target/doc/ucd_util/type.PropertyValues.html | 5 + target/doc/utf8_ranges/all.html | 3 + target/doc/utf8_ranges/enum.Utf8Sequence.html | 43 + target/doc/utf8_ranges/index.html | 74 + target/doc/utf8_ranges/sidebar-items.js | 1 + target/doc/utf8_ranges/struct.Utf8Range.html | 27 + .../doc/utf8_ranges/struct.Utf8Sequences.html | 122 + target/doc/wheel.svg | 1 + 791 files changed, 150214 insertions(+), 4 deletions(-) create mode 100644 target/doc/.lock create mode 100644 target/doc/COPYRIGHT.txt create mode 100644 target/doc/FiraSans-LICENSE.txt create mode 100644 target/doc/FiraSans-Medium.woff create mode 100644 target/doc/FiraSans-Regular.woff create mode 100644 target/doc/LICENSE-APACHE.txt create mode 100644 target/doc/LICENSE-MIT.txt create mode 100644 target/doc/SourceCodePro-LICENSE.txt create mode 100644 target/doc/SourceCodePro-Regular.woff create mode 100644 target/doc/SourceCodePro-Semibold.woff create mode 100644 target/doc/SourceSerifPro-Bold.ttf.woff create mode 100644 target/doc/SourceSerifPro-It.ttf.woff create mode 100644 target/doc/SourceSerifPro-LICENSE.md create mode 100644 target/doc/SourceSerifPro-Regular.ttf.woff create mode 100644 target/doc/aho_corasick/ahocorasick/enum.MatchKind.html create mode 100644 target/doc/aho_corasick/ahocorasick/struct.AhoCorasick.html create mode 100644 target/doc/aho_corasick/ahocorasick/struct.AhoCorasickBuilder.html create mode 100644 target/doc/aho_corasick/ahocorasick/struct.FindIter.html create mode 100644 target/doc/aho_corasick/ahocorasick/struct.FindOverlappingIter.html create mode 100644 target/doc/aho_corasick/ahocorasick/struct.StreamFindIter.html create mode 100644 target/doc/aho_corasick/all.html create mode 100644 target/doc/aho_corasick/enum.ErrorKind.html create mode 100644 target/doc/aho_corasick/enum.MatchKind.html create mode 100644 target/doc/aho_corasick/error/enum.ErrorKind.html create mode 100644 target/doc/aho_corasick/error/struct.Error.html create mode 100644 target/doc/aho_corasick/index.html create mode 100644 target/doc/aho_corasick/sidebar-items.js create mode 100644 target/doc/aho_corasick/state_id/trait.StateID.html create mode 100644 target/doc/aho_corasick/struct.AhoCorasick.html create mode 100644 target/doc/aho_corasick/struct.AhoCorasickBuilder.html create mode 100644 target/doc/aho_corasick/struct.Error.html create mode 100644 target/doc/aho_corasick/struct.FindIter.html create mode 100644 target/doc/aho_corasick/struct.FindOverlappingIter.html create mode 100644 target/doc/aho_corasick/struct.Match.html create mode 100644 target/doc/aho_corasick/struct.StreamFindIter.html create mode 100644 target/doc/aho_corasick/trait.StateID.html create mode 100644 target/doc/aliases.js create mode 100644 target/doc/brush.svg create mode 100644 target/doc/c2_chacha/all.html create mode 100644 target/doc/c2_chacha/guts/index.html create mode 100644 target/doc/c2_chacha/guts/sidebar-items.js create mode 100644 target/doc/c2_chacha/guts/struct.ChaCha.html create mode 100644 target/doc/c2_chacha/guts/struct.State.html create mode 100644 target/doc/c2_chacha/guts/trait.Machine.html create mode 100644 target/doc/c2_chacha/index.html create mode 100644 target/doc/c2_chacha/sidebar-items.js create mode 100644 target/doc/cfg_if/all.html create mode 100644 target/doc/cfg_if/index.html create mode 100644 target/doc/cfg_if/macro.cfg_if!.html create mode 100644 target/doc/cfg_if/macro.cfg_if.html create mode 100644 target/doc/cfg_if/sidebar-items.js create mode 100644 target/doc/dark.css create mode 100644 target/doc/down-arrow.svg create mode 100644 target/doc/favicon.ico create mode 100644 target/doc/getrandom/all.html create mode 100644 target/doc/getrandom/error/struct.Error.html create mode 100644 target/doc/getrandom/fn.getrandom.html create mode 100644 target/doc/getrandom/index.html create mode 100644 target/doc/getrandom/sidebar-items.js create mode 100644 target/doc/getrandom/struct.Error.html create mode 100644 target/doc/implementors/aho_corasick/trait.StateID.js create mode 100644 target/doc/implementors/c2_chacha/guts/trait.Machine.js create mode 100644 target/doc/implementors/core/clone/trait.Clone.js create mode 100644 target/doc/implementors/core/cmp/trait.Eq.js create mode 100644 target/doc/implementors/core/cmp/trait.Ord.js create mode 100644 target/doc/implementors/core/cmp/trait.PartialEq.js create mode 100644 target/doc/implementors/core/cmp/trait.PartialOrd.js create mode 100644 target/doc/implementors/core/convert/trait.AsRef.js create mode 100644 target/doc/implementors/core/convert/trait.From.js create mode 100644 target/doc/implementors/core/convert/trait.Into.js create mode 100644 target/doc/implementors/core/default/trait.Default.js create mode 100644 target/doc/implementors/core/fmt/trait.Debug.js create mode 100644 target/doc/implementors/core/fmt/trait.Display.js create mode 100644 target/doc/implementors/core/hash/trait.Hash.js create mode 100644 target/doc/implementors/core/iter/traits/collect/trait.IntoIterator.js create mode 100644 target/doc/implementors/core/iter/traits/double_ended/trait.DoubleEndedIterator.js create mode 100644 target/doc/implementors/core/iter/traits/exact_size/trait.ExactSizeIterator.js create mode 100644 target/doc/implementors/core/iter/traits/iterator/trait.Iterator.js create mode 100644 target/doc/implementors/core/iter/traits/marker/trait.FusedIterator.js create mode 100644 target/doc/implementors/core/marker/trait.Copy.js create mode 100644 target/doc/implementors/core/marker/trait.Send.js create mode 100644 target/doc/implementors/core/marker/trait.Sync.js create mode 100644 target/doc/implementors/core/ops/deref/trait.Deref.js create mode 100644 target/doc/implementors/core/ops/deref/trait.DerefMut.js create mode 100644 target/doc/implementors/core/ops/drop/trait.Drop.js create mode 100644 target/doc/implementors/core/ops/index/trait.Index.js create mode 100644 target/doc/implementors/core/str/trait.FromStr.js create mode 100644 target/doc/implementors/owoify/trait.OwOifiable.js create mode 100644 target/doc/implementors/ppv_lite86/trait.Machine.js create mode 100644 target/doc/implementors/ppv_lite86/trait.Store.js create mode 100644 target/doc/implementors/ppv_lite86/trait.VZip.js create mode 100644 target/doc/implementors/rand/distributions/trait.Distribution.js create mode 100644 target/doc/implementors/rand/distributions/uniform/trait.SampleBorrow.js create mode 100644 target/doc/implementors/rand/distributions/uniform/trait.SampleUniform.js create mode 100644 target/doc/implementors/rand/distributions/uniform/trait.UniformSampler.js create mode 100644 target/doc/implementors/rand/distributions/weighted/alias_method/trait.Weight.js create mode 100644 target/doc/implementors/rand/seq/trait.IteratorRandom.js create mode 100644 target/doc/implementors/rand/seq/trait.SliceRandom.js create mode 100644 target/doc/implementors/rand/trait.AsByteSliceMut.js create mode 100644 target/doc/implementors/rand/trait.CryptoRng.js create mode 100644 target/doc/implementors/rand/trait.Rng.js create mode 100644 target/doc/implementors/rand/trait.RngCore.js create mode 100644 target/doc/implementors/rand/trait.SeedableRng.js create mode 100644 target/doc/implementors/rand_core/block/trait.BlockRngCore.js create mode 100644 target/doc/implementors/rand_core/trait.CryptoRng.js create mode 100644 target/doc/implementors/rand_core/trait.RngCore.js create mode 100644 target/doc/implementors/rand_core/trait.SeedableRng.js create mode 100644 target/doc/implementors/regex/bytes/trait.Replacer.js create mode 100644 target/doc/implementors/regex/trait.Replacer.js create mode 100644 target/doc/implementors/std/error/trait.Error.js create mode 100644 target/doc/implementors/std/io/trait.Read.js create mode 100644 target/doc/implementors/std/panic/trait.UnwindSafe.js create mode 100644 target/doc/lazy_static/all.html create mode 100644 target/doc/lazy_static/fn.initialize.html create mode 100644 target/doc/lazy_static/index.html create mode 100644 target/doc/lazy_static/macro.lazy_static!.html create mode 100644 target/doc/lazy_static/macro.lazy_static.html create mode 100644 target/doc/lazy_static/sidebar-items.js create mode 100644 target/doc/lazy_static/trait.LazyStatic.html create mode 100644 target/doc/light.css create mode 100644 target/doc/main.js create mode 100644 target/doc/memchr/all.html create mode 100644 target/doc/memchr/fn.memchr.html create mode 100644 target/doc/memchr/fn.memchr2.html create mode 100644 target/doc/memchr/fn.memchr2_iter.html create mode 100644 target/doc/memchr/fn.memchr3.html create mode 100644 target/doc/memchr/fn.memchr3_iter.html create mode 100644 target/doc/memchr/fn.memchr_iter.html create mode 100644 target/doc/memchr/fn.memrchr.html create mode 100644 target/doc/memchr/fn.memrchr2.html create mode 100644 target/doc/memchr/fn.memrchr2_iter.html create mode 100644 target/doc/memchr/fn.memrchr3.html create mode 100644 target/doc/memchr/fn.memrchr3_iter.html create mode 100644 target/doc/memchr/fn.memrchr_iter.html create mode 100644 target/doc/memchr/index.html create mode 100644 target/doc/memchr/iter/struct.Memchr.html create mode 100644 target/doc/memchr/iter/struct.Memchr2.html create mode 100644 target/doc/memchr/iter/struct.Memchr3.html create mode 100644 target/doc/memchr/sidebar-items.js create mode 100644 target/doc/memchr/struct.Memchr.html create mode 100644 target/doc/memchr/struct.Memchr2.html create mode 100644 target/doc/memchr/struct.Memchr3.html create mode 100644 target/doc/normalize.css create mode 100644 target/doc/noscript.css create mode 100644 target/doc/owoify/all.html create mode 100644 target/doc/owoify/index.html create mode 100644 target/doc/owoify/sidebar-items.js create mode 100644 target/doc/owoify/trait.OwOifiable.html create mode 100644 target/doc/ppv_lite86/all.html create mode 100644 target/doc/ppv_lite86/index.html create mode 100644 target/doc/ppv_lite86/macro.dispatch!.html create mode 100644 target/doc/ppv_lite86/macro.dispatch.html create mode 100644 target/doc/ppv_lite86/macro.dispatch_light128!.html create mode 100644 target/doc/ppv_lite86/macro.dispatch_light128.html create mode 100644 target/doc/ppv_lite86/macro.dispatch_light256!.html create mode 100644 target/doc/ppv_lite86/macro.dispatch_light256.html create mode 100644 target/doc/ppv_lite86/sidebar-items.js create mode 100644 target/doc/ppv_lite86/trait.AndNot.html create mode 100644 target/doc/ppv_lite86/trait.ArithOps.html create mode 100644 target/doc/ppv_lite86/trait.BSwap.html create mode 100644 target/doc/ppv_lite86/trait.BitOps0.html create mode 100644 target/doc/ppv_lite86/trait.BitOps128.html create mode 100644 target/doc/ppv_lite86/trait.BitOps32.html create mode 100644 target/doc/ppv_lite86/trait.BitOps64.html create mode 100644 target/doc/ppv_lite86/trait.LaneWords4.html create mode 100644 target/doc/ppv_lite86/trait.Machine.html create mode 100644 target/doc/ppv_lite86/trait.MultiLane.html create mode 100644 target/doc/ppv_lite86/trait.RotateEachWord128.html create mode 100644 target/doc/ppv_lite86/trait.RotateEachWord32.html create mode 100644 target/doc/ppv_lite86/trait.RotateEachWord64.html create mode 100644 target/doc/ppv_lite86/trait.Store.html create mode 100644 target/doc/ppv_lite86/trait.StoreBytes.html create mode 100644 target/doc/ppv_lite86/trait.Swap64.html create mode 100644 target/doc/ppv_lite86/trait.UnsafeFrom.html create mode 100644 target/doc/ppv_lite86/trait.VZip.html create mode 100644 target/doc/ppv_lite86/trait.Vec2.html create mode 100644 target/doc/ppv_lite86/trait.Vec4.html create mode 100644 target/doc/ppv_lite86/trait.Words4.html create mode 100644 target/doc/ppv_lite86/trait.u128x1.html create mode 100644 target/doc/ppv_lite86/trait.u128x2.html create mode 100644 target/doc/ppv_lite86/trait.u128x4.html create mode 100644 target/doc/ppv_lite86/trait.u32x4.html create mode 100644 target/doc/ppv_lite86/trait.u32x4x2.html create mode 100644 target/doc/ppv_lite86/trait.u32x4x4.html create mode 100644 target/doc/ppv_lite86/trait.u64x2.html create mode 100644 target/doc/ppv_lite86/trait.u64x2x2.html create mode 100644 target/doc/ppv_lite86/trait.u64x2x4.html create mode 100644 target/doc/ppv_lite86/trait.u64x4.html create mode 100644 target/doc/ppv_lite86/types/trait.AndNot.html create mode 100644 target/doc/ppv_lite86/types/trait.ArithOps.html create mode 100644 target/doc/ppv_lite86/types/trait.BSwap.html create mode 100644 target/doc/ppv_lite86/types/trait.BitOps0.html create mode 100644 target/doc/ppv_lite86/types/trait.BitOps128.html create mode 100644 target/doc/ppv_lite86/types/trait.BitOps32.html create mode 100644 target/doc/ppv_lite86/types/trait.BitOps64.html create mode 100644 target/doc/ppv_lite86/types/trait.Machine.html create mode 100644 target/doc/ppv_lite86/types/trait.RotateEachWord128.html create mode 100644 target/doc/ppv_lite86/types/trait.RotateEachWord32.html create mode 100644 target/doc/ppv_lite86/types/trait.RotateEachWord64.html create mode 100644 target/doc/ppv_lite86/types/trait.Store.html create mode 100644 target/doc/ppv_lite86/types/trait.StoreBytes.html create mode 100644 target/doc/ppv_lite86/types/types/trait.LaneWords4.html create mode 100644 target/doc/ppv_lite86/types/types/trait.MultiLane.html create mode 100644 target/doc/ppv_lite86/types/types/trait.Swap64.html create mode 100644 target/doc/ppv_lite86/types/types/trait.UnsafeFrom.html create mode 100644 target/doc/ppv_lite86/types/types/trait.VZip.html create mode 100644 target/doc/ppv_lite86/types/types/trait.Vec2.html create mode 100644 target/doc/ppv_lite86/types/types/trait.Vec4.html create mode 100644 target/doc/ppv_lite86/types/types/trait.Words4.html create mode 100644 target/doc/ppv_lite86/types/types/trait.u128x1.html create mode 100644 target/doc/ppv_lite86/types/types/trait.u128x2.html create mode 100644 target/doc/ppv_lite86/types/types/trait.u128x4.html create mode 100644 target/doc/ppv_lite86/types/types/trait.u32x4.html create mode 100644 target/doc/ppv_lite86/types/types/trait.u32x4x2.html create mode 100644 target/doc/ppv_lite86/types/types/trait.u32x4x4.html create mode 100644 target/doc/ppv_lite86/types/types/trait.u64x2.html create mode 100644 target/doc/ppv_lite86/types/types/trait.u64x2x2.html create mode 100644 target/doc/ppv_lite86/types/types/trait.u64x2x4.html create mode 100644 target/doc/ppv_lite86/types/types/trait.u64x4.html create mode 100644 target/doc/ppv_lite86/x86_64/index.html create mode 100644 target/doc/ppv_lite86/x86_64/sidebar-items.js create mode 100644 target/doc/ppv_lite86/x86_64/struct.Avx2Machine.html create mode 100644 target/doc/ppv_lite86/x86_64/struct.NoA1.html create mode 100644 target/doc/ppv_lite86/x86_64/struct.NoA2.html create mode 100644 target/doc/ppv_lite86/x86_64/struct.NoNI.html create mode 100644 target/doc/ppv_lite86/x86_64/struct.NoS3.html create mode 100644 target/doc/ppv_lite86/x86_64/struct.NoS4.html create mode 100644 target/doc/ppv_lite86/x86_64/struct.SseMachine.html create mode 100644 target/doc/ppv_lite86/x86_64/struct.YesA1.html create mode 100644 target/doc/ppv_lite86/x86_64/struct.YesA2.html create mode 100644 target/doc/ppv_lite86/x86_64/struct.YesNI.html create mode 100644 target/doc/ppv_lite86/x86_64/struct.YesS3.html create mode 100644 target/doc/ppv_lite86/x86_64/struct.YesS4.html create mode 100644 target/doc/ppv_lite86/x86_64/type.AVX.html create mode 100644 target/doc/ppv_lite86/x86_64/type.AVX2.html create mode 100644 target/doc/ppv_lite86/x86_64/type.SSE2.html create mode 100644 target/doc/ppv_lite86/x86_64/type.SSE41.html create mode 100644 target/doc/ppv_lite86/x86_64/type.SSSE3.html create mode 100644 target/doc/ppv_lite86/x86_64/union.vec128_storage.html create mode 100644 target/doc/ppv_lite86/x86_64/union.vec256_storage.html create mode 100644 target/doc/ppv_lite86/x86_64/union.vec512_storage.html create mode 100644 target/doc/rand/all.html create mode 100644 target/doc/rand/distributions/bernoulli/enum.BernoulliError.html create mode 100644 target/doc/rand/distributions/bernoulli/struct.Bernoulli.html create mode 100644 target/doc/rand/distributions/binomial/struct.Binomial.html create mode 100644 target/doc/rand/distributions/cauchy/struct.Cauchy.html create mode 100644 target/doc/rand/distributions/dirichlet/struct.Dirichlet.html create mode 100644 target/doc/rand/distributions/enum.BernoulliError.html create mode 100644 target/doc/rand/distributions/exponential/struct.Exp.html create mode 100644 target/doc/rand/distributions/exponential/struct.Exp1.html create mode 100644 target/doc/rand/distributions/float/struct.Open01.html create mode 100644 target/doc/rand/distributions/float/struct.OpenClosed01.html create mode 100644 target/doc/rand/distributions/gamma/struct.Beta.html create mode 100644 target/doc/rand/distributions/gamma/struct.ChiSquared.html create mode 100644 target/doc/rand/distributions/gamma/struct.FisherF.html create mode 100644 target/doc/rand/distributions/gamma/struct.Gamma.html create mode 100644 target/doc/rand/distributions/gamma/struct.StudentT.html create mode 100644 target/doc/rand/distributions/index.html create mode 100644 target/doc/rand/distributions/normal/struct.LogNormal.html create mode 100644 target/doc/rand/distributions/normal/struct.Normal.html create mode 100644 target/doc/rand/distributions/normal/struct.StandardNormal.html create mode 100644 target/doc/rand/distributions/other/struct.Alphanumeric.html create mode 100644 target/doc/rand/distributions/pareto/struct.Pareto.html create mode 100644 target/doc/rand/distributions/poisson/struct.Poisson.html create mode 100644 target/doc/rand/distributions/sidebar-items.js create mode 100644 target/doc/rand/distributions/struct.Alphanumeric.html create mode 100644 target/doc/rand/distributions/struct.Bernoulli.html create mode 100644 target/doc/rand/distributions/struct.Beta.html create mode 100644 target/doc/rand/distributions/struct.Binomial.html create mode 100644 target/doc/rand/distributions/struct.Cauchy.html create mode 100644 target/doc/rand/distributions/struct.ChiSquared.html create mode 100644 target/doc/rand/distributions/struct.Dirichlet.html create mode 100644 target/doc/rand/distributions/struct.DistIter.html create mode 100644 target/doc/rand/distributions/struct.Exp.html create mode 100644 target/doc/rand/distributions/struct.Exp1.html create mode 100644 target/doc/rand/distributions/struct.FisherF.html create mode 100644 target/doc/rand/distributions/struct.Gamma.html create mode 100644 target/doc/rand/distributions/struct.LogNormal.html create mode 100644 target/doc/rand/distributions/struct.Normal.html create mode 100644 target/doc/rand/distributions/struct.Open01.html create mode 100644 target/doc/rand/distributions/struct.OpenClosed01.html create mode 100644 target/doc/rand/distributions/struct.Pareto.html create mode 100644 target/doc/rand/distributions/struct.Poisson.html create mode 100644 target/doc/rand/distributions/struct.Standard.html create mode 100644 target/doc/rand/distributions/struct.StandardNormal.html create mode 100644 target/doc/rand/distributions/struct.StudentT.html create mode 100644 target/doc/rand/distributions/struct.Triangular.html create mode 100644 target/doc/rand/distributions/struct.Uniform.html create mode 100644 target/doc/rand/distributions/struct.UnitCircle.html create mode 100644 target/doc/rand/distributions/struct.UnitSphereSurface.html create mode 100644 target/doc/rand/distributions/struct.Weibull.html create mode 100644 target/doc/rand/distributions/trait.Distribution.html create mode 100644 target/doc/rand/distributions/triangular/struct.Triangular.html create mode 100644 target/doc/rand/distributions/uniform/index.html create mode 100644 target/doc/rand/distributions/uniform/sidebar-items.js create mode 100644 target/doc/rand/distributions/uniform/struct.Uniform.html create mode 100644 target/doc/rand/distributions/uniform/struct.UniformDuration.html create mode 100644 target/doc/rand/distributions/uniform/struct.UniformFloat.html create mode 100644 target/doc/rand/distributions/uniform/struct.UniformInt.html create mode 100644 target/doc/rand/distributions/uniform/trait.SampleBorrow.html create mode 100644 target/doc/rand/distributions/uniform/trait.SampleUniform.html create mode 100644 target/doc/rand/distributions/uniform/trait.UniformSampler.html create mode 100644 target/doc/rand/distributions/unit_circle/struct.UnitCircle.html create mode 100644 target/doc/rand/distributions/unit_sphere/struct.UnitSphereSurface.html create mode 100644 target/doc/rand/distributions/weibull/struct.Weibull.html create mode 100644 target/doc/rand/distributions/weighted/alias_method/index.html create mode 100644 target/doc/rand/distributions/weighted/alias_method/sidebar-items.js create mode 100644 target/doc/rand/distributions/weighted/alias_method/struct.WeightedIndex.html create mode 100644 target/doc/rand/distributions/weighted/alias_method/trait.Weight.html create mode 100644 target/doc/rand/distributions/weighted/enum.WeightedError.html create mode 100644 target/doc/rand/distributions/weighted/index.html create mode 100644 target/doc/rand/distributions/weighted/sidebar-items.js create mode 100644 target/doc/rand/distributions/weighted/struct.WeightedIndex.html create mode 100644 target/doc/rand/fn.random.html create mode 100644 target/doc/rand/fn.thread_rng.html create mode 100644 target/doc/rand/index.html create mode 100644 target/doc/rand/prelude/index.html create mode 100644 target/doc/rand/prelude/sidebar-items.js create mode 100644 target/doc/rand/rngs/adapter/index.html create mode 100644 target/doc/rand/rngs/adapter/read/struct.ReadError.html create mode 100644 target/doc/rand/rngs/adapter/read/struct.ReadRng.html create mode 100644 target/doc/rand/rngs/adapter/reseeding/struct.ReseedingRng.html create mode 100644 target/doc/rand/rngs/adapter/sidebar-items.js create mode 100644 target/doc/rand/rngs/adapter/struct.ReadError.html create mode 100644 target/doc/rand/rngs/adapter/struct.ReadRng.html create mode 100644 target/doc/rand/rngs/adapter/struct.ReseedingRng.html create mode 100644 target/doc/rand/rngs/entropy/struct.EntropyRng.html create mode 100644 target/doc/rand/rngs/index.html create mode 100644 target/doc/rand/rngs/mock/index.html create mode 100644 target/doc/rand/rngs/mock/sidebar-items.js create mode 100644 target/doc/rand/rngs/mock/struct.StepRng.html create mode 100644 target/doc/rand/rngs/os/struct.OsRng.html create mode 100644 target/doc/rand/rngs/sidebar-items.js create mode 100644 target/doc/rand/rngs/std/struct.StdRng.html create mode 100644 target/doc/rand/rngs/struct.EntropyRng.html create mode 100644 target/doc/rand/rngs/struct.OsRng.html create mode 100644 target/doc/rand/rngs/struct.StdRng.html create mode 100644 target/doc/rand/rngs/struct.ThreadRng.html create mode 100644 target/doc/rand/rngs/thread/fn.thread_rng.html create mode 100644 target/doc/rand/rngs/thread/struct.ThreadRng.html create mode 100644 target/doc/rand/seq/index.html create mode 100644 target/doc/rand/seq/index/enum.IndexVec.html create mode 100644 target/doc/rand/seq/index/enum.IndexVecIntoIter.html create mode 100644 target/doc/rand/seq/index/enum.IndexVecIter.html create mode 100644 target/doc/rand/seq/index/fn.sample.html create mode 100644 target/doc/rand/seq/index/index.html create mode 100644 target/doc/rand/seq/index/sidebar-items.js create mode 100644 target/doc/rand/seq/sidebar-items.js create mode 100644 target/doc/rand/seq/struct.SliceChooseIter.html create mode 100644 target/doc/rand/seq/trait.IteratorRandom.html create mode 100644 target/doc/rand/seq/trait.SliceRandom.html create mode 100644 target/doc/rand/sidebar-items.js create mode 100644 target/doc/rand/struct.Error.html create mode 100644 target/doc/rand/trait.AsByteSliceMut.html create mode 100644 target/doc/rand/trait.CryptoRng.html create mode 100644 target/doc/rand/trait.Rng.html create mode 100644 target/doc/rand/trait.RngCore.html create mode 100644 target/doc/rand/trait.SeedableRng.html create mode 100644 target/doc/rand_chacha/all.html create mode 100644 target/doc/rand_chacha/chacha/struct.ChaCha12Core.html create mode 100644 target/doc/rand_chacha/chacha/struct.ChaCha12Rng.html create mode 100644 target/doc/rand_chacha/chacha/struct.ChaCha20Core.html create mode 100644 target/doc/rand_chacha/chacha/struct.ChaCha20Rng.html create mode 100644 target/doc/rand_chacha/chacha/struct.ChaCha8Core.html create mode 100644 target/doc/rand_chacha/chacha/struct.ChaCha8Rng.html create mode 100644 target/doc/rand_chacha/index.html create mode 100644 target/doc/rand_chacha/sidebar-items.js create mode 100644 target/doc/rand_chacha/struct.ChaCha12Core.html create mode 100644 target/doc/rand_chacha/struct.ChaCha12Rng.html create mode 100644 target/doc/rand_chacha/struct.ChaCha20Core.html create mode 100644 target/doc/rand_chacha/struct.ChaCha20Rng.html create mode 100644 target/doc/rand_chacha/struct.ChaCha8Core.html create mode 100644 target/doc/rand_chacha/struct.ChaCha8Rng.html create mode 100644 target/doc/rand_chacha/type.ChaChaCore.html create mode 100644 target/doc/rand_chacha/type.ChaChaRng.html create mode 100644 target/doc/rand_core/all.html create mode 100644 target/doc/rand_core/block/index.html create mode 100644 target/doc/rand_core/block/sidebar-items.js create mode 100644 target/doc/rand_core/block/struct.BlockRng.html create mode 100644 target/doc/rand_core/block/struct.BlockRng64.html create mode 100644 target/doc/rand_core/block/trait.BlockRngCore.html create mode 100644 target/doc/rand_core/error/struct.Error.html create mode 100644 target/doc/rand_core/impls/fn.fill_bytes_via_next.html create mode 100644 target/doc/rand_core/impls/fn.fill_via_u32_chunks.html create mode 100644 target/doc/rand_core/impls/fn.fill_via_u64_chunks.html create mode 100644 target/doc/rand_core/impls/fn.next_u32_via_fill.html create mode 100644 target/doc/rand_core/impls/fn.next_u64_via_fill.html create mode 100644 target/doc/rand_core/impls/fn.next_u64_via_u32.html create mode 100644 target/doc/rand_core/impls/index.html create mode 100644 target/doc/rand_core/impls/sidebar-items.js create mode 100644 target/doc/rand_core/index.html create mode 100644 target/doc/rand_core/le/fn.read_u32_into.html create mode 100644 target/doc/rand_core/le/fn.read_u64_into.html create mode 100644 target/doc/rand_core/le/index.html create mode 100644 target/doc/rand_core/le/sidebar-items.js create mode 100644 target/doc/rand_core/sidebar-items.js create mode 100644 target/doc/rand_core/struct.Error.html create mode 100644 target/doc/rand_core/trait.CryptoRng.html create mode 100644 target/doc/rand_core/trait.RngCore.html create mode 100644 target/doc/rand_core/trait.SeedableRng.html create mode 100644 target/doc/regex/all.html create mode 100644 target/doc/regex/bytes/index.html create mode 100644 target/doc/regex/bytes/sidebar-items.js create mode 100644 target/doc/regex/bytes/struct.CaptureLocations.html create mode 100644 target/doc/regex/bytes/struct.CaptureMatches.html create mode 100644 target/doc/regex/bytes/struct.CaptureNames.html create mode 100644 target/doc/regex/bytes/struct.Captures.html create mode 100644 target/doc/regex/bytes/struct.Match.html create mode 100644 target/doc/regex/bytes/struct.Matches.html create mode 100644 target/doc/regex/bytes/struct.NoExpand.html create mode 100644 target/doc/regex/bytes/struct.Regex.html create mode 100644 target/doc/regex/bytes/struct.RegexBuilder.html create mode 100644 target/doc/regex/bytes/struct.RegexSet.html create mode 100644 target/doc/regex/bytes/struct.RegexSetBuilder.html create mode 100644 target/doc/regex/bytes/struct.ReplacerRef.html create mode 100644 target/doc/regex/bytes/struct.SetMatches.html create mode 100644 target/doc/regex/bytes/struct.SetMatchesIntoIter.html create mode 100644 target/doc/regex/bytes/struct.SetMatchesIter.html create mode 100644 target/doc/regex/bytes/struct.Split.html create mode 100644 target/doc/regex/bytes/struct.SplitN.html create mode 100644 target/doc/regex/bytes/struct.SubCaptureMatches.html create mode 100644 target/doc/regex/bytes/trait.Replacer.html create mode 100644 target/doc/regex/enum.Error.html create mode 100644 target/doc/regex/error/enum.Error.html create mode 100644 target/doc/regex/fn.escape.html create mode 100644 target/doc/regex/index.html create mode 100644 target/doc/regex/re_builder/bytes/struct.RegexBuilder.html create mode 100644 target/doc/regex/re_builder/set_bytes/struct.RegexSetBuilder.html create mode 100644 target/doc/regex/re_builder/set_unicode/struct.RegexSetBuilder.html create mode 100644 target/doc/regex/re_builder/unicode/struct.RegexBuilder.html create mode 100644 target/doc/regex/re_bytes/struct.CaptureLocations.html create mode 100644 target/doc/regex/re_bytes/struct.CaptureMatches.html create mode 100644 target/doc/regex/re_bytes/struct.CaptureNames.html create mode 100644 target/doc/regex/re_bytes/struct.Captures.html create mode 100644 target/doc/regex/re_bytes/struct.Match.html create mode 100644 target/doc/regex/re_bytes/struct.Matches.html create mode 100644 target/doc/regex/re_bytes/struct.NoExpand.html create mode 100644 target/doc/regex/re_bytes/struct.Regex.html create mode 100644 target/doc/regex/re_bytes/struct.ReplacerRef.html create mode 100644 target/doc/regex/re_bytes/struct.Split.html create mode 100644 target/doc/regex/re_bytes/struct.SplitN.html create mode 100644 target/doc/regex/re_bytes/struct.SubCaptureMatches.html create mode 100644 target/doc/regex/re_bytes/trait.Replacer.html create mode 100644 target/doc/regex/re_set/bytes/struct.RegexSet.html create mode 100644 target/doc/regex/re_set/bytes/struct.SetMatches.html create mode 100644 target/doc/regex/re_set/bytes/struct.SetMatchesIntoIter.html create mode 100644 target/doc/regex/re_set/bytes/struct.SetMatchesIter.html create mode 100644 target/doc/regex/re_set/unicode/struct.RegexSet.html create mode 100644 target/doc/regex/re_set/unicode/struct.SetMatches.html create mode 100644 target/doc/regex/re_set/unicode/struct.SetMatchesIntoIter.html create mode 100644 target/doc/regex/re_set/unicode/struct.SetMatchesIter.html create mode 100644 target/doc/regex/re_unicode/fn.escape.html create mode 100644 target/doc/regex/re_unicode/struct.CaptureLocations.html create mode 100644 target/doc/regex/re_unicode/struct.CaptureMatches.html create mode 100644 target/doc/regex/re_unicode/struct.CaptureNames.html create mode 100644 target/doc/regex/re_unicode/struct.Captures.html create mode 100644 target/doc/regex/re_unicode/struct.Match.html create mode 100644 target/doc/regex/re_unicode/struct.Matches.html create mode 100644 target/doc/regex/re_unicode/struct.NoExpand.html create mode 100644 target/doc/regex/re_unicode/struct.Regex.html create mode 100644 target/doc/regex/re_unicode/struct.ReplacerRef.html create mode 100644 target/doc/regex/re_unicode/struct.Split.html create mode 100644 target/doc/regex/re_unicode/struct.SplitN.html create mode 100644 target/doc/regex/re_unicode/struct.SubCaptureMatches.html create mode 100644 target/doc/regex/re_unicode/trait.Replacer.html create mode 100644 target/doc/regex/sidebar-items.js create mode 100644 target/doc/regex/struct.CaptureLocations.html create mode 100644 target/doc/regex/struct.CaptureMatches.html create mode 100644 target/doc/regex/struct.CaptureNames.html create mode 100644 target/doc/regex/struct.Captures.html create mode 100644 target/doc/regex/struct.Match.html create mode 100644 target/doc/regex/struct.Matches.html create mode 100644 target/doc/regex/struct.NoExpand.html create mode 100644 target/doc/regex/struct.Regex.html create mode 100644 target/doc/regex/struct.RegexBuilder.html create mode 100644 target/doc/regex/struct.RegexSet.html create mode 100644 target/doc/regex/struct.RegexSetBuilder.html create mode 100644 target/doc/regex/struct.ReplacerRef.html create mode 100644 target/doc/regex/struct.SetMatches.html create mode 100644 target/doc/regex/struct.SetMatchesIntoIter.html create mode 100644 target/doc/regex/struct.SetMatchesIter.html create mode 100644 target/doc/regex/struct.Split.html create mode 100644 target/doc/regex/struct.SplitN.html create mode 100644 target/doc/regex/struct.SubCaptureMatches.html create mode 100644 target/doc/regex/trait.Replacer.html create mode 100644 target/doc/regex_syntax/all.html create mode 100644 target/doc/regex_syntax/ast/enum.AssertionKind.html create mode 100644 target/doc/regex_syntax/ast/enum.Ast.html create mode 100644 target/doc/regex_syntax/ast/enum.Class.html create mode 100644 target/doc/regex_syntax/ast/enum.ClassAsciiKind.html create mode 100644 target/doc/regex_syntax/ast/enum.ClassPerlKind.html create mode 100644 target/doc/regex_syntax/ast/enum.ClassSet.html create mode 100644 target/doc/regex_syntax/ast/enum.ClassSetBinaryOpKind.html create mode 100644 target/doc/regex_syntax/ast/enum.ClassSetItem.html create mode 100644 target/doc/regex_syntax/ast/enum.ClassUnicodeKind.html create mode 100644 target/doc/regex_syntax/ast/enum.ClassUnicodeOpKind.html create mode 100644 target/doc/regex_syntax/ast/enum.ErrorKind.html create mode 100644 target/doc/regex_syntax/ast/enum.Flag.html create mode 100644 target/doc/regex_syntax/ast/enum.FlagsItemKind.html create mode 100644 target/doc/regex_syntax/ast/enum.GroupKind.html create mode 100644 target/doc/regex_syntax/ast/enum.HexLiteralKind.html create mode 100644 target/doc/regex_syntax/ast/enum.LiteralKind.html create mode 100644 target/doc/regex_syntax/ast/enum.RepetitionKind.html create mode 100644 target/doc/regex_syntax/ast/enum.RepetitionRange.html create mode 100644 target/doc/regex_syntax/ast/enum.SpecialLiteralKind.html create mode 100644 target/doc/regex_syntax/ast/fn.visit.html create mode 100644 target/doc/regex_syntax/ast/index.html create mode 100644 target/doc/regex_syntax/ast/parse/index.html create mode 100644 target/doc/regex_syntax/ast/parse/sidebar-items.js create mode 100644 target/doc/regex_syntax/ast/parse/struct.Parser.html create mode 100644 target/doc/regex_syntax/ast/parse/struct.ParserBuilder.html create mode 100644 target/doc/regex_syntax/ast/print/index.html create mode 100644 target/doc/regex_syntax/ast/print/sidebar-items.js create mode 100644 target/doc/regex_syntax/ast/print/struct.Printer.html create mode 100644 target/doc/regex_syntax/ast/sidebar-items.js create mode 100644 target/doc/regex_syntax/ast/struct.Alternation.html create mode 100644 target/doc/regex_syntax/ast/struct.Assertion.html create mode 100644 target/doc/regex_syntax/ast/struct.CaptureName.html create mode 100644 target/doc/regex_syntax/ast/struct.ClassAscii.html create mode 100644 target/doc/regex_syntax/ast/struct.ClassBracketed.html create mode 100644 target/doc/regex_syntax/ast/struct.ClassPerl.html create mode 100644 target/doc/regex_syntax/ast/struct.ClassSetBinaryOp.html create mode 100644 target/doc/regex_syntax/ast/struct.ClassSetRange.html create mode 100644 target/doc/regex_syntax/ast/struct.ClassSetUnion.html create mode 100644 target/doc/regex_syntax/ast/struct.ClassUnicode.html create mode 100644 target/doc/regex_syntax/ast/struct.Comment.html create mode 100644 target/doc/regex_syntax/ast/struct.Concat.html create mode 100644 target/doc/regex_syntax/ast/struct.Error.html create mode 100644 target/doc/regex_syntax/ast/struct.Flags.html create mode 100644 target/doc/regex_syntax/ast/struct.FlagsItem.html create mode 100644 target/doc/regex_syntax/ast/struct.Group.html create mode 100644 target/doc/regex_syntax/ast/struct.Literal.html create mode 100644 target/doc/regex_syntax/ast/struct.Position.html create mode 100644 target/doc/regex_syntax/ast/struct.Repetition.html create mode 100644 target/doc/regex_syntax/ast/struct.RepetitionOp.html create mode 100644 target/doc/regex_syntax/ast/struct.SetFlags.html create mode 100644 target/doc/regex_syntax/ast/struct.Span.html create mode 100644 target/doc/regex_syntax/ast/struct.WithComments.html create mode 100644 target/doc/regex_syntax/ast/trait.Visitor.html create mode 100644 target/doc/regex_syntax/ast/visitor/fn.visit.html create mode 100644 target/doc/regex_syntax/ast/visitor/trait.Visitor.html create mode 100644 target/doc/regex_syntax/enum.Error.html create mode 100644 target/doc/regex_syntax/error/enum.Error.html create mode 100644 target/doc/regex_syntax/error/type.Result.html create mode 100644 target/doc/regex_syntax/fn.escape.html create mode 100644 target/doc/regex_syntax/fn.escape_into.html create mode 100644 target/doc/regex_syntax/fn.is_meta_character.html create mode 100644 target/doc/regex_syntax/fn.is_word_byte.html create mode 100644 target/doc/regex_syntax/fn.is_word_character.html create mode 100644 target/doc/regex_syntax/hir/enum.Anchor.html create mode 100644 target/doc/regex_syntax/hir/enum.Class.html create mode 100644 target/doc/regex_syntax/hir/enum.ErrorKind.html create mode 100644 target/doc/regex_syntax/hir/enum.GroupKind.html create mode 100644 target/doc/regex_syntax/hir/enum.HirKind.html create mode 100644 target/doc/regex_syntax/hir/enum.Literal.html create mode 100644 target/doc/regex_syntax/hir/enum.RepetitionKind.html create mode 100644 target/doc/regex_syntax/hir/enum.RepetitionRange.html create mode 100644 target/doc/regex_syntax/hir/enum.WordBoundary.html create mode 100644 target/doc/regex_syntax/hir/fn.visit.html create mode 100644 target/doc/regex_syntax/hir/index.html create mode 100644 target/doc/regex_syntax/hir/literal/index.html create mode 100644 target/doc/regex_syntax/hir/literal/sidebar-items.js create mode 100644 target/doc/regex_syntax/hir/literal/struct.Literal.html create mode 100644 target/doc/regex_syntax/hir/literal/struct.Literals.html create mode 100644 target/doc/regex_syntax/hir/print/index.html create mode 100644 target/doc/regex_syntax/hir/print/sidebar-items.js create mode 100644 target/doc/regex_syntax/hir/print/struct.Printer.html create mode 100644 target/doc/regex_syntax/hir/sidebar-items.js create mode 100644 target/doc/regex_syntax/hir/struct.ClassBytes.html create mode 100644 target/doc/regex_syntax/hir/struct.ClassBytesIter.html create mode 100644 target/doc/regex_syntax/hir/struct.ClassBytesRange.html create mode 100644 target/doc/regex_syntax/hir/struct.ClassUnicode.html create mode 100644 target/doc/regex_syntax/hir/struct.ClassUnicodeIter.html create mode 100644 target/doc/regex_syntax/hir/struct.ClassUnicodeRange.html create mode 100644 target/doc/regex_syntax/hir/struct.Error.html create mode 100644 target/doc/regex_syntax/hir/struct.Group.html create mode 100644 target/doc/regex_syntax/hir/struct.Hir.html create mode 100644 target/doc/regex_syntax/hir/struct.Repetition.html create mode 100644 target/doc/regex_syntax/hir/trait.Visitor.html create mode 100644 target/doc/regex_syntax/hir/translate/index.html create mode 100644 target/doc/regex_syntax/hir/translate/sidebar-items.js create mode 100644 target/doc/regex_syntax/hir/translate/struct.Translator.html create mode 100644 target/doc/regex_syntax/hir/translate/struct.TranslatorBuilder.html create mode 100644 target/doc/regex_syntax/hir/visitor/fn.visit.html create mode 100644 target/doc/regex_syntax/hir/visitor/trait.Visitor.html create mode 100644 target/doc/regex_syntax/index.html create mode 100644 target/doc/regex_syntax/parser/struct.Parser.html create mode 100644 target/doc/regex_syntax/parser/struct.ParserBuilder.html create mode 100644 target/doc/regex_syntax/sidebar-items.js create mode 100644 target/doc/regex_syntax/struct.Parser.html create mode 100644 target/doc/regex_syntax/struct.ParserBuilder.html create mode 100644 target/doc/regex_syntax/type.Result.html create mode 100644 target/doc/rust-logo.png create mode 100644 target/doc/rustdoc.css create mode 100644 target/doc/search-index.js create mode 100644 target/doc/settings.css create mode 100644 target/doc/settings.html create mode 100644 target/doc/settings.js create mode 100644 target/doc/source-files.js create mode 100644 target/doc/source-script.js create mode 100644 target/doc/src/aho_corasick/ahocorasick.rs.html create mode 100644 target/doc/src/aho_corasick/automaton.rs.html create mode 100644 target/doc/src/aho_corasick/buffer.rs.html create mode 100644 target/doc/src/aho_corasick/classes.rs.html create mode 100644 target/doc/src/aho_corasick/dfa.rs.html create mode 100644 target/doc/src/aho_corasick/error.rs.html create mode 100644 target/doc/src/aho_corasick/lib.rs.html create mode 100644 target/doc/src/aho_corasick/nfa.rs.html create mode 100644 target/doc/src/aho_corasick/prefilter.rs.html create mode 100644 target/doc/src/aho_corasick/state_id.rs.html create mode 100644 target/doc/src/c2_chacha/guts.rs.html create mode 100644 target/doc/src/c2_chacha/lib.rs.html create mode 100644 target/doc/src/cfg_if/lib.rs.html create mode 100644 target/doc/src/getrandom/error.rs.html create mode 100644 target/doc/src/getrandom/error_impls.rs.html create mode 100644 target/doc/src/getrandom/lib.rs.html create mode 100644 target/doc/src/getrandom/util.rs.html create mode 100644 target/doc/src/getrandom/windows.rs.html create mode 100644 target/doc/src/lazy_static/inline_lazy.rs.html create mode 100644 target/doc/src/lazy_static/lib.rs.html create mode 100644 target/doc/src/memchr/fallback.rs.html create mode 100644 target/doc/src/memchr/iter.rs.html create mode 100644 target/doc/src/memchr/lib.rs.html create mode 100644 target/doc/src/memchr/naive.rs.html create mode 100644 target/doc/src/memchr/x86/avx.rs.html create mode 100644 target/doc/src/memchr/x86/mod.rs.html create mode 100644 target/doc/src/memchr/x86/sse2.rs.html create mode 100644 target/doc/src/owoify/lib.rs.html create mode 100644 target/doc/src/ppv_lite86/lib.rs.html create mode 100644 target/doc/src/ppv_lite86/soft.rs.html create mode 100644 target/doc/src/ppv_lite86/types.rs.html create mode 100644 target/doc/src/ppv_lite86/x86_64/mod.rs.html create mode 100644 target/doc/src/ppv_lite86/x86_64/sse2.rs.html create mode 100644 target/doc/src/rand/distributions/bernoulli.rs.html create mode 100644 target/doc/src/rand/distributions/binomial.rs.html create mode 100644 target/doc/src/rand/distributions/cauchy.rs.html create mode 100644 target/doc/src/rand/distributions/dirichlet.rs.html create mode 100644 target/doc/src/rand/distributions/exponential.rs.html create mode 100644 target/doc/src/rand/distributions/float.rs.html create mode 100644 target/doc/src/rand/distributions/gamma.rs.html create mode 100644 target/doc/src/rand/distributions/integer.rs.html create mode 100644 target/doc/src/rand/distributions/mod.rs.html create mode 100644 target/doc/src/rand/distributions/normal.rs.html create mode 100644 target/doc/src/rand/distributions/other.rs.html create mode 100644 target/doc/src/rand/distributions/pareto.rs.html create mode 100644 target/doc/src/rand/distributions/poisson.rs.html create mode 100644 target/doc/src/rand/distributions/triangular.rs.html create mode 100644 target/doc/src/rand/distributions/uniform.rs.html create mode 100644 target/doc/src/rand/distributions/unit_circle.rs.html create mode 100644 target/doc/src/rand/distributions/unit_sphere.rs.html create mode 100644 target/doc/src/rand/distributions/utils.rs.html create mode 100644 target/doc/src/rand/distributions/weibull.rs.html create mode 100644 target/doc/src/rand/distributions/weighted/alias_method.rs.html create mode 100644 target/doc/src/rand/distributions/weighted/mod.rs.html create mode 100644 target/doc/src/rand/distributions/ziggurat_tables.rs.html create mode 100644 target/doc/src/rand/lib.rs.html create mode 100644 target/doc/src/rand/prelude.rs.html create mode 100644 target/doc/src/rand/rngs/adapter/mod.rs.html create mode 100644 target/doc/src/rand/rngs/adapter/read.rs.html create mode 100644 target/doc/src/rand/rngs/adapter/reseeding.rs.html create mode 100644 target/doc/src/rand/rngs/entropy.rs.html create mode 100644 target/doc/src/rand/rngs/mock.rs.html create mode 100644 target/doc/src/rand/rngs/mod.rs.html create mode 100644 target/doc/src/rand/rngs/os.rs.html create mode 100644 target/doc/src/rand/rngs/std.rs.html create mode 100644 target/doc/src/rand/rngs/thread.rs.html create mode 100644 target/doc/src/rand/seq/index.rs.html create mode 100644 target/doc/src/rand/seq/mod.rs.html create mode 100644 target/doc/src/rand_chacha/chacha.rs.html create mode 100644 target/doc/src/rand_chacha/lib.rs.html create mode 100644 target/doc/src/rand_core/block.rs.html create mode 100644 target/doc/src/rand_core/error.rs.html create mode 100644 target/doc/src/rand_core/impls.rs.html create mode 100644 target/doc/src/rand_core/le.rs.html create mode 100644 target/doc/src/rand_core/lib.rs.html create mode 100644 target/doc/src/regex/backtrack.rs.html create mode 100644 target/doc/src/regex/compile.rs.html create mode 100644 target/doc/src/regex/dfa.rs.html create mode 100644 target/doc/src/regex/error.rs.html create mode 100644 target/doc/src/regex/exec.rs.html create mode 100644 target/doc/src/regex/expand.rs.html create mode 100644 target/doc/src/regex/freqs.rs.html create mode 100644 target/doc/src/regex/input.rs.html create mode 100644 target/doc/src/regex/lib.rs.html create mode 100644 target/doc/src/regex/literal/mod.rs.html create mode 100644 target/doc/src/regex/literal/teddy_avx2/imp.rs.html create mode 100644 target/doc/src/regex/literal/teddy_avx2/mod.rs.html create mode 100644 target/doc/src/regex/literal/teddy_ssse3/imp.rs.html create mode 100644 target/doc/src/regex/literal/teddy_ssse3/mod.rs.html create mode 100644 target/doc/src/regex/pikevm.rs.html create mode 100644 target/doc/src/regex/prog.rs.html create mode 100644 target/doc/src/regex/re_builder.rs.html create mode 100644 target/doc/src/regex/re_bytes.rs.html create mode 100644 target/doc/src/regex/re_set.rs.html create mode 100644 target/doc/src/regex/re_trait.rs.html create mode 100644 target/doc/src/regex/re_unicode.rs.html create mode 100644 target/doc/src/regex/sparse.rs.html create mode 100644 target/doc/src/regex/utf8.rs.html create mode 100644 target/doc/src/regex/vector/avx2.rs.html create mode 100644 target/doc/src/regex/vector/mod.rs.html create mode 100644 target/doc/src/regex/vector/ssse3.rs.html create mode 100644 target/doc/src/regex_syntax/ast/mod.rs.html create mode 100644 target/doc/src/regex_syntax/ast/parse.rs.html create mode 100644 target/doc/src/regex_syntax/ast/print.rs.html create mode 100644 target/doc/src/regex_syntax/ast/visitor.rs.html create mode 100644 target/doc/src/regex_syntax/either.rs.html create mode 100644 target/doc/src/regex_syntax/error.rs.html create mode 100644 target/doc/src/regex_syntax/hir/interval.rs.html create mode 100644 target/doc/src/regex_syntax/hir/literal/mod.rs.html create mode 100644 target/doc/src/regex_syntax/hir/mod.rs.html create mode 100644 target/doc/src/regex_syntax/hir/print.rs.html create mode 100644 target/doc/src/regex_syntax/hir/translate.rs.html create mode 100644 target/doc/src/regex_syntax/hir/visitor.rs.html create mode 100644 target/doc/src/regex_syntax/lib.rs.html create mode 100644 target/doc/src/regex_syntax/parser.rs.html create mode 100644 target/doc/src/regex_syntax/unicode.rs.html create mode 100644 target/doc/src/regex_syntax/unicode_tables/age.rs.html create mode 100644 target/doc/src/regex_syntax/unicode_tables/case_folding_simple.rs.html create mode 100644 target/doc/src/regex_syntax/unicode_tables/general_category.rs.html create mode 100644 target/doc/src/regex_syntax/unicode_tables/grapheme_cluster_break.rs.html create mode 100644 target/doc/src/regex_syntax/unicode_tables/mod.rs.html create mode 100644 target/doc/src/regex_syntax/unicode_tables/perl_word.rs.html create mode 100644 target/doc/src/regex_syntax/unicode_tables/property_bool.rs.html create mode 100644 target/doc/src/regex_syntax/unicode_tables/property_names.rs.html create mode 100644 target/doc/src/regex_syntax/unicode_tables/property_values.rs.html create mode 100644 target/doc/src/regex_syntax/unicode_tables/script.rs.html create mode 100644 target/doc/src/regex_syntax/unicode_tables/script_extension.rs.html create mode 100644 target/doc/src/regex_syntax/unicode_tables/sentence_break.rs.html create mode 100644 target/doc/src/regex_syntax/unicode_tables/word_break.rs.html create mode 100644 target/doc/src/thread_local/lib.rs.html create mode 100644 target/doc/src/thread_local/thread_id.rs.html create mode 100644 target/doc/src/thread_local/unreachable.rs.html create mode 100644 target/doc/src/ucd_util/hangul.rs.html create mode 100644 target/doc/src/ucd_util/ideograph.rs.html create mode 100644 target/doc/src/ucd_util/lib.rs.html create mode 100644 target/doc/src/ucd_util/name.rs.html create mode 100644 target/doc/src/ucd_util/property.rs.html create mode 100644 target/doc/src/ucd_util/unicode_tables/jamo_short_name.rs.html create mode 100644 target/doc/src/ucd_util/unicode_tables/mod.rs.html create mode 100644 target/doc/src/utf8_ranges/char_utf8.rs.html create mode 100644 target/doc/src/utf8_ranges/lib.rs.html create mode 100644 target/doc/storage.js create mode 100644 target/doc/theme.js create mode 100644 target/doc/thread_local/all.html create mode 100644 target/doc/thread_local/index.html create mode 100644 target/doc/thread_local/sidebar-items.js create mode 100644 target/doc/thread_local/struct.CachedThreadLocal.html create mode 100644 target/doc/thread_local/struct.IntoIter.html create mode 100644 target/doc/thread_local/struct.IterMut.html create mode 100644 target/doc/thread_local/struct.ThreadLocal.html create mode 100644 target/doc/thread_local/type.CachedIntoIter.html create mode 100644 target/doc/thread_local/type.CachedIterMut.html create mode 100644 target/doc/ucd_util/all.html create mode 100644 target/doc/ucd_util/constant.RANGE_HANGUL_SYLLABLE.html create mode 100644 target/doc/ucd_util/constant.RANGE_IDEOGRAPH.html create mode 100644 target/doc/ucd_util/fn.canonical_property_name.html create mode 100644 target/doc/ucd_util/fn.canonical_property_value.html create mode 100644 target/doc/ucd_util/fn.character_name_normalize.html create mode 100644 target/doc/ucd_util/fn.hangul_full_canonical_decomposition.html create mode 100644 target/doc/ucd_util/fn.hangul_name.html create mode 100644 target/doc/ucd_util/fn.ideograph_name.html create mode 100644 target/doc/ucd_util/fn.property_values.html create mode 100644 target/doc/ucd_util/fn.symbolic_name_normalize.html create mode 100644 target/doc/ucd_util/hangul/constant.RANGE_HANGUL_SYLLABLE.html create mode 100644 target/doc/ucd_util/hangul/fn.hangul_full_canonical_decomposition.html create mode 100644 target/doc/ucd_util/hangul/fn.hangul_name.html create mode 100644 target/doc/ucd_util/ideograph/constant.RANGE_IDEOGRAPH.html create mode 100644 target/doc/ucd_util/ideograph/fn.ideograph_name.html create mode 100644 target/doc/ucd_util/index.html create mode 100644 target/doc/ucd_util/name/fn.character_name_normalize.html create mode 100644 target/doc/ucd_util/name/fn.symbolic_name_normalize.html create mode 100644 target/doc/ucd_util/property/fn.canonical_property_name.html create mode 100644 target/doc/ucd_util/property/fn.canonical_property_value.html create mode 100644 target/doc/ucd_util/property/fn.property_values.html create mode 100644 target/doc/ucd_util/property/type.PropertyTable.html create mode 100644 target/doc/ucd_util/property/type.PropertyValueTable.html create mode 100644 target/doc/ucd_util/property/type.PropertyValues.html create mode 100644 target/doc/ucd_util/sidebar-items.js create mode 100644 target/doc/ucd_util/type.PropertyTable.html create mode 100644 target/doc/ucd_util/type.PropertyValueTable.html create mode 100644 target/doc/ucd_util/type.PropertyValues.html create mode 100644 target/doc/utf8_ranges/all.html create mode 100644 target/doc/utf8_ranges/enum.Utf8Sequence.html create mode 100644 target/doc/utf8_ranges/index.html create mode 100644 target/doc/utf8_ranges/sidebar-items.js create mode 100644 target/doc/utf8_ranges/struct.Utf8Range.html create mode 100644 target/doc/utf8_ranges/struct.Utf8Sequences.html create mode 100644 target/doc/wheel.svg diff --git a/.gitignore b/.gitignore index 046966f..e1a0a1e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ -/target -!/target/doc +/target/debug +/target/package +/target/rls +/target/.rustc_info.json /tests **/*.rs.bk Cargo.lock diff --git a/Cargo.toml b/Cargo.toml index 1d39ae8..c78e842 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "owoify" -version = "0.1.2" +version = "0.1.3" description = "Text owoification library" repository= "https://github.com//owoify" readme = "README.md" diff --git a/README.md b/README.md index 29a982b..9462a14 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Add this to ``Cargo.toml``: ``` [dependencies] -owoify = "0.1.1" +owoify = "0.1.3" ``` ``example.rs``: ``` diff --git a/target/doc/.lock b/target/doc/.lock new file mode 100644 index 0000000..e69de29 diff --git a/target/doc/COPYRIGHT.txt b/target/doc/COPYRIGHT.txt new file mode 100644 index 0000000..af77776 --- /dev/null +++ b/target/doc/COPYRIGHT.txt @@ -0,0 +1,45 @@ +These documentation pages include resources by third parties. This copyright +file applies only to those resources. The following third party resources are +included, and carry their own copyright notices and license terms: + +* Fira Sans (FiraSans-Regular.woff, FiraSans-Medium.woff): + + Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ + with Reserved Font Name Fira Sans. + + Copyright (c) 2014, Telefonica S.A. + + Licensed under the SIL Open Font License, Version 1.1. + See FiraSans-LICENSE.txt. + +* rustdoc.css, main.js, and playpen.js: + + Copyright 2015 The Rust Developers. + Licensed under the Apache License, Version 2.0 (see LICENSE-APACHE.txt) or + the MIT license (LICENSE-MIT.txt) at your option. + +* normalize.css: + + Copyright (c) Nicolas Gallagher and Jonathan Neal. + Licensed under the MIT license (see LICENSE-MIT.txt). + +* Source Code Pro (SourceCodePro-Regular.woff, SourceCodePro-Semibold.woff): + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), + with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark + of Adobe Systems Incorporated in the United States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceCodePro-LICENSE.txt. + +* Source Serif Pro (SourceSerifPro-Regular.ttf.woff, + SourceSerifPro-Bold.ttf.woff, SourceSerifPro-It.ttf.woff): + + Copyright 2014 Adobe Systems Incorporated (http://www.adobe.com/), with + Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of + Adobe Systems Incorporated in the United States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceSerifPro-LICENSE.txt. + +This copyright file is intended to be distributed with rustdoc output. diff --git a/target/doc/FiraSans-LICENSE.txt b/target/doc/FiraSans-LICENSE.txt new file mode 100644 index 0000000..d444ea9 --- /dev/null +++ b/target/doc/FiraSans-LICENSE.txt @@ -0,0 +1,94 @@ +Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. +with Reserved Font Name < Fira >, + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/target/doc/FiraSans-Medium.woff b/target/doc/FiraSans-Medium.woff new file mode 100644 index 0000000000000000000000000000000000000000..7d742c5fb7d4597ae140f8418f52ffe03dc75343 GIT binary patch literal 186824 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

W=jJ>x1=hAmW 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 K4`YsgT&eiD=t+k3M&gZ?bM{*ho&j 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 z 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 literal 0 HcmV?d00001 diff --git a/target/doc/FiraSans-Regular.woff b/target/doc/FiraSans-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..d8e0363f4e1a000568d782653291e14c66ee3485 GIT binary patch literal 183268 zcmZr%Wmw!mx5nL_#fm#E?heZW#odd$yE_zFic{Q+yHmWyi&H4N$l~q}m+yP-{de=^ zok`xDnIx0s%sFQ!-YP&K3@i)`4BR*r2JbybVxE6b|KCMMLtgG(ZuR{j%KrjZPDU08 z0|T4-4#IbQ6(AG;B&VvP@m^sy42&Nt3@kT!1pBg{oQ9SZ3`{^f3=EAC42(jQo_0{H zipEDS7?^yL_quf6@#RbTqO`fAsmnX}4yI=q7&Xw}rE(5)FOLr}aDzPWGFtDL#S9Yn zuyV0>eCOg}U=Yh;V9+z51S{v(rtU899NW9h|6L!BwS%t}49tiF3~c@e41DBisL0BU zjispt44lp9cR9ZQ0I_^?%I2MX=OW(ssoz0|goUPP0(SsMQ=j+qCK0@s`|uy2XJcMCnL1j&bMMy-xBuR#vQuQY*FJ+!KV2UZ+I&JXIGh{DyyH=WFb6AL4{4Z&q4&}%45Mr(0 zQ=SPX`*6MUgvMq)eF2ubYLO+CEXL+$)>}dj<&v|SDLS>D(r)7np-TGa#@KX@Ef;d4 z{Ru*JQ^%zLn$Z0Zldk^`BLg<1F)wg?H?sEOgAU`M2IBXc8qfS*R|2t!%;>?n+G-x} zjpMU?+>M?yrS&QvH2HKD6znu=$&vpMAjUn^ZiQ?f&*|;1m>f}^WsbWVU5V@kie)@78F}?Sy}kDCx*F$~Ep|YR z_ilvFuEd;&NX?D&98XQH+D^M4n>Hryz+@B45TVob6}^l7?4fU_ftm8Ax<(X1WQ_#r zltY`tR>wV>z!OLolv zO4%}BzV0-3We=~5rr*I+pa>y&2<$UWHx%GYFor9`=b{QBdx-7ROqaGnxSTLdU^}rq zxc8N(0}K8Z3`WNxDmnpS9bro&cSvLkoUM$b~Dz)ePs7lNAj(%(t!F| z*UpH&bn$C|{m9>~VB<$oMO%iiJWM5^VqnylwSzZaPc1fy`{3Jro!75!s-h$cZ-Ot{ zp$6`SHc2}@F6`y$`5LSrw3fIk5ntioipF%=bN-OM=;G^5mbVvSt}l9)C%y8?Qpnin zYUQZV%+1`0KAqK?YIbxdwPbXEbz1-~aI;y3)oN(zp4idqPm$RvmDoScigccnJZwIl z8@wrgRVdvTZgx3&o6m{=F58l1o@NnSZX_l1%{e77T3u(krS&O!sHb2>inhzCrgHOX z{wkH|p^Sy}1~sx4NBs}w1Eg@Ta^Pxq-{GG_^Iq&ogTBlBn?*uJ<+B-wR-v{!+G2iH zorDExOc1k+V7s=;ay?yiJ?FdC&u+z9%5Wn@mETr1@Q%{fF0?mh!yN{7_3}cK_UUqInr=NUc9{ItwvUXwLZ#u&OR+Q zFwsuxTN2=Tur<$-_BUn2jg^=M$04CUEz4mvR?YCHZPcauTUBkoK|Gh{8%*bgHx>3@ zwH@InrIQC|R{1pD-d{r&?Z9dWqU+-NnOr-^RvnX$bw;KN4jzfR8bSN+D$}f zG%G#o?O!@I5t~P?vxOD>oI&`9_Bd*^G_9*u=||oU_C{&-`gNDQn^loexslJT3Qr9N zTkiXdE&uRmPKau=7th=UvyYb}zs=N>a}2nl9I(z*@oe>0?P@uuf>py`BfvP?D=ZZ; z61NKr*>YM6&J{7I=r!Rhd||`~E0*_$86#x1HB~%a#K%9qK~~zpkw1@tKjH8`gA}Pz ztB#W@Eq@%kN0b9~ZL`raYvD?(D#gbw0_J@X^^5sRqL+%X8p>prOleNg)*2y!yw;rh zy?p7$PiM>2)8uE^DUWS)fTEh-xQ`FL-i$k2iov0{MpvFK^>=qYJ$Y}ZFZE3F2QNR= zR8<~*dJV+q$k&JpKgzcKI{yUjx*S-xvsnk(%5gTY3bo4Up8Pa z;Ai5iJ2iRoSnEX5icnGXyzaNvhue3B@yFR;huy;2fCe=cP)a=6{A* zQ#M8w&_idKle3tf$$$HZ>!17Jr+4j~*}=tY?#X;zNu4JAJ?!_69YBKUj#P#fq>3;uXEw5|weY5sz?lm18e>4_aMXO13 z)Cg=kIm#O}!*0T3R6iCSw0qX7*h{&shzCSe4>%>EbhkSFSjMg-`nhE`MP3WH4fiC! zB{Mg6VfK1&ECc1K3j0s|!ydea~i!af&$y8#V40-*j=GQGruADe@%K zWFvy~*2~WPWMQPWg%|50UJ<K@<^=ivYbuuNL~iS zdaz3(*q@eejS-@~9xW~&#}epiv3~PP{~JmlfF3wbRx59w6A)IG%1b<*fH%N zO0{fP*R`=89w>Ck2DJn?yP3<6yHo*l$tr5Z?*@$SjUE5VkD&jh=XLn)*Skw@V|koh zA(%;`AyyV8|EINK`Qqr2{!*`9q{>bl_Ge#@>Po#EgWUV} z??u`0m}!fv7YPqLj`bhNG4(aU3-MjkrBx@^xm(S!CByvsz#H$i`2z_@>?#dKUWF~4 zWqN7lwA(8k(Xq<;JdMA1ZP>rGg`Z^198*2tjP9E4J$?T!6FJQU4mUr{1_|V!nKD-+ zPHbVMPoU{C+e&r28226;XqZ>1l-#c$R3`l~%P`gS{mYUa()7ozJ8kcw=@TAwRM#1* zx8h9sbojZQe^e_QrJ4My_3MWb z>!O_N!XL^SKchMQG(Q^cDxj=VM0#?iTp*nCKEsz&vbdjd7v3(@k`3#_tYEooOU0bn z(d4}eUH3rXF4;<75WLLG9p1t}u~16mtMa)F<5Wf-eEgzokL?5YqMT?Jv164hI_Bf% z2J!=Ss)}H{@;t4e&AAEAfyx$*1A{bT;izBhA1a+W8Gg4mLOGHG{8>I2N7qrAY=kB_$;$7m;1@xa18y;Wb7CsjkDWq`td08KzBgsO*y2iv}Sgb_bnjG zu(a|tKzm4i}e)`Dk(SyO4;P^B~q*CJ?I{cmLpJRHJ-fvV9+}=krWfq^E zfV8qF2e51or_P16^-uL3GBzopu@=MTVGRMj^KVAHnBT)oSy`v6ZthqD`EDRh-?AS? z%@{U*+hb0OR=0TK96xP(AY4Z|s=E)`5Z&m(iu-bC-zJM@EpnMt^HfeLic^L0s|+4b z&H}u>OD(m(2J&*66IsPgQ+*Z_j05KDh(1(nJ|(vJs5`Mm0B>X;iPu0X_63&e@!rog zjtee_68_JV)kbzzy($Xgm&!j^qX~ZwzQL2hwN`* z`Ci3?JD!)?4{ceiLT+T4q-`ld{3$Cy<&8Ch(*RweC(SPS_`%F;#S^@}Qb;j00pIEK zWHi_4WiE|(ln)*E7TG7|xPthVF!CCpE9r0dqGvXaY{9LJ8RyW;kM!b)5ACO8nT^V> zC8fi|oU}m=e^}R5dSCW4Ec60c-438!qdSSLG&;()$dRNVC(ysQ=s9O+x0g{&8vfK( z6hd#F4p%5ca<DP8?07Zq)x2*P*8#@o7bvi$>bux%C4rVlVf=hSVamRZQgd6@EIf=sJyLNVl#1IrOwB?; zxl&}?ZMbU~%^HPk7f-2Yq4$S=%v50U+UbgWZoHYs4bAe_8G;xm@&ce{7V=0x zR?W7EUtYn#bHIQ|H*~V?!VaMio8P7UcIk6K`Eib1_)Q^c@K zwQ5r}BU_Ry>`4_7#KT`%VNd;Ds%HG6t;m*;PIR$`|Fh!qVEr5Km6SU}gSDASBoZB# zwvFxcbX5=1*o~CFrWg0XCGmqBvRwE7g(tjXl!B*4!H4Q7UM0(!$yVLqo)?C zwaWCs<=gR^c;{Cp)#W>H$QDxfYyy}^cgT)3PWG~ovwuu~hL9U@-4o5c?LDOro!l`m zK@A+A9v2??SelpGlnQfu)^4W7Ah3~@fpUaGr^1$tI^&Z7NTv>aNE8Z_DyqdnaKq34d!hF z{jMYU``R2eK~L>~Q(;Z57$>A~AZ)AlYqxb8Sp6&ugF zSM>Ec`uJf}yhu%{ThM(qm`fi>H~5gId6AFJRDpMnlLL)q4 zYZrF;ExHGGIWF!#v1&5)C%P|+Q4O&4q;Tf&_}3#=GwhV#$yFTz-$_;9x2SXp*lFPu zZ$RW`i?sCvSj4&%y4HKR|8zf|?uGzNLvusdh)=KjdSGlNL*YTP;Li3W*p@>iWyHyU zOe00UlGduD$zKdVrIk~arvVS}=q-@Awc2yOB#HWm?Qp7ovoWssuI~jZ$f03jCe#}+ z3Fu!8A(kO9Dg=svI#pc!Txw;`jc^Pd?2jZ%5fOEe7Lf~I5Lm+$W+Mtu`i*WKFizFF zDmNqzVwaP7eFS{i0Fe)QC=1KmEalDd7PNY!h0v%`g*FftL)p?SUk8}IE;&s`VY1PH z-GwD{0SXldVJ;49IX%rpAyJvIlTOc4?5R7zo_R{`HD9LI}CjUKFHcsnWs5QDoTKmydq;~lOS_7!?%`?pG(z*S7`3jY8Es+;98~@~=O1Jp$ z2JD(EFX_LGStA+~Nrk%o2O@s1(tJ^SjZ_&0 z(qywb?Lp?^!#lMxT_XtUZM#Zl^-Qy$dm)RZ)%B_hpL!|+>W$@Cz|X$}yYYFjg)`9X zoFWU|vDs9@nQazJ&oLqY$r6WV-q_TMPN$V311?MJF{c$iklKRLSZM0uekO6&T%l{4 z8;|U0XQ~FXwZ+E>D+!PjkEIuCmQXfdyNd}Ihm$L{AMZZQG|lvpgigph>@r?6fd{G0 z$7#%h6iIwZ3Bw{vo#1bb;rJvJ zg4PA=1Aor9;n?R4(+e9wdk*ev3Z+8IMVv(M`v^0In1}vMbZ!8*$h&D2(-X$`ETy_$ z$04VxCig0K{?sSBxq{y=?h+i-U9iD}PfiOH#Os1eFHwP9o!6QotNcFe6w*uA}tFA?XE&?0{D!p0qZ z8U48m6Tu!ojBuZKK?0TwAZ!lD2lt$2gKYz0gEjPxj#+?Y^x0~IQL-(piLf259qk@( z!$Q8_HalzgB91qzi;#=Zd5z7cL1;d*Nz|~zP7^(1 z8R0p1a@ZC3Mm}sW(lfyAEqWVwMtj2|45{yJKy9LZn?9-7oN(yY?A}WnjY2Isp|MwD zrN52+{G^XI)E=i1$%o*aX~QQXCZhsY<@Y~(j)rRC0si5U4!CEj^Pgc?80Eo zH=aVzkd4v02=4thjzY0%Gk*0AhjJ?W*heIpKNWXsfSPcvw&Y~CH~g6&cW}Sp_bAJ` z7s-PdQFG)nHU6NV!(&~e4?tqu^NZHRWJYc`+K`9vrB0EtXq*57wj0-or|8eL8&t3= z+T1!D@C6y8pO{q80xlzCx`>_g_Voh4o4{McS<~d|Z={zmGMW)I zcsABmfo!($7V|x?YfJJ%3-3p4({n&ShxY5#Q zA1WM56t01R5g3JyoEP^viD-=V>b7A(A9bdfJf;S#kEBd`e$_WsEMkp&1b=;|V`f=) z9`;zjH5KlR@3KWfFN2TEkDG&}J`lnOQ${_&<541Y8Aq@#Jr*44EM`MJfbiEY5B%5A zB`a)>AcwlZcLO>z1|%Tw;MjwC!=HywKo%et42mZgCu%4kM%)t+FrmR{RtQ4A&ks#O zfCR%z|ALN(Rvu>DBE2YNfB8x_*dWTKITld(I-ZBmKnST|= zaYcsv2ops#Oa{vjmxqY47XJ;264N1686i^pk3Xz9+B1{e>d8LnIwz}l>3eV6^q+1u z7jpj4tMXZuMru=pyx+rIg zp`mRQd>AEQHn}t^_6V+74zVcKD}=meMtBQ4+S?}>M{o)+79Q|Kv!gOyng0QC|AEdF z;S?<^^wV&NX<(vuA||`$wChGZd=QbX82Yo&`4Jc51~I*?oq(;NEA+Q#A>%@fJ;|LX z?P7|diCc*^L#<9P;h1CL8#V)f{3^)J{A*iokUS;hX%R#o`XiZE@HBhkGX(E3SI&uA zFw}N|@f20jIxSX?i>@IyXp~Pu1k{^7k~I0<=ld#Ws(iXLa)-hIBa>sYS5G&K6T2XQ zSuFgumukmajGsGsB;k@b^|c3Ki>e4x;E_so2vwwg#oYyERbN(88sm&n+Wg#J>d@B-$%-gp;?ptB1xa9x1DPyLFG;6uT*fY|F!sCjCg` z$ysGe4S$Hml-sKK&25XiH8mW78K7JskZ*FK9#})5aA(Pqy3Kk=2zzsWquuq|Qz(O+ zM7Bv*svRl!fl1#MR@>##g&X>csQc*#!9pD6T%dBE&HtsLT7hB=!b#YSJFTyV?Azn||_jj;bPv4%t0gLJz3X|S6LvTg$6W}H# z$Y+qC&#;H%5-c6p5?C{TPzcb<)c%#vF{xTil}mI?(nk30Yx*6nJ|2lkF%fV?ARz(~ zqGJ6b3THxNLR}lvLz&&YkbfZWB3a2&Q*f{WZGPAg@Uadd5`hSGbDBR%(0;1ts%KEe z)m5=k{Nn#bUyOv~G)j)5B1)$;DE`NXiNi1d9IorIDwileqrWE( zRDaZ&KI*b19b=z&BKlX77FfI4EWE3qr%IBzaCicJeDdn)+l^0=SV(d#nq=ho;IQrR zl%k|y%>o*ICxo(PHzt8!lk5U3@0gloZ=ZgL%pR`PxTh09O;nqCeR%^Zk`J+srI}W@ zVtRceC=v_t8byk*0> z>%!|F^v-d+k!hM`#0$xVt(7rqklfLqgv%KLea7R-@O29jm&WW#ss@*a8v%;~vrf63!r49^9rot~Dm5Y&$+3de!kJPP(xf77 zaH=aae(}?YH-}{`aE>>tbjA=&WYer$Yze5Dw*do>cq^xE;(#k!6<$l-iH+k4iZqXP1l2rX6wnC_uuCmaQ!VBJFWbx;7n}L_@Saqt znShaOcyx_Pe*vf{-pxBqQBm}7B7|7mzfG2o`!oFye2DIm0E|_5e zx7syJ%g2Q(v7QLddDO9MWt}eWCj#YoDrfdffMvWw&c&MS9qQcx-i47ewOAm#*@zHW zePtPsn^(Hn0gT4O^0)jau$$+wY(@ecWy51gOTVHqynM;ySxu2J?E>cF8CxiqC{_n| z+RrN%2LUkWM<%_cvH*h>DH_&4lvAoq4#@|z^E*L>r4_6M`njE)gv+LfyP7RhC8wY1 z*FJf+)yJx1@3+foRF$6Q`Wap*m$C>~lG^WTmPYtSr-J!UQb;DE(6SszUFmy>e`L&4e0>e$(OXl%-Zz z^ZFJgWxgFP=@;=*2Q+oR>BW^D3qSidV5Nc*saWzRMW8tJdM0gq%2SH^3SmxtLo8Dr zn9Lu+XT~i99OkokO#3Eln=(q!C?|)Qm+xgasMKSiFN75j`(kgL;{!GsKi6tZ z*&$jTc3h3$W~O|dW4QFdoXjb=7TV)**`<4K{)OMCGA|rQGxcRegB4y0JsTQ~T|`L892a)j6_&smOdWQv)MiYtUSZ+ffeMDKFW}v>UA;sDAMFCNs!BV>hwKk`SBbWWJ>F2O*^nb9_JdlL8229j;{w) zadF`o53%4@=ntjaoGNm_n(io233*jly`^_MD9NjeJ)i4e!Voe_AfHBtj#5n{Yxc(R zCEW}(>A(k&>f{bB#j8^z!e1`w!uz#s2n1|wfBp)K`sEstihDc+gFg>(@YrkPcSfkM z<1?PGC#U-ja(xhMjmf&rNNNBOejNC0Lwl7hnqwMz@l#f%;X32Z24T*vJ z%#HT>QGVQ`{KM2ZP!0GGVoopY8|L%lp53vAsepO7+g2)^aFp(F-!Qj{=i?65MoEso)_N+SD|pd5K{$!}v?mFHU&HXj zyZ$iXA=|BAWK5A5CX%v1?zn>Y-xaW<7o+=20$tJ|1WUDsZr>erWm@t;qV7*}y$5Q- zbG#w3d2#2xQJMd@*JzekYASFutZckNhcVd~k2l5A}Y%`#5VmBTp# z{fo)+v$nNK_${VLJJmeGO-cK=V%#Cn>$Is}gQHCHTUao`rrtgQ&dQ+1jb5=+-`YdV z?>d6iy%BuBf?x@>V2SFcM*99Y&D_4+IW-@ z(H_>(3e`?DP;#Oe>z`%J z%)9<`opW6@9-e_5I>vigsODVo%IO1#Icrl6q~!tRiYXVy9B62=%!q{ku;*b7td&AH zOSNnOj(b!{m6}w{0Kg0Ony}50t6mc;rD{xRq5v&<84jpF&iCJJJGcr^3M+n;}y7VY&~k=VDy`*hxX-jUWF}sQ52z4kTp<}|=ALb3B zk5p2jlF^bBAR-SEu;$Pbcfl_iH;s@V-rxV4a!kWX#qm040$F+Wi)S9O2+$hz2ozh_Sj7_j(p?i zro|V4NcFsunfZ~%h+Q!s?&dQeuoXIi-JCL=iZD9@&05)<+lRv$<^NikKa>p!mkWIp zt8+n}p378%%fd+kCkUgJx51J zI#y{ri z38!$jeQ7-!(f6bT-BR*h2F!@gJ4S=aWKWAT+Fb4EMX4uDt43rip{IUFn&;VfORrfo zqXzyk(Wv})4>q?!&H6`@Mllj#(DQa&v&dJX0?=}pQ>*#|E2CH~3Aod#*?FDoZ!>RD z{0fk)jp6ONng$_2aBmEXuWY~{ZiG_04n<_IekdC6=_M~_dK6Bg^XOOOHaAbwEeh4m zpxkQjp=C4rwQ#>PiMtYX7edn5N1yR(ulh$^q*4w7bc@Y7eZGTp?P-1X5XKk|(ob4_ zmoWQj9ofhptWr4A))=@%)pn1okGqa<&GM|JX~&6N{eh2GcP(lp-`MJo`-N6N-D}&J zH1;+Qe-Lf#Y-9|T%QE1zGQM@7NGMU@D?tm$fJt%~HAXZ^W?v$E{~YmgA1v-&;b`+@?xY_SFED?kMVy@GViIyhh#1z zt7W{}adM-uhb%^S1B-FY&`vh+RucIkoZx&URF!z7kb^F|(_s$9y$W4EpX15Fc4a37 zm?&lh8uJjW^)2HOGA}0A7I(t3NFbqCSKdub9qq47l1`>)E-?m*!%Mrc+Y(#gfk?Pi7H(=_fF`7Z+uT5Y zP>FQtpRvsBraqv0QFz<`dUs0kBuD1w7Gs2)zEFo5o1egcC!o$1AQsoP3P_ zAVs+EbbQscgVr4x9*oQMUi6eMf)+JdSlHY66vK3QuVj~F)QBWD>8A({Mu>c7rdUmo`?e}ok0?{@VgvBIudkTK=*k{Q+C^q5Rk02ML$ z+5k|+GjnSzv+An{*a|kuE2Xz@SH2r6#gwWbN-5tKK);CcAGf@wX}4~%E0$!l1f#0n z_hIEkiz%N@PmHJhndL+=neDAU0i85GSn6qEnTzKA0Bm(1T(SjXqA4P(mtiPc7^jb| zgrkG8%}#{#6A9;s8?;NFx_>}3O!j@EG_=um^=^iPjU>QlJyBdFUd83yt32&%}v(RN42*?#b0N7`3Du9W&kyR(W1&Ko@n?Qfe#4O8J z%Ab+ho|F-2ZMMxCw8xFar*SCJYU;W*iXVOCc#}6l+pH0_Ix3?iY0L zX-9Z*2x)s1m1`Hf^BvmRAShMY|9TWDKmdmUN(UtzJ6m-sWG+J9qbW!F)vEjywPnCS zUci?O7R|@naPxWd??75!fJX1G(Xc(w==v4PRc`F+h}E&sd*}qf-keYB6^U`wX-J!F zVzjs{6s&Wsh>EWB80E8tYPqNca0K^<8y@MC_ODdU1nH?uMbm6Y4QbIG`pFd3^461Q6tK|cU6&GQJPxiM zU4{7B&e!=ANJ)FNZvrIIKBVbdl2*;Un<;YX3e^UKiGG9JaeD;P12Jh8K5Fr^A6tec zFVHBwTYyJ2bLbOSTj0U$IO@$<+XW(L)^(jOVIq}dX9B8vZ=u*KUZKhvSFo}zK`d;A zj+A;Gf_hy9ow0n5sDc9Y3I>o#Pj{rCKFIwGFIkWNU}Fb`QZ-3Jia%vjVNB64^@}(g z+RdWP`}7Q6K;euHcxVuWcv)vLhNzxbi_0^V+z~-!v%WQQ9l@^G_->>u`x%V_zy+x3 zD9wYdtO~96&8$eyKfB#^;FRhkEF9#|l7G=7hd!dydC4oJr{ypS673q0;c`SwqH5ax z>rzi{F2zK&Q=x6*(aqA%`k*~G%XizUk5*Hcdflb2+f+&?uK3e-o*U_7#0M2cWWzq< z%Vv*%i$CPlTRi?C`qF7BGTK5a)cMjTnR1PUR0<;j%#@MYHNV(rdd7M6OJ|nVU9pNx z-_5`GKv?>zYPov!f1V*2%hp5YLkW3R39qT8SVf@9AqlQX!5koW5rsJ;={MWe@(sJa zLz&_39FuG@(Tt;IG=6e#bq)K&$t`WOY8%v-g7!T)HlGaDBE5wf1N}%heXEPF4s8qq znAX+BL+zK&K_=8%V;{`NhZJma3!QOTvcDA9%9-6uEvGA???paL#zWI48g8gV$99J| zBv~@p!5cMSF&J-E>CoiuOm$L|0yqpPBKd%qV|p{-`E z8dEnVr%!j1+}q;=941;Er{)vZUrrhymMAdLhCso$8MyuKa235fV_7sfJXbNd${r6M z1_mFap&!d`$^$}yalHCJX2w7!rZK5?G4sD7UepqJ3vw1hF4+N&i#8cR|Km02zDrS= zRs}+x0`30#PKkF0)m-b4%!$909chFeuaHi@cSj*^^Z7X0a?e0fuSkFEGyP*-AcXaq z;>Vl+-I2k%1o<{a-EMpTV$hpabAdn_r2h}%o{_36vLpAfh^tB-t#VhzMmr&YU=Ypv z3)dj~cO{B687f@z+mEjN?9K=OBHNo>7+$`CB%yyNFZj=iW!IWnAg{Kk|5zrIvjaoR z;#PpTR^kKX5@^UcT*oIo>$n}zLg*#Zbj6L690&3wwm&-iGv!u3%}##Nk7Cz+2xj>i zl`15kCa|~D^TzVUcyPzZ9p&y==+h)cQ;0P!g)de&_P|KCt8i$(S_YzsV(%ag7OwfvI%(>hE!!o#D3RMUOcuIdQEw2W$3A8bBENlIvK%?;tY67; zmh8Dz%1q`))GTq~w!7xA^FZGkYwO`aUsIcSP0+R6$S~UImiBa~6SzF-h6VMC&qAWE zkqa;m^VA{&3fCv*C_=>3ui>0Iog{^X|2`RfI}|R-#}RBCPAZm$j-2A0s03WB{bF>% zdvlEl*1m?jAYO6~sc?TGF}nO=-HPqeFlOloUCBB2h2nkli|o}}!f!c+QzmwScK34M zV}KZO??k(@Bip<%x{ybS3cgv1J=~03SpDv#JPE)LIPs2=G3>(L9FZe+8XBn% zrt4e7yqJ{qj&(mZ`+H~jIbRThkTkjVE#2ZeUQ)2!WS%wYb+nvDyb@el?C?)!Y zCtjk=WDni2d{oO5r_L2;o}^LbT#Wj@#kb!dR(YrV%3whtOmn8h-}<#{ zKlbyM{`-zP>wt$=pgcpLH{5+-VqJhvT`u_)$`Wi#t7@Df^P5_wx@UOxe!nP*k^jJ{ z>K%10wrlpn=+6k*pGtB+9}=HRK}zdb#&6vQa%;XWweWlVOz;X}#;u8Akpux;a=y`R ziQvZ_G$1)rX3nFJF!YBECu6|1NCV`5C@Q6S>G4 zykjt;J{i4cU+YAk(f0A_Ld@i!(Kd#9YWD}{5Tu}z_3WfehU2mjSO3lzBtn5pZBOEL z68Fs)?hIE|)znYx7l3=65I)$O?U(xEEh0Pf5})Gv3xh6hZ$tsIeu61HuI*JK^V{Iwn+ZlPQaF9)8713UDz9*x<9IG zQ`+eT?t1!)MQ;;5B;3OO-)#9Ayoc6Veqad%*|B1M6rb18fKjlhhuM=itnw4)z&bm= z>(39wzHfdnPpvBPUe4}ah-m4YT2NKjZl6^_V;v zTziT6Qq9$%TJbz046+vbNY<96emHfg{5E*i)6 zYu2=#Fi+tx$_}LNO!ZABRpj}^!qdGgpw}zZ@9CU2fb>gBPt3Eg%RmoF!TL#+R*uXx zLqU-0%vpW`-C0pYyL|2ob}Ic-LWPwhByAY*SVPT)7O z>>VH4OR&prYnLY_bv~>$mA(~|Kv}=u$6bOH+AdKDN<#Uz=5!3o72?<}%7Eqw89;Tw z&X$V01$?RG9nm4#UBx0m_Sf-|<`20ZON6ib+ARCIV&7%d6Xc843levc=y})lBFWb| z1b2mzP)?>%l0o84cN{Sk)N|r#mh-vyUrM@&OI}ybFTv1swD)K9{t{*r%9(zPZ-&$} zIzG46Yt+I7qpTZo{Dn~2pm(exJ$OlwJgmF_Ad!tq9j#H#TLL+@{vj@|!n6uB7?vsd zq!#RL$>nF#L)E2`=FU}a6TN%b{rv5EQFa~u$q6V7UB}u%4aR0L0K_qHo?#;phDW(uui4oVE9xU8jC8S#e`d>{qi-~zJ|5cmDJ3}gCUif;|_v`n{gPC=_f}4Kt(#PJ}bA+DB3xuB05Mc~xHz1(? zkwIlYo4VujB`9Kw7?QhDI_+{Pn;G+?*jha7b{4l-XQXJ;=ENSijsEs)fv52K8j>8U z)X?J)$a*@VfF_WC*@9+SCWy+a#fEh28=Oh=AKX>QhhCLg9LFu<8p(F%>g20iewz6c z^mgWG3XHX{5|#pv!5vaTHDMG4mY;&yoHJktGdSWY%4Ov^S>h2*O^TQ#9~4!C^nT){ z_9E;w^oG$4iS%3yR^n83bRp9mBYkCipC|`cq7l--`Ef``PC-IA+zWw_TFyLYWCgHW z?7eHA%F&OK`HjyPk^Q0aGxAB3?z%bb0oZ`(-!|xklOA5$Tg{?K6CApO$z%RW?v0o{+dPl$HqYg|kCd6YwU%MiDr=~hw4NQk zgTNBC)wDkzB0|4T=ryE|QkzBfP47evtL(gqylz78g&_8)J9@5?qZD^LDGHz53MUA5 zBl^SE2y3Y=&}o*KJB#M8bQz9m#8O89p zccCw{8hns#U~5Ry1z9W42?S9oBG>c1;!dt*KB=UGLD=m>g_jUdb5y_P3YQAL9#3UC z`;@1sfNV*wcUg=4XmInxm+-#5ik1jLx!N?D0hmGA%#~0_{9dHWi6qZZCStL(f@stwU9jXIoct9XchFB=8a9BmindYy!cgIHe?jik%x zHN|7hChE^eL=N;r>1xlrrrrqqy+QwptYX-R*km5s6vcG58ElNAMV(WFBwmtG>yX8*E+gJS}_mNk) z5At#J2N7BXZx1N%dn29%BlXJQHY|c9ckmOB`^UD(=WPT+u}G|b3*$8Q$z)NV>3tCX z(^!57{AEM(^Lrn{r?R{bu72=~hu%Y3##|J>mWOVf|7=7vOFuh%VSuf&Yh;YCbDwBx z1u>%w2<9H1uD>Zjr6qTWG?(aq!B~~4&4Xn~hUwAe{ImZXkHVqaTw<86LD&vK8^s}Q z7%lX~!I1dd?Wz$skVS-_M6}e-g1nmjK+h4Cim#XQI7%A{wz*rW=#DJpfdgr_>jsn& zR6PhNZV#?Hpo-sOFZa_yw_FB~k76D`q7}`^4v$|4pWKWhvuCsJxk*-kaGI4whnhzi z5iCMTn0~=)f{(ox{8>X+PWc2Ji+hruiI}W4FzXSJbiXc}HcJ7s89!(;WRR9BzYu5~ z7KiZT_pSWqS8YALqV_zRFPx1A4BIAH8e=UIYDsp_Vk$hplwo^<8)J{+9FyF8wvA(S zh?=;!7a5bjvPA2!H`#4VJrL-V;qkxdnP^eGmn7~kJ^_O~Ms;ah2n6-OM z5AUQFK6m@Xd**v$-+d7Zcn+Fg`!rQWe>&u;HNPe&6b#u7-vjNxNY{dBCn@;n4Yr&G za=jDxI41D2E+SAS=B@-oK|QPP#5^?Z%*P}u)lg=cfvg2kSYenM;suwU-H~I|rVo|y zaeLHb5FkF(93-zvI21ava8=6K@@r-Ez6R^^M%jh+3C$3&efRVSxt0fU&angbwd5Q=9qrcO#+qrMz+HIyFjfRr z5$a2`eD)JI5VB%f#{es)K+g4(At{ivCg=s!;W_!v@6P(U@h+|@h?R2=TygppDpBLd z${r1tymN#yT;S@PWw1j|cbS8C)$=D)aajcW)_B_9rX^S zB+qfGMv3QKvx&2bo@LH;&RjkV?hwAtIZebef6rX!!D48IW^h^b9UTk@_HoT-MuW?< zV|gSe;(;yOUAKPdB*PeQ8F@jlp_kr z>&QnE^_yvCa#3kehD6u0j%0mLfpHsC5?7aHaCpLp7o=#9`9b?27fjwMX0> ztrP2hH&niM)?IYzT)9QvdBh76CY&)UDo7^PNs&&wX=)jHQU zTcmi(^Jemi_j_9w@bU;wj92a`wT#PYo^F+A{eAj744&=?y@PZikXR~?K{kuPrpX_K zWZa{Ty%wEz?BI{`^JNnJTPWO9jZ+^-$*APrXgr2Les#a&m`XmOSa2=0r+-MaPqOD3 zYWI**^ogzAdswK5%#1C6CZ5VOuT+mr>8G~IJ^OR^X~{;wOkms_RLV75UDoezEa)*k zZ(u_~*f#kyIB$bILibQ`tD^tywK`yJ)chpX73^B=4}F3@9l~8WU)&tV+y&j?Kg=&% zKK~*GyqG+P&LsPAuNh~8Pf`&V7%pPm0%pKIJTK$z9Ku}DH5brbsPy=#5BOy>$ZghW z*)-*MxW1Je69&kLs}_99%V?4BkU7(BB}>h?B2&mdvwF~}t)*Ma(pr~jy>rg3)~-6p zTGOnh>(;DlmU!W!##2HZSx2UZkzsgM?S2+DJ~__sR^ZrrL6&jUI_Jg;v0vS7jo#%u zab1O6q$#H<|7>?GcKrMr&%f;%LcnJZ^cf0Ii{>TY=o@buZ))uYLhjzPItv|nf?XYj zwmgIMH*^j>qg-8uPISgSc-48;Pcz1u#~bcu#vy5ichS0J>Hwn9x#senEnPSrxLd(; znC{#Ka(P#I*Q4HCWI6GjI7BeRf&|Cw|U=t zmBQb*(!Vm9zJI(u?%?WT-qO4Lfpn#p#kDH z+dAyZ_p0(Lglo;cTgyPuSkRie&fB!jpv|Jq%C^$mT2;%Z`nvgC=dPS%PHir=+_tZ^lXWt7O2HnW`R_<4w={vuRn^A`&*CTULYP-Gm;g#u? z5w9{2Uym@4Vh^xKvq#WF(y^q#jeEVaRnQGK=$)}%=G;K*AeZD1T}jt&69QN*42-k$fokHeyhvbKx zu9c9cui#^K8lQvP6$GARsQwg5M<(9_}z!OY;77|+c}yo65zhvQwsvV%&vKG2R=VJp2tE;(!ofuOtk9p_G+0KcN4PR;l`t%GR|c)x{Q9G$ zjdu}T7>MPFilp!V{0!ntcxEx>i7mGhQIGU5KL{>Apwhi!hthaClNn}LHA@-m%3Tsp zX|GIZ3+6Q()8F&l1BMiye9eX_@2%w)4}*JOLS`yu=L11=NY^s9tUYbL;=orh8LF1_a49n&+qz1YNrl^J;QVjvfI^o}RQa8!p zoq!=0x$V0=F2^ZwIFc*vhsl8o3baL9P75dj5vM-<OKT|pJy-rj&tX?9R28Z^DpK7_-`BQy z*ta=qJ!(DJ(6ErY8FxKK6n8Bcvv&o(D*XinkWp>@)*~(02sf= zI;#IId0=$l5B`Om(%K!=b5q!mB?~u$g8*lj@Iq52<?PGY1`vRG_pSB;Gxe=;yT(EHMRAK+G&JFDbUbma;=!M#a#j-W+> z{i4;NFU7$<{{Z`d;x^3p^^vuVH8i7M0T9j>gqTUWmF7DQl<9LG1tP! zd%%LA&AaiuQ5wxt*=wX0>~q>w=6qoc>6A8HGxF_`;8O6P7&=`F`Nc0_r(Y!Ol#!p9OxMK&&o6T!442a`7Z7+ZUv8l@khtWU&G6 zM#S|gTPPwA{nSJ4)`>NgH4rULNRf&z@z)fv4{V>g^E>>R0x4doU#Rb%178CFRO0$Q zQV2`!fAH8KdZv7dIWL3KBl(OA(?3gBla_B3-X~nJo_D2*TPm+cKN& z`lx^}Nv=WSWnh2#t8Wq!f1oZV+19{S$9ma%S=K)A%AR?jUO7a_K;TPSk%`wM((G$( za$$}PPH!<&9BwJ_S@ju;p<$?#@3t+XM;_b)b*g62na9=*u61}-pw$h6<|op~^nQik z$o%=#LwldO-^_-s{apK*c}44S4>vo)E3S5>7=aOqflSVgUh~{PV4{8FXPXXVBSC=4 zYQ?8k4%j2N3{Q4W23$Gx0{waw=|)-zG*{upKMXw|!#=qrV6r$TU>{4=|70CVGzq+M z(An9OP4kZO7WX;)_%&^b)U|TeBwdm25l}sTL4v_cX7EI+Od5?Xsd3;{^*h<5qC@T$ zZ@^ldk)(rqZ7i?t%Gt*Lkm51Qm;H7ZoA@ED-R z%2TE{r=(Nm?%Z`?YIJpAgU%jY$vE`ADYkprWVKgj(2P*xX8_PohGU9EdOsww6ibt% zVcLpv7Jvg=psf^>ueR$~`dC%W#c`6aIwt>n-()jfbu3b~j8d(RXLF7VE>N zG;PZZ*o*=lQ#-Qj#(t@my)OYv%hFp~*E{s$tm)KF2G+}6JYFprW_ISqgE{)oj zPI!hN?#VgwFHCxk>Oxtd)QpGGhlOVOn$jeOnuRGXV=DnS$sR}@*6kxxV{K4<4N1q$ zrfA-i*cDw1wG>sRjKhW-hHa7RuIVw1Q4Az<4h$tQIhaOp)T#!oYwc~~EnbD58mt+2 zS9Qm3ZB9mM{X}$ubAdC9%k4pak?afV)AvV`0QnIk%i2d^=vK8(ssH?2 zgFq8|z3$C2IyIbbqsSAnYjc6JX=F7j!^|D(H5$gyCtPbEjMoQ*Z+!A)1-L>pGNvhN z;F+|#8ZC{okhMjtvA9xhHSO8S``9b$uvELcTqiya(odd}jPc!0^?b_r3weT%vN@HeKtQt5HklKht@Ks)`!Ql#L*})-=bO{Rni1 zw{MOgo0B}0!fYFE4s#06FcB*hqh`SOz*Tv+F16MupIJH>aE~>8GIlAMStI&#>u!xS zNnA#}U^|~VQe#(bM-?@n53^peL8JE!cmA+}HH-9{mC1oS$mV=$UaHDtAZ(D2T-NZo z`j~3XewMe}RohkBYOCxl;H2u<@TnAe_PvZ@jx)JEoo2iSsCxIL@HCz|PRnFLk@C^^ z>P^dv`-FQ8?{ul9%3^S7Fp^?JfijD5gSW!1AA9|Xo9L}7tl=+ug=Phgd3;^y_a!Ua zeB9OARhn^bYvMq+5%+Kh&!t6?N7qu*GkrDhXd6_VF;Z!lrny}_Sr)!(+ zQ}x`UY+8qg59PR!HF?XFJH$QORP&+iNj#7n_;E4M(#yh2iX>a!Of0n(cQFrHa0*^< z3Qe#&`w9a_p2vV<%Q0~O_ddaC0#XY3R6fBVzn6fPt^7JA^qj>0pp@@7JX$p+rxZ?e zF7gUHu~zPWYwtotHS81r zmEQzz0oUlLe;_D>maCPk1!%Wu;n;0i^^`k4bxe&jOT?83Z8`HhD>$n~q6NiH(i7v@4lyD&IOPvHeC8@82-1tjd{3M{YPZ@FT}O{X*pz z^X@GbEfVg}ZpAL%O(XjOf}a#97_koH6(|M2&*-FDYr~qFS{h!~ZXVh%PRwNO_F+{d z+H=FUO}Q1WJLS(Qf=%YSG|?kl_l&PgcwD+F4tjZc{c7z54=bN1a3v88e<N<$8;=#7LsnHm*|!imClddxm_K4xta&pOY`&0<2dnbmp>nZFga8%Fep^|dO#?-qrZI&-O- zml_{@A=L!(u9Z|=@>dlfE&qzcIlWmyU%#Tf zfm@oD+Bvsb>1A8~fDVS>9NyfwsN7JpRK_?{^0%avpoIS~>HU4(LEZiR)xp(lP_yhx zK4>lPc=n~t82yU-BdT1Og$O~ zqo0Ytzh<~fs3XxK)3G~BZHH)4xJLT5__vhF`d1+6&#XOZopQl^X}GCEBc+U97dSz+ zmLSu%mDdJOXc089)T=QMxPOT+SEw3yzpzUM6_Hd z&qX^eAeR>%{SMuliU2RXR^lHVc#WAZ!WE#7EVsGo)(6^>9dAu#kficS$6f{TD%ytb zE7n)I%{ACtmx5kr_wWQd0i+t>_gyGgGLpbIQ{63sKN~7^uW5f%mt%qD`|1|$mwuMf z+hOxq?zCwxmv-1G^m>x0Z`A#26!WnCP~m*G$o;&?RcNfWuvWUl*)K1){1?wPyyXf+ zh=|tPwyF1|yOmykJ#urf=Ke(>>xHqO0WOWBkHKS+fqcs6uA=wh()C5lBd=oR40HwY z6!*vrm#jYl zzv3g8(@x@f-~IjPvQQTAr*C59q^J{JWGH(%?xZS;mTfKSFI>5Il zbEJEak$EZi=}eZLr;hmcUHrvczUHjZP1?m8DMRm)jh{O>1kYighn$nP!ErjSDW@07 z+X+qbDNAp0QaP&lY5pbzfH~p|2Xjm0%w!Pchq4&<0jB6TDV+((Bpe=MW}w6ceu>#- z(|0^6ZOAn|X4fvsZS0mDlutCAs%vF*ew7V<sl!j_iDj^GkBA9lax=LFpOOExP|TEJ=)^01%hum zxU_sh*!dIp;;o8|ljyZV0n^Hy79j|clUbp+e{T7`6j8GqdJB6CFY72Tl`-#G0=&rr zGIHekG2K5472;W8D6sbJ_U*o&w}If!eP$%Vz=>c?_YdiOQ40Bcf9Y)W7;#lr{eIve zxsrA#V%ojyamkuMuj}iDs#q+7$f$y9-$L6jg7RRQFE%?I|iNluesC5vsV?E68Ub&Fv|Q!Lrw7>wYRE_)`I+ z{R`Zyg!0~IZiWGfP8rZ{af8z)eHHiH71!ed%_j^iH^|K=aLp$;PHQ+iPC?=0KPCxT z_;MdsyJXFs)(9rNK-2D^trCEzvjnV79_IB0MmpjCdZEH;oxI9-)+6{|1<>n@!vyoM zgtD$Ord$=z4hZ!Gb5H)YM}+PFS|>%z=0eUDW$-bB{Ea2w@pR*TMAQQ(>5V0cw?vCz z{+v+fk@@8!BIhDv?Yy$qAy!65_|nOgKEdT2!TO_PnsC>hX&bVcfKSx!L*o-kL*~|n zBZ+rZ55zJvGq?d_nL^L|ND`d6b?Vsar8n)|H`70Zqq8zFqpTxX654EJIZcFN5t(Ee zX{)vMR!BIPYkWUEX+J!Anm}nxz1w~*o5A}nb?gub@Nqqc{vtx}TJ zX8OY}XE#gaX@G>r1d^gffMc^kG|Nv>g2PF8)(QCC+D;(zDaX@^{k?wbv#aP!>hz<+ zo+p8&hvVX^>EbG~ZH44giyVYMdsnw$SMcrr=$>2Q>G;Rhl*x-Ii=TzH&B}kwB}(`M zz0AHrSpEWXA*5YG+Lukr;AIBV;{@~@P7==CHo>emGz*Zc1*q_{UfF$#q3tMS)kOy6 z@rGxNqJS{+D52j)T%A8ZKV4K20A9dauKfz&&q+z28d5O)!@M|;6Z1EM+eIA1?2-v6)ka@*gV%#j!o@!qdMIQO+_ge1V1im&MBNGYoCTlDP*He=>Y4 zJ&|O))MUTSkQ9UGkjKBNA{H+O7jyiP5mmMQV}+ano(>bj$gmRoZhJowzQI7AF-%c} z6bBajj!eT9oX7F87)@*}db<%dD30wfHY#m4J-HoNOwLiG2#!%&gTX)Xw?RIz^lwn& z@2osvLV~EY?6)|-xZf7cHx|scTC%CL4pP>@?7CV@=ICj41&hyu;9+?1@P)-^N3cv% z!Bjy}+Jp+rzj`gS{kITVekY*docAC8x4hFHFmEft3d~PRn~)`&kX0~j4&S3KjPZu14UWzu8Qk6jj(KFZ{8FdYn2b{A%gh)=?4CCWVi` z_yMGTNWAdo`v~}=m~%!WR&JnjUmA*$bEowL38~BnqU@TRn)LWn3M6;=V|i`%MgA2i zly3d_TBiqS!yAm|Mbv{Fz*`YtP1#Erz+1@fNtVXzkLiVEuSaVN?g}qy16tTi0B%K- zt6pcJW)bQHlPh*bCv`@baQg2~qY7o3ojQb^!*lwla{3QsjeOVvoD;$#Jk^A(%S6ER zmdGzi%{C%Q%zM@FzxptD@+%ELe6|q@1l-p#^v>l_k7T!^4yTH^0X~5WkYQM#3ek2x zefL2f_$1E;nhdx!zt+CGS~_yw)2^8*nLkjyrmnv`tn~RylDqyf9|+Cl9C@mF`ucRm zY6(_4yyKgQkd?*k;bh_O2us(8pKhFp7#OcG7cQ~v_c!yj=r?|uGkj6!joQ)@;-p@9 zcm1#Is^Cl0M$(068(3#Jjjh2=s`_i?$PyxKZ=b|a2j2gXd-EUEt|#NapY}7*!i;b@ zc3w69diX(dT%Xsc2t@8gR!g!=xohZUdrRl^-0#-W{_K14_DMU)0XJPjt`KY5(#e1n z9!68CfC9?{JCHR9>@JNrTv5AsyNT+*6hg_!gDTI?6PS$yQ$HUS=vObUCe;-pG!{js zs*#GO9vS~i{d~fH!tQ0w7x0Eh-d;H{mClAXc=e{%KZw^N99_f`@hR5DX$w5;vFM@Y zbCa~lfFtmIlDU`H^x$dnq3(I4pP?ip`{*fp;ze(fL9nc*z#M6haNc58VFI7DEG|^4 zwt)CVu2vHNo)PXS0j01M99-`*EdPYJl~Azyc(|{mW5nyMKYg=&X5nzXY^<&AxzSv;9$2t+K_355-|i zOWU@;sahCn(8@r&?rMn{GcQ?%#B3#gxKszBTnr|WxKxAW*4xqScgB(1lu~4V+my)~ zBIkqBuTE)J*@`2W!VzhzKl$!39&j%QO&)qp9ULSS#w`FT{4^2lMWQjE-%E?e(1;8E zGMlR3dy6=_gx@5>=BzEZg0D)@w-%v*}X$W(xKZ4Y}c~MS1_?peI zpKm+#VhD%Uk#>EWi%#ZCL7XP`==W4jnY}IC7DQD>dJ5$(@gsI6QaTwnCEHu4Ogp=1 zI|X)i?U*8iX06lxk3vU1g+LE@O1Z@#i2*sVg&f$Re{obpG^qhG62;7>g5B75&?$4@ zY8u9n?35|^>kWslza0Fo1y()NXa^t5HFBzK3%(l&hSkontxK@d!Y#bpy zLAIght(S^NJlsc<(APcCP+52jfXSnw1G#r+dxcTi_RRN1Z)>Z?skiN?=5q6iCcdLl z5WH{rGRhTx*Q0N?Hk?!!1EmB-dnC98Jlm{-7Oz`d0DxjCe|6BKKtpceQee|sK1m9h) zf>4=qP;=5BkI-gN*71jbQr0Zkhf5jYfnLrr?Z0T&%Ynh8)<-mhIt@lFJVX1F*ybHp za0tg(CJ(XygVirJ>XV0W#`M0{$Z~q%{Wm2Y(~~Tdb#jLbT>X;GL#zu?^QtyhX?>p6CnN~vi)F@TEzo*}WhqKqes=&Tq|xFY2o`(K)BAeIg6Oc4aEO>J|8;K8BBsgv=!^uL?VG&2fBW^mQv6kNNnkHXx z$WoDHF+Sm%rchAYz7T%7s5ia2QCahbu0LF+^^Z*&TB5V8k$^cKgaKC2b1NO1X|qmm zI%Bs^NqbzSbVHf@h3LI(``%fxBAHQpIj-K+GKHRE?>f5fX(546sq;sFY&0#=iEnFIZ4D z-4e!fWVuSYr*UGPrWO(P`ZMTBdZv(dAo#_) zaRBLtcb2zizLSUhEK=Un7%M5}*1wmW=9$g!oIl1L@%u^V9-N9N5*lk(BQ@?^S>{*| z!qQh$K^2#P;izv5Tq-W4iKN*T)_Wzv?NJlznLhqp*U9iN*w)VawwKNU?POy5lAmBi z!+fHebKhpi?)7&n!^yI9shyli;jg|;V4*Yz`MKK=e{gaNh;rZiBQ8R1(c)h(eaW!7 z_Oom& zHaVZD|G2(6QL|$Aljq;-3fWgoc@~=1KaKj$O*CPAZ(Jb!i!~|PyKgyo)GMj!MD+KF zoKMm|ImZ*_bVv8)E}Q8a<$8nRHw89b350Sf*@(KA1|eillm3`cZPVG{QTHSUjFfXq zWud=-yhd`C7r|^hX&>M+>cpSeBQT+y86Z_ix!TuNZe2$R~yE}IYf z#V+6;uB%G*w1({8l;k znEh8}8kvppNi~@LXE^?anG=T5NLDSj(8zjC#KMZP%guTX>OYx(5tpJDFvP*jm?(<*Iq6qojt z^W~N*4T6Lg_Tv48fRPuRzg`*7N$lk?Q8=VYZy8)@jy}AdE2prvJZhPi%8*brMT02s zFp(E_V8c0NnHIY6C)S^6;Z!Gx=%~|?kS0mQfsm%*?T{%aG9_x#Br%C(+ciZKY8)eF z6Kc?iL1Ww@dEAZIYu_w!U_aUK+4_r8m_H_1g=OVJ&-z#mwItG;?D@7QW7AC(p((N#4T<*o25_;?$ZTLp_r~h@GRwc zJmxM-uNyXba@IY%`w8c`kBZl`a{A-P8P{)Kfd`B#Ya%Cj?k8C{uZ3Bc=rR>qL#SY; z?4gKN;|MrjHq%fz5`QMZAjd1TqAoT@P}@h>|G^Jb#DCq*ygvuv6X0KLnV4n9r+6ut zHK&apI?_$=$eDGfjGDFOIyR=)3<2emaFV?g44TtAoq)d<1}aGY^)}trg!F8>3I=>X zZ2OT%h5q&2`>Nx?t^fz09S_09#A5X#k_umU##MP<(86YGK15R{3=!d{!G|R6-lET1 zV-_?~TS|CdESs|7KgVigWL5@Zo|Gfq8PO zp(^Ccy1N!sz8Bv9x<+8C?90xSPt!f9ZD;V<6a}(yg;0>qM_gP3X^ONI5a)8?n1(9Q zk>#9Xew~Vbfjo^~lBA|Eki~6M65a_GXxq*$MFdqH?#^3sYI2n;(#pjjT$B#gToae1 zOT=p%b5@9f4(9kHB`$CYx$SJY3$Dy^hbrxzkH3MqiSXp4tJ$^YDIxujvbTFi!9K{y z@QYXFxzdeiAPDJbf9~WUI*`ZiknjGgd~4%(?%KS=s0H6s|L7Jy^vc$1gM(@4C3Z>ADt~JD?D%hry$+``36)j|e-Wyv`eExlb!ay zpvn;ZUq~Cgx>p258eo8>*OT8zy&^!@0Dg>SLhb|DQiP5BJw!-|NVBA$gQHuo`lH^~OywYeo$(y+pd0fj;85<4+ z8G8mMHCt3A*o~8Kc|4SZiIssQI=0{jB7UVZcen$c?fYPW^^S3H09f>o;7`ud#+s@g zx=aPnK?>r-*xqh>{bF(0JtZEgkb>%q86V6 za&bxUx|L9(zW-1`k_`M8m?}v8ftAWgtogNO%zqgE`G$Y+lOZ7KA4E+xO9Gs59n6%x zxP3>80tOgocDN4CiJXa-()3;j*woFhLOJcWO1rj7H+b5Tf%>Ps%70cJ_1hZS7qO8I zD=`sdDa$c8QT~BUcIm-3Ft9>&@N+=v_vFt31>bo;2ZC|`;)=>MwBm}&Fy!HOOHoFs zq{9Wb9_wmIky_50tQ4iVB79iI(P`6LkqADSdD5zB6F&U=*et?-xGVOFF;B!=M3XWB zPxODm6R%sH^8ZE7aH28%Pt^eRum7O0Q3Wwc<}?vWGIYHJ6B4r5EU3X4P$#M}A{Qw6 z*@-yw&bwQuy>=zpw0->C9vxthvD_`*!s{Qnhi zq|Ka@xdQc)oZ+aYN$T_1?9Cf$t9a!HU6+9GWO#sjy z#!_B29yYE|pf(dUn>D_!q@oitlLZ>RN*HJa$7sa2wJ0)LFWH&b-`d`C*eG%6=`=qS zmb@NwH2Y_Rix5Csvqi+d!2Uo^3gtJu$n8lOu<>?EzDhot4S7{lbjrg&c0W4hIr$ad zLepwKb2h)6zWF6H$Dq4o<|4BH3&F3>d=28l!g+-jT&udAyytp3R=YhTdi}<;=?2GuRUg%^sJ;p9SN6~Mlpn8kTvZ)@Hj;y4|nLR#3lj4hhek=EmZ_wad z&`?~m4U&|76P|?wLv%yt14Bw~x_cgW?z|QtVz$Yuk;Nn;n(Vw~aC@^~ zA$ngD^UN;g6W^N_o7|A~Z2QNjrNDdoj-Ts+7>#A`k<`I=>9(}f4E+ajdWW))(E3Ti zuK><2+aUM{n$O2A z40yL3$n`pr-M6f>ug0KUgBuXqSJwF_?UDu_x%0hvfqM(LU)}_JH_5nDl1(2tTMQgQ zXge$uhkg+pIc+Ehc}DKTT;PZZy4eT<_51eL$ZRgqoo#cHP&UyQZVX!RB5;zx#ZB-@ ze=6KX+6N-!<*2$x#bg+NfmD5kU`;vJ?g2&P;$e&y_{J9iq4C8)7q;?;TM~ zAS|4BL$*%OUyc3qC}f)=(c<1IGS1uR^h~4tsfaAZYt-x_+aeNDTQ`PZ80mX`oGb18 z7cD3{C0Qdwdk!4UX>WBEB*K;3s9h5;>*be(X?n_HHtH>15o-AfkH&pn%)hk6$DZo& zWxNG~h=ZB-JP>Y8MAqUbZ%_w)mL_b7UzmQ3CtrJ~j3s_ut`65$BmPW_UKJq5w1Fwh zD_$3?v8e?grLrkZ`>ebv4F9aWE)1WULozw0aS4dJ~s zSJ^{>c`u-2Oe46$M)FbSQN|~otk~U)=X=rxNyT}Oe9%GN@h#7TPtLUL)jf1ZvrXs{ z&=Ll_zfIP^sZj-33zdkd=~}JisI}4CLN%F9W`w~v=yRBU~M3SOJ&(ebmaWq5f)#kFI)dL!0A!`qdn0w)|d85cq~?GV_Lw|>KyH@+2MbDj5kbqCHwA}UMIg7H}*0~tpxqB7rMt3#Ct z0(^*es{s#|cnAxW=)+%}E#BK^Ax8K~v%%qaS5GJ`o1=>(2%ng<)qu_7PY?9^_2RNDPoZ6JY+Lx({@fe#FqpU!!(iT_?q#4#36 zAArq-V)bAj{EfmIA^z(jAd$zF<7l!ffo3%@*lUo9a_pb>?IYQ*fh^?OV7*hSR)mwT z@3$oNU2l2O<^u3;!aX-dlu{~&Wbh?LQE`7ceER?vMchO4r@$-dWYR#eHsmJ>;A~{^ zj8*Loi_4KY{ftIPNq`%8{*5>zAZh{;p-1+VuN8y5o8Xko6T^I+0E>zY^X@By64y`F zHyk2%pAhh}&}l^J_dbXjpvnaA;|IE37%Eljr%z0RzDhXVy9r3btRYD44+<@S9B@3joY<>Ym)=tJ#bfy4B zLmbZ!^y}3VRJnt+VPWSv^?#el?{xCAo#T#kpm;&0x_^n@e!yCO4(nk7C=( zURs5lrX(iMq&O#|CCjHUryM2gCJQEerNE{1B1VcgOdI><;ojInJO45 zn6{6l^`#BybnA5KjOh$44=#@{PqQ?6@U&#QCBL@pw_B*&%4Cw9Nf0}LJvW(sRKv_O zIHPRoo;G>swROm&;%5A295v*Q9|4KLP+&SRwJ9LN_Nc1iv9MS0 z2g%TJ^dzSwD~*0MV*+HnPP+)w{H0mOUnXkJj*}djGL~YSoSr;1x;pxHlyWq7R0aAI zx_vCTL>sJNJZ>^>%wk+_RBmi%_S$xHGSkl1?oS235O$0 z%uJyMP}6?)aCTY12zv>eH3y7?`08LfSN$hd4PMRv?)G8NRA32@o64;K6dQ^HwSw|N zC7>=)GN?Dy5GoDTgwjH<-X3|lM92KU=g9xpKT}H5!e=0z55wP%xdn%J&XuAPUxYoi zzeU>L5PD&Jw4d8Aj+QF^@QhRcen!tVQ}g((Sn^=4TqdD`yIjxT(M!#OHDHlaNQudP6)0W2iMJm>%`!CAS?aB0Y*!A@5!@C661JjR(2W<|Y7+jAJuE*Z`d;0mQY>5{U6%ij%fwIH& zy+#ooBKk$7|4l}WkC>5uc0QSYb-t`1VjEL*60r$HN%Y_%+>rg{NZPA%+n$Im!e^AF zI9wEFz*0CPDvBX8yDThw$*n4r8m7jpue>bwm_2S!Q`C)1bbSf#vq11z zTx?!C78g7w@@-`+vXCzOq|6i_Wi;K_sN1$=EIAJr1GnI} z_zRtV3BoZS#$tXffCVuQ3t>DK#v<4ilW;#Cz=L$ob~+~;X2)pEfjKb-b75}GgL$zt zcER=dC2nw|xw)9fRD(t<^6jAC-e3-0kdJJq-}>JinMuD5zd1rrJm2bDM?}75oK4XE zunC}KA*@ff%!1-(zd2wIn(xga^Mg5Tj+mq77}mpnI2m8VDfl{0#cB9H&c->o8rR_G zxDGerR@{bP;||=3yKpytgZuD1yo^`yXS|Bn@dnG&4Djql(Ld>3cpdpPUw*o5EXA^ZUk;}JZH z$M86wz?1kRp2E|ZhG+0Bp2PEa0WacDc!}(<{Obs8Guzy@uq{F6-9sZeZ!VaN<|lK> zTsBwC&*rMRX0DrG%nfrB0R>7_=%L1@n1}=MIh>0h;5?j<3veMW!w+#eeuOLVV_b=! z;41tS7vW-Df=jKi(kkm&Z3EU=wAT7I#D>}oHq72{v)Tu2l+9+d+i07^=Cm<3m(6YS z*t|BMjkWo00b9_<*+MqnhT8~xpN+H`Z6=%9X0cUlRolw8wry-%+s?MP9c)J$$y6H2 z9q#`fN0LAz89*cX%BmhvQ7W6tr()%Pm0d-v94e=ZQMpuZmDe3r`Bec`P{pZ2Dqa;3DsCNk>AThs;TOr5>+$RT(wXw)l;gKYOUI+wyK?KuR5wu^04Zxx~Q%yNp(}n zs=Ml;da7RPS=C$hQGL}js-Nnw2GIUM^_&`{2CE@zj2fzjs}X9XdO?j+qg9GZrDHFv zv1+**rzWab)C4t2y{aaw*VGjCx|*uqP}9_#YPxz$y{+C+Gt|3krg~4!QtzwTYL1$# zK2Y=2e6>I=REyMNwL~pd%hZSJBeg<(tX8T|)GGCy`)R$_5 z+Nd_E&1#FT9(_?NqzeZnZ~!qxPzA)jsu|+OH0%gX(*ANd2G=t0U^DI;M`R z6Y8Y;QJqq!Rhl}Z&Z=|jyt<$+s-M&)by;0eKg$#9s=B7Gt6$U&b<+b+c+yjz=V>qC z84o?{`Cf<@>Sgf4yl^kVyH6hVBE5`WCNHyhzn9f}z>D&-$s>BZ{#x(QJN4tbuCAvO zbbZ}GH`I;v6S}c(qMPa`b)s&jo9h<3rG84c(yetH-B!2L?R5v;QFqdvbr;=LC+TiF zS$Eex^wYYh?xlO{KDw`dM)%YG^#J{>9;lzwgY;lML=V-&^z(YS9-&9-7xXASTBqn2 zb*g?zkI^sdv3i^yuP5k;QL(|AS zL2b1#iKeBgX&y7ROe@pcv@vZ>JJa5DFda=N)7f-2Nv50WVV*WUO)t~i^f7(SGp4^8 zV4gJt&2wgu8El4_p=OwQ-V8S*%t-Ts8D&PB6q9ORHe<~=Gu})v6U{4Tl9_B?GgHj# zW~zC^Ofzqq>E@vIU8GFuNus_+$_KLk~uiG0w_|o_MfR8rK zp0(%gMSIEqY_Hj0>`hn?a!5MsCxcSlx-Yonp3vBp=-wMd+V%TOdiNqJ-b-f8A5`zv zJL=xstbFg9ndZGe=-&cTz(u5iOGpKmkq#~oD&b1j!cWa=^VuC0aU*HsX0zq@x@h*? z4P}g82W7AZ*2K2h4%=e~?1-JPC-%bL*arvUU>t%&@e4b`jQFgRVu`k+G`;r}F zU$$fII6K}>usiK8yW8%u-`KtOTf5JGXZPC!_Mo4|5Aj3&41Sm&?nn6d`H_A`Ka)?j zRP^47z*w#wexdgRttxm#Q1Z*5h$wN>%f zR;628m2YiT`E|=aMO$2hM#s``((UzSbPD~p{^p3}J9GPy4)j}o+Y#D|o=d-#x1BSa z@4#=*83i&&O!VYi$7GJs=;3s{_itLi0U}4H+mGaEL_c}!h|JN>>v)&yg7k>_A5jzB zlZxQ>sOci+@_$zyK(TV;AL8Wycm97{_D^}&-OalG?KziC{!P~PujE{R?m2hPx9)zf z^=FyZJ@TD@;yHhwU;QDwl0V4fDxBYKzNlVGf4}+PYVvoP*MBq6-({e;RoB1fptonB z#VPkp&piKn4eeU{eMbAoeD=TD?EfK~bx-4t@AX}F>fg#wf0vuur(7oLd-k|J?kjux zPjb%x&3HxDG?66t%fs>{MWajdI>j5L*pi8&Neo4fc#0BbC?Zs&D3CyU-<;IF6DfIb z((NIn)2XCFlSzqZkm@cVgv_*;5GGHdhNU}UJtLYH_#jAjq=8L6TKqPS74&<{v$S+5c-%TVRn?^o0oBU@P`N|sdi_PQ%d(A;})SNQs%@uP4J$l{| zn1y^HHx|GmSQ5)(C9IBhFaaB3Q*4f{$QwFg680cp7(jk75>s(9PQw{E7Z>4jT!m|K zJMO{#co<- zc8Z;DXWF@TkzH!ZH@>Bis{$zieKf|BxFYuT7EB!V8 zdVjOO!{6iY^AGxm{geJ#|B`<_M228USV*RjsF0YD*pT>;5+P+nDuq-JsT0y5q-jXY zkai(mLVASs4H*d1%PvoXRACTDHB?cRk!q(y(3iGnsG)Q`1?Cb{VIG|st;W*vrD`0V za|}+=_8GN-cu{R4-cY-!`l{$<{FylKBF26mv8) zg_+8HnK_m@jyaw=fjN=+3Ud;3GT*n?m{XXqGp91&U`}Jc$(+u7i}?<726GnQ`S+Q# znRA$PnIACcG3PTE>SM&k{G^sLKV*KyT*3U9`3Z9sa}7V!&zWnPUoh7(|G`|({F1qW z`4w{$b1QQjb35~E<__jg<}T)LN88WjA+OtG;z0)9Fr~p@QG6KlVK!2v;~0Pd79$Oc z#q8#SIYE2H@e$0A(dME#NqZ%*9O+aJ^OO0J_8!FYSP*lXOXd{qmBb1dhcV`|IZb<| zup$=1T%>Yov{#x`Ego~5pUoNCdk8CIVa#K$nzOW52CIE`9M?8i)cs2fuS4$ed1wo@0G*&?)6f`bDqY*R) zL6!@$SCEyGlsSP|4-jDa|S*bkozQtKk;*$mAKA6K-^@bh+Azo;x?O|__d8D?yxzCJ8e$lE*nGKZF3R7vAK!+ zteX+vSyE}dZ1WMX*jVDvHb3#IEkL|(3p(|-6l?INE#x%Z(hRcUc!n5(XNmXWIkNW} z{(=W_gN?-VbSxuYAZEgg#LV~;F$-S$kFec6Awkba(9;q0R0KT}K~F^BG5Q^+AI$@L z4uYP7pnEUq&I`Klf<`Q8yn;q6XpDkJC}@0wMkn0ZY!&O?4_35QgA}~q%2K?vt!;B+ z8{2}|)_o;mYuk3j$8CFJ1KWYv(EUsOpBxv|il80m=(%hBqJv@1>dny9l_ihrOz!dl8wBDf<^s&^IuIo}ovPNI=o;Ka*IcD`^l#ePgqx@x*IEW{EsU*cLg$I}^LXEP z`xK#z@VCT*?rGlOSKOYc&+A395RZUj2pDsmA{0>lkU%{Qphy#fZ;~d5;`cN=v)IZs z8{=&=nmdK*Y&7R7@&U!OrjQ8}DUxM&-yuO3icX(GRx3y;;@ww4(3ECyN1%8I_mgd| zhkDdQCW>eM=xo=|{S;rOLRN|+b0C_c#%d_!zPN&TT!-tR2#>a?`}PWo;n%nuO7O@Z za$jFT8M5vwl*Q|K9U8gs?%)a1j*8T)v-e3-gW8ZtYVbHT9|sw$O*}YCo6;-C#O-?L>GN=D=k5fR;C5J}uK>A^GxK zunfMVza4-dVH2E&G}sI0;3DjUOK=ko3Lz@MNl{5WDhhaoy%$6gZ?rc-jP@pZuL@Uj zeT|3+km-VO)oG26QBs)pgx0CH;*}%SGr^$wP zhMggwu?zsK zFW?uDo%}+6VcFR)>KBzsesRCJ>_+#crKl_Fk{j0-ooNPl6+IwI^b~y{Mm!_>L0&OX z42D=SR6GxHVuTn8g~ce50!2lt7y~85I57@NiHTw|lonIO6nI2T6$_x8SSpr5eX&BU zf`($XSPf0Z8nFhR6kmvSkSNxRP0(Cy5nG^**d@M&w&I{T3!TMzaS;ZH%i=OTC$33= zK{THg43}DJ7%2?}%ok*c422XKF2f;JM#@NdNoJCnVT^o0W`nUZTE@TxnOnxftFnMB z08?e0jE6U55m^hS%Q~_Nd?FKNB77;E%NDRfJ|&-mjk2|D1Dj+!*%7wLF0u=JEt6yt z?2z4Mci2ga(i3*cKC&xn)G^{Eokv#}FY7wwH;V&ZO-`|d{iZYfO&9i?uIx8S>^I%mZ<5(> zy0hOr&3@C9{iYZDO>g#_KI}Jr*>9dZ=&_L~vxH>22ZMw7;s!MfNG zpTbty8r!h8_QhwgKR%1Y@Od1LBPeegK=utMyC#u6WD8j`)6ODG=2PFRs88yTdOKu) zu!rptdzAY8(Vp@%`&s=cKbxQ3kM?u;IsF(vubrV7Uhse#OP!b~b8GRN&U(l2p z20{Y)!3)#~)P-Dugg_H0Xv&-NP~229m7s)ss|pXAR;DwQGF?qKsAzhaXP}DdZ-ziE zGt10}24=BY42fo`Sqja}hvq|QZay*}LkstY5?VQnTulohw|c!0>{W5EG2BxD?x`U6 zRET>j#XXhbo+@!qHMuSKCAlyKnWd;*N$vgwKrMEmJ0l^B$z_U@CO>E%f&1M1VN&Tz zrW$1DwsUdYg}Ch^)OHG#HmN2RYMPhLBzVkBHg7?F_db@!;`(f17Mg|7p2ygM$Jmj_ z*onv3na7x9)|js#*=#bKpr6@lc0+%Th*aUx&vXAr2U5k4L={%QE%cZCf7?rr{WCvt zv7IuT2>_H^9E5Q9mKL&6#*zuLQ|6L|Vt|B~K?h?&0mx0UpfE)Q7YkxJ7L=q|&>Na? zEa*(C|2B*zy`K#eI10Q*QD7lVfyK1E&aq%B#e$QtmSVwa*h;bB9BhLN6cM&lM7Rb! z;1`MudnqoIhwnHpL^;J3F`|L!EOI%;6%RYb6&0Q0imIfzgXk<$Tv5|0uBh!4S3K?% zS0p&a6%C!@ibhUx#gk5PMWRz&(cLMoc-kqh=<5`hS|r7#R!MQi0H?TOh}cHUP^Y_M znD}0trPfJzsXfwN@w(GpF;yz5#M@4H#XC-S#SEvr;ytIk;(e#PVz$#=F^6QGsQlqE%0 zRjDdfR-?>yoP1PmP#a`*FSD0f)^Jf?)^t%`zT=|2oaar^5psdkZPN7YPo+_%cAl0HxK2wb)eaRP1LY_6AxsRWY$Tkr zg@X_w-8VY-(X-A5k+Kj)`HURdGjqJoLKR3~$V$<9I6NR%%heDix5zD!jp~WLkloc+ z5KWcEQOH5n#c{~#>M4k!dg&+9ey5)W1Kk4MU^LYoeIX?aqfn=&}OQ%w+|lxyuJc3zrXwmM$L!(5zz=bim9!r2cao&E5FvmZt| z`(ZTMe+*u9_QQB*KTL4m46itEhDpww;Z=?t)BXoeP|V%{004N}V_;@7V4T3f%D}+X z#T3E7z~Bv`8RHm?7;S)}+^ozXNd}e#2B!Z^KnVsYa1L>CVmQFS`~N@l@_*kM7?_tc zaw;$|&Iidc@iT1%QVI;r09mUJ7XWzL&D?jC6~(tN@T%(SK2=8$BnjwLpBbVs1QAgX z1tkiiNDwoqs7OX7gBS=BRKNtNh>0O*!GK}_lnjD^5+vvhASx;X3c}sHzxDIF?t1I3 z_ugO6wLa6sz|8cit{tkojzWk~2oVUO%F|H`QS3?~1^<^zUzN$%1CdU?9?4Vmbt_Kt zzfb=A&+&i%Utn69cIGBC#hkLuOncMA^fZmkU#5i_Xl^zgQhQV1rS_%vrw*hJroK=8 zkjhULnCs0g=4-RTY&LCdQ#!ATqME29nuvQuXVFUx5M#x&Vxo9Wydf5e-D1BuD1H)u zN+T=C%Cd&6DX%v7n8xN_d$YO2{vdCbedS|vw0u>5CRfQFa-Tdd&nTrzsIsc6x<%ck z?ooZzH1h2j%gM7EI+$lK*TvbXFZpOml3 z+42oJLmrSn${%Ebs-kk$)#_4prMg*7Qg5qQ)l}QYwlb5{9Jbf78#5GEbY)W{g>F8>p4?GLts1n&D=I+NE~ewx)?0Yet$sMPbo` zuJ_HNofssBiecg@u|&L2uW*&Lval>E_uB*Zs6A}A+VAa;cE8QHN9;DCiEUjn@+;h;!RJjf2J1+{`Y!PUWaL6hLl z;GUp=Fen%r3=75t%jmMYoUWlS)0gYIx}I*N z2ZlAWT4eRhnvk_3YmEzC5m(&Bu7a!Ku5j17X0Da%;O=nuxjt^78{wXJQ{A6&DlQV2 zjI-iOagF$jxIx?`ZWVWkZ;S7U?}|Id55~RXKJg=Q-?)D~FdiHajYq}L#V^ON$9eJm zcuBl6-V|?*cg5eu2jgGjyIra`80rbVWAW?*JmW_0G+ z%$&^p%m?WLM0tp4~3{?(B})le6=)4`(0AQ8`ggk(^>VC3DK=xSXmv z&2u{C+@G_mT;+0A%WbSMzrxx|Z&Xd?K9JiZ_mRA3@@D1D%Ud?P?Y`i&I(zQiIl4xL zMMl&V^~5y!IF0)?_w8yQjk^dU8utr=QbD<(Mo>Gb`_H)drg0w}JQfV6 zaep?L5WE%43g!g!gN4D`;8<{67u6+nDH`{Sba`D<*Vc7t+^^D&^%xrW?#Z~Xbjqb& zG3Q))SKZZd^<87v!nJm{yH2jF8{i&y6KUM1#UeIw(YSP+i7Ur7<16Eaar3zKKjYph z?h^NoAC4c5`^5v|LGh6I@%ZU@d^{V$@~-ff8-yh&yE!|C}>x3XF;EWp#`G~ zUM#pGe|$mH{8tM4=YNQwQcyPeSpMHX`B0zaW5q*j4z)a#Rj~R{k%Bb^Yv^CmxfdKO zI7%On=5IMv|4_X{RSI4?l*#`fe|i2K`f9s^)&<@2Y25OEA&bbn`7`qer*`v?En2gyWFm{G#BhK`xkvYlP;Dnm9Chs zoUSQEx=y;@|NQsq>iqTOvwHulpO>!u&u6v%oBv8K{PX9E=_>pc{I36-I{p7oO*Rv# zB2q;)lg%f#iEU{Q+UxbjR2g@e!BkxjQ@uT7t}^xQ7PHefH%;t*Q%`46-7I1XnWCmG z)y|OeX--nv%TaA_N7cOr)y1cLU93m7epON%cZyHUZn2$eBUi{G@=~!+4WSO84fO!M zsSD^KAEqu~HuVAA1^h^T0CfR!4D|t5QzvjKbpcnJ)#@hd1SWAWpgvP~s+A&3cB5{p zt#Gots4j@x8iNA} zwH2SKdg60+mAq1|QE8Q}M#(?qSk;ND&E@iG@uE1V9#cC-5BZg-D$}x(xKn;0o{^`; z0o73)QN83Y^T!H_DsTP`On8 zCEu6J)C+2&nyeP6cd4iOSZ$E4sh{~uek51OO>&FeEJw*fvZ-7so6GCvDJ5k~b+_Cq zx5>%!dHITZUX4{x$(8B?Ra_311J#S_CF&n@sFSIpbM1QjrTrpZ$!@S~sk7Z?H`|SN zjooC|QT|P~V$xyW0V}g08Hq+Mc$T?PDLY58K}MZ9B-mWIwj^?NB?_ zzGkP}rFNzrZa=ld>}310eajBCv+WW)%g(UN>?igOyVx$YdG>Yts(sf^vM<<0_A~p0 zonoJ|FWSfKM|Pf_V^>fW_|U#*pR^y?_wDE5spz@z&uF~uXZweLMH9?3;r4XN^o8Ls zW?XnI{5AY7JRbf*6>oSnIvNo@9gT@bMPnloy+SpRf*=Z_*P^M>l<;))Vt6KcDf~Nn zIXoLp3eQE8BOSeE`$l2(b`(Xa=$&YKWFi}-lMee{>a=gyx9L0eUHWd_LEox7>g#j^ zeS>bRTj?8hYkiZxS+~*c^)0%czC(A?_vr0+bpw-9w+yJ@rZ5OP|sW^&0(Nc&&avypB546}q?nQ}@w->4)`c{fIuJAJu>B zzWS{0r_bsBq0j?D88!=>)4CzhgF~%{grOc9M*6WZrH6$^KOWlf`mlw5B24Qi!}Ii0 zVIe&tJYSCti|A4M>F@$QIxMEggvIsPu!J5LmekLLrS!Amg<(6gM-zZ_=tq%d1g4s-OBu$+D+EU#Y;E9lq4ih62TNxvRe z*3-gE^c!In{bpEIzZK@{x5H}sov^x|9@fx#VNE?Fyj0H&Yw20xWqNj4Th9qE*K@-< zdR};io*!PR7ld{7!myrR6keqlhxPT6@M`^Tc#U2fHqgt$hI$aC%i&>RT{CQ|tA~ws zwXl({5jL@N?K^gX9b(_KgGD9TPgIuu#WixgXdowuYvqfgzI;a9D?b;H$X()bc}PrA zg~ZFsh^eZicwLneGgOY4smh7zDi+_UHsUMQLTpjji#@7?*sE?8hp5;6Lk$uq)L<#p zXereg8K`H(-)e*`uNKQ(wOn4J-j`L?hw?hLOoeEpC+Wh@0eeaf5tI43|g6 zlk$jIsp^Z>>KgHZswI}I+TtU1x%gPs5g)3{#Fwg}SgWoR>r^ALUNshL)U~pNdP|m4 z@5s_BPnK0P^W#Y5Xgb~x@>M!M0P-_BJ_vFZ9lL7|>{GJ8+Vmi(S^CTVTfZ^*h7Yx6q zd0;sn=7T*<#|2714IxYpvv9}BipZ|McIY!i@`2PK89_QcBJT}r<6IEL4FoOjlGJcjE$j;Zw?zm^Ri?b&z())FtXX>G1=nr*nj2m`EB)h z?6-M5mS1~3{@XnsiydHg`@j3o-+u$LBpts6Y3aBNWMQAzh~)9#1CqyKug7uy9jGDx z&qO}p^B|F&2M>U}-RDFiIgY;v$uau_NX`NIAUUQBK=K?u1d`|VVUV1kkAUPj`w=9^ z$5D_!`us~IpUcl6`FH*Tl7G)JkYnihD=4m?zk%Z1`#UJEpT|M*nEU~Xulos5SJLq$ z7@kk3K;7hP08t$Ge}Uqha2gcn*fXG}((!LlJde+U;@p1@6wPCPFqJ%Qybwl?2UgnFetg9nbSdkV3${1J9?#6Xbm0 zzJcdfVjL+7+&9PzJgUpG7$kMExJNllmH@8zJdYDJRRqlUgW(_E{3FrWqB0m(m_)5Vvq8I%s^7xvOS7_nFC4vE9X&;kmZ5v7T5j+$6-a_ zIwvc6JJAzJ+z%J>5|8GhtO8;r9jkggr*nbpmaOJ+>{SOb3cW>w=Y35OPaw_{9K*GM z>!Q5O9?f-G2gG%EHEP9=!-+76S z*MQ==*Z>68O4$$;&$(+sQ0&O-K=IsZ1YB!nV^DmJn*i5T*%TCC!)CxWST+a6*Zg`= zJP%p`*H_sR6kop^fb+O)1&V*hjlgwL-UN!ry)|%c;69A0Cdivf?%d^Ll_>5P+d+~y z+k@i1?G{M#W(QE*tKAAoZoLguXXN4}AMIUUO`5-8shh035nTJ484KBtTpk39YQG%p@%$YEifX(Z>NP|!&J^_o@^Np7&!(68j%ICS-ayOW&jMxRqR0j~+=W{>mp7U1=d{0bD; z*sUJ_oNb`^e7^R$zu6AzO{}F8MSUMY6wl3XybFBaKorl@T^`rI-Jp2R?(z5<>;+NM z$I^E`XYcdt_0qof@ArB7fbX3v_#Wb*&x79suhqGqPVl+sLvk;mz~k{g1cLLyVUPM+ zc?5WE!~Hr_TuYAvuXE&2pj!F<<7eF0NP3-L{2V&wQU5J}1;IVYZ@~AGlAh^zpEHj8 zdlLK_|L|7(?>~Y20!dGE()UfLfY;daPvE^_@-N`~dh)c_6Zbfh`yA!{>-^i-le55U zGkFeFYve2@Xbva|TwnSANOF(lBJ@m2-_!-UjPZRa&T&beqnx55;QLD4GbMc!=LiFQ zpMra=q|c)3q|zWppqEPeDIV)Wz-w$(*rV}O=L4@@IerqKl5){L#A_#sRl_2SXDg)n(wN`cgV(f-YkzWntdsxU^>8mc`F-5a^Utae+)wcOIaxzf{Z`jN zvUY9Y@tkbvagMtdl6!*JL6Soo0pH73je*yn+&3q^b0ySZ#`i{(dD#p#iFlR+mC)W8GZteR>?&aI~p0zD-FPO}mcK&Cy z_kI0v+|y*-*QgG_eUG{oxCX1+ykY1k65MOv0ZEO&6S%JPy-}9b^1Fd+eDc~l`ux=i zxVG{AQ^s|O*A>ayg2(SZ;5y3dhs1qYVD);tORcTYjmR}J^; zB)%Us0=S<_a@k1qTS-hZo*Pel)Hkcq9{0XuJf06@y?4kYo=#getqWJuQGQ~bJZ zA$lXeAC|1cUjweed|xaf(GMj(QA_kdiM!GFBs~=M73wWW)&_3_uQAj+kgN@+d;Il0 zkH>C?$Jc5maNntBd0gjad&RMaOxBTuechUiwI8ohc^#RI%>vNnuoh)H2kTp=%j5Y3 z)0O-+Bf1KnRWQx<;eD{{{r*W}smE0xg5{W94(Uqht(o0`=N!y(O}Fp(iQVY)9kEro_4R;Q zzK-93rM^>r3zqxEU0^v^?*>b~quK+O`<%UCIlt@!%W=LRG}rF~pt)8b1kJUEe;@U? zmSaC3Ea#d6u$*fSf#uwD7%bvHdu<)pd47r1wnbRlske7U?~R%6~R*82`Yi5oE20COR*PR0+#x#pbA*Z z-9c5bl$(NFu#^*mYG5g@gBoBd_Xjn>Ql1Ph1xq;~s0EgCL{J+n#bj_fSc=u44p@re zpe|U7`Jf(Hsvp5sU@7K<`d}#+1XqKlJ}|fr(mXGkK$_>ponR?f2KRua8Wr@0kaBF$ z2O_Em!NU+z&k#HU5!Hr(;x?dqYN?I}UP$#T=noOqj9?I?C~gDFi2=>ui0Vi17#ONU z!7vCZ{)6F=ru9HD0@6IcMnXvIyGudi7vGM4ShB ztZ9rRjKkH=*|MJu`hX>OI#V-5&KmLF)%y&7;0wQ!lG2=VpRWQ)NA{( zp|Yx@=wCDAdQ590P3s{2gTJnPo%i|I z&kp%(%qaHsT^{u=`fl%Qf4$jmKVFR1GWs6xsGnP`v;RBxlm9cj|6i!C>j(bjL635j z?&9&EAMz+}bXSl6uA4_|BHi8Nf7ipKb(8Mt@%QxdDE4%3kH5cSQ?g^+XJJdf(Do)01Qi+X`awN@{Lkn`grk9q*T z7(&jMy#AoRDdd=6>QOJGmqD2J*PA`*uQ3VF^Err7kEB0@kn`+vk7}j<2*UGy{IijM z9+0qz&tLp3V3f}tB&6O{f9{R;d5whBr|MN6&(YNoa=!k;8|(7|2}}67`=9x{7Q&J~ zkF4`^c|C-j<2QIbr#C`K{fXWLA=ih^9?$nJ5K>R9zw&tAZ-tO+#x~@qu%*wx+kHIj zfUvC3zdL6dO*VRJ{KSLG5HgO6@1S9 z*~jNE5LWcL^_Y*jIbLekAZhwccvd@*reGLBr;UzvNp71e!62dAz_nq>w{U?M~ zeGdA|$NFgqbA7Hk2Hqdw&IjHj?ur2K18~KF_no`q z!21uJ1K!i@V&G@St~~JmU{?Y7S*fcIf@+_u0sNfO)d4~I%3T5cJj~SxLHW>K4g6fq zT?2yhk81$@Ov^O{LHWmB3;cY`H3r_x>zV*RXL3z}_w~AFz|Wjq3*bG$t|joZD|Z9% zo=(>a_}PPN4ZMHU-3YkJ%RT!x?aHd zvR!ZBy^^jE@I7=l0C>Nh8wiSWg?k)$pPYLF_&%w75_pfDdkXj-s~Zly$IguazQ^h& z0`EC<&ja7nbW?%%fVycQD3`f6fcHYVH$hPTa&H0ee{yew;JN<}@IEa!9R%fBmj}F0 z%gq2mIoHhu-m~Rqf#6t~4ZMHL%>lvjG#7a9mzxKIYKEH+yywg<06{gwEd<_k<`x0} ze^A_F;QeQA2?&nwcY*h!xuqaDUX}sxV{`8TzhA<=54`uqeE|G^3HKrJ-WRtV_&pEq zBjCLz?qlHhb+{G4dvx3$U;!n|EIWKi_rRf%nk69l+0e-A>^B_wF0u=fv(?;Jxo|7w|J$w;Oox zyW0c&jMnW1-Usi#1AboX_5tsScl&{#-MRz7`{~_5;OD;Xd*D63?g!xKH!dG|kFP5L zegJnsh`)a04gv4+b%%kU-?$^ddwkuGz|U{oQQ-Z)?kC`9IqqlRy}#}k;O9E-81TMf z_bc!-A@>{b{#W-q@N*P*9C(kc`vVluqZ7b;W8F#M=PT|M@cvi#C-5^BeoI13u^7>7 zi794cir0u@DyI04skTHkr(=4}G4(bP^)4}^Ivml@jH&L%RLdehQqK|7?~Ler#MBeS zRGT8|onpF{G1Z-jUT55#P<%vGZ(^z&F~xC2=Mmoq5r6Fth^UstcR@t8B<=_i#cxcx zKc*a(qFfPoA(WpZiv5^!bIkXXDW}A=R*(4}GL2PC>+rZQ{;w1<^$juKH>T?vQ_hYl zS4T8 z8_|4@DF??imMO}^FiYd3nl+z;0Ww94g&Waa9M7b>XBFbN}7t!~`%OIj$ z6H^Y0DR)J5ZDNYmnBpm-z9e1_5&zzgAWd^A{uokx-Bv)F&;JuhQy&?B3Tf&A;?E$W z*p5Gkh+;lo2@%D4yc#0P3-K2aQB1}>C-{Cf|4fS8nD0yTyx0I~iiLP1q-j3In;=b- zFy?DRzbB$tinl{VF&6KDh+-zD{1Nm0XPQqj<&2o`IaBP%dmv3Q74L;K^=I*SkmlD; zxgn<5Pf@=ZQ{2ZC?-9jDoDV6g^>G2DI1VV*WBUCO)u5QqiQ+nRqNL7<&B~TBl|BeV|nDG7Z2`|Bz`6hWdd_3ow*BGQGj@_ffoOD6S3l&6z=9 zXzVhB!O*4~J@0({R_A~UF4CT1Y7%;T<&Wr^^b1*Xw49)2b z^@tg|4u*18W)7HF={O(ED|CDx4Ap|n2Vkg&%X|ceYDab&Qgoi##lg~i%Ps|$@?>@n zSQ@wNieM;)v#W!pej}T5Wj4)OL)SZ-`kQR(*9_&f?2ce)eq@gaOSvn10$5rHW={l5 zuRZ&Du(bBieu2>3u~d(;Ujj=tDEnow{QDTcIUyLzBRLTm$~iejz)%e2Tmby`vYcXIC`aU!1Vgzgrwka%UpZyLoTH-y zLwP5sDj3RpInBXP9?aY6zBkwyHE9Rrwh`)%4uX!0%7Xy&w2} z2)Pdc@8iks0fJ&Qw+|?)F}V)|zlSIH5l}Q2^G1WE8k;u;EPa38Sm5`w<&6X0|CIL( z@cUr%W&yuHHg7KQ`(g6tL7L`L9@W4+s%vQ)i`i`<^{s!aALZjT<@VE5k54P?y*PUg z%*#UlUNj+WyZ-{+C9lVL+SI)VcwE)BFuM0XXXZ>%n?BO0O_wz4qh61!>XBqymTizF zEX$US!3Jyy9oqpM492FI5E2Lwl8}0nKoTG!*N_`hNiR2*kPGA{BsV=IBm|BBwe~4< zMj9FO-v8eJo@Z2$RH&n=Gc-S@GNu}7EIzee|@-$}^n)5`k`x04WowclBnpe8J1x{qm|$i*h$zmC zo2Vdc6()*{MX@+g9Ps-9b1tVtED{T=tTs=A#@l@?7H{_^o7>ubW^>qO0HGpwMaP#n znR|U}LJjs_^OoKl3@{0M!gsc%(?jj~Yr+-z?L$jnGXROOobEKh5>{amtPj$I|1ZE~ zUJa(u%^g>qzdB5Z+V1>dZjdr-?jSBwNvcSKoG&jj%1BwM&zoC2S`V>{OHlac3U25|i0#+Cd~~W*opWZ#7R;SG(PWR41wvRq|v3Rj`Wey)Ou z9*&hPbbQw9FRf}U%x8IKkFT_*wjkebyPabL(Xw=71|vG3p3wR9D1FJmzbEzaTj+}h z{QV1P-A0_mL;B=yn-!2E5H~dmEQQp9|a zdnH>jCva1|J?WF;M$&!{uxt9ts+)U{#t&z~HVT~j&$^2*uA5rABO4CRqbGG9Ro1(V zM^~&{dh_e{cyQe=ShvKNEz!)n?*ooZ@kJk^Bx~8gj0bSlQ%f%x2~y)jCoo6}tUXG0 z$vcn_^O5gtlnN!qevfFT5o$4;Qb46JPWKaPX4HH!Ay)Vkn9@cqL^N5%9mH&&8JDQZ zwAC~b4g(&d;bDOGQacfXD&96Pd(BiHjVa|6mt(+H*;qni@iCYHMn%Re@7prZQaK z85vGm0qplzXSHDk?i-D8e>w+~y_^elotIuzXp;)o`{>8Xdx_;y#vXa^BgsTgeR(VW z1^hIr%~6?R&4 z@qpj&FY%WE*SaDhN0H4|%Aqx{0^z?QgkO)8mPI0ErIDwMfZaTNdn6JFgu{WH@MP?t z6ZC_I{d`Uzzm5KzVf~VXOY|LF!S>Ir**wQwB&Dh$5>l-&z zST{X87Vh10?v8~G7XF>%knD?c(53wAI4d?FU3_m19q-`lP;^2jzFUw6_k zaa@>B`#D|U-tUnMiovcb1enbrIfT^sBgFt{g|yP98i$8DblWHZT$-5y!-UQojjtKG zP$v^_IBc<%Bt(EJ+1#!f>Fsd?k$knKBM`ENOFM^#MjBKSsXDrMUqx$qqckFQ);5j> z?q6mBE#F_1_N(jE$2l!bt~#ffiI4TKrx>oaZn7ifPkIjMq&@hQEeu? zB{d5)H&e{Wjz|Or0_TfJB#L~23eCtDZQ9;8w;6fl^Zu_^{Z4LfmhtO@rNzairN#cT zi7d(3w0H7kZ*N^4e3g`!m*CgZ1z9o?mS;ZwB<$-S0CE@cl0jMaI34*mlS!bdJP>AM zs24^pW=SwnG`~oeGIqO*irikex5!n5I@wiZ1(h5{p&rJS`an0sYF%+53F`U1w+__x zZD={~=U3TF>S`Zfcy2hf{}(OwAN#BQWmr^X!T!OeFTP5JOVhW0{NqMiJfiQ{UGxP+ z?CDqF+iO6Jg@k?faFUeLiQB*`ok+aAN z4;MO=e|B3S5%mO-xWI-8`huRY4^YfrOMj;-{mQ@sb<(ff(_il(r+?Rdbki*p6X<(Q zyg2bcAE$fMcb`73tcS~_>UKS|u7I@-8;1FMe0G$NG4%LQ;dyq`PhH&!lVNa6& z?A-JppL*Yow~n`ccTdmc)W%&iTZRwJ)9n)*zQ`Wka&FHC`)fbxYVE0C`c?DDP|rU& z-ue2tZiuP6;g~WGx*^GRLrm2TZ|CsXVE#=oUIK8|A`Ru|fpt{E?KybaWEM<2C4i8! zSuXL=WYC~OX&$MKBxk$ILa~1M+rhn*33;u9dy}XQnP}b#&Y6W$E2BVk zz%a9%*uXflYOn*cxt4uD*93+`nHVY;$wVckurE z6|g=uLZ4Xy&X$q69Pm)C&q_g`m5>&>32nXt)K-PyP=bRA0MCj*c?;u2-KZUG0!Gn_ zi$qME)?h1iX`~u)iYlUaZLV$UAK7xjo-MUhRsd$_?Yk^zq~LGx}bBL6E^y8I^}XG@BR|Nyq}<-B!k^2XwP3g&q{h6asKl zaTcJ4%>^?bLEjt|q! zl9J_OZxE4#8qgZT60WNUtYv=}*@3(umA#!jY3`2O&>Q z0#8{$_teVOCN8T*io#l3B5*#)0Ah7o9eFmGC`HUR59fGu7(}(?P)G|ry*o~wI{NS( zO_STN>f1iR9=-F6Pu~xkW$9N}+;`FCaa|^f=WvqR>qMp#C802 zlwC8(`=pE8Z`$8^z|f#^OcYEvDltV*&RVFhC{+mZ^9ji>$uH)iFef}_cQ_(8RpTHW zTy!}VKr~_XZiHuU?vCpao{{_SpHyI?eIvAP>0S=i3nPEkWz(d-evEgh7Q1@qd$L4pLd)d*L9Tf`3F&V!BeQC-UH(vpuASOxgZ~0SupP?$~r&>XeF~|eFOAf zFCpFvFX&o$z!e1k@MZwdQc4;I97*~TLa(c#k19w|QD9U*DkheGrL1>4YrP+*-{b2A z?x(-t`{f}GaxHMY2=2j7WM9RqF&j*S{QP`RzB>dvREeA%RO8smR&cTehsw?L7oWf4 z*5lXCrhiW_ou6C3acXk+#TV{>Y~9j*)IT(_t}8=tfy{c?x7d-)xZu#}O&N#v9udP_ z9>MGM1$fR*s^u6)3Ixg)(7K)>CKGpZ#2Fy9t>Of?xr$KY(jcdspeN`E(r=~z_VUZL zJbfd*ob7sH;&&79X3FQ%7r34nR`tZENoM?zK7JGZp<(=lK7N$`N?G6OLcYFAa;sbb zn=aVln+=o$dM|lk-Phrg1-1vQP6_PY1x;0$Onl)0g2f`t*sP2@D*?G)nNRnh-2*eS z6V_2lDixd49f{d(Wr<)ejT3f&6{=!}4rD8ty!X({?Fyzkvh>PM5FCiL3=U4}IJkxW zw{CYP)YzL>iM*Lj)MO^;=P-=AnaQQ-$BRq=aHx5PyDI<;-$ig)_}X1Q2`pv`f>%<) zH$KBYvc%1?E53h-M`{`}TPl3%Q25U0r!X*czOuOruNu}F*47C;dp%#Tm&5VDX}vB9 zLxn5W`^DJJ9p78I+zZ2p+On3b;jdba5yr@@e6AJf$AX@o0|=_5*y|CkOhl6x*2MM` zW`+M3BV7m-bTD`*5_l-EJnIaxT4AA*WSIdf*=m`HMfpnI-Y|H9WeKVsPZ`34Igm~7 z!gyf09v!@FB_MC((Lg;o=*|HX;8=+V){))vPM;Ud2df2u3RaetiZ&5!Ls75^qHVtp z3A0ng`A(hmO(xq6vDrAybKtgG!Msqy?@BzdqFjjwMlc>oc{bA7Gyr@ABY?|-g6C&LjXbiz;eJt}Jst~ul*fOlAr`n?#@vdrY<>KgK7O1Y)^rb- zG1@q%;~X;V1pSC%{5gI6HjGE;Kr*L8LLt=5s!RAu0!aWGN{{()ENR4vb$!Jz?{* zs7*$m(HE*l^{`EI@{g)4o0!mpHq~;8BFGSyy3?=F(_q`j(Y9xJ?o|ojydJRa@kEU4 zn4PF&W>Fa~a3zCQ?hX-c+c=3uBEd*lvu#y1n3Oc@)?nPW>we5^%h;x#?$Mq#`7Ps< z>qh70j+z4lqx<`}4)u>U%@49un>*$1hSuJ71HHW?gKhNZ6wq?{%P*&2#&8Xg z?F$pI=T-3D-$onA^s*w)Pd^EJ{RfaoJ`zAb0N9pc#DOjx}wcAuc$7+ z)4rx>_LBZzre8d-=Uuk`wIlX!_GquY8F!C%ys-4^-~CRf(<3^a-bH`O>C^^$`y)=L zAlFMkoOmcRfwBZa%H0;lT~nDOO)VV+*hcKy$I`n!q_#`of~Y(bS} zHz2&HKYKdCKf^^jNmM8#g41$&LV_NG~2nH?tFyc$v+<+~TLg4JdSO02$#%|4#B^D!kd(G;IZ zEZfehBdN*e^{d46 zkH!SBV_fa3ou*kb+*Fes;dhMn^{wftortwGo!>XOt8HPUcb@jU9D@V>Ybz@|6E&^# zz4PZ4o6~>PaCjYjW{jldQ9M;Cq86c)ia_Qdyi*uLFk2*$>+!9x_SNly^Il3;)Y z*@@wK_~7AT{OIBLr=O=G`g&T#HPF|G_rt&8y?Sh6i1W-PD$n>0<0tj;TT~vyn8Oga z`z}%KzE2XBme@To?#Fm*K|aGn74QN;pwR_xt4L;s5>!2!fM@)~@2Cj^Ab9#kH88RQ z4w%Vy55l2G8m^%sv=TTj4Pgevsv;Yz5V1TCyq>SC5x)J6>yHY#6kb9a-ytYcN_Wv! z-J$QgQwg>#k3O9KFg<5!y=rg1BHRe?RYqo&{ zB|r8I=b8a*rA*U~Kke?Y;wW3dswAq8kF~aD=twyfYl$a?8wW4wX`XIUsj8v2ZK~uv zdc%!duj;H`-~Jw*#9nJ}+qU=mqguRzJOk?%h)XWwXDy0R<|tw|Zz2hw@yz@@dsN-u zE9pP^{$9oHu3M=hLj&+ecCH7mQuRQTpZoj^#%s7NzDkWvjPmi{!?+@guTpJ`bNDzK zyB(aau2TK=EqwfYm>kG`l&e%9CA8c}IsGSirPc6Rx6)~}1k~|Y)iccs(k*wOH^4n- zIwlEb0qtoM_e)LMz84jVB4#EO1&T_%Zp=-nvS9Wb7=&g+eq^)ZcL5_`W#IF_FQ{Z9 z{8mj&=$M}u{sWx;`?N#^?d$dTYd+XU`0;(NQ}g6VP3>EpK{;p_Wwua3XNbZmtmh4MbY{iv%{KdO`4KmR!G=k(zqoliIl z%xH3`o>Y-y;u+7i^R?q_c!f>OJmv|9Q9XFG9HDj~+3R%gXWzW;^K5En9|vxtWGmR1 zi~L*=_%a{%2eT{G!1A2J7a>;=-#N44Mo=5ni z3K0jIj5cAwic4wDsLqzrVTT&mg*~m=Hop!2(>3X*=$aIbrhlf>Y8SWXuTt&#&HQsr zr>`VvFWQJxE))ff-4k$hCW+7BK+js9S8+O+8G_pxf3#VTP z9vkC4aI4A#yS4YF4e-8B#EIDi?<*o=Kx&`_0aRfD17JoV$|=g*^! z-_btv8|!E?{Y^#RXz_djq+yv{A}Kt=WuYpTolZv)T5Bj1Tr^B6N`_0R|MK*osCgfV zmM^7`(fxFQEQ@R3rs|G7WgP4(CC+=BYFFK@fBpra`yIqXwkZ@)r4-+f^YlqohQ@Td{UzsxI=Kcjt0?B$E%4B{gy+Xw zbtgKXwm(6^8dw$3ezC0LIPZ#0oOzGwH`s$f$84qI#{tGa|G;rjD_7^)G5RSA7F{f$PoIqjk3$6Ig(v`t4JZH?-b4QYDCmf7 zn}1L2%YXzL?&+fErJvu~bM4Fc8GS&1-+<33B2{vd>huh5= zEf^MJaUm?Yfqq=vYx%~UzmVNMbAP^XYv)_8e`3c{nh6KrpZ*Roh#mbSfR}$3 z-|PF;JPDs+{Fpv|oac;kc_<9P+9KqfC&E@Rm;{u;$N^r9WD=B95K$y^n5n67L5cPP zqJ_Uo=g|KG`*;QQ*a^Bz@af*0UJG>e%UO|Tn8%3HpA8qUp}1%CR%#D`suK9_|`yA89 zkJG1g8`(JjLHbzEb)KNVQSHhEpC2F{a;vY9F;Sv;W{C$jpaxLZAquzZk)dsz2?8YG z@HmyAA2o&^TC-8hM)fE}Wd_B7TCW<5=wE?tWle)1tINm*a$yOEA+2DKSkyx#q)V`- znK-MikMR7r%<=+qr6!{d5zDM8Gjaj^QbtNKAxsNzWkpaFZxi9b(|G!;^K>{`JKHB4 z<~Leucl5DSd(T<=h89(c4-M8eE`cDKu5aSD&EqO=i_ydKU~VrM8zc`;#Zo4b>FlE^ z6R>gM?_yHyjKm$7iwJDPv1weGhF4Cp8-|oc$r@VME9kssd_8x;*bL2&o=fd48O}BA4UF7P=i|h;qxt1b|iG&*JIaMnZGyX_D zyd2IEAz^h6IT5L0p@yt-qDVG1=o;V25zM{iua_QrG0 zf$vAQY+c+n^VC!9)bx8U-T$6V8{c!_lJ{<2ck>;$-$cFCr+)rspyzT@Lz?A=@_c4Y zr&EkM{kR-fQc+P+Q&C;*3YBC>khPP5)+E~PZTzQMVrqzoC)gGZ4_rGveeJ-ATvt1P zWVnBOV_oy6OrcMJ)VHGCSE1&s)2sXn3^6Id?o;gm=0b1r%c@@yqb*pF0 zHKc`{CvRPO%52IyWj4Wo{gfGVcucbvMGBhDT2wrd2m}%>iDXklpe9gVt(-F#pXr== zbr|W_bDlcqfH&vi^J=@Q?U`~G-9);vHf7mqv{^ZgHVdNJa2jn@PNVJAVlmI!D32*4 z7L=HBb8{#}NON~{S4Uf@Db!d~_2$l^&wz--Z+J2tU5S*{52(*f?}(ch6?*5fpx>;h zU0E(CZe=Arzg-#EYF84ZmCVRnu&jq4<>Z;{U|Lfq32bKpwOXawe4wEPJj&+*`W@zp z+S<}mj13V|+gjVw+*q0@t%-y(Q6ifK-dk`Kf=G9@20g3AidM(u_o?G&%i>3lm6$s^ zJe*h_O?vPRadu3{$8q|EK{hD0EES}htdl{RS`=&mEde_TSmlHyWLwTim6Zx2Dyu82 zVv(YXqH@32fP%anC@5#EK>b7NxR{r?L`pZWg!bm);h0kD5{NvU8%j+M^7EQcX5?QE z9dkm>T~NlK)5mY4zt(m5J%WkL$`-lFN%6cLPBUL=X+U7qwAx}p=~q?6YhwvqELK@~&t}1|`M+BArPbH` z*QULbkDukbJ9Ydvl1t^nWf&fRBn*~bFtc{EzII*(!0B(B2=-pNg!Qi`aX!~vbRpc) zXdn=6j5Z{y)%~%Y?f!U;Rq(6t6;dn~XT9;B9Y^X#D*oTMcl2!cjz03^_}9LDhRs_) zx%ZuKym{KXp97s-Pddm}`5cTl)aKhLNX-O%i&2y4rDl@}%e2At6!&A9xl*RB?%V<| zdeAbj8yW~{=xAt9Hbui_0i_(&x=K0dS?wEb%&HKjYgdI@cwl*<=pWt$-yH$^Z6*Df z`#F1}oj=cdA}gr1;6GD;;zwm(=+43h|!o~-%+%;nzU8$Q5&MNdTqA;@as zASO}7szNSn#%Dw$$-80$Ku~1F`>&_x#{;#+(JCFu+eYG}36yZ92~HWF({8MKkXO;sZN!P?oilaEZAl0Vu1MT>QAVfHAWMSxiD^HJKTA zK18f~*5x~9=Fb5j+b}siymBHsYr=MYK9+wLhQs07Z~`E$auo3s|6ps-d6w|f7qLqE zzB2(W6b~;QI4i&@ai4yL{*&jufc1xIJ8sOyQ(~LEW=O9MGvwjvCyzAufQyE>zaDU( z1RlWZpfP#a=LT~i3Kp^`FuR3esWG5{j@hirIUv&ur!%%fWu@O=8Ly1_EBxg(QL|RK zk)u=yv5X}`PDcwb8DjP8fe|7V;q_Ic>j96^vgrDnUoCEYAmDqdrsmzn#q2E)UkU6W zUE_Ic)%&ghG)f0OH`d;K$7g$))wJ||>fL!w+0x%ks(iX$jph81%doeBom~hrOrVbx zX3MZ6x(vIEl^WzhIk%J0;s9?gPy)bWStU_gWPqilyT71rP2m38xWi&y?yxj8R8)u} zS{tp&iu#JWcvLJG%c9XLJK9o!61J)XysG0uzX#&3dUfZwY^6x~E{ee)=Wu;H-#{)3 zKhW{8TiywH5Cy=4iD53H>cJA#Wh0`Unk3P*GoQP$dCT2c1r>_vWkiPG3$Cl;zZGcy z+nYzqcd29HO`+uW;o*0^350MTO&I6(n=$flO5`}GRTc0w-&uhNvMjugOFdfxo52SY zTeBx}p^U$()kOReo|nvj)#G4tlU}x9wPte8)TfC45MWt*2JDD}NGRlTxEzjHkmsTW zgGQ4fCxC7iNzzo*oayHyj!pJG7xHN`uN98O$j=*G__;n zrtR~arx)@R)Z|UXE*qOjU0r?f=uLOre)BE2>*wiFo`>KfjdGn??Xbm@bJapG<*eFn zC&ccuI~|2E*Xl5qczMEVWg9Q+de`xjSD!Qg*oJe?nc6(f9^HH4fs2>eqv?C(>C~F^ z3woU`_qCr>ahgu()y{x2X1s3PGOl{$7=-zkHTP``w9=#%c`LY4ugWe&7`%)2wL9rCnyS1jT zXW!hG8`dg{a>KgxDP+d2i}7IDhSsX72M;Lf@#@>FAG%4=kgC0tV82v(@9hfjxt!F* z%FCG91Xh~4gy$v)_^7aKbVg@Zlg6W%!=P{s@>AxBFsd*XP9&?(1KS}G2*d)>c*q%x z1krXdDShpXjMlE^2Sto6LVk(4LcI%XuNWD-W_-5KvI*0M(w`mb<^H}fU+ocead{1=sR9#4I8MLac=*ZGnf zTf58f?7jN4hv|Q<=pBRgs_WI>0X=eO5%|h9WtEtofTe0^5WT?sh$^R(5bP1)_rgOC zOagUah(0LjSy?LDnBLss`G@z;&(11{`yrxjJK~K-*3zNnsN=E`Xn07KJK$qDsb~Vz zly~+JFfmmWOyYv1xrEvQb|%ry??)jNc6h^)N+db8LR?9l(DyX#aA>UzoE9a@-t334qPUp(_1N!*O4C8;RNW&j}XKAoY3FrDE%>ipW@Sn97jFmO4(aqSL_!>Gmj`~ zjT=Ppy9!`S!&+^wT4JjQl(fyav>DkJt&KR`kt!?-U8UzkEC;%qm+uSx z=fyjgb%1#5#%%l#XYbIyi>%9=K};>%jb-~~#NSCBf49&dDdXuMbNp%J$LKD@{A2p~ zae6=<@64M2AiY4#;bx04UP@^kW&dd}g$ zc#qbA?8mG(&CJ#EWOJMhxKcn_X#xuXO`qXj-(Qr-6~w!kCrOjW*GDdxr=Ac2IasH3bc;2tcEFwZ@bji-s9-R(&q{!v)IJtQt z!D^+r3)igFFM@4xeD=Kcwby=$URYA=T5r3jnr;7|^sP62!$EuLxl@CV=BYh8UXSVP zI!?E%aCBy^_d&X#*LDPXUUEpT$g`tXPjQl&HIPhA&`2^|bbt^+D?P}3PtR`;1Z=j^ z*t$`AgF;2c9!Hrs($&;4q<;2v)@Og5ewdG!0DohyHIrU_S?v|U>(0<7YnNMq-Y~TY zEN7xrX)F0Jm?)`WtpHdIdq}yR@JOCJtGh+Ktv%arzxDR(9v`j`Zl2w+acaZdJpJ_E z3*WMr<<&H$meTL+-#9Ulei89e1-wLnm!hceLcxN3tX|5B9I4t?(RWc2sSVfYkt4~h zm*i@BIDO1eSw*kBeCGw5I?s?^|NNupGzOI(zX%@uZqdF7uwJKq#@J$pJYnz-!X{Mg#m z*!G_fU(kK{Li&Sra>Iu8Q}mmPyyEYTdYW2PJ^gc~W(vk{=e6-TrNp!YOG6C#UmkCxvQ+$ zCpjfYwZqP{wZids-{1P9%zu}b9VNw#6vBEoq%x;R^A}#q2?PAL z+Krcc^+Th{gz3;O13^$Vzw}WOL_61O0~>cO+W2%v*LR9_uM~6#Nu|RZbMQ9fqN3YD z)p*QWSJReQ9R3We=aiHk86E1~`>fo(xOHY%U(d69yN6RpHs`H>`{G46wXR#2JbLkU z2M=9$;mz=S?Jbus+`ZAL8^56A`6T_BVf=_b&i52JijS*jEKSIzXK})^LIR1RCR)`q z73&+GspOJA&z$)*yc!A|wd=|9e&nC#jm)92Ii(aCGB zpw?2KdBADt9m{*Ayr9GyU@wC_t{s%iZ4%=JogzjX^eP;u)8W(#oCF0SSlo2?HHY7N zyc#)X2EpTDTbtW5-fb3J9B>i-nYAt)LkqCl`<(@_` z4IM5eBgE78p^l0sf26FUEFc+yr@tNS^|;!+uo(o#(cWT(bCTZo0gGhmK4_L8eTpT$9^X+@^q21p;weQyByFW*p(%+_+&^75LDx{xLc+8~wf)=bGH4E7E zc^Q{E9mr)^(68{>;P&S)_|S)TQfvBEYM~!af0S+p8sP84X`oTne-CroP{vQ{vY^sB_M*5~xK-bUYJ7~iIk-$_5K_7l37ejQ+_z*DQTQic_ygt8Rq)=@1Us5_%P z0#iZC1H~Q}vbiuzHJiB z`pMdY;bhHG%!s9@Nf8YnSDE=@7rDUKl#34pUa=~UKG4EN_Qu}ya?Cd<&DBkS1H6ZG8lH|TwAaq0I{6U?(gp&|a>oZfp?etNHA`~h{G zSzo@+IRAt`|0w-|Vf>grew<#UjGyl0YuCmf#F!DnbUMMuJ)~FeB2+Xv0J~N-CWjYm z=l(|@DCg1<|Ry{E8Ys4I8x zsl{czr%Fj6guThKdQWA#7I`wAr!JVTPF8luM%f>D zW$57+w|mDw;)x+XN1b=h+{c#I39 zd7d9^PyhG)JPpvVq^}-+`4rb%u=3v z1%A!PI&W*H&U;R?F5C{cW?gtaD9~MK@X}YV_)q(0{Gy-UbM1FoVLCN5O)C^W>ID1y z`#_JyByxtFpT!k9KY^S%KZ}{1pSd@Y^RuYu{LHPM^Aiq+oDSgCs4?e9J30$WVKwK+ znDXOc-%sBc4_|U!$AzhqkcXaYd%ZMbe&;>bL0Yu*wUNQziSfQ$^4@-U%wq%?i?oFl2LS2Cg6b82*9Fw<~MWM$G!hm-< zq+bB*s=7I^bDw%TCXqZW0n1QxdjwO|r!YBk6c?p9SatYv-FfhwRP=6^8<(@es zm(vG~hO@ z;uh_ko&UeYvHAZ3jxEbCcYFgJXWjOAMiguK`z*ivv6qaHXXR-2-H+{5vb2HC)*oj! zD+nl?ITfKM6^C7!J0b0Av5}crZD#AvJgVk9C@rREK~OJ_=Tn<4qwzadJ}kgv7D3eC zCHJEH=DH6(9Y4U|M|cFCrY zZoU#nv{n{t>{`$+a+o4luc{Apjw<~ext1_QH!;a}Xz@h7aBlK$q-Qd^9-+|-G{xZ98 z9q$bgCyiiDNBG^DA_;=%sszrcb}%zuA7eJDH-Lc$FshisW-xBrvYza z6>qxSKmB)(*X8(={*U6X)`R#nTn9?d3V(+TH-*Y)MxTClXu9Bx0z{!Ni|_>R;m}TG z@-)Z~u(66PCPAS5B2kGnfmm;(CUa+ySuJH$v`VRRDyleY0c=YGk@jOS4s&<#@&Jp~ zWI;^K;t7N_3*vc^-!`Q=p8>fIk1GJ%y!@0%7q5Ie=YunHSqBK64!Hv)MoV);T}@Ra zq});(^X6%}AsIQY1jODHm3~_j;k;`^`d4Q`ufh{X`3>Sc{f;*#UZd;|l0GnG|HCM| z`TeFAu><6GJK$fg0<{VX)h4B)T&=3Ow*W#wy}xJQcd9EyQJgg>)VwT(+D=4fVWMUK z>W}Aqaz-xi?Rt=p4}ci@rL)Re&J1vX!WAiubhb= zbU7^Ra`-;HH%=cX`uP3)u1S+RKBu0ccaQ<{QQ6lF3bzS1t}6rzw;U9%n5y6k7dI`b z-$JTtNK+ou4i#n%nl?X6(>57zZiNS|m@KtI#pY+J*vigMQS2P(lzY3;@<~)j!-jiY z3*O)!*Ry1o+jC#>dfOQ{$T$4E6?eXVa`m0j@t>#T{{fWmn*0YJQ5(;;_lNnu)RI%AbxoFK-;luH+5jry)+q!+i=jUvpJCBo{B*U3t_A1g$cElYGc>+0%S z>(GCX)ZpE+c&pCxyJgQ3>u=AxcJ`lVL^jFXL;Lx&z;VWJeZP99ql~Z9$3H+%X2#h+ z^zp;o=ThQ8m9QsX!(Fs4JdQ11aThHNv*p7p?xJ1HaTo2J-U4ZH`CYU=pD*kS#a+=A zchN4tidKsP(!aP%%IfNEfvLLri;@cijY9$R`cL>2xTZp@aX@>EILeqiXynkMm}Nw2%$*WDxxAN-(M10n zYb)}XGYqiNdpOS|w1kqTwE#IlZ`Px$$)V0p)C!6mibSF)ht71D@7c+u z59Pe(_vjf#Qz+NHzaM^MpZ7_it7)*BVx*2VlP&UedB7(yA?$Sulr=U~nMJe74u~_0 zsj^ZgjM=P$fK}KOY;zz79|S01}@nh^A&T5D?CLB$LyT1qOGoOn6vSjaPrY%>7j1j6n{Yby|ChKFj&68OHyr#z`mT zl%1Mrc_G8oDojiyf|$yqbPN#31d;K~AXRW0d-0T&5rU!8Uzmp<% z?p1jQz)wG7p6H3m;i^rG{R`!ht$pj~uG1Oj(nRO(-IvVv^&POin%+EEUWk~b#DC64 zufKgwb3;pAhFLakI(AK9-Nq06wYIUbM=;p6LK)ZXmnt!7Hjo+TvRfJdgxU{g9`u=; z-?beeH)xe@zI;$x7SLr3FWlypZQ2;s#{TbXGTwZX=agbnjWbJ=p(1N{=qd~=qLTC@ z7dCI}pYF6y&2`R|4$Ivmt)AWx3*33b#)HEnUF;=$`WNfcp`Cm7&To7@7*o&Z5I*7G z0q)CrKIC!w4v-|gF0xt6hnzp%$#KBvaNF`^7H+V<_Uo#ycL1+}O(}rz5X>gPkr|0~ z#V|GNHAo?Yg^9UO62+i_a^JLuE47tJ&Y2u_`t{Ttvk{_|QJi5K_Rhh`8w!LquBnn+H>pEER_Uohy7#&0#EU%4-|jYYwIDI{-G zs^)@NE+aC!2QREPiDneh{OE2@zo}jcSBBJy;{MfV%9WW(+(O4&&6LU7b@nr|UAu+_ z^9Ec&Pq;PAZ}Hgp|fhW1-3nRmZHWx0L0mHg-3of4cXabMD)@^S*P=y?5tjw;a3lEjJ&%JfL>t zW2ZJfbjii<-3;F^dgz?g?Z;1?IDY%_+kU3C<5P1&9%Jt!A+ZK&9lxjdt9{@1b7E&$ zhsVl*rhQ<)epBW5$_kHQk${#hELBtpYBZ1;quQ8C%@Gr?P7$?hQp~efE=O&63!j0W zQA$^>GMAI8@_(|e{{p~radD}?8JvDM?mL$<+!ArzJ%CK)1q9U)PxKNb=*f~r8lbTr;@6Vhy z@6Wsm-d}hl-siR3WzJGwyIq7>TF(1HDZDDn)1JH^?({XEYHQ15Ur zL@%!>`wsWTWp}t26TjZ4$C#3$)i&{bly&POwWY0<^61DwMN4JP*v#H*JI)_vfk1he z+qHXfao*+W>AK_arb8nr$N4(A?mMKO$38(a<5qqA*W`pg{uLghKcvR!|67Hpki%1l zcRYg0F4R^6nE2L@6Id&xDDAz zFq!MJ3U;>^9KRG0U_^-yn_q|R9UM0F*&n0d2H1k6maLa2+*G-jy`~Hxv`GvP+pQKx zM)f8eS{B$M7rPpPVf)%pZ75L{!(94k4R5m%Q7bhKJ&iIT`dU%)X&xz%+HC_n*2OD> z-ND8d1<1NUOHdxIE*)r>YCZ0)RU)X_2j8VD+Iu8t^cS>7HCSBq`2V%Q@K7ERZ1sSpl06Rw^$ zfHJqcC{a`!sx2$t<1Rkhyvt;lN7tZ`kOu6-WpAAW%n9B0&Z4p|k0pIXnrxsK)7^^z zLm$x4t3WG7Am6vk4vgKnU3k3*s6W8lSSD7bW*?b!V|S|(tI}WLiAeZz=1>SPgDG>A zRz<_wT?NKKmCwPlqExR=SxeS6Zo2?P@l@}*YIv#-MDJ4B+N!#@ADlWgIzZh^>zBu- zkPluLEP%xXR$QY14)e^)@-o;AKi*1b<0T~glGOcNC~@n|e+GKQ11^?`Sc8v!B= zHvxNn@KO?`q3J}|o}s>7U3IeqvmJSz&13zkmR|Q}d8DnMjkA*B`m2Y!*runCPahoa z+CSNM@z7xZLVToh+@Ck%s7N&oEIoYTPERZzfB%*_w7Xy*geusFN{~+-Z@2_;JPiKUZ+Q4e}}H! zxZ&_DP(1$H)rps=>(r0fpI^Gt53-e2bF}!(aJRx{(70g|MKQqUe# z;IEdmL!#QS3{Q#X$V- zNS`N*jo8R~BOg8Rz}%-Ztn~horT6N*bYvuD?_YYCft`>JA7g(990f@O=_Jo6O-?KQ z;QnGNQG28;Pc)fTg;`Pz0)mUSz_KaQ$|*C-TZJrC&9x_b9;8jO3aDar54x65lCmf1 zNtHXst<*4mMlNk^M7`YD+1SyV3^j!6YpS?*u8P=~Y3FR|<8!!uSQjAzIk)Qgi>L$* zn0&Hl+hnM;vO5$kD4uRn5jrQ*;x*0bCv~LK?X?jw%q^b(>a6b_vy2w6EsoWq>@6si1yXzVz*R;3w4wVfLoN#(N1A$n7q(&~8xNqI1J;Rp|FJ6}LRFrv2 zqioykIjJ2Xf9qJ=x#y`onGo&;*y>0Zc~Q-&jZv#P0k~+Q7NOC@n5Bf;7~V%Mnp0JA zW(GeE=SVr{nAAC{C(>re`xkM2o{;*k`p(uQz*XzUJ9Hy>fLy8&V~!iLmn%k}2d~T)jeIQxukP75HoUv4 zExfj2WbN3d_1{cCZ{+kjdg~8`^xJj1{MN1=1B>l-bgOPvT zY1E{Oe0-S4ed6TfvYTQc3>eYNo2Y>bF^MV7y#s@g`(U$53u7+JEIc11BOn#`F4s)m zZ_9|sh=hI11d-o?x!N>6w3A7r3Ogg*y;E(@~j~M}}n4L=> z&@pw@#D*-3gY)Bb7C(NR{#2u79e-dCIzb|qmzf2VSV9FbOWiJzg&Bcn*5cGVjQ3Fo z0tj4HG#U+}Evu2tOqEPFXtW?>C%G@^aA7OC!|{Z^`L92hvgLg; z%aGD+!I$uUM{>WMR{&m~*TV#}Uf>wiE`gubyW*)w42EoX-1ca$iQGP1o?4{UIIKPk zHoeg0a#gs>W2g#wbKc+zH5fdDDfv^{mQjKF#y&H$v~~Huz9RfSv#;!1YzxtBv&&)J zLqcFV{JVmS;zB@=n@Xl)KNF>}z|5kUauo5XF}^0`d`*=~4SM&%MYI|+g#)^6t<>LS z?CgXALts5%vqY(6i%_$@!NRO&6Sf={0m1mPX|kU7>ZJ=HMJO&G1lgYMk66! zyO(`(rJ6X}F%`VC;b`jOYg=~?Ua(&|iP8_C?l`pZ@R)Myq{YvE&*N?HR^x3SBbjlJ zK7NpX!!Yj9$B$q?1P)grhpU=2k|B8j;mWgH1rZ}OBKG|jQ?TcRN(8$Zi2@dZU`&DO z?erGS0A}1BNrZTLpaIY`2jFr6Ke}aE5N_L^9JuJTWJlpyxYN|Fh=d2moVYkO) z(XhSJUJ(iTy%vl_WRiOkPb&$;ry}TXLr(AB{VPc25J!$7pZCUN*Z7Q7^BbLJIt_RU zt9U_M{zi@;3&&dqKbLd-U>>gv@Z(;ApU_JDtPI_SR-$KR_|C=|#p}VIbH<$AGcnB_ zhE&~|Rr$x5r~9cKtfbLJiJG6=NZQFK<-m&kT)fjI&hKJEiKPa{jpyk|1x93ltqIQYQuLJf#G?;<_@@v`?nqS{EtXlG-N?KiQ)i$kZ(sJIW7x(8-Sz$+6OPP}HHdZ6uc9lT@DQ9?J z0=Q$??M$gLrz8j>*AH}DOho}Nl2QW4#yWGg2tuhdj}efd!5nqwNy&Krp+UpX8G1K{ zYfIb1jmeJ2UVBGhYj<1KP%shQ(YEctkxO=MVu50RyQ8o=7OokqZm4SV`MSz0H;rHJ z@XoDSr{$m$Sho{Al0LZ`Z*ifRX{eoDaeq=dyHXDA!7p&R2ysPSkzhqRo{l<+qsC(M zB)r;Pt1VjSC)}o3cpL_w67YWXs-ZRQ$$eAfdpoYaYI4o-+T@xhpE-WRnzp>ziH;t7 zVSCM*^}`1@UVk#Ru;&}`a81?NbW@$$JM$I#IbPTQC6Z(9d0^@AwW}9Lh-Y3qM)Yy* zQGM-Nb(>-BnT{d2_D^2jv3GoGU$TA8&{f-#Yi@{}eNAhUwa3?_@=jjA@!;_KH8t&p z_MVQ3*;HNA^jK9*IR1@23u-UdSJ+P&W;lLO_4^uYn91BxZ4xY|Jk?HfgT^wY0?KPr zuGdt*FGegNm@Q;c^?P>`Lq=An33WiOSuv4Eom8!qHF-wP3%P*)!jbx*6*I1tkbz`C ziPp6OgH1YObm`izT(R5Ee$qTNnCfJRro%g~+|(EvtG|Bjz=*l6W2md4y1%lvYObqc zI%{aVp{JibouHTU z+>p(3A+|3s00l|%`5oMfR`lveinGS{AOYD8V>~-`r(qa&L_KVbMEGH&7M#kuJRF38 ztOlb-)Em0>W6!0FCN{*n@@y$~7jL-0PJaN_co^1L4z}SHvbO}J6W&oc;O-#r$uh($tpG#QB`5bI8l$CaII zj*eoB(v>|HW^KF=v^)7-+R@>aIx6zE40n%g7z+Efi@TqRvf|)m2YY{NeCg$a;%32P zS)1x^?C2NR7{CjFzy9UM7E@;%wHiyC&0IIW zm=#Nt%e8I*xhKrX1%AIj$>~bAuIgL zQ|$Hm+c3t)Ds1DueG`+zOFL7xJoYZBGZ+k&uTgqg5a5B&@H6WgIgSYxK07Lwl;*T9 z8n4s974i18YJ#f5uu94|u84jHmmzBnaPgNCSiq|(dtNvHY0Fb=z$bz4rbz|J+8R=i zcNmxWn2BL=cs(XN2nBWt>|!xh>}PB&KabH-GZiJg=2sLJ@T4UZnA1c~WhEiCiR!A# zXk|DQg!itfiG=XJz^J6#V=IoZ(G-qINgxt0rWH$JuaEi@fuLf4B`RDAcV`c%Zx0@2 z4-B#NleUFAbN+RGHG4j^-W+@R{ya3hY(w@`#ldqxhYQ{I?&3r9KL2k&@Gxx(ztf!B zoFE39$gJBqPtoV}@xP-UVu#iJNYH0kAxI?9LM4j4HsKip@I59yC}}QwClf=AUuiDG zqxwqMh1^m7Rt)0P)XKR1&*||W3M=CC6C?lP>*VX=@q$xoyx_xJ20Wks4PS2vY_ya- zS_Uij!-|WjSz+ zn>FtYm=%l0XUxrAdG$VF_z_X`m2F zDN9)1KnS!@Xj3RlD3AgnBqbpQGMe{!o^$Til`T)w&!@jn|M&&QGd{YK&Uwyrp7X5V zhpSGj>7_@{g7yPbTX%1p>uA6CQP{lOo*3G3@Wgq2MSm)t{OnAjZ`kE(?@T7AKe=i4 zGjmfLx4CWgzD8ftH?HHFGmLcyq{Eua2ZmZRrQC7p*MeFDY1R7)RYh9HSaeCC+GApd z6`la&>*(rNm$gRtf`H^#34R(q>Ry}QU$pDE_eOT?f23}9T~#`8K+lAgA4+F8&XtGR z*XHJV_ABr!&68r7UlK9Q!xY10dJK~=;R;F`zFg;aDX2bSP_#PA$G>Y}#XH>lF(v+( z{&tK!*M2kZLto|1lIg9?Vp;p0S`VmqPPfB(^wquv-MFZP^hv!4OU(Bzl}b}$eqe=W z!E2vX&#K+TT;~L}3H`!0L+Qxp@>;C)S<@!xQ_SUv?dX%EyBEuwg(kv2Hr&)>u7#Q zXkui?+;HEH>6v(}t1xih$i&W}_VN!#Mh6B*u3#^@Z2A3Lj=3DshC*g4zj=o`JJgo; z<#OrFNFmbW3(XY=c6Kwj&wIt>z~JQik=KYmAwXBM`@brD&F|!xZXiE@3i1l`a#gLZ zxv@@BDkwx16{p=BNRt|2O1K^(P$D^#H4?H}J{cb$92$!!|Nh9GZ$9{VqsQCO1pjGc zOS!Ir{w{Uv1p9XRQugO(?(a_LIzk9TD4FKxH|BQ(Vn7<>9%KAg_BGRZ$QZw;YCLI- zzk?k#jn^6D53nOuvDTE-E8U~T^eo3VX0x( z^uk0XpsNR|$2U}h)E~b1vW|(i^>YWag}blXbloh)s*h%~&nDHQ2M!(<_=hjDugT9y zZHN!u+U#;#n9MLON15lT=Y*hFv9~-vPcWUfnexg_N=-I9P{}Y4vcne+U$|lHU}s-y zHa9i7PMcd=DxEkHV(&e1L_2>p*U{hBx^-@Dp{ePev)8-cFndA)TkH2QsdrNj*0|;j zxLp$UV&YrWq^p?wja#fi)F2-f7uTmk=?p?^`NXAbSg~~Hg3!Bl-8yY@DmRpV0* zbHU)TrG^qKdA)P9b6Z>6`a5zX=T9Cz7O<4RBURBSB*nCFC|F+yS1jfV8U#tVQzIo$ zFi?vgo^oh$B^Bgn%3oKSR?>j&H*oU4LhIk4Iq~Zduvx6%qkk>l=z;)vQKO&ws2Ew+ z+|=wfly0}cyo#P$J&}Sz&-WX)92>c4X6!&mUurrxIXk&-9qY0Ljvbjgeay9dKcrKaM)hlZZI^1@VV!6W_01Ge0mg)}J3s7V~??Ck_-# z^WoB0eGL->#mPu?IFl~!9oSa#*zPs)K^xfI&Vb(yrixXkL!{ELNB4MCI3gt35E9RN z)bx;`j4PcL*n-i5k9bt&{90?eKRI!tv|+<4Zed+}X79dx_6@5z#n$nZ^l?!0 zKdUviGl#t|COhlog)HeVSd%p+IqdazNBv1jw!$?dos{Y%r>o9+)Xnsa&IVRrud5&~ zm#)Q#96Y*Fw6#72)MuO3Wn1IJDj%_|Mb@obH@9wfdUAYhWU#k8Q0Vn|RbP^#_*T_c zrNkgUY%Mh=xLW@S7A2EzlNzYM{)A9x<~FcU>n7QQ+e(F84iwtb!~xP@-^eZn#kHe+hx}7l`TM(c8T@zRu|&m z=kv;zc^>D8qu_4jQEaRE47|-0no?iXT*%6{Q zJwq`j-go>U$cX1azEN~O4(!+pHfOrp{?hZiL@aqfSK5uV$`zsj^Se-GKYEU*xCG2f znUsnajf1NmwJn+zRhzKeh8e?&STSJ)C9BLAB&boe`L1G}5hLib>P21}(;~%SWvWkLj+z-^^>RvUETh5@E9Sos_UzYS2hiE^ zDAa8Xivi{kafFegj6xASvR3ZJ$4HK>=XAGHo)W#xGj-@XFc(HUo6{*@ zIz_stP_+gIs!lh@yC6Z8Eh^p9$HzBcV4U{(ZQUJ%+al+&*Wa@5nvv3u$IZun_u@Yc z4Ia4Ub+;k^BPG5`HpNrirjUNE%OUBrKuf)srVi)IdubL`Pw}&*lIWG?$IK(L%bpT; znTq3QUxe`#*+WkWdx-keoP8R`i)0TyCG4SXrty$5evcS`0)8tinxs14#bQ+D`xK4; z3ZCz#c=A&sp1hfG;Q06r0*|9rI;^=(y_+~EhY5>$zg@8@q+`>DSS&p z6)o4xh;p)NQc{({#;YJ1URTLBgGVNp8WS*mmt8X8vW^pfc_XP!4Y3Kga! zdT$x#AuQ#bmT|#M+&sgMoQ9wVmIOWo4Ae_?st=8ifFV85F_dVpTQ|f$ zSl%CKwrO7KCkbDWCz=GMBO-QVM{P$|tny(4c9sxeN=8?UIAP7&!1Sp+YkGkEVL`0z z@_L#Y8w7Q*?A&W&N1v`j7yZSXQXEg}t%phn50(zeZ$(-lP0AO&^wR8izC(QR3&b&} z*uhgGcCeksUpm_%Jwbf&qTtJ4A>C;FGlYBY)f%l9^cDljq)ib9Ga14@DcK1b$n=@i z%tSPs_m|o>?j4Fvd)4(r>_z-O;I}@K3oi<}u$9k)#zV&VJvc5Y6bGClTDD5<()C(> zOGLIR$<{`Zrj5i+0RvfWiWLY~AuX!ph9Z7I=GkHJfQ5tk((|hxTGm1s>uGCm%cj*> z6w%dclX*o@u;>W{ZF)TLHbM70Dlx%Ss5CtMf(Qp1`*5bw6cMyyi0}d)4g~&m06p?R zXP?xn#q2h`;DA9HaMyX53QcViqSP@ct@?Gc>pRc#hXna?_QX?pXk(?dC6DxxbQ2heG|D#egrFz1Ic%SyG4Khv* z)$>Z|H0k%S{9#LGdL)|41?7VW^@yo9J3GF)FFfr5J9JjA<3ZAeGtY3}8_|S#@(+S1 z|D@xhgZ2I_Ov;Jfb?nsA43oa*B@+O?x0%56;aVH=`BY^HFSkpdyzJXwx)2dXhRfe) zZND|J{$+{u&Xs23?LxJsW*2`!*_8+GVh3qAq)|W5}a^^$2Dt4v>l=>x1594<4pzT6s731tE}kBK1pk3-KEkmS*HAx-;(N8k;%`3z$L#7ewxdo zDA;OJ;)OQ6fh!2)tiqFFKuxMCkLBy#XI@JJ8TP6PKUaBFN@9{a!(J?rRq>i;>RauQ zVz`oUC>Ut=p_p|^^Dd{u0#+)@x#LmBVLpQPE;*}YeZ{JRSr})>`vc8!9yk471@sI z7N8AV381V37yt@)bIO;%K&uGl>rGQorKL=5nqa2LOKRCX&T7NF*6H$>Vm=JVgyOn!k>c8Ks`2Bj1J+_GFQ0(n@r1!0||LV@h*^u7@_9@zfR?OXL0ou!0->Jw84fT3;JA#ibjhyOi!MiarDfB~>dL}Sd9(Y>15{P{fL=|SU_OeA=lv_I*7zW668cX;z8c2!(jIMRJ1`c=e|rm7aDnncb%oZ2bV|0( zV|y0aVyDCaY9wAV(DIM0ND;_OIlro6k^njZ)-3%q@uz2q>i$?6QwFAvWsB-u=j;N7 z*uQ9SY>9pNpOtT2a7;Tgl+P7gV+*qwUN3);jyE0kA7df`x95+O{0M7-db>@jIJRMe znFLxjBH?9-r@64>m{dZ=W0=jN#N01`d%;ylbn9S$!n=m(hWc=~(1)oF=GkX}_HUs& zo&{~LH697VW$E)aFpCxQybv9RrQ zt{DDZy+M|S`g~%zZ;!p96!aA0L*08=-trZ3tpCd~*m78A1Mc$M8++pWMK8rGVZJ%U zj|jtU5}~?Tw3_ED&>u$H*AWHhmXq33omn)WE20+nF_Z0*g^RM{gXaOaAKhBoviIPg z#;(qFQ=y*iefzd#(_@KrPhouf#y`Kc?!-~K&3)#dHmu7R{PAdmuP~6wO=ZSML;g%_ zJnaoH4sYKr;^!~0VLF3g=gV}9a<$hD@|d|nPO(bNf<$1mig$vZ96bQ%4Q32d8A=JrEgNB)yO=5V#mr)vzY0EWY;gvmTxuulJZ#@t!en=SkUXTNEEBV83#~@vF>-k zsX}AfqSt$A5i*|fRU5o2qsL2sk-G+4rFhcgOTzz5u0h=)B>pZ2MIug7{`gX9Av@Sw zT4*1Pm$o>@&g-3NY+WqM(LD?36}q6ar~D@PtE;>GCb@C*a$jdxudcJ5MSECo7I=8m zQf0i(7=M8Jbd#*0wdSNNHBTlHYqnIpeu`LgE0&Vm_B$PR1;t*CyatuzAwFh@$7FPi zu1;mpJp3pT71UJPh1uULJ$~mRh~e{FlQ0#pUrqW5dH+Yy)mo(ituG#M5JE5aoY`&I zZ;`K0DhZSU+PGHSHB3Q`82+4l-Gb*F*db6UaX`TmVSaF)(_f%7fv>WXP!DyU<5N$1kmm@7 z<(zY`kaNZ4pXU^;F?GY28U-6|^CQBIuQx^|uONnvN)^v(koT~{iU3{#X}C?XC#_HN zqWfI$No(?&7Lg6mSIRS2wiu}@+)3Jr8;waRCVx1dgNX3cebF@TG{&En?jc>L9e$iA zKM!|iLVB3b-i>D<9+t7!ZWMpB>A#7nSe$M!G`6XU0!RhK1L5ZY!+(0kmgy;SuptV8 zgM8xpljs*gL=nR2uK5TExljX`l?{o8ww72l67+jLXaEG9x?jj{S9y(rr3TqNa83_1X{lTKkYMeQPqwnogv^mc?8<_`6$zVO0F4Z7S%K6gh@Zer4eXG1)QA?9 zC{@Gcd(Ks!F<4G7gxe<`*1gbyOh%G2-I=aJ4pFUCk1t2r994SjKs8m#FTFyKmH)=j zV@+h9-?o-c`!6PH?_PYiO1m{^UuVz~bX!v_r$S@BUT7uXKSWr%dWl2_!SZCNwsaxKu?|q+Yea9%3#yh##%fkerfqs! z|5mXMx_2L-bsW&#o;pxxTA0=7_8T?vG!K}V)A(C!akFGjeqg4;g5q=N2*tRDK!zVelD=HqU8XpK9;W}J=Bv)>wZNsTaH>?hcv zMQEHw@ zKNcSU`r}{MbJAssTgU}*KmDC)+-ZzIE!|Za#~gO6YI@FZJa+^8SJSx17{8VMhiN=y zjNgOfq7FAN>W@QGn{=_(=yKYuz>5<34)wa@7^NrKsEMV3I2I`iRJRmEI-XkNwm z4!hmqws31p)E#mM+k=RGjDaLOFX^<^B&3|bJ#*DR-AGlNt}2=;vp1@D|7aUlX7;V1 zF0Z9DtyL9kMH%^eTC<;M@xQWWpB*c$&#~q&XKo+;BRXNmjrTx1Pi#JB0#I%6_^Id7|VoBT-V|@GDf$Nf|7% z^)mfkYrFxj(p)YY&GqEEI}6eFXtupMpr-LEWu`)Dy)WH48GzkwR7q0GfIA+Og( z^D^nKbJD0$)J1noL(&79FBkyH>%^j$1gKROo8eRLG-v}CCC8q|tOqx9IBfe}JfQ)X zulFA6kt~W$vDi+odfysvS=QnLzHF#xu)h!C%W~P)IIn|FVI8zYHP6W!)zIfA+8h-- zH`S_x9;?Y&f5I~76_w8y5*6E5QL!RRG((oWi~WshTr$S*XFsE!5qwnLVY64QsxLUmJ4N_q zRP(XT`BHCJo4&4#*1%aYH)N1)LmWbp&2_cm9&hE{pzHzS2(dW4YcYUWcAnnukphu|Qg_XT| zhA2Xa*jE7kb)#go3$Tk0vj!FndKYvs7{VLBY}ql4@#@68{p8pg80 z+6z^hR^3Zh#@eoeL*JvLhO?LoKuleW z4I#x(teP5$j%M6Yqzf0+En9E0>TAg7~}im35npn?laXStz=MThc!8*Yt`=fKtC z7%0s#HI{6P!#gACOx96l)U8@|(Ga*7Zz-kKcSda&SPPQ=3~54Hmt6bv~~d7((It%e&_;+CDt*te>0Ma%}!>m;Bf#$YzMd zNk7XM_58h^r3-+@mtVhQ(|3W+cNqD5i{15ipCVEpyED8VNKNuFMEtBstx{Gx{)pEl z%SLfc7TfsRtTN4RS(k<;V6c*2cbPPvgzc~}9nI&E@i?m1E?iK`(}XoQ*y~Y#HOu-a zc6WUJT5FTvHFJioy*{kjdV&3wj{V<&wc0WU8xYLEjHOT=yCv*@N_`GctFJzzB#6(> zrXHOswDzZNpPFhLZq08vaM?A$*>$6%0Uvw(f}=kF$Oy4B(f3B6?_Kbb0{K4(mugCl zMM37d;UZEHhmy^^oIFcSHrhCvf#*Y^)=X;S<2 zc?6~vie?w{gQGw-`d9hop4WQ3w*^DjH~QEQZa_$N>-B+~5;yL`e_a>2vGDloI@xQK z@}-YY?+ldhRCN38Mxje@so{IF8S?P+=+8Ig4EjsrQU~0tQ{mxa!iQe2yhG(s4VjFK>>m6Eq#l9AATH{f~zwGR6ZM9fB z`#X!h-K`z1g-ps4x3r|w?T8PKa!y{;#I9}Du)hQ;om<FZua8gsdXKlr3;JwrJh21@(okdZ(y%KvT@x- z6XO?6%pMB{HWwdxCVUY zTV*PNu~jwKjY*jr2-bbNj&oGH5ZgFz7l?1a=N^@e*NS+wq2We+a0!Vy8qRF$LXu@u>P~_ zDf{iG_a3scYwZX3{-3|zdDvRM-LwaYbDoxN(8Abn1^WOd6G6pl!E7&!z87J$e}Iy5 zb%-x})yZi!F!pLcv8**yt!O%$Y9)xsRHh0D3^t~^ma66+RjR65Hg~MrE2TrPta?j( zuCixhz4s9IR!(|Kq{47;d|Aq*{SJ%G+C-fXBS49bUJn>PQT+*JttXaiLh17pR}xtI zBEnDuN?)MjR3Y!{@dy)?{@RZrls=(+jhvzg|6~39_I`M z_z`flZ0*YUx6Yl?Ny~8x-lASGCQieqLMJwGIqy}L&yAJ4Ou+ZthJUx{TL9-75%6#c0qS4iQV>~=ve@KJcr~BU&vT`ZgE-H6IYjj;SGRGvjB}o`+#O>zx;VW2?aHEOUb~`?gIM=w zQ4{|bzFkdTW~HVLHfw}|@vso3A;mnTC!Uxv{44zmsHCx^N9fZ$LSNM@VfAy%S|e}! zkX60ubi!do>#K|3MX6P$iV&LP2bY!ZD@YUpv0HG>xMpP?E9I!0?oEBRrUJ; z8Yn8zpiSzOMzHVH;DD*`6dXVON~OM2@_wfU&Zb;xJZ1FkNzhXDhvXX1ENd-YUD$W3 zYou$qzc105=xEO%^novvP1l)vG{W^{_f+?t8X^fKnalrErv8ocW2LU;iS+tdDY7v) zy1TP)|GMl<*gj=%*_11Pc_bDdPWG=KE3&KC4;QBfnul8D=-Xbm?S|Q8uKbdlMY9Fo ze5yS=jrVmjoBdrOchS-F&zG_N)b@s3XFMz5vAJq`jPvJvG zZrFc6$pOTe$EWJJkyQx}heDoEpm*F;+T!%j_sCJ(KHL1J@;}LqmyC^zyoPH?w>T_x zi(5&)N}$iWssD6Q8r6p4STa#awFI!Gi-h8e4zy?(Rym}S)Yk*=$)?)dLH2|y(6)BF z8BEAf*>RsJ2@0$!L_Y%+o&AgIiMtx>>Khv_OoWH~izDI01@)e~x<*$#kyPyeyyG21UF9upt=4p;4r|h2 zz4Nf%w^NS8VUgqT2^!y4ev4~lx=eemO$+`?-j zvAlr_&K77#6{EegUV`IIVNGPE5e*@H_6a$)ZB}lf%%Aer>~#d`37-$U%>w%8yMcLJ zgotXi<~}CskNM{(spisK$rlESf0gIzr}`%4maUu0H?cbwTy>)vk$ZCu^(MVe+*$#T zTL$e)Azc}?5$tvgf61nCL$(F!QsQ7zR{d5w!2A6f>a(dGpf1Pid4p3`^`$Uz)1qge z>k5S6XE18KH0#-I#K|$i*V>zL_FFf}^T5!Yx!<-R>G*N%+j1j(`heEwsk14vf)opr zM3zK;)N0Y1^r`8DwYrfGM;0;CUD>yB9{$-beHKRf!#f9uXcDaR%)^xQ1iS*;IeP>7 zkPizV^81WjCoUUGLN);L=0S|wWh*KO4Ge9=1${u!xt=^7RJC71>U#95bHM<^Lqj@=~u1p^k^Qx;(y>D8TYyT-# zr7AYPqoYn!rdDkzwr%B}qr*&SUit*?T}jc1|W@;upWAmj``9|KsRn4#JOB}2KNb998;!#Db-YO_SFMu`wEewTC~XW@o;L{==Bu-$60Q7SwQSd9U}=~>AJA7GQvvama3 z`(Xmh=Uycz_0ZI+n{x@Q8Zkqii-1F-qKz29 z=AbqvsDoYv0nR5{hAx;n|0P}d!I4!W1TVn0NWwP zN2;EGkZlxq$_sK1WOotsq>!|(Al}!cBt-RJ5J1|vwJ~$s$~^>_kgZg;T92AvHYaV9 z{vNgpAoimxUt8uCJ4LClyQ?D~3Hg0CSF;GiQL6@Y)QaGR&bgd%b>KB!8#=hHBiR=6 zC)G@MvUhv;SRoo|&lkJ93Z1c*Xk?)MMCte;u-zuxb3Kvfh%cB7Me-YZ`nMEU0T#g>QoS)|c(XS|N)Mk^+qNt6q(gr41Y7eaorXEpx?)nh} z)A|63Kv-eABb}nM;Xs!2j;Nk{#S@9ke{avU4#!=X-cy_i3=HUJv0c^A;>dx)y1=49 z=|0ulkym3XoWjMC+!UO`b>X0X3J2y@fs_0<)PG>THXa87)9R9$((9BhY?z^CZtA~W zX~t2>0Z$jw9l1&ZIL^OPe|pZwC>}aAd9ZAg%Wip#OizB9WRbaRfxhY>uAtC z%CXurNEOB{fmk?%C6CGGwBZ(9B@nzq46s{It&#u}{NT&cyI)^*=F3Tb+UYzxVUEY; zyWxwvw1S_3;(-RTJda)}d6_%zOr_td$LH}8>3QL|j{9X-MM>iE{;BE3QmJ%<>vT&p zkq)IcZ)6j5SG!+7SN^}bbg=3>TcmZ`XbW?4Xf(^b9T9MuQ)Y)NXk{gA&!c~PEP@ch z_y{sbJ=D3blyI9l;(4E?k=1V$SOXc--E2WS=5(5D2?&@ z@-dDbAmcOg&tT3)X&v*5t{GX_&~}*bSWjHBx$Fd2PPkDZoD%1Fz>e({v&>QZH68Og zUB{e~%jR?)bsz$VvTWzIX7z5_?4;md)l>bjK-v>;GHbDn!)%zRqbw^=%fKjZ8!m^<+&)uMfj z?pP<>$;VCO_puFvS3kwRNargnZPhlX!+Hf8VN8hL)kgW4`J|i6#^P~Fif7{)HNgv? zJi*m9W99{~#5}kaYsFex#}dPQ!K;hJ?6cw7+%oIq3;xOq@B>`O-@*DmCdH)$%Fot# z$ZoNLVT6G3K5t`#MV_}=vAETWalK{TAtgEjz!H2Zj}PW;098~^dMIdzi3_L-Wk^MV zu_Ki(j53&Tp})|hx_YN@o8Hje97+wJa(~>`z<1|C_uJf(9yqY_K%LhpohX?j&On69e{B zuT<+YUi+m*x6vT88uhsVk4lo&E**X4rN=d z?&Q)Q@(}auaTKF)EIyLjvkM6OjjeM(*zk>P$I7lSo89$Wwy}OBFGf?gH?Zr<|Ja?Y z+!u&Zd!^>}fG&g`ycnajPrKeBCTW5)B969-pi_mTu|Q4-HCp2lZdkWTt*~%7?_^k~ zbcc_QJFiPI{h%{A$^6>eGBW|Ijr(H>I^kMyJ-`2^Im%Hgvq%S<_+bY-W#WgAvAYCz z^9$@R!47XjjtA8hqmb4nDgl(N7R6#!P8z)=BuNMB5c(2!2=%7Y8I`9lseS_*cm+lW zoKV%1V3+=5b9-yoVxf56#K`t^U!uRgXS^>LOGhTz82j=KE>~eo|KQH9lsXjg5B2wT zJL{MqcoqZ$`#IsN1+deF!%hf|Kun1jlNbT&68H5{by=Xn-|R)7pE>-jda{FH(SRC5 z$RYkByZ+*<_x{aHciZ;a$#o;MGh5jCrCrPW*_HX8$&Zx(y>E1=|6hnss_+M-&>xTl z`Xm};Nv2Lm3#3*Fe?S!uM@mu)YQd^&Q=%KZz~V3~_oQ1f?dZa;;-G)HbIV-!mTQXp zMs_bxcK38-rZSnG7s}DC6JxW%hG;UHDfA7^sPo0?je(||8c+FyBjcQJ3;fJWbJ~U^ z+&T3yGkXPqI242%r%Khqw#m4U=Gs$n%c>;A{8gu~wg#pHZB2UuV;l9$M$Lz|38<}c z`_jCA%X}%9Zjki3Uj8ceK=eTxdZ2aHEXVheJYBv;1!|h@td~5;TTHO?i`v&Djfxi!Uy#4_5%1D#i z1l$+axW@+4DZ^~&TPL54NDd=smhNQ--NEp(r+EXdsNrW{YktD%F8={1w|b_A@BQ_w zCo7!r92f0r!n~b%qzQo-besvVMUSX++z#EzDxz&1k-H=uN}u+sK9vvyjc)QfnkDS# z(_8HErQw;SQl_wZsI9dPFY_i3v$dbz<9k!EdA-P-}se{6T$r=y9OZXHOr5_S>~u zCaOnYfDU+wf5fR8l4o~`wd~qe`d(?*$G?Y5V(ZFZrd54t_D=Y3_5oN~WnF$_T{p0Q zmMY^OWBgY3bJKXp7{8}#Tr*_4z zGU;Sn6%wxd6_9X!HF)cBpaNDxYR3sMr-I!$PPPOu%QYh z396;3Mj4Y9<^67pOTngjPHHs-2CcP(itavZr2uBlhv6~G?=0y#p;>yCo`N^nWp=do zlR(54pU-aZ?dj^swWrm#R$tuL5)RtEc2CYzM`hq@b}0DYBIH+YTX%c=jW>Ps+_c)%GCV-8z0VPZXagnq@DbXdgI`KgAYpv-M;b&kj&}OWnT^(Lz^mm>#cQE;p<`! z2f3|mCCrW4XVb~ndG0q*dj+S{UeY^I7mVlWNqCb(k&o7X8VH%<^{ur?xiTmD)f4oc zs|$fwuwt!3;2L}=a0>B`)8*uYh@Dg8-g$^UY8qcM#y=qZ9*8G(R6c5qe@K2^W!(52 zm5=N982^6L`zo)S=27$gruo3@ORHY5nitg=RKNat_6uV@zcSq)AC?`JbyEEOUJ-vc z-A`1*b+4%5dQ9Ngg@}#`#Py9g$rdF61~CGO>J|P`D-Xh2Ec}u+2L-U*3>EPlT=5Xz z#7mLdyyS?p3VeVedAexX0JqOgv#!@^sEd=BpUt%=5fIwcJ2>U_Dx=-$|fa zSXIZCIf!m0m|^7@WpPg+{rYbzP!JzRYSYvIB+l+DALpVfy zoY#x=O3!P-O0`Hg0y-&1$q0`d8dV?8O36q~xf&4tyw-etrFi944>`hOuvHb9tR;`L zRrn3~p0$MXGH95V%C#mcOI)v5SyD?PzvJ9xC3jX!lQqjq&U|!*Na4LCv0t1`0-m-I zex&FX$3d7q1O}Z@sWlwyzWkA6Z@S~K+*qEb9;967ev#_omNl0L?3E^p&Qt=AJlbf& zbE7hys3f{h>gI##Rh}*sl_F|7NjPr-1B-6Jj1NN0`o#-M`$v~J*k`7HeEo5)ZvRep zqWqVao_FE_LOz`szwh8{M@8RExm})+nxu9u?Sgr_Ed*AJ^=p#ubm8m9(lyMM=L8yR^E~@p zd73bmVV;N`UneEBxXX@3R0NP@2I=;CyuwC-&!El0)_s#Vln!2Zed*vu7al#dm;HTt z15B=${R94i^GKgdviWa?Og}^Cl#hpu@q6TgX%3gQcc>)ltYAHOBCEES7^t-mI$b*cbZ8DU$KGxJ?zLo@UN0q)R=^&Y0Vi5 zV%C;Tp3`%-IJ3*}T{7it2^MGjQ6wLedHznI8MC$`76Ts2Zr2m(Ws$k+8DgI}GJWO# zxzZMgx?{9)UvKx0=`lHaboZ7kcXg+~$P?zv*Pq@qJhHX?XqzN@wf%(p4YX-3ZU@kv zz};CD&v*q-XYHylTMP~r?d&I)zwVZc{`P$*F1!4q_x||DEbxa%AAM2Jt3w`cKwSMg zfzB??Rm+AD^0AeJ>JJGK(bszUg|7aIbW`ickNnx24l1Qf-1E-lKqrv2pFKhRL!V9j z^Qhp%J5A#uWBeXbcgV*jWBh*hNM)RKp+|)d@~xVm{}8)J&lQwgfImZs;)V60jSf2h zA%9^!4i#0A7+m-h{?pZn}b>hHXz*nP~_F}&e;Zhc!vduddT zZl3KKX=D?{J-211^LxkJlk@q`E&jkzJWhU%0_jmfDI)c1U0BD$7VJ!(vw>`NP`v;< zB77Ef`p8A$345BH=%N6nLoxUVR1)CIBCw?zWS=Qao-kPH#B^u(k;0eq2k(F961!!p z{P#LnvB{}B@4WL{WfN^}1`R*YK5LT4&%wC^Ualv33^(0;wM-6^Oon*`8)Q3|3V#dlNqkgJ%@O{o z1dFkRJu!gD!|d(l->`tY{AbMjCw7c|y?pED8TQ&G%>BX7B_95kI3ri^oFE!^igDTb z^qgcG_ZZLL${rMb?B2+pg!y6q#8sNB9yrK>Jy91pP;-WYv=_ovWw+YQJ;9w086C9- zC~F$E-P5o1+_L5g1OhFAmP`_aEXW(o#!A_3eiao?jDiFlRf#j)(zG#69LM< zxv+k2pmX%9T${hmAAsGf2P~t4dA)VUdLLjTM$Xi|Bon?RWWs=? z=K{T*=&(*3m6*lq0i)2#C>v9@U>1;dnY%RMUCS$*xx!jfst2zs*t@FufoUH-dYo>$ z{1an8-zY+Jlei8(4|#^>0q41%f4>D|1&WzxEEdi)RpA1ls5x99zS@ryBG>6m-{kC4 z`3HiMETFqgM+6DqqQ?w$p7kIt>M*^LVO-maF%@*x9Ik9H#r2krbaRj7K_-Sj7}QGx z7o#09q*8x#ziMaq0x!R2+pU+D*|95k-gf!s%`@+wy=Q6mf!X`S9y~_5+JjoL9{Y(l zIP4%Mf=uBVsI+LI7Gmt_073q#;RoY*QTa+vvqz-K3jM z%&2YsV*~9hQ+m9#bLYO2{H)ijg){B5AcuJ0?U~t~dJZzJAuYXIYiwWEN@VrPB@L! zBabN#Y;H?FAOPCs@pP^@*xKLLo5hy%J9jScN)ELVPP@%JHX;|Cj#RtedVXfR%f;Mh zZuR?ZAp3@Z7JYEv2PIXydGX;8_BL$>!!jDN5v(^BHYk*tjl=TF;bs1oO3gz{rK%y$ zYaV1dY}DyhzY0c7C=^md$*eEaZnK37DN5YQt}I{j*eYdPMcL9EY3b^Awr(y?9T^z9 zXufwQYTNR6lP%G8`Kg81Uy!Jqsmr$I@-wer-gDcgOmd>UXDORy>7;taW&g_MBH~mx z%l)9r#0U@f5jb-ng5Q03=G?G&7wHf9nqIK4$Oq9;Kqo#--U6TGLwV=1+rqqIZWXF+ z!v4iCe8I>`U>n@*H=mp>e^-aFeGMumk`2E1-{k@7Lk=3L-iI8%5B`4;sTpRx3AybR zn~--TTBr$m+vktm_14li^d{uv!<%^%^6kUyPiT;yx!T->oZEYIu=Wt)fz-=Z1eLL( zvdl%?eo)?F$%HQ+A^8@PLY{mASkz%dD0guRlNfBY^Y$zlM3Lu8&zI^4U9O2{-{REK z=jHx0PcWr?hW)0`(;7&&bi{@?{NfkJez33OepoM|IbqYP&%p0a)J3oc3*_Gsv=4~< zU=`s3;r*%-VDuJ!MUTo#k*Pe{V{ei6)yeyN`8HK=(3ABK(I zj&Y2@B@|mwKWchq%Q2&yM-+j4-&fwnuLkTN4q_f1_ryY}$<-W~URwH`JU-YvtlVFIf;FydQcithS@!#Tah}J{J}5T< ze>K4A9@U2Ga8uzHXO`2zUpA{^!|rg{ixJ^z@RTwZVVjy71I>-WrXWaIPm{w&O~F(T z>}enB#z9pP?N|IPyj&`6{P*#R2QGZ?hROAFvv=Gf4;*^m@W#N)tf!~gTlfOap&&N` zt%5w$#0x~BPQ5&V!U}T4YB?(@`t>a|gqZr?UK-~6XvmA@zVJlZwT+ezOHb7VJw z42($E^60%M=rz@Qd3e1S{3V;lsoo18_G4w60$1_T>T0hTYPvF0PU?pJ>T<7$6joEK z%f0+7>b>+eZFSVD_qz0uV|bL8E?rJC3uO9>auH}wsEq;F3cqK#;`fYOg%yN;&j3oY z08dY;>G!`kUZ_vCfkcU_X(IGev@&ymAN4)3}& zKf5t=$=Myl9L+KgVNL zeEe_VAT)tQi(>YB1P|*%eVyF~+h#}GN3{5JFt{ldn|uU?KV9>{o8d705)DT~qK~4b z$~^oS?Ou0jWl8c`_3puPdBafsl-gQ9 zw4vOvYK@?`SJslGwV?Kny66A5YeGy$+Zt)@N^$6%-VRA`FY@2d9 z#6Qawa)tJ6CY@4~iRQNERuH)a%UEx#4a>OJu6?fxjIn=>r7G`U3C8$?S6uf!R6pM> z^+}g#7gdlL)2Voi#VYqQmjlc$$z6?-SciC^4y)y8J#$GmyUTV2G{`VTnIra1Jw1pH z(9_q`*WK0GQOM`oO-KRhbc5|&n27=77a)X*0-stNDRD0+#5hsKOpdKJkP_cY)IhSF z`I?C$#yK72yv@)ye-!j{>XVq(d#_bJ184cA5rdYpqP&N&$h~l@ZqO!OP9Ts)YGzgo z2iHQ@w@9b(!jqX*K7x6JhRE^x+-{%W=XZPEV7d7N4iG%Z@>YU~&IW-7NDCh@`}J^w z%U2Tu^i30=JDkS_zXkaGH*k3WfN;;--g@Qm1It3a^5gDeBlLv|E_meh?@aQygyJ-urf>XLc)4uUp z)A{@joX;yL$X^cD;8Ebae=!Jsydte&dFO$e? zAR$V!L$U&|9>F}~FePh7ESnIwSd!GVnvN!;$wV7ANDc=0*{p-JDb+ZeZ1q-LSamGR zFRt1Y<$+c3s5N%Td=?W@PU-+l_HgAa!t`PmyQKhP2wfnu9TYthL&llJ)|l>EQYfF7 zqqO3iDrKZC+NLxJEYz>56*DFuSlzPX0M)0imZVChES6Lz z1!@jw0ql^ANd#$6Q#}v}5fLq>)PX@$4uSdlxeWmk%P)wef%|w4K`1e9qR9BnGkV6r zHjz7U=CifrPhPB3alR})P&vDxx9H>i)apEQF|8l{x`f~AuvJ!%M+ZZnPB;P!?Ov|8I5E4&j|_ze!k97}!Bw6OHdTT>he{LI&Dt*4?7 zm8xX8v05&e)xltk-O*^ZLVTnW=Ji%-VtG&Oe6f!pLZz`3>{Y9Z{-rqqJ=BjD09|(P| z{TZ#VPs2YSjD^FoSUA)&WZLqf-b*&WZQZ)gPWTgv$0PXX%$H271Jmy8mw@IMOW5%_ zfZbR9UQfNtil%)X9LRZ;YjX~po%`XfQq^VB+}zaE9B2+S`I_)f@ijTg1O%Z(vqV@; znCVbfDQ4~L#FayZel5T6^QUah`Sb(l{q0C>|0C_{9gn#_2Q%`{yKXCIzxB=K^7n7P z*`RsKpt)n1c;xI0@Z+7pBbb#sr)}_H%W||0Z4RsLunXwR><&a*w22MpapZA64u;h;l&f(J)>Vf2*O5m6xV(<68-Znr zy=}SoD_p6*j9~R;eSIJvXo*GY{q@b61aNtGkkG$>K@xDiP z7S~U2*tKzPw6w&$C-*GM{cr0ZtpD=+J93?Bc{w}S-^H=@=0fMeE6&4v zOyfmk{5R73Oyk{RTz3BMv?SKlNNeiE+p>*Wl#YaKwR9?A+F5nr2rC|Z)X??PNWI*u z#R5__+nj0#)oM-j2UGp0Y4Pmqn|fCuJ{)-staz}B5G|^u8t7qP{e3qB2~1Qm);4IY z?WNO_Y0Y_q7B5Rr8orp@$K58Gf0R;Ya|@Bf>vjhF%8h?mD#-A#*06Mi(l{e6_+*z3;85D zuWO+*<1QgAGfY2)FwNM&`=>C+e8N-kP0qsxHHGT)b-9k7NbBiH8?2!Gv-Ou-T=RQ} zTGFm{uIaWrj=_B8E>~xLa>Va0A9RI-*#Y)8cKjsG|CsReJ0wqaPqMHvM>zFx{w1f! z*;MC(2kj}F&2JQq7406uTI}RQ4_*Bix3+8BjvU)1_h0?s{jY;tqr80Jy6bisy)T>T z4hZ87V2TqW|00faxKi~B-&$WUN%i4+?rHJB+uR;c%4G{0-%ZsB)xw45Fg||kahSvC z<(F%G9!#3~ZP|+x`OwVY>9Ry_rt=r&=WmCQmuKTNM?Q}Ay+2+L#)v={p!*Hp;7b7SR;ux;FA1?qPmz5DS7_V|Z>ELn z%QW2we7WUin(L0Lxqb|DS69V&crD>a#T`AU6^+_Pj3?V@cg%M)?GD_^O%3pdI!`Kr zcQf;d^kswr@D1p=kstlgCD&hf$>v}EYH@0M!+O-i_U_+RdgDUb_hfN&tcUN1^1I3$ zEzR^c}e)q8)<%R z(wh;Zi=&FUL_5rSN<r0an+41FrgE~iWyKXyseae!Xc8? zYF~3IUF618py)swL6lws-W%b@O7w&+4i4OfZ(qj12HYGxV?8Z>xmp5sHqe#l0R(7Sjs680f6N&s-z7s>bVqPEAZ%c&<;wgsheNWw2!j4(!;M+-%{lg zqkZ2S^vxCeUS*z1nkSy%i^ong!^b}R#nL>!wkX__Xr%>$-5N83E} z%-OXyo8?tjv87g@yvl-TJwRXXOX`#^(2lO?j_1M%p+#{i7MH2bom;fW)7jo?buCLS z7x6o-E#d?hb$i~ZZKgRjGtP9b6Vi?7A@_glrkdm2f5>kl0B`qsP#5^X&kQx1I%7dR*&hTbv>wd;X)7+fl%jlSH=7NdOs}uCj$K^@5@20f%SeA~6;@ER5la?)t z#mFkw3%y(DD4U{x2vV9zr3 z@0pmK9PHFu2R2{h&TZ<`Hrb*_3LCP?^gtxkrM7o16uUbIBhmiNFz-RaGQ_*BTkF6B z4pTlX>A(>bi>90^PC+-SM;@MR!8{28#G_`}8_N&B@YrKNcj2`Q{P>YMJ)huRc=y|j z+&%|A_LHE;`lO%~#ppnk+1W-olkz;(EjyUi#YmJmu@Na1VUsZ7CCq3UhJyhv_dLEP zx@5>9;?c1^Ft4kaEe@%8qSz<@)l+EL_>0DT-LPw_d&dQRUwvV&`zqE~oN)Ea{e!L! z+`gATQr`EePnq~KW$>Is+&Qqfay|Okl<$bVr5D);VO>#_+hGtH7#=`$X^@dNrkhPd zD+n94{c$2;REl`K*i_n9>7QUiYETD6h8mkaJaTN^_45Pq>CVAPZDP|$%Iw6a>e=M3 zjs05+oBN}Y!Oot(iT5vV{0PqngE^6IFv)d;keM(0fp|k&KRU~SH3gI$x!sm=R0 z&zC;3aq;~VgMA&n;fSt7eTZ^NRISaVL+LakMS|y(AaC(Qh?o`k|L_Z6D6tKgxAQyw zZiNNDj${%h(ksedQLlx1+-pqZrz_*H{&`{Z{|WXxhPC8i?OQ<^l2EboF$=RS7^eg@ zKsvxJ25ec}!sSd9sVBDBbb9-S;H(rq1|T-OYIkm+Z8SS~Xv=1;^L*FW_nyA$mbq(Y z<%zbo!I1yNWmg^#y?d_wn}K`o+JDQ8Vc-6VGziHg2h&8ol+zY98`*0SQJC3Ra5KA*UcZW*!#Tsu zp6Kv;R*=61TK#Sp<~vb2OvRv%$eV)c45ld!nXy9z?1~+Xg3bDPDu;eTmzj=2b@i; zhG2+_2WGI%VFzIdnxSN|Nr!dZmlgxUAkH>n@*C1Cooqr4E3Nt~q*=*)B&>`6qC7q+ zXftZ&z+=aNXp^^{#|cy6!QPqt+!c~;3xO=e`y!#mVJ~4~?68##H{l4b*gy%MlSZ}t za((If68s-?&*Xm0IFlt6eoRunUl46Ur(L$XfaGq>gK`5A+%mOuF~Y+l8$$foRA=M3 z0Y>_11vH>2PmaQujg7&N(R-eMo_(OakFwrAuweoI+pyP=3-xq1cJQ-trDPf(G{#@j z$H5-2CwZ|$=tB4CG?Bgt<2t5mc#&V2o+cS=?IKX%i=|RUcG0u4!smd((M9KZFSh|- zrtdoYM;Oo1dFJEK{~I5F2F8bJ&V2lL-!hL68sjgC@o%GsMLOYLp%W%n>V#*13$OH( zPRQT;$8Ym^I3Itnh{3c}@3zz)H3Wn7~++j8Q~WUAMz_?z(OT zT@JAtfC8hXl5(OJionZ%&~0cuy5AwW#OMBUQH-A*k-kHFwO8PwKUb69<(GxrgKt3O^wyxAk#h$bn&)mf3R_m>2?_mF4`CjD`mg3lL@Qw)SvwOKd`)fK+XJ0%UB7X2n zaV_d?v{C(>9)^QES>6;-Rg^b@6{@PI=(*NVP=|&qHMoW8h}?bV34v3c*UzdI4SGzZ zJ*+DwaH7oqipn8k`9r0H2TO;Tt^7x3Tlm?}VC^tnHbS})pTFaqTpn1@-XVPfzQZMX zwMOdXLs{^f!VETjsF})T20X?fQ*e+~2+BEG$Z^KIpG zSsT%%Rf`eon}rc{y>uSN3rJUpkgfm%PkfDz9KzZT@~=At>-gh`^{@QE!gJ3V{>TuW zSEtmXMeL$t3=gi5VP3DN3H_ybc6~lo@!<(R@yz8v|KWvl|5>U01nYupPL~xSI**s} z^LVk473C-CJNP)>qu;1JPv`$KV=k?52Vjiw08ip}+hCpb2(pC`x%itReiK>VUIQ4n zMUNI@KL(V+74t&8u>5I{r&(2zP`)8kKBL{IvZ6=*%DcjS>Gt+ypt&*Bbn=t1lfrz|aTn>1qBiKi>_ zP4MRDDId5~%VUNDr~|y3BTOAeDk-|~NIjSM4xXN?vng6>pNH>4Rz0+|1e)0|ezEX~ zVLMLn?<9QBPoKR-;Pc%g@c9m(jSIW>wD7@xL*KWm@&D58V6lGvGhb$n<*ocP%Ui`~ zR&3?d;(j<^mkIK1m2r>>Un3d>M1FNWdd2J9=mD}Q4kI-h&7W#A_&pZ5P%uLoq$%91 zVDWMMeK9`V&oa;M9lrFhIGrbe=r_Q3c(9JR(QW}%7C&A=hsQ~a z`QG+={LOTr5^6Rxpr}d^^cj`c>fW&It9$L<*DGDL zfB8bN@o}B>U9{IX2;KB+dhWOUQ<#G)m9)BK5Id&wj9y*^A8^>M3QmM$$YE*|&L^rx z^cRo@^eP7$iZfA@qDm?l35aWjx}pv-pUIj_($S1I{^^l_y44<;&v#8WP43>XSW2nM z!5D+TQiEaS^a(YS&urbd$lh7LpwN>}TkH70GHLdaYW=4P<+U3&NK~$d7ln!H_XJ3E zB!GaR6JpA?51~Rq1G@ef3Ultd=9d=dF7~f6*A<(755!A*ujzxkrlNNs{caZY`>1KW zXpH|x`dDS0WXa7d^qHHvEV{80Z{T{1jwgD?kWuFG|B`-e`kcHm{<8G%EA$^7)AHV$ z^Dg7Oc|JEiAHyg`2=T0SEIcwk32@aa^ZY*&R>DUU@TOGmVK7&(t)Qn|Zw28Y6yLk)0r49l}{oO@e@)7I_cNOs}r1pz}qwIGOm0l{b1@ z^}w=*0DFX>idH`Fl2}!f(qG*W=M&qFg%tAnS+%sqk=WZOYs*{8-C`~5iSgdfLiv!~ zzm)Hh^jaCBZ4`UE2Qde(0aF5be*|7+YeoEET^A+KL)4dQ_h2?R92KIbX2y_fYMKeG)3rqOG^ksl>qYF%M9{2J2gK>h zWwp{%;c?{>`3e({r}VSsa@?TDW?z*1>HZE^$2P0tuaq1UZVK^&`V5b4nww`17Dbvr zHfDYO>GkVRZ`yQP(@t+%+_7`v{`=*L4Y!m^Zv{Wbo!xlJ$x|2q(6GzpemZ-1 z37PS3(|FMs|BdwC$~gM6thd*E?s@5E(|ETS2U&7TGK~)!<1d}!IjUsKig-o@EZRwJ zf=4vuN<>4(yjkp}hC#{}qZkduc{J*FM^jNX(dv%4!?_^FC`~~a+nThJ$15S3u2p0+ z#b)|z5s=n1Vp>m<)`ODm?IM>yOY8lgT$d?Wv-Y~aR|(zJSXL#5Q*&ARevF8CPG0Jl z_Gx=oM0BiG5gia|RwJV0q&CD3?%EPu}ssiPwn<6vbS10DT+ zJ+VS8pGvNRD{Hi!8?J0^D*p9q)Uw!Ws*Tq`F8lg9>6JI+;>*&%nD}ce(V|t#NlO}B zuntZM;33{p+D+%jwetM5wQ(Y}<=WaasixMZcqm|6eqD{_>rF{kt@snna~Y)}r(z4M zSL&Xb$?$ySXzGKtkBTn)$WFRTGNfLOJEdH8ryMkR=q>EaWLL?$T_x_r3+3BMR`zI} z=qP6he9Y!`hypZC1uQI9CPz^|c4V@YEoZY=?{Hs`%HDCE+rFE7>|7hLd-JI; zzrqGcl{ue=yR=Ih#+y{HzF~5KSy+I9-M-KPI^RanyDc)aoW$}zULGf!*|$*QuAWKQ z-7QJo!`(y0-n7~hK+8`j4;s_WzQ?qMyIaHk8w!9htHTt7H5I@|$wfGEUqowE?f@@h!%%-Xd% z?2@&a;72uzbiVsaOkv2v1G^NOBM9OY29rzO+t)DFAGv&))476ThP9ZR*vG13gg^YWZ< zVJWR9WYHv9e^_dbXWJ{c$+mUc%vGFDlW#urUiok;?%RB`L77~~nKQ;YF=*0a+z&Ug zU)QKtLHna@&`p-!YPwhN2X3=VLD1c%HBGPcu<_f~LCNBFo^CBVGQ*lfA&0|a2_-^p z@t7m%2sAZV>=wJ4!Uz_g-LQiIU zYR?@E!NCJcq zAc0VzVJRtFp={-4D=oBPD{XoY05GCF(KgX)J}83&AMQ+04w`f?R)Q zPG)wAUn3<7C&?LC*{qN%ZU!+d;PdB`4!j=SS$Tclc^#OK&aC`CpZJ%y%gnZ8p1jLU zSX;S#IVM!S%DT>T`SOX&I@N0}8_WOrjcRm@AojjKxXdoDR#EwIl7ra zR;8X!Bj#FaqPa%dKvfhaBQotKqf}X1vQ_?lhI|j1R{UG+Fn4y|{B@Zj`{YvjS`NBF z)PyUu(|838Y!wakX;3WJDJLhVAje;5@jBzOvZN%uV1VHR;U8LB3l1v5yi#AczOQe6 zsJ^Z*j8s2W>Zq^HOfQQC*mi%rlP+b#yHl?CxBc(s3Xe>d6yTLDsN^a_(~2rW1VLdU?!pL{6us{ZEMslmwh zR(ck9%@;qQhp{IRsVHdQKS__^>GM4YW!(YjD&-%-bh)`g?g|;3onT3WXWRY1+A=cKrZk?fsk*?D~l7rS1`t}C!l;%kIf>HdFkFGxM<@%^jm zb>g4AXO@2w;*ZMD-i9us^5Q?KZRLk`T98oNO8bAOww26}YH$ zeR&E!hxbz3CplxZe(-sU&F0NTp&$r~~hg_KjK1Yr#!`a{4KUwH&XsRl8=ev#W z{?_u&0#-v6(@NIgOH_7Gaf<5!`TB<|l-Dce>z`M1azAyLb0e&vGNe|OJ2M4AZ3j@S zpa8|v+}~*hAc~kF>VAKj|16-`Gq*&iJ<*?=9!o&TuJ4Lt%e*+YjYqZdSlMxXTRfBE znW*GJoy>zTt2w#n_jAM_{1V%nH_CNtmDg`W3s@}u6kiV4x$CJGgY64J?XasLlp^s= zg+=e|>ySr1PCt|@gUv9%WBJsyz$d9)=}mTrO65{!*39pB}{-7pE^Y5@Pa9MujlL-q7l<+vvHiwZF6Nh@JB8AR>gUoq}4Mv z4bkCCF57(Wg#y~68tg8O_{v6hwfAep-}C+Le9Mu;-@N&oS32y=#6Ov= z{30(2ufo0#k-2KUCe&Wl8w%w)GhC+3 zoRZ4ad?4=5<|cy3u>01HEU@NVl8ws!FSy8Lvj- z#(oGLB4fKwpG4myHW}-4YQ!QT{fvE1opPVk9O!fEg$#G%u6t zOHKQe&Uk1v^8if%0_Z+lsMy{5G>KyegBSSCM@ z<%u88T-x6>4WBi9ths5n+|-Ajxqi-9<}Fc6;zP?UY(;a^7GB|1LJLC3iP6_!@k*Y%h5S9dIMXSnj5KCj)0c}w?Y zDLw~4KkaJo68apdO=PplO+r0*o4pDpU1^@6 zKx7V(N5CS2S1PK z1}B(qdNbLdUVJ@_#{t=05iZq283jC!9;;Zi938fiB}Th4O{`HNv4D}6N$SKdg_smR z+z6C3Hd4^Rt_#r4XMv(;J9pu)&ZqY7m1znvnt1)E7f8Lb;CiKe{qqgV>vi(=FXOJS zrq_wS{PZlWC%q>}{_IzqrT%bm{Z2Wa-x;2-$m`b&IytXjOEG{k4;cioOG}CheBQhq zMTWoOEE)cmgm;FXOp@)tQF@QbbN*)@R=(cYJnm(E11q4i2WuEea&ipNhf*MU#nTi= zqR8lgK7Pj!5Ec?wy?(5}Ql1gpkCkus(7EInz$C z^YpM{f5qgB$la{CzC+%d_n;ro!im5=`}iy5d+z0rCBH|0zL(yEBsrFNZ$s>PihBvI zU-P+Q(&xgxJ7(QW=aeDc8yDlFpYbJphBxTeE1oX%X_>@7te)Jh;9s`Pn|VT)VjO*Ch;LTriKNr=>)dk4Rpg#K-k z0&J!z5~+V%@tWf+ue*8@^0(0+WgG#|w_+V~JZx}dR=7xi0BT0k)(2`Rl@_NqKo@uTX&)zy-$16@Xvw_P;pE* zdR6LGgRj@g*T3ZMQ(VuHuYbj`35m}UNuC^`ThQZoW#`t=_mc*bx0%!64M8FV{H&6H zX1)LmDK~&G0gD6)+T>6pC5}E@`VF+NG?^`40#oM_8nQ7y@DrgbPl4NLHd#~?F^+Wd zsR46XV|IvjajdyQia&h9hp}?+;D*Af(22rs(}0^BuQeM1V390uo{ueF0AR6Y#!sja z3;Md)3Zs^S$)T1k1waa$0=8HmHCqT>KY78XzG$>zMAKJU(q22C50CVWom1$#hp+Wl zi*NKamX(ye>16%WUL&}^#QtfDHDP8b6zHEOK>suWy|#A$f$7KYI%oU2(|3LRF)Bye z7he=-7~T&5^){)|l^u4$Txac0vx#(Puz7=Yf96j@%azyb)3`RI7)II&avU7&li`=^z&N$&dgkII86_|9Ss5p z`-HtR6WR2@9m!ST4%^61jHR5>>*G&Yy*?8#588XgVdiY!pFX?#s>ROgaz5)XoK zcQc(6>w#l~P9aHpf3f~~F}D}iGC@w0@_GkM%xlo;>)ay-w-nKE=f{jIHSvy;7 zNZ3O`60Z$dY?yrwMWxkY`(V$p43ouMnqq4!YVDn#aC)lN=jXm5Ucskj7UtPnvJT$w zuxsY2+*vs}?V)hTkAn+)vh&1$4GfUE)njUZjOUhu_f95P9}cpfI@4N$8iJ-<<8pm=vqg|M= zN4Bh-+P-zg)b`H9hY$C3%$yjA`G-sR4>=3TTQc&R9xc*9gFH^7UJ>*6(msf^&60&V zd7)39CCUZ@xXN03sQRwAtbg2h;v zp)%M@L-@J8f@80Yj;0kAp@!rjaOeq>VIM#2|zeN|{w^Y^j=W4hUG8)yhv%1sWp&2F)jX7P8F z6g>Bs)o3(5f&2wkdTl_LW((RZin*rYce^-j%)que%#rUirt?A%orIau3Av|m+z{e3 z=|%iAzC5O4Rh0!yH1v#xY-UU`w7^TCI21?bKmv8=>Te)qfj<^`x$j|lpMs@e&*OM; zLfcw9ImBVVgJ*CWq|P`|4)F*09nkHLLu2qO&=Cz( zY;L!$urB1va}5YSr^VuQnawWo;JgNNeR@v*C(^n&$lWTWVl__ln2JMHrDkj&gos-+ z;Lvz`N(M|S1E1k^po9JbRHGALG71g)*qTb?@4&jrO<_Zf&vZ^M!d!yY9FI_MJpF;B z{A7b=13z=HC8x=6NXc!18(<5~3QZsI&y#XrYVwv`U?U2Pp|uaiT*f{K{l3BMF>~P8 zByFn`URA(R7dQcL%9xWf(608@NN*}t{~XdoCO@6mmE0@*EqEth8+q7+NinAD@mYY! z#V3W1G^>kU(UEAptmk9N$B!Wrmm&*GfZ4(`u#p5=kAZ?q@}p@DF$syL7ull?rnLT|1Rg@)`e5dCdw!+ER1T*h`jh7mtfkD$Mv{$ zlhhR`rZgS9Re1vi$$L1D$?o@?EOH-A(pPGB^&$-%*cvT5o+6%iUf}Wm!om*Q;Gg)?VseSpcjNKG{DIu>8iC=yhV+BQ~MInln*9~i7G>O${Us90n zo)~GEKZuUh*68YVnNFmC^;N3Z6rEnr@5E=ngUjZ8+`{mH1!;8#q{pwD({g%2t6xDj z=P;+!sm5U!2O_D46b+P0fGQics6PkmWI4VZUtVr@mfMA&gx4jU$7wnjm}P|?ExcCn zS&@uIM=0dMCYu%?(3YSVvh?_!5u>=;7-{Gz>g}4!&evz6`TtU@zkB4!W5`nHAAINN z(Rccen>SAHKDV{k*#6?oF?3^1)-PuMKC^0jAt#*v;`DmqVWOM)xFSHlWg(*=W})Gi)Bif7|mc;LYo#WztN`96MX?=9CXa-TYdUv4^nAN%lJEUf=KVqMTwSdKD% zHV~nFr`nGj6ROc=5>8`61xyfhg0^@}{Jw~B@oS#+f^dtYz;8_{M^|B1@+-twFWTK; z?Mp9PvI1Q^bByBlpFCZ{ci?et5Zg|{QjGPuWUU@am&X9;!nJbrGei_H8)q|-MwdDr zZTIMj$Gqd8`Hm^^&kMV$em`#t<@1lsEWoVTkG1=GsVRN@r@#ie{|J8YBajp;*P-#_ zpIKdIIj0b0ESOM%SQbNVtS+-$FB~ ztzWx+J^#qy_r-6wEbI%5@3Q=;0HLQquDSdf{+ZUB0pWouk=_W@o6$jM8eju@M|@)n zUBge!+=1_p<#Qgvx+AFtt3Lp})}?0(Rh*6+cpR&@sF(JYcEE|l3u_Wbafj{j8)19m zFX&;T<8;{CQ3D+|EukccK1&B$YJ{qN!$8eG+E)Yb8^UYoP!kAOk$pY{?pmmQh#9Mc zDkp@?WVPXqkpV{;*&TYFGq$@bDqL3wFr6VA<4zWci~~vX9BipE<_c$dZ@! zZ*+p#A4%$12jn`|wQ?P6SZN+oXvae;*8WmF_3pbUN8FFj<5!>P|DYc~jPd&f;dedZ z_tj7=MZUh5%jY`D^+V__$yXy(kv&iqE>FRt17U4J11g*bt$-?Um>5Z7*sPLGX)<6b zfhJ+bE4@Wk+KtI%fgI*OA>4(stqA8_^q`lz;{ojiSJ!F zm4;k9(ZcgCoq3XfM11)0X1$k(sleU|IF;J_5Ano{b^h- z^fSz|Vf!14emzz{zyQPA9hP7a%>y^wBycN0Ae^-VO_#_`&&|mOp>H;27{M9pH|T5t zoTupxWM?SD2uzHDl0>VA1G;U~-TlRTI3sg22) zC&=1PKYfy~BzxT(&eIc*9n15fQk|0%rc^pRZQCm!C4A+S@)!Z>op6e9a-F4L5LtOl zrlo`YyoKdMpXB%8^*yU5NuwP4XqsJtj3J+i;IcmLQJ{`<1grK?ttKm9a+ zeB}1+TW?=9eEYU7cP<{h;@TsZBRg_1p0{FpNbVV!H}o`(@mpG~L~8P_Q{vlG=#TvJ zncHP~Le3(d`;*+`Dhtnt=V&f1_%8mJ{QjSW=N$gM2mhQ7{_s?Kma9l5I;O-0AkdNt zM}{AGO|>@gVUN3;7lqTiI_%!pr=Prg`BNQ(C5F!QP%AnqcA=+WEb?r!Pa?$kSiD5i z=iU%f`QLITE)(wv@YSgVq{8NwfHiQ9pq)18c?}rK8Yp?H0_mg+yIeOdOpHL;uF@nW`e>Q>VHUp952-;>y zGA`p*sfjb?Tf9W+fpw};1PDVWo|`ILP#fJmwSS_Ss2O%o*48Pc7sUgOXh5p9w4Og8 zpEsb~s>nXjsQH*ytE?(5opnT;37Gf;_=IbiLY67eryjwl*)-nNWPJ$@n_j59&u5s@v5xlmhV|!ez{80* zwGQ{UiEqJ}umRR3(-B$n*T117LXB(1*nftx??u}9(U%V?hNu0#_+ODZLnm#lKWp)< z)f!$sty7UjKze&e1{iP;ni z-td10l76H#FE$O1C}~SDG!!hO>qNK_(`e>g;BnS#ND(%j3U7C^{tQqfKgt%M#ez*8 zm&KWBC%z&0@}=PAC~Nj6wk9QP72Z|m1BcIh0t@gdlsz@sz2KY6rqJzcr#G!dqvHMe zz=WQVABzt*NA`VeQ`w#kafWoPltWj-Y+9e3vQl#M!0E*}iBB&m z5nYfEd&RGb!`RSJ9oAQ=UcqPOu5MejzqkL=g)NKAYFoP&tkoiw_`j;P!)4)uHc#2e z9ox3uF`Va{7udXWaL?|XEC~;A61|7%azn+ZOr%mfkf72dXkErBYk*5d{2S%)bdyx( zJ>O*V6D^U8fdL>v(-ZW>k}%N3HCOKoPx`C!TPwb!5l()Np(h@E zvM7I^JL?~VyEbKJHF7<*H(3$PCSeN#e+;ivlKyDX(S;zp2~8}U8iLrZ8>YhT)jio$FQ5+$ z&xALk7j~@q`}-Z8e!uuC-o`^GI+^cY=*K(-{Mcq%6wU)GnN~%@Ny3B<4u$~h&jchi zaiso%bPo}jP*p-lInML7v1U$9;PA4O{Q4YQwv*)7gY8gYAg@5q7iJnB<~>$LrOF3a z?Cb2@xA>xOYL`q+jT^5&@A1b+mn~n!A0NJB`_?-~zIRM~9QS_qq>3J&OdUS3 z@n~E7<(I5lHohRzN)B10_$kVBuAIMmi+CSO>*#8mPxEqjlJ}YoQpk-5H73NuQ`Oum**`4N+=Bmr%-!`njX8gVlu>K5{ zoOFIHBeIBePKZ@~#d4dp@R;UeB8iJhB)7$dUuRN@6e|U*I8A;Fr^&HnQ}^B*?{P@& zjYfNyNlpjpTt3O4#%t2YogYrOVJp;*R2m=B%jFqqDtYFk(!#Co|;az5#nu!K%~#-05}nry*hph4 z4=rTzCIxo`>{6YM#EN4c2eX+HlA)Kql63Ngq%Vgzhec-+J_V?bA&)$v1=j(zzUYnUu(V{*l(xG0w#(~?|ZeEd!Qc|?zAjYub z29X{hf_B|?Ku(9ml(cwqC|f*~D8C~lY+Sp&WukTKx{JS!&tly-(K|Os#NS?Zl}s4^ z#@u;@koV3zB+hoa82v)H8n2CFs2EX*cp)Dl6_2easK&(gSS?tBs1a>=t^x~YN_LL& z{aEgD+G1@HxO6?a_$eB#&PvK-g&bNEZqugoF~l?Lm*5S;0f=e-Z^)T0Jh<@O%@Z{N zo6n!$K7ZlpU|(GI9u!L`dKHl%3MEJjPdr8%p!w5HympC9gM zZvS9#;O|t{KreyoLDr~0Wc5TO8`zG;+`Mojga5CH#o8MqIuuhV91bvu9odd7movkj zVY8TtS*%ZL7Hi=ImjGHy(|BaH4qdEWwRmi`O1xOTW^sa%eC`Do?wI-Q1(#fM0m}{K zZ^Sg3xbAQY(t7X=$dqX z>iI5wyp44s>#$t2w+TN#2QvJ#5U+u5ol@CemE660TI&2n`6Vl4A)?3RaM`2{w4doQ z$xHHr?;0y*zuq9b(dmgt{MY!zduqoT@vqFCj&jM7cY=Rp@S{#zvwpo0!E`!_&X~sY zc(?08bHV$bhkXvF?xaD-gSe4|Eh(4pgw__4pVI_8orD>ZxH<)k5Q!Me61<&Hd>b2` z$=sddaq&%-S7szW&pO!Yr6s&d9l#1Laef-0w!EIgTP1iMi!0J}v*nnvBt5@T-4CwM z5?_H9o4`I=mP-k-D=av>LlpgK$7H0lslLQv%CTo<`wQx#-Z{Oa+qR}ucLnA->vV=3 zS8h|LrlK&pt5mYFM=}31D0-Tf4g$q!y@S_o9 zA@c%0b2sBLbpsO4#{7#`7}KioW%C+*xM;D|!LMG=+@VyZiJfx>Cei`3O$P;K1`o`) zZ@kM|S3EgcTxYv+)uX86p@+mD<8j}(|9<2Vk3-!d<`b62)e*!$7H&G|t)t_}(L%@N z=N#7*r$E8D-Qe?Fv}kJ8Dwr{uEzz2G!-R>i4Uc<}_}cJZPbV6$6uTnv1Ipky*J=hV z7I`=i;Vgd;2ErDx=ni zN`=SqSb5;p&Oy93Ubeufyr3nuzL}l?3Sgpe$>VZqlX*W7F}HLf-*o|@S1Dhry0fSU zG`tQpYVl8!d@1he^m@hLQpc$HoB7fjKSK1ll5inW?$sn>$pl}FFNsbyX>|Swa0G?} zKNWd2Eh+T* z3W~un2l)W4g$rlf=M8 ze?uwQN;&vlm*iqWS8Bk5Po<}(J@iOWNf6`ZQWUmP==b@`dn&*dW z`<2qJZ)>Y!N^3{4>R#n9)=(*@*Appc7`tVyJe6w>=48!dxajr7?@iu41+z>NU#fKK zNvEvx-6K@@-P85tWftx9xfn75Fm#ih|%zj3Zgm%nLFMc z&X(>_qzaHb$?wO*M*NRVF4JVTcx-ZxfQAGYB%&Qy($^8!eRjazq{mdB+tgA{z4tb^ zX6*_}`5xV8AElHMCq6yjnuyI#Vg^V>eMZW(GNrdjN-5K2Ci;p3CZbm{KhaczkLVHc zmz}bo{1EX`;dhmR&+rs%qmujxC<7?Js{~^c)*%biQik2 z@Ar_yh|_u$P2md}rp!S=X4KHPF*p|gydbt29<3cMuBzGEx#y@hwX5H53G4NBCT(O_ z|D}hQ@e>P&rm#Ng{xCncv9#nnH?@ayYO?Yi9#hTwZ*)I)uXEqdo%;y=nS}mouAbW$ zHu=1~T1)76ny|DMSORMi#JKT$+zJ`LfG&WdQCclk@<>8=6u;OIm>m9Ox3VIP(kHZd z{h4ZNYU*q1@$?J5#U7JEm!+700s%lsy*(D|DQbpXI z$%jY(L*0;YK%pBx3iF>+Ii%+XC!HHsqz3g`P3A1{YGImUF(wr$ThfHdu^|azNZbh~ z22Z<;k+!(_>CtyyObDPNt_9nZjYP)}g=OozE(yT=LqAwKBl5zY?})#~d`Lm3 zW{$;j#bAHXTrorOIzwA->%#;;#NG!!1!tw?^bA9(kLkA8E=o!_r(aBK| zsNYQ!Z&f|OAAjh9-FGj1?A}cGMcdl25S`io#TT@{FQyCTp}LOE<9`)$VXq_?^oOvd zr@eMhqCb)A&Fuc4%hz8ea%Gt!mu8uqOY;r%FU9q}^7TW!UCwjZL#}tR>#qNQ__E?? zza>UHi}$@pu1_#t(cV=wuVNX?s{r0SuDHHezJ3UD_vGtO%h#{v)g0?FjSnNZe*wGy z6-iEz{6RhRJ!87ETB?(&P?hzZ-ozxNg=xwj?N30jBc7<4k0F>p9LxFn6&Y)k&2fzR zR!WKg%gyzNd(*IfmkP~9`k)UqJ~Z%7g_6+V5i=mYUN_F^bO8uu))LSXJ7{TtCMqde zW(akU1>%kmg|lp#EHszJ+-6@MWOB1r;XhMj*HhHS`G*ego`^0O9vT2azGn0K ztw@;p7Rv1CA8aIY&w2VY!HLI&ej#}G=Ib!K!EM58c(rCL1ZS{7rA{<#nl z*4T6rG|(^zD}oASLO>atw-$MP9*bAY2nKoq^eHtsmr4`bC93(Swne)pi&k!16X_pV zeChs64)jG`6&g^gW%A1uHse=VGg2L|q0!e!UtjTp5PCXZ zTVrogifsz}NnCgZ4JqVvP>M`T{JRhUWQmYig;xYK3+A|qhy}P)ie#o(y|mmK?8ew+ zf-wy%HkJK!Dooi*n8WR|-o>bA=Sc&}6IsQ4A1C>3M23Oy0}BPLj%}68PSHFnnZZC5 zc%YOVrd6oqCAW)$Gi4YQaFygm zNRXdCFG&@TQ-GDJpR(voNCA};VgB}nOi;S+D#_X}4HsqF^lIqhh58^5NkIw|o#rgF zIRlm*m79fLM{Lc3{1hrdc>e0hHe}ZqwYNA53$405B!C2`V*7I>zPfvF$l7Nto0vow zQyDH}2R9K~Hq|9O$mDC7yYxfsNFf6)8y1A*~+JQVhZwAgEyikOO8Br8CD4StQhc zDZt;U#J}uOWNQ$lgUxFbq^u1=FJ2*~ZJ<|DAYFbb$=>MiSLAN=pXmPprL+7Eves`V zepjA5A=T6ns6VcVM*ite^E=O&u3}x3{ThxwO`WyYbjX5H~7dv9}yOKRfuwaLY-J zz#^{DefHp+QVP}ugvNL$dG=JiAPldc7tn_#qT23WsRV!$ULNZ^!kMq)saCkbPrk&B-Pvsz<%-}4KKNW>@`1}=dCh+@{ z^-O#b|F?5z?uOi%iHWJJu8Pl{N$*^?taG_CcP5sDnvQAe4tH2Gc#R6WbZcNysx@k8 zu*Z=;NL!^GvsI*ZjY0)C8jWtF3$|6hnJf;dwj2`y8bI>N62QN{cR^!m9Tox?AO0Y7 z>4Lthu^}u2MngNN3|I_oSbu}+`U~?H_07j3fXVHTcsJfhLxkQ2e1;hKkFoVx2vIYy z11c-`Wf*zX1I1|o4l^yc!+^8Ujg|63cY!AtI(GPIhP;d-hJ*%iUjY~gj86$qNwmV- zHtb!$exG-2K~uNC&>N|(Y4mEcmejj?n(8YSy1HA@hnH^MbJfwCc3eN@w&poI?S7M~ zbf~MMRva2RXJTP>O?YxOvHhk7iRw`{BD_i;G{0mk;J-Kkjj_Stiik8)c8k@oc;igq1 z$PsQ@Fu?09J@ZQ&)1T0M(^p#L6VLV32K?XSXlW9t8)3wfHaDC_s`=o{L26YHgG;EBGH`vI4w@A`|_YSq^PF>Wh9$r!{+W|JC>A z(W7r>6t7wNg4l#E+A_JS&Q8}O`VhZc8<)d54^<#+EcmkR9Bh16Oaa_SO;J6A&yhw{x zk${5;qELYM-MD&B*OJb?t8Tn(`R1-A-CL$mrugp1_zPuz`5OL`bV2kZ9;*F!hUfdR zz3s)aTtoH*;?v{nbW8cU%?bIrP_f+O^_6Pn7dx`$ndclrw=3#ahTalL5cv8^*&flJe?F_vGaQ;x`WaWuA@wil4IS!+7vlpey1Xl9|BoSAf5M z{^rqmrie|9*E5*cv#?*mq}Z=Q)(|5UKz)yGx~@GM?L4p=xy8SH{yA@a<&_veX9z!E zX7cGF@?QOTO`ag{wK!a0Ab$Bc^jB~$^p}?DJRx)%YZ<;fHbs#09LSE?|Co zX{L(bHMUh{8L!-V&bABwS-31H9z;7Y4t>QN@jot**Xn0@tQ5jOR&+r{CZk47hnLh$ zKVx1nVDh4)e~d=)fA7A_8()8Y=2PkHHR3&+hNVRuCaqbCNh8a}mTom?kYysDxUzg> z^=`cAhTZk+d$(LvzrOFvE3P=myKmSxyr+}=)%WsCFTW(y|1qYY;?U%SLXc@EJB=io zVqFbg|5_AX8$~aO&A@wj*VxXpg8smd%5v~oqEGCVYo`4~dcIs^Jt%{e70-tn>p#3N z`Ve{=o{wILNPfe&@aNOvtfaU#{1&?*^ertH23u2WNM^PKTdT?4a*m<4#h;P;$jYm) zni8TLQhN0H!E*fWYGHp9Uo?I;$OHa4Di6XGx7LE^^cnvVR%i;iYHmq*ai)z|@fGDc z*($ZlpyfHW&<9yzJ$fAva29AXq=Om_%@KoEFMw*noKuB`pdS@h7gm*(xC`8VrX>|% z9aFAoUue>rH2VOYx(c&`;r;(kP@6*%gO@3;x>} zxU`6I=0Wm&N-Y}#C}zAs?-QDp7`WisFmU(}djF<~@n+10ql^jk3?q1UV=@d}@IS!7 zK?|hyJC{5b?P{CX(ABvBt&T1ppWu!6i*MI7hH77xF${KcrXNP;UzJA(D_iJKiv1j4mN%*VuipMWe4pn=fwYn%9j6?j9aR zS`oA5`RAV(|95#+|t__Y$N*s&XE`J&o0OlmN0KTVBRnnRkLt!&9P>6RCmQ< z)@1fkY?&`k`)4(appXwXLfb>RrQPG3_cW~Qn(8Ra4d%>?sQ&N={r*;~qq*_gOBU_z zXlQVlM+UndWHpd5T@PTo;xKPg?~Npwx8`J+H?vQPd6QH;yw(+%x4QGr-@3B1EIU-t z*sXr`RZUB?w>hW8I}+sG*Y3acy2d8Eb!5D2WYA)(&(5NH7d-#}5mK=YLThb*oBKP# zzP*nLuOzm~31*uNkn3NbF5`Yd?mxxue_!&gp)dFk@JwD~dhkj9H9Ti4UdMA|(t>Bg zqy=M`wC1@nX}Pu>w{uQR8daWRZUh2KYg!Wup3}YjT-~y0bSmY%XnXVgdHcdGyu0I~ zk-)|64)WEtUaKDRb(%CnFjBW@Qj z^gt3)H%)fSRwIR{oZ~bT02OGK%dWWbZ=j-;K&q3(|CT1Y<#QerW~8Mu=1-*1HH9-V z7zl=lcMC7LyN7(8E$+e+TWN7|I4j!UAHDU~mSwzqG$P*9yCjs=ZuYi@&`5nnRhf7t zzpSgp(9?C(VpuP2czuArz-#u?SRS6_hx|8)A8!5QsVP`fqUE|g`2CX(i_K(TiPCGmOpLw<&*F?DT=_Pnqp(b%Qilr$hNh+ zwPbJXUOrpEU2^Vwyzx&PFH*`l($f)rNpz68aB#snad3XgW5IB6i>v!9+oR8Ie0FN0 zrR8P(MQk?HlTXsKhxkU$h=B{91p_Ay7?Lehih;{1>n{l}?b;NLUOu+@`;%jhjW55< z#-G6yn4frplYGYe$oY3>>|1ay?3?VOk+E-He&4cHJxjW$r>+{h5Z$$V$@kX1@)!Jt z${(q&e&jYz(#!Z)cq75RVJ(H>-V~5GPC~o|V~97r;+1H()Hnhp2E@pCWum8gNmWmD z!P;o_xee%&4V^bl{`hV3#T(yZ#E`SM7#$Z(_#B`G3&{wE(%M+`vI^R-LnOER8 zW@K1&ScPgwdz)*_EgEYkwbNi6AEYx|59ucom}PDy`ItQf?lI&#Vbft8JDmy*2Uue(*}#d<76wPYSS_+dWw$ zyD`y^rUnOMpaY+8{XkNGWexRbE*?p#>XG0FIgOd>d5Nw|*{vzraeO*{2WP=q1<#DL zin-e`ztbZ|AM?1~ei`O7b-A7VjpWDSIXvE3F;>AjF;?^~+hiRc56W|EcG@a^(WtM| zzIMe$pYPrcWA51T%I8ww1vS=VtTgu%X^He!^{DZo$Us(Fe4Ca?QKdi8k{~}7iU=81 z4W7lp!RR-?33J8stm|51*xL2Kubkv0d{qtc3C)eK3MR!@NrTa0YG9ZfKA~e^Gx8Po ze0X>BiLF0J{%r8f*s2&4P5k_bahQ1e@C&29KIWUiW3-YpHVH;4ct(s8^~Le6_{rdn z!w;tZIO@+mT`KtSb3I&FxIHIcKFtDZ1(ODEJzQQqP%F8FB4mJ!;(wDUqkycWGKvuj zVv6`XFXsz*=zLU1ttlQk0ZWB7+f)jr!V2+hC{?pEQ>Yk|=`WX{RCY%dps5N96~UfZ zjoLs!YK5dxK&cAa8`In=IgMr%bY*!r?5;njyK>N1mKDqkcXx;N^+SDKL%**oEXvEy z%fD@1o;fewS7t*k9__XJ7VYhF=QLU^YgVmZF%q6X4(;JA-Ie*Jm4(!XH41xZZ&8w)?S9MER z(Yz*S#-XjTNvxW(*ckSR_-vD7sDfVuLuFiu7w1Fh=@k6JFNgIRi70%zI?fTcYCz9X zbKT%64Pvdz%IoZSfooak4DZrsRvtbyW&C~0J3J?jqWj}~!I-X8(!m)zqjam;mc*1U zWtb>42pQ^h2dScsfv)OD)-GK;az8x0r|TCfuXdrIlgG1pe?|8FT$roinJ`y{^ne6e zjlPN)D=*o<_J?N5V;Z)#np4_FN16MT+X zAV(`Bg$E};DX> zsza5PW#S9`TL$s=!ZId%oAG!KQrAC)bgakYsd`}UctuT1uRJD&G2{Kf_m~upADDor znj^-+*y!EEAerL_AB~)ZdK*}e?gYJ+E9RQR4HQ4c0^6WPCL*X3LfiQz`PdB9G4N0< zxSaqOii>pP@f4BnwHInoXSdDNU@+9B8FoZx1-&obF)x^1mFc$UngSd5v*>U< z&<@zCU15{o2iPf0yUVN>D0T|G7ljfa3Y+i=(5dEl=#($Xo$<)2WUAP%^uRP>?AVrA8}Bv8|)Jj z`zP_{7YJsmh#8dY8aCPqyM3vM?&!mJ#Q4|JWJ6da-PUpBIoUi z_^4G%e3U}SVsYc010SUftSvT1MiOFcN8h{^ME%cy45I!m77xes{5j!sC|qk!(Fq!Y zk9&gZ)5r%?w2gIK_32 zT?ha4PZc>eYL;t*?_a@5Icn$&k`qKaC0h_Ln3MMvZ=Ma4%C=`YGtUH*k{gQ?f9_@5 zLu)!$pUI4qc7>E?7POGQ6B{Xpv}@KTsr zECJ!7RAfxMaF0R!#IQFm5#i1|#Z3=9z{S%_{7XRV+pG`NN%R1j!#nKyEwT7L;l(SA z7q=?n`kZ|I7}On>uZQL9_o3G*rVMl;a{p`W{%7S_Ead4W#YY9tf{*$UsKCT~Bp!r7 zZ@-)y!|x+wy}{mpC99=aN_W1k&X@E5&(D7Lf9A7#(s&Ji31>UHlE|Qz)1L`t_~%@%3@mL6QuAK?*79|{ zpc49QR-W&H2&EbjE|Av`W?h8n(n{n~Szc*@wZQN7=@du|h4Bj6AaTGY+1?Y%T2?nT zjafq*m#wQ=);csVT3HtAQcsGxO)giHe_ne_BdQ0mMtyL@4SR<6cDEsG%FNF~b_df|+6o)Ns; z;qDFFwl%oRa{_hhNlfY$`&&8}ca>LHmURs;SYNcHICpGqeV2@1`cdo*JrjN@-d0M$ zFC`%k{U~BA+P5J_(Mo)Ny&NOsI;tOiCfJEj1?xv9yv{NZadRgin1W|TFe#Lz80^Q6 zUu4ZtRlL4LUnYHnB@08yqtu;l3Dr$(sP1Ai>NBAb)0Pdk45t+!F+UEK6r6=hngfy) zQ)Xhc6;j%WUXwslC)IHf%kDTToiGGSjCXM5l;&n{p_}9@;r8UcK$w+~~h=ziZz~SbO zyR4Efv*@M^Z!rGi_3^pA?|An!Q#p zfi=-?R5mTN)&k)N&?X-wziDXp+kHp%>nE1fL>FkYhsz($II{Yo3HrrTme_f{gO^4-Hh--DqG%e zA)n{aVr1;MH4%M)F_91GHjK*BM&?9omKI7GJ}_Xh)O5mhQgY6hbv+q zQJBaE!yF$N9}j0h-)ghpQ$WJOBov(B2Y|E$3Ve+jzZz{I5C0s3^8<52d_)&%@rLt@ z7Oh-$Vanur=j^WxY#9A(e(^cmCR*p!hgJWW`D|;Ky8Nn&sxLAZ_kmMj@5VoWYVEA- z7*4%@w|l|F*!Y@oaS@BdVLJ|TcP3>W_eqjZ_(M6zbcVzx&W6njCc|dQL68_W3(e5n z1|nLi)oyPsmRRQ%V#WF>d&`#E1CCM)S=6d@p($}5Re zA%{WI88EXKlP=|e7)ed_Ik8y5*;uSIR90tLEGe&pCL^A|ce|9<(b;urxCIR@8eTMp zuI_4X?rIjlEDJ6F3Cm%kdCFGK$L$Yi=B4v0wa014rm!B`^J)YLT|sLz*zi6DG>h9I z<1!&jPoqIm%-1H!!6}NrjT~tVy44(a>v-6RWuDLG#s69JNtJM)hJv^h@-Bwtk|mzC zysURYU3Ru4^j0tXm2q-GkCzF(CwF^yF40MH@7nz@sct&2;@mj72Y%+Ii}&yPwVrdROS z$p;9G>Aw3o+0Rz}AN$#8bVccBtHu`QS>0?LI{nD$l9-=uj(%#vSUN?R#`PIuvF}49-y_-cgL6DTCg=D|ju5GK3cVzTs1TEC36i?lM$j1{ zATUe|#M6THIsk8-CGVSRu%wXEN$At^0(#Bx0PEGVd}wIqBi8(c*897L_#$VI75q2G zBKh#wKtB9K=y1wTk`s?!>gp0NrCITi_jwZY>nl=&$1C~YglwWKZ zjjznqfzE(W_E3EO|L!5=m(~z{^ zom1|2=aT!~LF;rc^D05VySxAL^Pis-A4U=M;r-p;?^g2pal+?CgwNvn%Ii5?zEDW6 ze-)8^Ie4$to&hK6q#1awc$}mrvEQAHlWcnOoMSzsJ>Nd(NB2%2=^5?)#tKv_{tjux zugG^P(!YzpD8}d%`Yzvsb-nrF)&itb`x#aeV9&g2Hc&EKR;_X*B@w#am1#BcK*_kU z{cNbDc~N<5Xx>1>bjz+tFt@ENG(X(dm{w8SR9R8f=B+M^*7Gfe9VIo*X`1eNwF^rJ zYTd5d%E~}rS)soy(-ri2<+aPFk#&?4c4LcD0!%uI9qD3#Ne%6NN6~{Of*$14qFT*g z&&7Yew+*S9mNtsze62XsJ{Cf+uv$)Of)~HTaT32O;r7clp3=y>CD-*LcbDA%ZX3QI z@RCp|*nZajcTNI>bg}+-NidL_q!`HfS(v_x$3QkhC`O(ae}@7Cc^?*r3G)=~G7n3L zj7z{lI*Cc*l5vn4MGriJgY5jvhMzS=qfI}WmevhnJ(edkzd-N(_r^^vmfrNz!Br?#?t!<5 z$jv>m_eOpmVYSpw@wIr}^TM?<4|MqVaXsmj^OqJ8k*&Ng`au+Z2fZt1!lsvcijwC) zB|RU#MV@b#d(u5ke*at6lkOBcfq$N}C!Le_q|?mmNmrLyKhT`k++_7UwfyKclgAp{ zy}C9-Nfo+9ycMmYaTEM(vUblQv7?eUsVCh#{Gq+cB&gPqG@Ntf z_H?VDJsrns#^C?7`j3WNfGvF+{z!@Z5rWV<<0k+KA*i;0oqMr)Z%%B0r#X8AJpR!e zE?au#k?RlOzh+)pHnk#(wnvvu-MvQ@4r}(Fci|pYQxpFGmMi%Wsh9O4vVV z4EyKe6sK7n_V10E151B6`Xr_ZACm9GH|u{_N%m_T_Rp!r{<#wMGEEZfUuDENbA&vf zQp<)QB8c(AKxpoYJgkR4@A8Vo+fYUTy1>!qkgcZR{xUW6i%V% z$a(S-%b}y^%h%|Omo3Mwa^${vnmPL70eFTcRKArxUf;JP+`hf5uD_tFZeH6G%^Pp1 z#yb2Bd7*57$AM)N`#Z97>WdeT_bi{vbkI2NDfBR=>Ff5yOH?K0o_LyBJ@Ml4fx+E- zw$u;hm1orz9n`#aLeAO7&ZZ9!wbgV(E<`%XArLI`?UuRQx4 zz4Dx~UU`buoBT#tl2Wt0oY{@_oHCFwd)B>p^`?7rS$2pyA8coT9JW^3SWlLM{4-bz zZn#pnI2s+*b!`YI6NOjpo#AUg7}(knCk>^ZdMcvR%!MU%QV5bO0ZXWvjU|lM3|2;> zFK+$W)QZ-&ckmand&++LQ&wjU&eAht37rf}=t_nq)FfgFWBv5zlYxi!M59NS#YTtm zp=hp5gPQbLt34~0Fy_gKVF@+Kv4kG}`c=E;O|bE68Ohn{oA%BrO`%U7)5AC10!3Hsip?c%BP&;5dY z@wH$5xTWRCPXM?Qdgl$IZwi&9cOJXP20z68`1tmCUP4ZdvVk5t_uxEem-kUaPbAzNZdvfaDYX1y!^Fy|1(k)C%$zKN z-?puM(V~CV*B6vl8FaPP!K&6rdb%E6GBB_>O{YswOLv&-r9OFZ-tpRc7DJ(SGE{QN zN}em19m|!=k!y=*Io!@nWo>cI+_lANY4J;Uw6^Z(@81y)@96Iw(V`aZaMz7G@p;wa zF21D$GyFhj$7PdCFYD?ZpPU>Qdw;Te8S9bf=Ucf9=#i(x`mA2+k!O$Vkw@HlE~!VJ zGonzA$o26jEM6b6@h$NnO~I>KdEG`+LxtDpHkwT~?e%N$(l0=}nrh5pjoBgA$+hnN z!fI@DU&;F89pwD9Kb}9VA5A4mJcjP|nrR1E*2Hd6_@fzzK{qY#?kRdoFmPw6ZF@yY)LK7D} zRl+s{=-x>=CPI!jaB<_4ZR7H>k638r3w*F){kHG1ASe0%g%nKR*T8JX1ZFbKre=0u zJjo?0IE0jl(U;&Az4s7=2ol_);+H2lxhEd@MwnJVy`-(5RgRo+#XRb_PM zcpUDM%9QE($-Srz)Xy57)K#h~^Q&spQff0SHk)l+-#*KuD*IcRJw6Y=le1trog~2I zO2lw#;(Fy#{`2!N|CzV&l?NH$!Cffx8_qE!9`md?PA9=}y5e!1n)qIMQXo^{jprQ9 zsLo%yG`~7y-}0M~=I~({_q{8xd{6vexlW;7G47nb@??!O$++>o@?cy$_(q$XqeDY5 zW3s~T@5Eor@Qh_F=LqqwREH}J*j6$^?T6WT&X^n0Orv-jMZdg&mX0<8qh0-xS|00z z9@RTA5`CAGWSlv2{grQVwi`!bx0?9Lh;jJSX!KJOTN6aA`uz2;N*@mOXC=XPD#u84 zXvw(Fr4i#IaIC_^iEmZ3v)a4^__?`|%aV)1L=snZiI5+A)3Yx0%(YiGBt2kw}=p|_*1sK%y<`E5?GhpLH( zZ4LQI7ecX|c_@}M|MP3&nNdwV6wE2qFH#LOZB0DzY^@;RK=(Uw}J-kO5d|VLA$>FM8d`yYuR3byuO41-c;oVo!{3@Ya_Pip(Gw@4pd#_#K*{n)a0;K_ z#bPt{I5yLe8k;HP#Afo4(ukE8Tz2#tb@%@n4M&BVpE{d_iQ}r6u3IR_*S2cns ziK;n(Zl{E_L4&cl=m?!!X;aZVNC#%7#${rYd`VFVzyTB#go18tl($KT`_LH5e1d!L z5!*lx&4&b7mx1dIX)<5Bpr#$y+Jn-8DeX#h50Gl>@loOsW#<{=+ISe6LD9?sY+r)& zMSNDeSUo!~0Yx>W;5)hN&3!43$Q*#n&AfTpa=6;;n^z8=P1z5iY`+7ZYa3j3RL@gI z@`WORxE=BcO;gU!%z9&5pq65{d+lBnk?F8wUO`7DE)|eT*KgawOYG-&#`>d$eLFVp z5s6UIwlFH%CfT>@teqoddt+0(5J?M3>@vC%1d{5m}TQX+(M z_~Tl3X#9G)7{_CNeq}ndsJ*PLEL0Z45td%NTq-ni=5eM0mJ6m;7K!Q^|bm!YJDZYq(Lrh3+Ngqo|vqXx?Q{p@mNGbfhK+3yfEE6oRS~oV< zdhPhlprXI~r!))vWkugDIsNi424rV>I=G-kNN%a z5=0uW`~5A5JU{y*M4kn7y*ct1j4fOt6)hS|IgeC9tyx8rDk_!|g;Hucv6R1nlde-{ zo;S1)NEAb5=bm%c&U`rizh6C?7y(}|=sNdrP!e1XZcJ#BK3eF0oAS|;=En#Q+`_;m zpM;Y>Uq|t|k#PKQ9E^XCG=CXWf9^wwN3~E7Frqst1t59y^s$xZ&FV6+x=V05)F>vDo+Y04Rkzjou$ZjGD$9=A*`V4a6D+s%k*o@dcYNhMNfv55F z>#64}SU!#Y?$X9Xazsfc9#Y7ShkU%VEvFk>W)f5A^1CBhFYaReuC3Td<`d!sTQ3gT zgN#VuNybAa;~*hLl&frpGCiHe0h zh3z!(bSxeVNz+?~5HKr~41^S>4TNMx)MOweS5jri!xdNo>%*~R93<-u#>PPk={QJb zN*v@%Yv3Dio!xXfdgql}XaD|pkP&_T=Rbcv%I0>wBk3=|tqqsnUx2L*C*;TVsk}{)rQm4wc*A9 zb(3PTSlkwuLuHq{98N5r(N1}s(r^J>ZxjcZ@tMMKQslcsu{ zo@+l)*^Npk(zlsd!a#~##cVhEr^>NFY%Ep4!aGfEaYr1Cr-)i3z0KW4l?*NXkY~a4 zX@WAdr>z^OPu7jIELt~?xzwXWBRR&>Ebi>Y<+Y?{M zqoDXVc!sQpW2k0oXJKDRJ*w555|>FEvY4PqJ;@2m6fPQ+sRaMU($0A#$+ln?Ixc`^z(tU*K^+e4@A8Y$v*iU=f#M6Cu>9bN+eG!QEfOO4x(fWL*deJjQ>x?@z8MV*lkmrW|rS` zU*gTC%2@29f@ewpX#YKlza(A<@@+x?%dGDKc{i4E&!{e(o>LdjuvlF7^nn$s19V=cBxpL^AK+1VmD4ndo9P^E9fIn&a>L4Qn$4B+Z25= zX_G17^}_KxP(BJ9Wp7?8?vS1Zb<3W#IYR}53Oawym={Kkfd)V%Ia}mBvU0Pg;3SNwcpzA&44@u2M`MR zYZk2l#|YKfN9l8_#WBwgM{;B`nNenNqJnXh`;{<##W*~hzm*kML!83#@Zn92? zHP>P`8S&*M4kgSKE)q%@#DOg+mQagA34LS<9o%B}$QtTK40=9K1MIJeFW$cWI$5EM z3UV7YhUSGW`N^IF*m#z=GzWr0YxDno?s4k*&$q zmU9NCCNOtmEGNbdpoi- zVc*1ah!=3|+7Z^jC_WDM)?(a zAYy(c@u`31%R7EI-L`(i-FKq`)t`Vhi5pn`)Q8{a=EOL_&wM}o{(AVC2mi{An4p9Y zP^~G@j7v5lXY(k5W6~tr0-H_g@LW2BOeKYI=KlQs^knT^AW zvT;}vxR6w3RU3}O`WY&u3M`5J;B0c{wf48$VP`0J672V7Tqm`L<%v!BJ@e{SHRF0! zQIOIc+@b`gbBhxd(k3M?NJMWMu`)=7fdrN=sEn7B! zb)fUYD=t3-G(ekpu9ccA@g&|GWkg2p3AG(EQlcsF!MQy-J`UTNeeS^fd>LLR2Csy4 z-71t52Q3nk0#O$VYDaOMU>_NpKJi_MLFDA=<8*&0_U1X<-!ZoT82)@KUNfj&ffw-D zMD(7+lOv$2IpC1L<~GI$W!|0#Y&`g*gg@Y9Vip{$NxTdk&52QPJ2|>6alt@h#}K}U zP3}obEwKeV!Py1jlDm**2Nqd=dcJk|oWxSxp@HMFb;~#<1Z$X@agmtw? z+$&jy^~OuCI(KmV!R|p+-xL)#-LmO4#LMd=eYmzMeUJ7$d}k)Ii%3u?3xOy-3PdB3 z281ajelJ#dqGY>Du9Wd1bpST4S_IEkK*@v4{Cwi6pZo-b6T`2(0`4HE-l_d_XD1K< zStlLS^eNugkJ&gz8;&D2M+`z9ikktg=wgyVK7~S#Fb5Gq>ejPy&E6@kDoDKX&X6{Ok1Y zZCkc&0r$>s+w#&C{H7++Rp;%!j314PuG}%bh7XR4rYC+fGqYkfKe39SYle|pOjoG< zWe)87cpsrbdYl4E+0=Fj_B?bg4+^fqRuYB)GNcdZbSR5k&*;xLAF5b zU*CbEmP&#lVDz3!aiYzrsG&6V(m$MI$I1Q~_ zZjkHU9wnL`=X_C~X(XhQv@(1C1+x>g`yr-4ayj!TqLz<;SN_BgA2JN;Y#IFPxLs^FrpNM*uMoZx^aFmv5D}vM0(Hqa+ zlYP#%ZMJB2e{Wmgjp|~D#%j~#UA}YVs^Q+fo1-JuI(t`Du*=Ep=ihLS17D;RTOFwC zx=76+P-q8j-skKGzP)qV(BW08nJnbkZAkRw)s7OKUgfbI83&hTljE;QGovC=;-}<& zy_Am`fEYkX2zw+K(ldBWsjxyyPNSK#LN3Q77&2Cy2MJ8zSe86W}HS)({P!i&hLa9KTW6FXFkaH`c6gAJ}4}cFSr{URnpDlcDO}q<)8xo(sg2d3y!*t2>Ixq|B z6F*G6#PXPZ5TBJqOC$>phLC6QpcaljepM+RzgTdLG9JIpZAomW;KL_WaCm6Bm5>>Q zxKU6%x#M-nm^PUj1G(ior`fKvDz8{caj17{0%~PYWA-Fo!ft$2jTW9B(-$PqqTA;i zSUR!~(Gek_>Bt+j?S_(1NWm-YnRQ`4`g{63d_Y#gb_2?5hcwC@X^xENguqFh|`SnWbF{Y=w>XAo}~AioFqE(7z17cEI% zLcuc^!2du#2;o_1D+DhRcd_s{F+7`w-^;>Z#_${({`Glq85chH7YKied<4SfH2hW$ z9F0f8h2#1_gDmdBadLPq1y`lOv22fUQt%?i$wP>@vG5fv{7O0xv2d;d>jE@fDg}S0 zd2j<~-RyXMU@Hpip4XnaXnS%U9n?DFC$47Olk4fA))Tkiz_usX)j_QvZoh0^yDVM% z++SdOa-AL2dgAtrIPJ`OFKEZ>+swh6-%b6m;Xmcz z&2Ndf=fPzua49QWDHq6Au_PX(!0+UY|K;iV@XYyeUVtn#HJVx_H zt@}85dM5{u)3kHe#X*e^J;BRn+p9QujMoRZE7|r^4j$w6!0nQG?Xq<32v0fdw&4AA zdlHWqj1N*q4+jrkP3|`h&s+fi4hIijP2vG~n1cteCh-8=!@+}BlXyVGWn4JgZ`gkl z4_-~;0fZ;<;MF7^&^m%LRYzdqDlUBPQwYz;^zT)g{>9jSjF|qtO4GkeR@ZnD@eq1_ z-WW;hAg^IKwLWi5vvA%f45!xT4Q72Hd>e*m)9{a2_&A2=(C|OZgUeFjQuyB2IrF`L zflj1apc7rh*~d3I=lr`YoF{mTxQ;!aEu4LP3wT-ha?XCe1;Xt49OCTDTOh=q&xeyT z5!9q^n5UzuQgk#{=Mua{@5_%l@D(ilO7JkJpX9!r8cEKJyDz6W^ozSMr#SSByDz6W z^ozSMr!u-r7gL}>cO%>@cPR)gL{>UoQ4`#IJ?GQ zUiZsChHO;L3sMT#!bTLMNGYgw0IxQahm<}>sf$r240`f*yS><6E^SW!&^IV zZZp;wx$8YfW2IW*$<~#~vfW`!#Qsm6e569T2^R_YGJFX>K)mVo$@5ua_G!Ay2elUX!RTP&NB`yXt zflg1RJ5*Rk*A@{#T+P7Qf7ANd#*#j^o#+-mGn2~wtJP#GGUYkh@Vio{M55-n5GVa> zgR}?n<=fBMJiC3z=EizH$mT~HiYm;!#0T&X^3;#MbK;pFJ$(PuZM!eKZ1?G#gFB|L z*^Sp{WbOmvkGQ6XB9a3a1Z5i|;zYX+z?X$o7^?zu-wBn$94;HX)NRjfmetjPOA$S4 zgY(LQYbzntgdw6;t8y|VVj&Ti0o+RzP6YL$pbL|ELIM#>B9-?j(At5X$F5L1G-hY1 z?ZhkKlhO9X-PF=~e|5K3FK*)7J->$NgKZ4pWAa_*O(YS|&dL;v1k8AIsW%~v(u#^n z56`3Y!T&?H@K`~9h1O^a7q818|CqRRcqQ17xSgVx*pJl! z*H;yhOT;{Y(*~k-RpHqxA@Ot|qIp~E<)aU5sq8Kt0{113f#;N`KmPseK^vM&IXthA zLEQ79I}>C#LUg7On~f}Hl8hlD1ITgKgcQTZ86Qz@OJg`n+E`Q1Z83?iR2X|wyw6!| z4%h3hu6*B4V?K!ovl*HaLPoXWI;h56u%Sj zJ2>TdF1ql-!zpEWo_YG2r)i(S56A$CyyJ1L3xX%Z-o&i}cxDASYXo*Si6@DNhS0d= zay@;QLmwbSJ!qqrO%478Pg70li7~5HFEbRl!S}#ZiJ!P_naw%yXf=XF4S13-ic5rT zl>gZX#78vmY>1K7kqX2i#JJ*yR6=5xJZ2RH9DbJrWv?7#jzO)2-^)r_29F$bd z^1DmR6nO=M13Nd6Mx!OHR!uGs)Oa;YyUzuweys*leZ59z+pv1~rA#d>vXoR4GQxy# z1hG)c{*6U~c#23Mm&;9Zqs#9>hz>j&4wm@JwIsR|go8!sLYD5%^J8S$zi<782l8?S zZT-#*!4De*k`gb6a~N&TPCkSpq(y9!TV*216Hc zRJ!sIuSp^c^6a58MUOG1+2f!PWdb6~(})IBh{7TXrsLp4TvNap(Ji1*Du>dEC{)r} zl~dIOeAu`)+_7q`q%hcHSPm}OKeD58tPfJ5n?u1B>-QbT>sk+S@D{k&I_%|?=~R%Y z+$d%kltir{kid)>X&gHRbRr1=T_?qHNhWkix|xRI?|SppO1VISLx9yH`c9UTm$g_L zl?y4vK-eNDZ`pt0(Ef9+rZJ)y4 z=qA=A-g~ZaS-fM=73xg9jpfcF@GPXGIZ*DD04R3~L_EkJ+}PlZBvA0|@iqf!GQxoTgiEwfIcH}7hY$k2D}#Gd`>2nTNW;K4Ba=-Q-=gv zqgE(oczyyjy_CCLxa1l&`K`n!Ly580p`jtT=mw!2&LiU)(42T88WVvR62;<)l@}bo zbU%7$J;Z5LGtZ51$!rqyc-W^0y$+-E7`?12w@dAGBCiNG`4)rEAyyX&1VR-3b9;Q` z9riW76>&*cthQ^~W*W5`%gghNhWb~Vtz+Psi+XpTUtLvGv1@PNMNI<-;-drQ&EL*^ z^0J8V7zI4Tt@#SJ~h*?77y0SbdtC1ABz=*4s8&J1SiWJd#h1FDE zVer1nkXv0YBHN>NY zx6=1LwpOOuP z7t$@S3eqhA*F;1`AkSl<9$E$q)sg}5Q+HKRlGWIttqcT1R>(ukODu&Ze@n?oU#ZKf zBCCT{hHSu>$C~m(`C6^D)K!64X`$VqS7d4eLk+{T+Dvhd)q?p-KCZ*3LVhelB#O6Y zWr}!oMJq6lwvj?f?BA?{+{|T1JE%}|?!vLW0j0+i8y&@3t;%DW8S9QcnR!2WqUC@z zvr!~UT$)9;w0F1Bv2GuLN67b}lqY;3hmYnhqBvqGB=CfSSf>?M12J>b9@#xhIwe7A* z#-+z+#}Y4q{TYEk!a|y(t@VsQLjgQ{M#6Zog3hECo=LTybrXg9ukepk_>iJMR=YB0X@AjCMMa_evGPQZ1#ECr z#}>J+7~67$tns};pKSPQKA zZl@+!V?nttT`mdZsK!ZFf(9M*xrHJ+a~UmyibO&vfj-n3Toc>5zU{nNcXau%S=l=# zbxjWEnlw$mSbn98tZW4jp0lEML&Jmj?tN%^OIgD@qxk(jM`ZZ}5sUfsb%U{t_Iz@AXK8oI<@>IGhWHUB--ZWin2I@p<9`I#cqu~^R0jxt zex5diFGRWrl)4CP2Z~c=b+D`rNAGdM)8}x@#CY7SJj>W4LoA;Vx;+9aj{zkQU=m9{ zGGlX>beEMiOAMP@$K5s|<|K_#lDErhOZ>)W8FCg3<=MOe@RWZ`Q~MfUb=BEtZEK$O zVGi@bh8j@4vHs@r<|{I9uC0s>vVIFT%m;)I$dJvC!&w%fGK;xM6lQTXE$SlO$cyQ+ ziO3`RBRN*cX|y;#8x>@WQB}w^tkB=hdVEBYsaHvb$B!r5dB~~BY&Peay@jqKM926V zY)?RPxt~U1Y&1m_n51+k%2WytHe?Qn)P-duJsa1p-&VS!ez;6iS>02qtZ~*h)mCrv z+O0V`8RG2jWq>?*_|RF=U9HWXd3hQM8CtV`nbW;`gku{-Jj=M0uSfShUk@W;a4qKR z!EyFj-IG^nt8m5pdRyEL690up&Gm}B{Xbs^Y z;*n+pK$%MfLOMe$4+&BzL>r}i#HXh_ncKEg(2ni;4z1l{LUw(JTq##bp#ZP(V5f2s zO3TB+fRwF&qvZJUv97L->oy`Kx(Dgbbx?`UY}g)c%IJ!Mu7iiMCJkQ2+A~t4lk%sX zl|OaFD?~cDfxah8g_Ba_79uU&G(@EB$4p$3_Ib+=?(;J&Ja;V@zKVrgySQ*0)4$|4 z@SU{qo#2}sxRC9~ozjn*eg1s#bP|s08Po84z#}xg0pIU1^OAz!CE@IQ9a1N8;S%k3 zscSde%4xT=-^cs0;QPsTyf2Hk+wuM^-oG91(^Bup`?W;>Xx|ooe}-*G`?s)t72A&X zabdfVeZK_!dfxkyUSwzWA|3HuTDXBYlm-s*b(}~GH$~IK%{$Y>EvvY28}nX>e_u@t z-wAHu=x=sbf721~riB}bZ>EJC>3T1za5(;TMB3-g#PPIn3vn?AKEw8tyNlb;Di&^? z;KFT8KXAT3N(*><->!(;-mu=k#64i?jdee83sa2PiId zZ~t2Q3GrgP9akP~n1#S8FIpis?zY(5)~JjhvLA zTvfa&SQ`_I<6<~V$AahZ6Yya%%BYK<8je^z9;1;U!quK~Pgzlc(QS0u za*^Y+%jL{OW(c>(&B>OlwUCTR{Q1lBK&~=Jogvd@RVYIawMEHO%EURk>fOO@(VpnE*@*QMCbEdnlGJ73pWsVriB}ceQDs3F03Ka zK5r&&P7Ajnd5MMF7&tuVPo;(Lq~$SuKZX0*MUVf}v~UCQAjf`dXYIW@;;(7p2IBTK za7YJt6KUb586s^zX5z-Qa0_ve1D|30$=%NFXB7*#j&b2O)-HV;_(59uPVik0T*&t0 zPU%O@K7T&=RT7Tr;2xR|B11W!ex9KlrNov<28V7?rz@8t84{itlMIxSERNJ1#%;tH zG2=GmastoRg7)Ev0TGhYl7c+9%Wmb66Y1xW6Ghs)rC1tLxq*A%l%8NFZdq^(_5aWL z-<5{4rp!M*eO+Sy42_Ku$0M0s8cQueX_9Paa>;A9C<~L<3?PxjQ9*U_D5RmCh|(4> z_zHd)eoq1^?Sd~1N1PPVjYS(GHQ~xo8q%AC>=0j=^rm0J_A@8L>rz(sjEHfXl}_Fn z+1WcI9q396HvmamxRLe^oewwBzMk{pX5w^OxP|x&2R_5XbBW(@;Hy};m3W*3w=rtmYq$_;9WV?%aCr!JZZO7}oL_1#RCEAUQ z59uQ9Ce}wZeLG(NCED>mENGu$+wp!ZXkW#)<9%7sE@ay!IL0v9ZkcN!-kbY1)*f;Q zB267)9$N=E6K5t0M=CRMwg=j~Y)Z&j>r<|h(|zseuXdh+(dydp@KbEX3 zjK)gU6~<%#41S)U7edeGg)k6ItztSa1o$i=ePZhqAp0=sPpHAIY`pEiqdqT+4Y(8M zN>VMX4VscCbJ3g*X4d1vl0K({aM5f60l!0wayoExWVZM9w|(U+GtWFTFFWS?*{$nd z{>_K=>GJ7-ClbxTpc2c^=%Q~Dks8{6>q<~LqmP5S4E z#B-n+W!a)@AOP4`YR-pb;zR|tTXfC`Fmc@tD<0hn{*utr^-mYCx4M_j`S2Ay)ZZ^CtVd~6={oA7yu zZ>RD%h;ei>%0%;yBTjD?a zua*ThX&24PjF4CZEI7}V}D*r+X>ER?{ zK+C13k}xo7mng@b0NHZRrsaPeX>1*gHT9Z~b0fU*7fWeTOfI)ah2^jWotM%2be5^Xq+t$_>s(Ng+G7vedjjV0l zy=-8OwKc9@w{p#@)oZ3_)bUo+`hosE&0nC_;o>zAxp=^QM$ciqfX@YpCE+P&5q+lD zh!j;W+*L+41# zS|sm6nmS9ko`9OoyAbdNz9*k6EnX6 zChZd=T+%0|?_k6B&gzl8B71#7$LLM@P42>?<&|XQ`b$?FY;xpQYIW;pf1^}anoU&x z2P*HSk?^2nft;ms9w*QOJyn$?|W4y_h^Ex7|wLI#Ri<7r%AX zaAbV2y}P)?QSI&+8|^5l@)mo>!kydeo6c#qS#otci$zD)8ZDI?#hNX%>okU{Tu0-< z6{825{@bF{SS%WCF1{OQ*3pH=k5>{1NGV`Sk0i&ROwP?&Rf7Ryh|A!#TIkgkFS)uY zqffumLT2n~R{R}yINyb5nlzqtqcAxxW40}6LM?ey3fc$D=KGDA7?}BNaC9#-eTx(0?QosRJtwl zvay#Uc=kwscJec?4$}KTn`jQ2EqL&L^wC6 za4K2y52feCj!G_cG~6VWqtl?&L$yLd$ZeP>Wrz#~AvIe+NKTtoc$6mRc;Tj-#yUH{ zHjCuV=H}RuXRD*Ftx<3r5;=hb37qM8@c(`O|Mqhl8R$R#IVp4f-{=3tXReI?zwYw_ z9pOLxIZ3M@N&7ji4)nk1^L(A{|33eFKQFKWWB>Iac!A7;!lv*6C>xd*2(bALr_SVo z7gij+WW^(2pE+yu#4XQ&K;l_&5cDVh2C@@(L0O}At^oX;=E_Y_>Yy?tji9!@lPJg4lAsTJcBsQxuL3<}9xq12)$Hb$gSXyfHzU){EQbGwHk zCZ?p4h^k^Z&T4PNDC4(72$EHFInNC;#%%%7H5^f4=}52CsVV75Ra$la8fzB}){|NcAgysu^N6<6%rcg5xV zC>tGUB#%M)r|i3Y6zBv{I!ZmxCxFLA5F=gM^5w609B!Y*tE->KX zNG4^7@yN9Tsg^O~i)KCcYSaAC5DRSQC+X+$4`LL?y;#P&ww&gSD{LqtQJs zGD;1z)(pH=CRFxwUY%)>+%cqpRwTTv1+Swmfn z-TEUq$82O{6C%Y17m|!)^uh_ZQN9v-v9Xz0CX^ZqTu7O*1(aHz59N&q9}NyC{_u3i zgO7^42XDXq_6G2{HL?0T-=XLt@=f~*#32i$EEy!=gPd$s=#R!D7a`#D_ySZP2a^u8 zySN_kFq@%r64My=IjYXc1p9pQso{uJu5h|sc9}?OL^;QkQ32egge&Nf+rVv!Pkj~3 z)>N%+u34E^VQDIev@}#03iWZYjvV-*Vars*>dJ!rpe?t%rKKSw6ZFvM^uOVH>EOxO z9LYh-tsE|uRYStj(MXYts39CFpDh_YoV?}3SYc-Jhp zZgCQ~lU#txen~}(qrVW@S>0b=IZ=J~hMKLN?X}L5ig-W2cFIz_p|I7!t7`xcm9A`# zZLGfg#*Md+=GB-lK5Hm(aH#F_vVu)(sIxiu5jc*|du2pQ04gIiiX+x@Q-}=DOCd6h zzS=ST9k~*nd%*MH>!0JF^uL#Q2^=JcP9Haskv4p<1lR8qxPFMw1&C!4Nr}yniIRQL zYo|r|-RU)BL*^->M?lQMi^hcyN910w(dZ3${YH<`T?lEOh7F~5b5bABIdt6EX0PRh zIH8Uw#Rw>ntUVydmsmzTzCLGiB8U|H$1 zP;I}-*x?U$dfgqt^0@iaV0me|T4<=sFR3{F+epA!=2A*@Ex}L?RjcqV@LM=4fi9Q%%A+o*}F1eBd|oXr`4IjfNmXjGxv2bsz95NA^00yb7nu2GKyy9!x?Ple=h z3@D0Fkd+oTZfd>Z0`;NG1=`Lse}7rkM0InJtd3Mi!ankjBj;Xp$CSI-eZdB2VPK-Z zX*!U&rf>5^XFM8XVz+|$uGNSlN76DPoT(i<=TMp2rHkIJQk-blj>g6v?d|w?d~!05 ze#qM91EZq{qtSz-qX(K>*3WL)uwl#Wdgk5;@+A81lVM66{*#XTfEN(=q3#qOhU3RI zoH)EE9d9{9#$q1#xz0TwxH1x(FW%#=E6+$=c$ca(~Z;u8x+;jj@8#N@qbS zs=9_^D35^e;riSSk-GVOB@MrT-x*9M>Vc!mC-S~H$3P<;DQT&W^;WKp(k!E)rMU^R z49F4!h-DOvSHMxX7gcp3uDx_u)t-m)cxW0GeL}#>_s&!ET_vatvNvwCIpNQZU9qa7qMlJ5=o|}g!g1uGDtRo8 zSI9AqU!XKhaFqr|C2+WkI0PPF@ul8@&esU4CjuSe{FcI+O|iPI?yB7Gf@s$zRT+7~ z)_AC((NR9IjXYV>RZ=^U#mj3iuU;7{DK4|wTk7`4!j*xr#TM$J#$JXJT*0yblRClN ze4PN1_QxNm-cb(M=PkJZxUMmx?b%tWw0$XM0M%zoN7!jgNm9c9QQ~jGx@D`YHpI3M zRMZSKw$)b{i>-06ja>VJdE2U{wN(SbNKZ$56O`^p@p-6&<2nuJt|ja!`(F-3OBtMY zt{T(z1q6K}g`n$n1fjF*Q2I$Np>a48RTZ zWp)zM>L)56ahYWw(X{a>Wi=B>pIH=%gU>#!qE^}(*Ox@fINBG z?#sVD4dv;BTO38f>Bji#VB*lgIWs*Stu1JLC=amWUo1~gZKG3 z7Q$b@|JTae^%H*g?tP#nBQbN?fxP-aQ5?$JYZ{@{+U;Xx?PwuK*7iaf@-;XHFOs!g zPMQwOa?V)R_7WaQik<0X?ZqfD8s}I^OJ#F!<@)#qZ6SNKpsDTBV1~OgURROd0OjnJ z)mYB1?8y=jv_m<2#OKJ3*Pa&(2a5xgl#O2Ro4b}Y{A=WF(l9ZY_yr`!&x<=J=F8bW zxJG})ekWg2&OURK%a0T9mDLTcuig-iOy*VOHWxRvH&>YoO>uD6LP;B&Tp*@I;28nf zUg+e?+O~hOtc_idoCZg(nQ}c^Qr1qT-{&lY^t{aFwqC!reoG0I zw(Fw{rR|ae%Is2z#cjL?7lB`VQF;3p$iVU#IL?u`eQ>S#w7l&{@^jPO+Ai~{1gx|js5VJ-aU^Ub zUF;(8&VNSM-o2&m*dg`B*9dhz_ zWzhOoMMCWQCKq-hWnsU};wAMPv~2X^adn&nHQ*`T>8B6eus@s#Yth{l%j5sOYnRIR z9VacWrs4d@EhP(h|GFU9jMr{kC~-uA^Vts1-46=LQz!=H0UpZ3h-5`jkXRQ6*OR~a z>@_nlmyV6OpZp$t&MtPNH5W_46%3rWfrUFLIBYkQDz<$#O}m9|53%i@wC(8o=cf67 zF5T{D+r4Sq7kj_;bKY;|^go-Xf2KX3ZO=>Fj^4j5&HHVf{;Br-wC(8oJJWpM!TJ8q zG~-*?o}ae85w_Rj_CmV7pK1p$VZEq$?(bj{+==Z3i^-{9#7dy*>}+p`KW>M^?RGld z;Lgo!*UrwaUAwtDKCmnvU$%_OVpk7;DZs5~XzNvUOxiDL2ECPmKFZf048bvLk^G7B zQX@Cy#pO?^vU%hhO8&%rz?Uk1`T(!Z)*3%4PQ2eA&vlv&Zgp8`0NmN+x7T&o*H-m( z1WgvZO6P8Z@Akv>8iVh45si_E1MmfQ0A(q7*0TX1vmk#Lv@Ufs2!Fc>r_<(iuwo!S=r3~nT?Kg_yF_dCIxYHqwYRDr+!-!%mrMEn;!sOCKhJG* z=2qA&28%*j=*MdfF$2uNF@G7o-vLEU5vBLf1lk|j+puMws41{=<;oyX=-*$vmSET9 zRw!N7MyipVnFV-)Ozcd126uaMxx?Y4rA&vK4NhfN16gtdQ1HIpX0K=-ig#BOyL|4# zxXDua30S=*Cth3MT~**M$m`7c4Z`O#IF@lZSCmsP8fnaeGG#WLrV{XZCLrMRTbGm; zvFwnmu~4#u!|4<=Si`0$X4HHQH8vzA8k+ke-EAv+19@g!Zh?=V7nV5cO6;WF12pkS z!@&CSwYv>vig={tjk5fnqQ)>BL*v{(KnKQu6idO;?H3gcq1X>Pz8bsn5g-NY5|`;f ze+@*id^q1#aK0+SMiilZ*u`PRqb-l9(}Tav!8+5F;0%WmH@M z$AU>$ewpU~6U2->CzY5%+$)1)8Hd;gr3E;38I5}~7WWzuY(0q4*x0+Ylm)cKeTQtfj=w!MB1t}XE*Y&S9OfZHB| z?L+wc=Ctj8*#8)Ax1?>)hu@#U?YT>QAHCn2w!I9tkK^y#(vH7zt{8OS@7ou7e-T)P zzwcn$dEEB$IX75=+ns6qF9wy6zPv@#mj-%$88X$dnomxMt9dO%2uzd)B-<-DH z5Bnd(?UuCd`SANQxIK4?@4rs1Uz+wZ*glTGZ%aG=MoPWYW$p55mVrp{o4={D1B6 z0|o$@1<;B-kRE$NT8~c@(gNw4cvok9^$o_$az=74Gm)~h0*4Oy&$ji}96Me|(do5w zH-NA3JV`xDAmW9otS(yk>J=p4sfB`g#M($3OaleZ3Hgl$OFD@S}S8Kl;J8a`^P4Sbxqz znUMK(Hv~n@Q3TisN+gYz5BDlSy>b$Th;oEhorM1Zn&gS&D6UUci@ zcG2}80Oa1hSpnyDJRW}xrAC?LQ%Z$5)8n-3w5)>8eJe>3Y1)abm~(lH)u5L_s{y6S8Z~WqC#A1!1RF@3rO?#mlCsv-tts zuXmts)Pr)6u>r#sX?k{}zEptb~tq`B=k|vxJq>1=8O)owm?}6`gz|nk+ zHMSn`HzX~g(cycK58z(jhx75k5wWDcjZF$ZiOW9c@UvZV8Ilx24xW$X;K(g-2UYa) z{RupK`e#YB!~F+|N8y?vTxp@|ldF&;ogb~W{cTpZ{-W(_r3V0-r&O+I7 zhTF1bSv-+QJe(;d#p1CxWd9t2zEM*?&@V0YEY2aPRR?z=wZ)BK)Ivz*7Y7GBtLnJJmT|V9fd!QM~|A0g2!HL{u=z({9^P5_%He*MgN$!AjMtG{VK-C3_>5#Fa&|tEE$Rr zOhaAvu)CZ*uO=!_w?R)*LMxPZ2>vV%<3onE30#m53wx8ib~EHJX0O@fu)*&c^Nk{@ zhP}^$2NQ}{^kMbW&fZ*{1NrIBDUTi-d2+E+diseZa-wnPfx9todQnZDd31UPta zils6u{*_b)jwo-`1V`_pM-Qf1D)U1)es9RGF_n1oiu0=+8eJYuW$+$`!Cjya)w~rC zVB5<8@g2OE5KeprpJgR-x}3bA+dIn#ubTpHTf^T7>CU>!S2(0iQy$ zANb0fU4Q1OKijY5od?$ua#AuAz89UZmPqtWkJdkn{XZ}_wre^yN8wL>tGS__J_+?V z9yK2YPrpWC|7+2&!hg}%C|oZD&yqP%zBNY-oVyd6=8bW#zwx!nvvZ*TgT#-(jo>Gz zr%mL}4!CB_TuJc|UUT`}R`B<^AHem|p?dUi(Ff@M2+%<-yw;|+$-$ozhPp0F#vtYj z$>VcxK>RU8v>8yl<|j)BtRUK*R`e}Cdv6E@io`wle#IL*GB9u?=KbY?Kyg7qagf@> zZHfDV4*22jt%aYlU_SKi(Zc&1-@hGt~7(09DvTF++R-N&o_>F`qX@ zAfxyo9gPdfF11`OH&I#;Dm+E$Xb8vED8oKHt^pK-dv9-w|AO6 zo$GqXSCo~V?|a9U8*A=gR73(AT&Dutz6dId0aV7of;&Z= z4Zvc8LsBE1QNfG^4~!WJ;+}Y5SJLC~6*{~gXQ7YRgofa3x1%A%(Ae^`vx@N8aLt}e zfQ(m4i11w-kD%2-xEcd=dKN%-;FL2`9a71CC@~C>?bz}B^W^KFeb~;sjqzc*1OQGy z$cQ(wz%WDiBS4|QNT~zQ!;a2s=Vf%Debmowg8NhjNbxxF5xt8a(X~&CU|Sw;Te+aE ze(nM|2RCe+SkP7u+W>BxT+rs7n*k1eWu6j?rNjgN5ZygCwmWL8?B5iPZtAb3)@wl@3Jq(GL8hb7v-sO(xF_%o z{aqW~7mfGCbwJ0{QRf1vX+1%mJQr;Hx`pl7A7C?_V+SFJV~|VGJhDlgLV=x#$zS7e z)cC6!Vr6Bq2A-?q+@q^k9o^OLU2*O=HgEpMxhod-lQI`xIvf=vg(^sDb&O z5PTZc*1hD0j}sLAnFi~K_3(X1@cWJs_fvToz*}G)`5x4rj70khjTk3wqU8M?0gsQW zW)7o7VWTKYOpS{j5(8AOQQS-b6e@vhPa3lgY86t#G(twe3qi>Pi+JTJpE}(lX=B)H z@EERV{{nBh44HcMW!I@J1{dc~GI zeozdO6Ut=NMQS$kB+8BA3K?)FQc8`~@D|LVGyO;jYJBK@cwBIN6dhrPgX!5c@eo{l ztiOtv)L%8M?tm3oBoSQ2zIgq-_cFE)Qrvu|vgzDE=GGB=c|k%-MA3TS?UqVVITE}? zDDDX0tmR0@9Ho6%5Qv1Z0dyfbjL@cI_(8c`$%Cpb${da|Lis$Qy`ijvaoOgAEb>%b z68h`_?~;%Ny>l;orx?GpC6Xh7GOk!eqVQKKAd;^o(K|?LcS!2B2!vn*^mqsozgCW3 z%M5F)`s^&;c_B$Wj_=*S58vCwDscqU=)W zfwgL6hf<>RCC7IIo{%~h`~8bH_xWx%b_;S~ zxUU$mBxu35VpG?5XlWKMk60$Vj(32rbF&IOPJW9pqq|dCb_N`gSq=p=oD>OrFf%!k zuvvj@ce-^-Bi_FsOuhCwR)thK3Hf9SR=7$eXieHTqM2n%FIi*ZM!z> znrkFQRVpPacB52Nd3emk5UC{la89gs5t~k-$#HX=1nnNPL#`A^ z^-S_U_D+RP6h$TSn^)fz{B`9(_paVxe7dejUt6_$e6qW{w8Igww-f{#b+zHTe&41w z*;ij7?5>X1R@w^f3hQ8NbcN)qs|7AwmDN;MZ1&ic%Hqy2_PvqL74WCYV{nIpL?dXX z>W->&fe1vbBq=Ht!IQyjEiZ%HV{E(EjJ%!LMiCH`rGOCgQM({!#7)9^FY;Wh$3G%AI>1x&YPh)IZ_V<;69ib|$1zi5$%(XmC@zDL?Jm^409@33cq6&COMl{;!z)*lN>BoU>i zJ-VO#WtzIe$1Xeh(9xDGb4dYMmiR__r51p#*Q}j&gL1h|Yc-WyLX8(JT6!4a@CT%a zyn}EN2OkgzD@NUu(M5PC5vB4# z(Lp2-il)+jC;24g@GhsrZnMgrc1V8}E?cJ54A~T-I%>)r)e-Uq;1BJ_iOf$nkwfhh zIey>W=BanO7H)+E5)3%7lhzvCfxh#ibK|+C? zWJCRB1e1bbjEVQh+;A%gH2h$m-j2AQONek5(oFp0Q$u=*f6zvdCfn|{H&y6+g2tZF z+YOK1W_YwIK4iUn+2C`Akh@i1>6-gxd&O{DN5#;cp(d)X0mX+%F;yps;RU3asvE%2 zOj3Lle`e?qDZYtrr|^*!Q*{-XIg{e!>}MJN{0&OifgAcE{`^g*9lV9Ve;1oOO^Mqd zXLE$1?`w!$VjUgOE&)Q6MnWjyWD3gwQmJSZ;y7N%5h|cv1ffEabSm8!sHcV_Dy>$V ztF;((PAZ$2T!!#E#HJJDrWA9?<@6o;&+fTrvM0$Ep0g3k=msg0(H$Bsd;vr>rGp3ihdXBr*ieSQfDL?jbA`OG zgV!2=WXo;m&BojKiH`xuY;T$Y50m4@y4u)~CUFXKtE$G@0&g>uV*st8jhMvw9#H!F zWWERFxhD<`_UeVq^$q1@1{ ztE-9h`_EaIb@X~sS2$W*WiNC9 za)WT8+^~dPKz*-}VZ*5$pJBxFq=Sfm>Bkr0+y4o!eGGE#`)ID+F>wy$+ItwTJ(HGe z-*@Fxj~%19_PWHim}{SX)5fzs9Ik!cqFkF``SwZ3x4R=93;Fg^410phu)j19ezm)u z;=yb7DQO;jcqPSy&vyU<^Wdv{F%RB*KIFkW_8=a77sG?Yn69I{ijqiSdR{i4iJd9G zI-J6n=pmnk0^Ye3sLyTYxeJ7 zNa1n(7MR0pbNhpE7X^r|+o;Sd*a39{>idLbm_S!LLSzOX7D2Kx)<#|U(>J9BgcylB zYnbm4OMNAhM?VdruvviW04(?(^(+*FvyBG3Tw#-|_x>BhjyEf-&W@rolyj%NY!5 z*vjI3h09j{Hs04=J>w3>$7{Ov;mYadxNBVQX#T3*3^P2qylgPv>8|nYu>T|Ho!@0Y zdwHi?)vZ+03aQD&Xrv4;{EzE(Y58PYy^iIR|Ks$gG+cFYy@}$hXq|t`@>Ts8;j4%V zI|vCfw@ZjA=39%hV1}s@5`qv*h>0b>0MRt{*))upX1`ya|K7GHh5x2e{s0lhc|PtS ztVs7$tNtCjpK~crox-T!hm5*9Be4=Q>d9qmqBUB-y~zLUvs}%ucTFFo_(7g1hj^Mx z>HC>D$0x1-YlxW#DV9y`x%Klnw=rUc9|_6-+uoaiw^dvX!!vU?NtR@5mn>PfEXne| z$+En}w!Ayuve=2^*d!!Q0wjTiBtY20l0azL5(tz+%hEuBLLn(3Whrf0`ci013x$@_ z<)f6cv_Si|bc00x&&*uOl9wb<`n~`2JugJEq2>wjK;D~SicV^ z_4{|$-MK$izqiMKfkVlhr5A$jL!=MX{O)()@8LI5zUFCkHzx4D2AS9{|J~|V;+o`s zkRN>n_g;)_G!KNu3@2+ za9+7P%bro}tE(Q#DRrA2`Vw!nV&o&MMW0cdv&v#NWK?>`&}{ogQM6C!Az^^}r>Kzb zUkV2b6Z@CV$d3<`b670oPE^7F;(x-ubPtk_@IZyS0f+y|V;z#`9f?NA)^U2#X557f zS-m3~&B1FQfHV;VwxvYFUx|>6=CG*K(t8B{!-XvkEr5|;bRX_Q?;UHeILe=Sj~;7- z`-gEi?&P%#fU=0RBt?!%65UUdSR{&iIw3`Rh2I++>xO^twT_Imj-r`311N?k|14CJ zA0h`>za>cb&BA<7wn-8yll3%0i2zi#uMt*|-GM2$$Tq|yGO#^N{?N7h?lotO7k0PR zw@lo#X5Dapcf--Qt4i@{T?>b=T!eRheqppaenbCq(zS2N+PhaZMweG#y>RV4tEf7FLB zSaDzPo@@FOctmi2C&2a-Ot85xMDmBx)pukkb9Xd}>R2HUF& zqt;k+rPrwwB@y@P6sQ|Hmrj*#DF_r~q~#w7 zr5ybQo`QEo1EAEkBr$Px26&A;Jz842Jl41_-@mdomiQc48H+#A?Q_qst7vGbz=zFa84?!xq~qoanV37LF#vIKuw7)IGN zu8h`r$bwPO@-$#gvn@3c5=m!Z1v^*Ct4{L6NUG7#@){@8Lr^ObchvbjWo4n*Mcy1GYbo{cPK644YJK74p6{!6_5 z>T78n;mXMpf=MRWmuEBDYsLl8*4E?2k2K@$@hkAw0rpJqB&Z|rO!(UH)sz3jH4nJxF**c6YG?F$e zlSn6+fgK_6cng75&SEhNbQBh3p<$o!($X_dEao$mjQ4cFcO2_@?45<- zmj3fPzw`cJbyE+%Y}>%@ob?0S1}=4bPgdM)l&; za5q^F*PoyD`U&epb}!e5^sY~-b3T#GOVBp~8T3hIQbGn%T}gFaf@g{5wy<@nC%wlXNW*L{fOaV zGCA(=(d$|sXOMu+4*IepR_ZddxN*CU&@kR))Ijo#EI1h8ffg4ONGywadU6Jk&~)L$ zTpLPA=)YXw9hqorSXCch8Y!Rek}o^YcBloHE~{*5jgnh7-gnW$3p#7ocEu(lCI0o- z2HKBayk_l5JsrKYMyHg-6OEpvHHNFuo|utfQDzk+doUKe6HWqw`w5!RVJQRrT}c5q zi6-^a@I2ybIpx*VA`QWB+GPIoX-}oxIU38SRfTEs!HR>X)sv2C{TvqT)w=g2Yyq(lP@3bC??;^8y^@L zr?2LD73EDE%A4Z9PW;l+$bMmKKT48@61b{HO+c6TGkj^L)9xRQRW~<>!wLK~_cV8Rw1u0((`qxP;L?2J zxXerWEKc2$cj73<-%vlq*Q-~WPZa6Xk)JXLILWse$QSdbdFQMe>^SM4GHY>)S&RMG zT{paU?=U{I|Arg-Z&dZ+Ww;xi{cqXHIVpDXCy^n&_*&2*7pppCrfyBhm<-f@m}*8b zkt^HC%a5@bHI^>hk`kWAuF(iJmc2d$ffs9`QUse68s=pJyTXQFTYlH_9{eU*bmaFL zLIHd0?^p9QFgd1S)p{is;Yj^5>awijjZ>AAqxH?`Ozc4I`!^FyI=a3pd9%Z ze$E{~pZty6##{#K(O@i#*Db{~=nW(Tna@XJOH?l%O;#^u>oAt7(D~%AqlZ~lQ(a0` zQ;Ps5()Z%8KJo}IjGz9)AL8rDf!*_5!?43&wkAoh5nd@OM)5G4m_3%Q_m9KL>?B(BSPCKTDyp%R{*T@Qyr z4_}xvZmx&7#5Set;o~XbRp|=&e^i^^_i451aZxvyHf6NF2mh4Yz$)z{pna~tyj*|f z&Z@uIx#SX}BaeWN0bf>;1@PIr=@C9vqSK>smc%)yr0yZQc2)OmJo0>o(8}KW(PyoD zXmXK1l7paofMciYo>`U7?8@bj@n=A-%!`k{{yM&!Ong}U4^S>ToH6+Ss&1jajjCIS zRzd&2lEv`70c7zz+{g3K?_B;dACH|0;BtZac=EqR-|RdArEliry+50eHwbP0miu@# zF$Ve^T>qHdii}8p$RP7`Y>E=XSP6m5H~H}m`W)LAqPQN{N55dp(Jv=CcAw?SChUs8 z-E^hJXFvKo#s`m~e)2pSn>x!D#dJY66qPJWC{z>0kKywQ^DX+vBz&uVM2~gx-Jio3 zXs~X`9$zkf&rwhs-$mOw57`7OxeysBJZj#(s2XkutqIon`|Z0!xkvv*Og5KucRQXR z|6%>U66->P!@W;ESN9ky1X!X|umlSt(Wpa^prvrN14qeb9oCQ7_~lKH zmlim_C&icBhd{RC3wR98=O%v*xH*3cH^JIkXb0n{!%pk0<3BOn#Gj2n%W<=Up(g$| zb}`hDoH^jZn8M*uf6wG{wl)`zJRy28StY^;3tEv zUD3qAHlH2Z1Lg2vyPYl@F&+I=ZfJLV{C#X89sAr4!$NDxzIt4PYi5VXZi6|u1RV;U zGpt}M!wD}&)Si{B%o@i zU<$^xDNKM^PXXrBN#~%Ad@QU%F6hIhXX9mrnKl!gWXZ>D7SiWLrC!pgUuSP%g&z%{d+x=hxb$AP<12S< z_|A7W+@tr{@t<*V{AckjyN4`z;)$cbMru5)LAZ&mRogUWDiXA50fp*|U>xy*a&`D@ z(U8qo=&=(kZQCZxjo6|#?fkPas(ZVFhK zE*^&kzk?p|!9Q`|OCP`2V^`rMAGjUytoYAxG5)i|ee~cHPZ0ksaAp~05!wvMe(<}n z%~x%=*@6+p5%EQYo7|40@6i^B6n{%@oYrIjt^)Howc-lpj(g zJZ;5}FH_@&C8R~+m{zM%1o6b`!(KW_I z47au=8KbR*=P8_?m@5fq3V_oABHG6{JpTBGXZP;ii^t-3fmt&W|62TAY{yovyUSQ@ zXx0Z!y+QM|pue(w3Z|GbdAMroXw_ebhSmvJb9$b-S5dP))4kMH)6=6Q_Zs1G6K`T@ z2tSTD9@&aF(ssHgON7IqXCtTuEsu@Zu!ht{wSu52!V)URV4YFR3|vbMtu&#G>9C@# z>dVj)>Ic!oearihB(Wfu6>>j4Iab?J+uT?W4b}t-0>MBasMonw_bBOgssV5&)h6cq zg;sToH#KW=q=3Z*g~`6}u3odMu0?C zpUMV|rhLM@JcOz%^GfoHp#`tSBu>y!nNJO~+IU!L}L>jmv6G>*Pp#-g*@?6JgBuWWi zWLB^+G5ZrEY6@9GkKlRp@@Vqoyt=$-b!BOBK_DwP%j@JxkTYgUg3M3v1J+q2nm;A1 zke858ByPulymol_+9gZ(3=i*F+P$r#hSn&tDB(tNohYDXUsnm?D~ ztQ6ItA3mIqB~3yWR)Fs+3E(Yl29^i;qn*e|J)EecxT3tM8ABS)I1Bo7(@4SOV=UPt z7)}#2o=-2g|p0@h@d5$eXvpK_5WO3%YvJ6H`v4!arKQ0zZK^`b52Xv%MBNJLbm>znj zL0kS1J-|vGaz8bF!LFk*M5mrRa1maFAL#@3#LL?!;9b*`b=ug_MsgV(tQ^6WMrqKlz6U*t9K4gGz43mfY0Sa;?lr)_-n^bL=0I=TtpcKgyxL-^>q zWi{c7w(gU@ddeyHtUCGrjd)R{@|mZhFDv-7JAk*H$OnCSTt-@(IU!tVG^8n!50|Ms z*=D2T@_(G^^c991YkeaNV$EIO%rwjHn$ohE95XjXw-=Xn;NZf=Jq-uH_=wF$&IlF$ zwsCWN8|fgDg2JSvGgff+Lz4H?za zwPdzJA4=RMv0!6%FB3Ma((eQbK+|@WmJ}E9)LkAHHEIOqfieR6^gP}mOZ^zIN=*_B zST=?2DT%!WaLt6LPg}oy`TEMy#`yoaDE^MDj9!43Yw`BF{sEdEe4zj6%L8hD0+NY86nbDlET0)-3B3^6 zLd}@dOlEb(DMU#df4KUxU8|m0Ofuhn7uTzKtzTw)G@V==I}okYE3osHB0X=Jj4gGf z{m8eLIEJ+8`&Epw=zdknz4tDIe?&JBZ^uszT%XdP1+C%z<)>^{(MVREmVn(gs==~6 z)pg2E>DLuy3JNn1tw`q6Vj+U*@qv*rd{@DuZ}^E92X4D<;KhOKuV=V4p&gUgiPb_c zaHSojMF6a&YE%z4WG7e*i_tO=n(NT%Xd618W`R8a+%20=-?)0!%H>Ok7cc1R?rdvn ztgERmD+&ejT~51AM@-adNar}@mleAsVh`CsY=T6DFSSvzAjJMCVfv#OqQ8a%@FyIp zRczsc5OUB9elZ&H+Z_S;;MAp?|8`leU1}0gWmmYg-YkFM92gOJ2K(zsD8L z^74h9QK@TT$@q^pmsHf1^y2e2$NG!v%Z_^FuLz!4n8drQTRp=5qi-*83E#bV@JYdS z^tPU=HjnTX+`8bqf(sWfatTl3E0z6%r@buthYE84Rb zoZ@hA>!@@))+}c7A>k{^VBI-D{u*MsY^Oa-ua$@hPA793eX8qjp>8}CQ$9em|M%R9 zjDPfV<{ejnKM%gB{PTP6A$I0czKc7acq0B*{HWdIv7dE5&n3BL@}2{Eh|}}A05yo`1yJbrfUZ{*#+jUJ7`aZ_yVDs_3#uqr+ummd@??b zH%~OYY4&qs9MZyM`=*SvabP@i2+jC{_^u;QVcpCj#J>>Vmp%Xs+79i{V|dC%6~Ipm zfRi?%i_o>`HuNC+4*D5-3;i9-;6xVSS~S#J2$K=Q9_#==S3yV6KhS&VZS*VjbMzc~ z5G?fy^j>2mt% z@*`jR#1DU8uc@UUR?s(%{>T-dxP_yK;GL|apO2<97`ZiZ&!>62>ytkc|1us)itI}R=322vVmtEW<8Y&s5TrQdBdmexvOCA8t8h@59-Qi#G^_+xXL9~5pzHDya674`Dc8uwCqFp@g`%pr5 z3ERmAu-HPhiW*JN4>q`l9#N4nQfNsF1qq@eOeC_vuf{xAYAA>9@_UfSoNo*IL8F6# zVe=bFvgBBz=o~+X5s+2;5^SyQo3(2WUwrfaj0|4_TWT+@thYw$miAI_ zY2$F+aKP_tD=DwFMrucTi~a8xH8wh|PD@2aQLe>)S9N~(BI+*%{BEDil-=3@{*pBu z=vv^(28St_@9}#~?zVb=qhm{f*`hNuhbhx&FoVMc^Vf&>;_Jza80Ob%rRNFA0c#>R zS3S$6dyvNT@H0Ad+l#ieK%~SOrMa!ej)xvv2LFh6AYOsNBunehf>!hXPRL%&gRk@g zlBHGC?*GKrA_t4U;TNA7`0jTHo?+G^;At4>_8yft^UPN1hQ!=w(LOs;lw93 zXWS(2C4Xc&;|6KYxT%Hd%#_q{n57SM@HBAhc+j9$TC#P@+60TRFus<1Za;e@=E$`MsyklkYSzU1o4dL)^o<34-JlsAgz@e_;d3@H zc3X1%^tHe9RC=z=3#}9h8Eh|3p?e;dNNA?eaX4(dv&u>rwFYW)i>!W&uP{)YjrZ)4 zGAqlYZB}Qo!H}El^%ykY;CMi|f$bB3k2#ewopX~K@=xnynEZc!3440U8SO_Gq(7G% z^RT5?R?c~%7DFv4>NlH&oqQS&O2Yp-?;q~#C&u%&A+l{y1o{Sg2kGK&L-%RAl zMjz7iHrgMmdtc|H578wv_g%Df-^CKXZDMQZWmx961kT6J}>$xXJ7Zd;SQq?zpOZZ`Dy8=AYB?G=A$avtFA1uSSU zLg>iPc#Q3lpCw{!0iJa*#(zS)%_=t9R*i0=-t620dx0f4$Y0HC2J z^3N22aQpySg$IRfc&z5(3`G{wkV;Lri7BL}E+QWa3S zKP7VS?xrgWcU(l?JoC)5;bH#V-^pJm-x97(=b3EaDWQ!r6}#sU`TOMWgdIpv<)>D| z2zCZ(!biH8nL?Mfj4=N)EH^pY@+&f$HdzBfI+aRtuQgd0D;mDCvaGAtQ<>@V z`W)`!3S(oPSdm{@W5}q6o&6yErRdKLHuB3g9lWyosf)QlJ z3^2!>8d;?xfhSOBL%OqGQF<(G4di^e%#mx(^i@^R_%0H^iTrc&dEwh?9EC#byz?>9 z47D$u+|d8l`i7;#4L7;&Df+VO>ztNf6kO2f3R=aMorO%;r^$nU0uoFVojBsN#b3lG z!PVIbeZ|QK@Z3{u{uij{2vUlM(oJfRG)$0Yrxp{Pz8`F!g+$04MMYP{V%62~a(O&1 zXO71uJk?ZI)`-t25IeX%ipK`>7KUf2azKuxU5VF#(J)g1S1`_w5`!q2wzO7GP) zdrd-?+>&d_v}I&D4Rw~N-{!RlmMl%C(^zMz%NLABLx#@o^b}TR8i-!DIXuOsFsB(H zE8h4FWySd?A}g4z{#L47>rTowiAsu)62FlPwue(>@r~p>m{aHM&*Ajv$ldCLlarID z1Ks{!$OqkU6B2|?TsH`t61w3(B!h6GUwAGM^YJ9xGtz0NG)vNQX>Un3OS;qBjjx$( z1bCkYk{Eti#=L%aE+ue9rj;GZ7G8pq4q*i)aCge@Qxz)VGD|v~$%rdE-<)p_NFo&6DF&E18;U}1N&kn0b4>5K9F0XAo` z*?Io{hV_GQHk>?2u6KR8=pNTiMO>GEc`^p$`v%O{mqC|*gP*%S@(p#qK(>=>piRVh zyK5GodSX_eS{3=Tv-F8eeKb?*)45(nt_7HAC8^r!w&BDH+J;lTwk6boeo7tCJ|^n{ zFNfigNZ$c}S|2M;#2%JYhIhW&#j}YX0PhDUOYwrq-y=aY9zTdU&m9IUj@xk5*PnJ4 zo!V@KN#Rrjjk%zrC?>hF>8uzk+!cz_8s#XPv#DdnzkqSR6T01zs@o^$lf@v8GQf9)nbA@Ifc1Y0UF881 z6L2!$0kAWpy_r`=*>olsI82QCTDA)rkM3xsec0o-0UbRFP=OO=Pf5$3%$3SmC!6Y7 zBrHi?ZJ_iZB+f{t5IA4AhCsEHMG5<)DS!9)1DZ=M+?C*#gjo2kw8iC_VnNrmM_atqMI>u@=8ykZb)TU@?O zH^Im)iLoWt2C9MQPk3p-WJ(Ur(RS1R=Wieb%Q`oKeER*Qb@I29OR%7MEq=>nomwHN zF6ra_X3{x%FYJn8FWu`~EYwFzjTEC~h zV|-O^#9OI!DfOk%g*jA5{XYH#;P?T6<>T34nY01j{g%;PGp9QbK#1rX%C=_n`mpf{r{4I`RTlM_!QBk#Vva=&B=O z|N3UPe@Fkb_HW0m_V46o4m$`ex&q5N4nP8qqtikQ`5|F})nw)4=lw)@kd~LWP5XF* zwpLBs=J-A{{{H0e0N(~w7z?WSoM5ZEBk6Xu0U4laW=AuiZCoGPPErAnzn=uSn%P=( zZRi=WkcJ+1V7`b?LnAGUOeAVnNO(d7d~r+5LqCF?q89o z8~9=v|I_gtb^NN01moWp-yYZV@yGQ^S#TxU0^?tPtUVS1xcsb<5n=f|aQ{W|pG^L2 z@{wcRPo=^oBO^WUQ2ahcmO=Ynd_N{bBN35?rwN#y_ouoNjnZ&jG+;KH8BYl`P>ruP zE8daD`X#GImR6My4UuJIV>>nv44i?~weK)CQX5QrE-poCE-O$V&)~O@xnC4k{MFYr zx$xUJ^F5bpc<0aX6@6ZEkLlP%WLX+T(gqw3f0Q=jYPxP7H1yETH}n3zqz^qHEIv`6 zD!o2YN3u*1>6=z3h}ORRJgt4n*7XH=zmemB?7&89XKL@{IAFg`pm)Ij6SQAtEBooV z+MmQ#Vy{50o5_RY>5xOHw$hrv#Ew#IuS_n*4wZ zO-q{4+>;QRW%eeSO?-fO3iH)SE1-t%`D%ZaZ8n^V_;x6io_4DJ2}V7~f@}l(yM(A7COpMQtFQH{&@Y-YD#%IthP% zI!r2FKE;}sW41M~n~uNc1+bn6c%NhK%EH&KywjGh*q$M|2Jrrwu63B_SnJq){G|>$ zj%#7A|BZEy)ZWjZb)91_*^=Vi6Nb-))BR10>Tfl2)84Xs5NCxwGt4^4b?Y z_pA5(24@MkPP->-SJ`R8roEm!Rrqef75|2xWC1_Pn{bmDJv!05pW1H;Pxo8iozrh& zc-ssF|DW*-%yak!Po0=w0I=-=p8cP)6U}qliSK<y#)sA{h$}Tsy_B|-N#@hiEE#5?^FH+n!!7B z5uCyFb<9EY5asSj4qq7N8c4}d-hs5abmys~SbY7bTZ zw8H*@S@%%?-&x;4crtUcZSsxDUw}M1C8ndNcr#caCXe4SGkRN>2*srP4sJe1lNza+ za)FL}w&=}KzGM#qFP|L@mkZcNg&MwjxN$+T$(fm79{F~CWqE0_Mq9zQoxJ#UbR+nZ z1}Z4Pl;g89S@mEOrl;e%J3ET|?aXkqq{r`qglPmYoebbBhAQTf zK?*4c`YGEBS!(+)<1)2<&?u%XQJ`>VVy2Eb?4!qkortip*cChtcsJ-7ccHt`?^6e$IradOamy6H#~47H)uhjJxqNvR z(mBfj9th;-8R-!6EX`bB>F^)WP2}nH^`DzM=bwiEmhr4v)oF0g{nPKce|~3>9DFw8 zg~Xc05ZW)4rr)!_qctdGPu+9eb_C}8Ob9o!e1L8=6wAPj=LN#H-3q3=*4@W(t!V;4 ze!iR~`jfRbW^BlF7*W{W)SNRg-ICh*HQhspX7RJ#q#Iq&Vn;&Wwdg?^ir#zqUlbQ(U<*$&s|*DalBn-BuiA?V3Y4q*vPbnDpX(6{q$k9=ESq#zOnrm?kOH#+1_6XFe{FW@+PM(rlK#K7(<+sP>gE zIjP;(3ij1nCVv`Zb!l=lX_O>nkXkyYTbd>~wI?n(-#a0}`KRLuP6~G$z`c&a-4Sb@ zAvdSPuHY%)X9`a3i3`s6PDpV6`S^k}A*U|<56UUaG33W{(aZJjZYq%fGO=DM2M}l@1N(;>z zyLJNWttYnMGqrvG$~ zzAq(#3~f5B)6Tjt)o`qRDUiKEL8Gp#B{zBK%9^eu5GdF2y{VR3L!Kum*HGKS`UJ!d z2s^p%RXd$+&5pILJ9gUwp4K*75A>f{+wyVXz9Y45GI`%*30}g^kLJ({&?X}hu-zg6 zZ!={fh-|rljP}tqFbs7oP`}k`&9Qny=0H%UM@R}%v%5J=VUyh<*GBmT>lX z^V@oc2mSVyb#)*5i7U6PxOuf;)AY`7tgdSk$lXV~jIK3h5y_KN&gW2?+(9zgIoiBf zPI6zIZG~@T$K*(VVnXcuqp?f?GGO)xe8oOp>gk5 zFMf1j~ra1ERHqF8|p5?T;PS!F+_ ziPX}4YTX0+pQ3Y>SWNU(QJ7Ue`17{-V_UbYkz&-{jPEs%Ke(Wi~B z)n#ERTF&YFOZZiQX9j&EGD_*&g*bi7Q}peKh6ViUsXH&5cxeAATeeN?UxR(||ASZJ z`j0+}|A5mrjzgPS$VdIoEST-wByG=1uC6I^%|^7UhR>Ae_Z3oFm4Q~(N^d+j8_gq- zpwuLx#_Pr+Ez$AoKA2Y>YN{;LnNDr*XsM~i=F_9S0oU(H{JNT2!<#2pm$eU-2jUwo z$$X`B?1hvjH8W_^l|qwV)Nk`!g0?_Fk=@Bi@99*TAWC(S5{UBA+zrEx^L56a) z4zT%2qeIse9cHJ~p`1>Kzgr)F@wC%$1%59+-qVBc?CDX@Fi)0{yMR9fs0!T}^SH4n zcrX!dSSE!bt)R$+F46*h$m)sn66lr2hzMgel|P%cHGNu^jf*CN=+l4^oRG`3c6Oqs z^6~B+joE`igo0JU%F<#0#~%oQuGRrNiOKY2ax!gKwId~eoy}wo7t}^g$)XWtkRI7? z?OK#QP_g2)>J=?RjSIV5dF*oR!+DbHkN7eM7;*{)<8-`z~Cxqr3Bh{)GjN z`i$PAYkR*R3SpA(U$=JM8jdGgQ~pfAlOI)}|KfSeay@Q`6_Amam6;(*q_o5*XcP@A zs7#A<_qgY}11IiKD=rt)MI%|1xWNLbUDd}5_G(#)V_GnPAHY~mFV}nzkN8+TA*u(Q-k{Rn4KZ&ZFGr9imlH6CLO^EXU1E;E41E zX_T_ucweF-ZAqd4^o-|b-aQ(l>4J+zy@B}-P18-Ft%HRq50k0 zt;{n-!cO8wK~#n!=*pP8rqpd0C0(SvtRNVWwNh55PAf|?5{2GGJ#&dI%1+So!L&9p zEyFC2X%s>;kWlB6dr|vbfNnAILXZO|&*3#RIPpA5vfJ zV0JVTb|hkOY3?WBt6-#tC2*9~zruM9q4EEM|MM*oZ9`~*rtzez&dl7taO)ua5_k3% z)_UPr0ZFog1?i+K8wr^5uF(Ma(p6CD6MG{Nz(5j96K97`FoBriIjHHuFhdDwuH- zBMgm(5!af;jo@a5EPgom!6}aw^^s7+!M~&B2w-lq3*(xJv%SB z3I7I+oylC^bI&utX_D`!0Y`qcpJTw~a}!bFksTsO5s*h7mOzKO;Ez1Zb+LCeg?_Ne z0)AMeJY|*y0VNXr6imN~(GR^-C7?u_AG$L|wGX!9(** zE;B=s#XN4*F%;?L1zKBArN?P<+VPV;{RR^tNBY50h2rL!4UO~U<#G}q2T2afr>lH+ zEQt;i5v2SaA`AKqMP%|dAt0$v!7@s&Q?5~^V;~R!h<(&k!862RimAe99v@7f%SBzP zb;2eZ`^MxSV#MaK7HkrF(rO({Erk{A5d1xuyD+MYMf^aE;p&P&w$owNVjUJVYEX-y z+FFVIH82DU3w*i$Al)QIN;1<`GSL;yYZ{(b&?wT;Ny|Fz7WRO}nktfPt%J_LA5` zgOxQjSXn_Dt)iiI)WHnqoJ#AHC&mizg(&3DrzKnc0Y6O@6-d~S>a1`b6;%~eg1TsV ztj?gnrmelt$kn!We0=;u-Bwo?BQAqICqL$B2@K4?KtpF|Yxg-Bmv-Nl1%xGb6$N2_ zj4(+Dz<KxhtoIGMuD zOB^%{8hx|!ASsy@AYle&0V_5pD@H==h`?RUNh&9yXo#u+t_Uc-(N~Saf0OwSbfSRp z917g-r?o*8l?++8$zVOQ`~?LO3YMLMMIV57KqCy?mN>Z+3i4PphvR|;jboeY@|Ks$6@h{(8^Od@ z=+22Y)B)XK41@P*WP?ezHfCi7vn&nH%p8Xl@MnTW2(*Mf{+eB}P)k6p$tOxqW`3zC zIrM#^HF}od={Q%g&3EQ&Bc(#=#n)qO$;LT8MbsI<*A)dxM~Eqdm;-ujBv@0W7d3Si zvbZy4kp(Muw0Ucm)#=D3W0`hA3WEhKn{0+`L0nMj%*C2=130iQeWN^<)*CFg9IG~{=w)-hq%=lELCDHi z1UXZ0AeLZRrKwcW*<~@Oz!5EyJw(ykbQyMyxyVqX%nQ%c#F|KhCeUWkix!hozapqv zE=ab{LXTb4I4pwEg|o0x&JLSJXN6gB7wnl}g%DAnYZD}kR8UbvbcI=>-YE*1y3AUW zpwF>7vI(~6uq%)yWeEjUR>4yx;~dct5O9{D(?~{hPDl`qprJ&f=*$&snsC@%-Y8lm$(ZM{<~Xq6G+@E8I9zM9=q0b-wA!gX z&s5&;)Me*MAx}`&7wND`(Klp@QmIwa5G805H7;%Bmb#d*RF)gdWl>+H!NiF50W--k z5u%d>5%}Mr5fxt!&dw!gW*clK85k}s0UeLI#Q9|&YlR}X{SwafyF~0ZlxuLVv(hMI z#cU5)OnRx147Su{YQ!uHw%c+v`3}h-*xee3JsY%nhC4eTMR0A7)@0WKm1=Z~DPR>W zIa!(6Kt)=^re>QkPqry~ubdYx^ZP5zI#8g*X3r3XP>$IsfnAY>g@8fK!E%*HuvQfa zz%>CE)>$ygc35-tf~gibOAwuUF{@BVYAOnV?*zA7ClZi8AVTbVbA?khhqGlP@T$uw zz+8!TPhqD`610L~6J6QB3^pII1r|rZ)&MV}N|dpfWzWE3KG9&&B#3ss5W!}Xq@nzv zC4WV)iKmeHNP|qs2_9Gom4dGtLp{h5vv#*ON2|+9OA34*m&1|??z=!dYX9&2Jm^8Q~Q-_UOLW)F?N1|C0>IE2yKsxk_AnGkbF_Db2F7wxlMzkA& z?H!^M#5Xu4M!~5QZ6r?z&VWVH*+hc~hP{R8byy^lLu9!TjWg{FybE8A_u*UcetZu; zh`)uOK`pIb{0x2)KY|~^2k?FH`{3U!d{sP{MufbR1%kd@nLVPyfI>Rb4{;yT? zf6poj`0WnX9eA$Rq}>U_$|bZ?uWYl+Hu`~$B*dj`C^0ZUgPQvjcD|+bzt+uXXWfJ> z!0=i*lwr`xqLCzQ9j8~wROAxid!rH%46-IeEYO%pb|E2JBLj_OL zA__i-L_m)If7UUr!2kgO000CVB6yWaxL*%E^#B6{=l}o!0MZmtb^rhX0MZsRWBnBV zp9N3^Pyhe`2LJ*90RR910C?JCU}RumUjFYp0|V=pzaqaQSOXYDe0e@-PVgw8k3_`0W&0FB^Zs$ePFYCW|sAgv;; z8*cOz#fl43J%ETpwTfHSO5K;Dr3FO+Q4kSPgxBxhH}B6&APZVfbIy0}EceZFXS*}` zy+4>s4S%*_h}X;1JFF}>Mb+i`1;MTe?`)Gw^RUVEN|5K9Y?TF+Q5&;OD&g>M;5$LW zQ9KI2L)jurOfpf7K6uB}O7mEFQmy(8O(*2Z_A8T@PD@a4NGJP=NreQfykF9GAs?GW z;W)!hk$s)-W)i-ia+aDlDkJuim!h7tOo9I*Wp*HKoXVEAL$DVCRU>fJeG|L2Vji}yh9MPU=3}PX zFv`oMe>K6}_qv*L#<5r_HRX1=$+0U)I}>)3mWc%W5_@KAYD*NxudA#vAl)Jhqdx^``isY>tJun;{~-F{ZcI!xZ~dkYgO>urU@d zA^)*h+>vO+8lUInU8J?AyqalH2c0zbO=K~07jqTqJ%^O^j=^eM9NcSr1y9q}&Mb9hLc!KZ_+s^ILxxq)aMevp5BjqG) zP;44Rc!s(ic3(Pdw2XG9iQQ_lwXA9MCrmp+9# z(^;mx3X)bU#8Hx*&~A#3Si zW%lRW`N;Sh{DtXUDPF33isDbAtXYf&c#Rl`S!NKFLMIqzXJFeIj6tZA31iaX8yF{% zZ!rHH<~`Fh3j6gaJC-NtUMAtUX}_$6^Gw4CZ(l`N`E%tsbGah^EZ;X^?!Rc-r1Kw9 zX}kx_5z1+dyHL)WjKX#0tZJyLHxN6<;<{!}MdAl(crE89)R z_&?ZsH$?GAuwk5MW8vko@GaQ95A7HUk(|z6KGfvdHNi@|g|lu6X`NUT$C?85xAqY~ zp7Sb?^Ip#IsqEcfn|g;v@Y$j0OPi|Adli2?;sn|w{FpX2(QuwfY*SPl^f@K{cCsS; z8_J5}P4L580xWIRJU*)^nX!XKRz zlf|^X2JBMW-;eMG=%(-k`LC46@*@+jIW3}dWB{)Ds?J4K;kjysyXJ7s`Lq{;IqW zvZnvVeA`?N>tf;O=+{;kev5w9#4ghhy6c=yQpZbhCUheY%->-(;S-QMk%h2b&#t7M z0OL4!?lyV;YJ9H+rm=TFcV>A%C<)&R?6(zo=b#h2hx^@FHw_v8_3NjJdhE#^-}thg2Xgn3w}`JzhA;cb*YtZO^F!KoHvNUfLc;Qf z@FVIP>H0R_^`(?DZ=}7;$$N+RgYbrX8_7@~IlK!=JEqeQ=?mp}i(xz8fwWa^#`uJ` zMlRPqE>GtPSBE2W=7$5eLyJI=NT5;9B(B2I08%5feQ_&d> zmy>pRct;SMF=pl7>DWf>ayE$W)7UAxqq@77;%qE;u(W*#RrampewdUc<0bZzzOWWD z)VAES{1o$W33KQ<=Ew+aS?=!bzeY#yhB96+klvd94aA1xcZ=`GSo(uV=Z>QG6u*2H z^XF9BG(`FlEb|l0o4M#6h0X3`9m?Az_iOcuLf=Lhq>oJ)Ht z<71@y9{3pe4wRqecSQeK`hS7jZ<2ibE@_$cX@|Z^W%#l$Kh1t~KK7Ecbq{_ZB+ewf zTE`>hH*$UJ#Wy+HA9$-d}-{{W}+9W=myp?Uljv`mMH_8#L1!>a=^a!gQukS}m_L`*k zDSY5qA8b)3>N{Jq(z||b-&{%H2WuT1UR5svwA2i)wKA8b(?v)48bZCabI zor_(7{V&NHNP5j2EocW|!%VSb^!_d7auz53d*A`M)sah{*m^NMPJ9GRhKZE(SK7@O zMCWU@Wn4y^gs3ceAFf4L_b&EoyD``+XPNA8cD8BHdK$`kS!`Rf7aytjpltkH)#DCY z=-xWA)aR2uaVWZP(Y{mAUyncbI^}V0$k`%g*p|U2LGvTzO+?O~QupRYot#%g*+(;E z|7PAMp;)Bu;T!baDdS$8>0PNhMP7IIn_T9zyobC?8^`JYGs^Tkd9&K+-c9Z_Cy?GK z{!VhZP#e~O+V(IJ+S+sggS|gSwuJhG_reCkxzHpG<1@Alf@o}Xd}@2&!nVpO-wzr0 z!v*Ussr$M+OY!yU>G{cBA==mVTo9kQzWT{}UfP%0C*xv zSac2wv3pGV-1s`ISId3{X;?2(e-?FSp_3KfFF8|+s5@nE#fRBVyF0q~5XoET?nUdu z`n7E>+`W@B^!~op#ibu@Y40Jw>wE`lc^5gPH-JMV_WtpmsP(_Hk3+7rjbKy&q>m5z{H-4U>KYTC%HU{cZ58bCiIPki==&0w<|YkW(Q}{#(w^y zG(}E!jm0ILUnRY(a;_<{H<-@Q4~n2Gt`0?CuzFi)x-Xv`sgXwo1XFpulkgQ?b>=xbsX9fZ|XhIUO(6TTpOusN6TU!S+A-QR5WoIldFt=Wylh5Wk3_a$ z-NfSsX0(1&VA>?k*7pMGPftggll5bI`A#ptir#6^RLd7%d^2kdq<{Vu#CMtAGUu5W zLzElM5Y3xyMoC^eeHY^d`d%a7T^zg{rHP*UVU_gffAK$Qt z>6BQ+ocSWmV~-J==5uc-JRtu@tzTta4>`~=!6Ey|Nct)|-J*Cbe~Oc0k24ZWby_zaO5M&%sN;GX_d%o!*B&D2F$^>+w)*g9XJ&6i90 z3GUPxmzX?AWvnol_;UZ@d-*of^{>`CN5IhZZw(5}C>Jjg4Ev3}nDYO@xZyLfMy1GJ*Ze?BD4a2v@V z3D$=)ING%Zf*EjutDFAq%SJASn;m__x`VlJ1>vV{N9@I#P+rE4&tpTt7p3EmMfxL-|1iL(mOi6 zX^v|g&0^(&SrL{Sm7Oj>s$;rqOH@ZxPgK{nI)AWLkY!SYh0kF(Y;$}bY*D6|Oh}qF zFvZpRkZBoV$2i71T=`M^>~)-9QQM?m&KvF9RM*GB!4iCs4E;?Y_h5Oy(mTYgFi-t` zd~rXUF+*Q}hw%XC!$aKV{upfYZ{ob3Dfi&uMb=Ul_l+!lcfBsyW}h;RIj-`7`R;v@ zc-`dx7nWw(n|Ru7*Lj$ab@vDG`}-X|2^F$cNTDoaU&}JG@5VBWF=och*oH(@DlxVi zsk@Y7pG?B3l&%|7afsH%A6R(Hg8fOAUfs zU~h4Ki|bm~S?XcGjtwq%Fc2yEs9;m|VGrl!oYa}tgHRiGv47LVNHRx88HZ}3BDQ`{uY8ioAG_HkD zEqrQi4}#h_)TU=`y40p~ZQ4ZIk5p5nd5NT79s6}$*ST>`%ewN`#j`HXb@8Z6m%8%Q zmA4*jJv{2+QO|vSd-ZW?fJ*~&)WAG7h-VX+91X;6AZ`P38>+LB+8V(&rcq;YnpkV1 z_NKTuH8)LhZhDf@x|zN;qervmOh1~-(VS)v@_EP{v@qK(?6*{NOL1G`(TYziJX+z= z>S7SImOo0KHgtSgJ#FP`OXqepYbR!VJ#LRr2YfrKxf5I`@jEYMYVORhi#of~w>#hN z@ZI6N)iCU*VkTO`t_Bk zpPKurIY!Mfd}H|ZS9gDBr$4Rwi#0q_HykpX%ci)$>cV{wngG1e>&q~k!njx+ah z^pC@PkhMXs2hn1XUJTNUL2|{*6)*2#YYFxfX_RQz63tp7%@XO7Xy0;>MCT-&lH4Tm zNpcR7oP!~1NX9E!&BdiFuOjFNvzSD7s| z3(V<4zAxjqh*pd2Ey8cHn6Iem75QI*dDZo6;$-2QMT@1bm)$VDbMz(0ejeXE`+4^B zan6tY@4p@T6y7j7mh*cZuN5?23Aa)|SL)|Vx~`<%O0}(|+e*5%?9s&U<990(1#7;Zg3tx z^o;n>?0$&bht@x|{*ibat!w{jfD{jmGP zcpjnC5qckW29E06G5BLNIR<+S_Bf4CsNsb9JIUuH9w+fQW$l!@PO0k@|5N-=@joTk zX`D{$?Z5Co!~Z+jvu6LS{(tYBd~f#7!JdOXN6T~goY%AScwcZ%exT1q&*4kzxiKa^j^E71Z)WBI(?LgCSD2FqgW*v=pn5y>*Vmc_D@>{<}IX>Jhu zM-_G^2;I!TD4(M3Sv-4@6$GJMwg;hN7lTmoBCH~7%(@4m5)*>ZtgHYw7Ow7t~_lylfRqWlXrmCG;5|gv4`l_yAYN#qkHJEBO7@ul< zs`07Dr#kM{)lmIv5W2ra5PAUb2jr2r zu#weROQya^^+m$fk+%-6b#SdCuJ@Uc_nDCQm{7g?44-;p)WfGfF7?H&PooBK-d#cs zY1)uR4e8QQ{zmp2)89Kws0mCHdNg(KT_w~ErkUK$)ZJXH<_Ch%gM1#6;~_P+z^#S- z7Pz&wj6-KWUDV$Nhc0q=rC(Rtcco=lJ?jeB zP0iiJ>?US+TzaUfhx?x5_M}-)+q8Ku5s!fC(dKe&UkfA;P*ItLO-9d_axp=T7S}+ znP_dIcu%>08jq*x`i%L0#(Y16(7J&$K>AZ|16P9-i~X zoiFZuap&vxd}nCB+UN6IK-{~GIStgof-TE1)bWv$q6i~F{{x6S!Gc)dgKcX4}{ zzTPcE>%@K!$Mr+vn!b z`)0^HW@wx9zMWQIsO<~=`GPJx%*>ax`jX#HXJ#k-E?VvKyW9P4Gq=Ya?!kQzo_p}# z!*{Q}y`HCg@!5;_Uh(&u@4YzgGY|XB!#?w{Po90w={`N(r>6aC*{_!UxO_#cukbv8 z)7RpC&F33?-_Y!!{vL!oB=;eCykCaCwfC(Uhy9;BtX}V#p(AQJLXV?-kKuR>_87g7 zoA(p?d_w*c_D-0Clk_}En^R(*;_H1fbXw0&)B802PxJW~{26+lQNtM;e23R}`u&~t zv#!tLe-`$vSZ8rLi~skq-}^nM=5zXSjy~tnMY9oXBAd%ruuVbuAN|;9 zHiKocbxd6Ex#64PZic)0Vh}EBzv$&4d`rOW7lZMx8!ny^giGL50;du=Y;6#}74BAX zZgX9-1gpp*SwRpkg+pnayz7SVz@dydWpOTxdpSPkUSx8Ym$&>zCRh2ROs)!iE2yc$ zdbT$R->LRHw+G?7#Jfw*yI}6(f43NSi*fh$AY2i*ihL{KSBYkoaHxb^C7M+_5QHn+ zuWYX}4wc2LtcJ?s-y`llhk|gG&dgdB`R}FGz1Hs&=RQ7F`B$}GZ33fD^$JYv>SB9G z4p+B#zj_}?V))dceGPimEy)l^qab!k=4Z@qIt zxV|_IVwsv6;?~e!Bk>xI4Z@B6HrAsibZx3nO-nNCO~q{%&rSy6=4PY08Xm;sA$%V4 z+d{4uxU}To(ppP%)+(JXVdA$kC#`7F+FomZt?AKP{ZV*Ci66C)>0gw(qvVRZ8id>6 z)<)fJ#Cljg5BqJaf9=dde7yxw98tF}8X!n;cZT2ucXti$9^BpCA-KDHaA$BQcyM5e%n#`npAQtz#XdzI z56p6Q1^$>Vote%PXS~<0&P%Ck2ax+{5q!Sj58pNv$nuEYRsLciNigLzSB%$Z<%-X! z$gx#C{Fl+-^0@{@O^Ni;fAeu~0k4&r@db2=#kHBh^tOmTNCP*6?`(RNki;J@#mW&~ zWF6bi>hg#O>;o`hqQZ6eoGu(MP%Cm2!VL`&#H^Hf9aC&i4xgEKXT^+u1MGMmQ*JYi4x%yrK4H(?F`5Y)FhMzD&m0LImTf2~ zg#QAjoaGHxf)@JXrqItFYzTdUb;puq5oJP^{U`w}s0fS#QB^Uj>|kEYrLspEVmiox zyaQ2b_R=Udliw(LQ?4F`NFIbp03j>ruMxY#KX=eK!*_*0e~_6_?PtUqvIUHT{@;?Q1fmN@SH~&$}9&eqhHpPdD{#aIYiw_gp z1ZKVt9^yMpOJ^ov9NGTLFW<|wsGGmSFZC=L!jBuY@=fR$0CmSES;oFe-}~1DBycjD zPL1)rjzryNzKxzIWO#NH?=P_$#9q53XpMRW{6{~(KEn<$jrb8MFFaVd0Lw<`?V6FMvm0{(iTXyCy3}-t8cD@ljSgsZXw_V0wA$MC|Wr^++aO6XP`_(BYYU4liH78cv z@ekok-bARJ|DW(9dEkENGysh(D{a#|Eg&KK`oKj_2wZ2?)~%gpLx88R-@uI7TdK!Q zi0yE45h(AP@pmoLdYbK?Sxt%ko<}W^{a#>!Juu!obI>tfXoj`g6+C(UBb#EG_{H^N zrbT$={Ri(6h;wFLz?E$VXqT^j3!Y||yFI*$!^%%MgT7}d+<+Fqo85d=@Cw$&n;(Fz ziy-Moh;czLY_XTQSLEzXW9;rpuQBJ$n64P8F@jon6K(hj!xk>AOfgH%_&dYX^Ozm! zV=WSf{x3fb@BREV^6Ce=r3P0fjna=D(=&BkEXK1Ay}Q&&Z&V~{!G zv4_y0?qkB(pzU85XZP=W*<;UA*XwXzuZ1<=gB} z4p)g|j>1m%p677j3eb|o;BufZV#Rm*=H;I-%K~Y;A@j1&ZSO$0{gnWCmK{WK`;x?d zpY#%E;(z{bdVGPED-`^Z`ax}ZT+sfpARidMV$sdL-;{-#bG<(430&u{Hjl|}Tiy8` z81u&X08vaJO6^12`i@OtwdJ(t@vbXz+g`Im{>9z8!y8h7;claNEQ!f^(8qkoYjPd` zQWsXee!ghe(AuyiUV;A2IjBu8f9tC2aLqoj?QQG9b7SW}ir~ZJ>W*n(!vCxEJUsFp z_i7CK=3V%MF9scjQD2@eN1gi&E=P~){d!%F(E3T7K3V_)7g;xP$AjE9;E{V#car7+ z^h@y@zMf|ja>%%cw}v$0f+YMAg-9r55W_EF*LleGE%KeX zB|!bX4!VfBf00 zlo^cGp3h>~8#hR^=qyG;v*bTdoCk81Jy&~B%$icO{RrfrI_5AaUwWt?`QUV(j(p71 z-dT9ewLJHp>A$@x&|2_*o!JlE7BEoGaooRx^<&=k9hlTto&&+9+VDQj3J7lSrBKD zva0LB7Ks2`L!~!^+Gr~((GG1p^W2Es8gFl$5gLi`jzOh^vz#}~&Pp*9>y>2Qs9{I3 zF+N1Eni{3^3l8g;+Swt$p9>a4a+r=TP{ld=9}2lc<(LcpIiqxFq{&0f8Z)(4W0a`G zwKiACRy&hXI}RSOoiL{03%Tqsc#O97E`{@rp{@%bbZ7qa3%Sg*WS&&JX(uM@+5<#5 zJO{Cx$*bDb4wW6qZK}=mVS1G@@{{va__eatJsb*`iTkLT{8q~0 z2IhS1*{P+XI^Gi?%{pW?XjnJj`ZdsjVst5OA={hYOp)zKD_z&s zRy~+;bo>5jeZDnX109GCkMsLN;1{O~**+V$3Wxem-OClEolOi*=W2~OP75D>xmaD3 z;OS%yc?k8H(fv39$(gkO;m36vj(Rwq)iwloFH!E76kU~Kb)d{vRtb`|$ zFdc-u>p>PMhmN#?;;u`H)F`!_pcRC&q;;Y$hwj9z9BME}*1&GgY(-`7lR<)2)scl4 z7rXe>U17)l5%|d=!AtoS-Z@})TihlPVFouq??e|G>}Z+IvjFS5=!5;O??D?ryn~cYP{9G402vcWF`^Bjm=)tiRi} zyCC_G>Bha(SF5{o9!QVU^=D(rhr7G;uLAe&tb%Z7PVhgQzYeusE&p8H%SF)y&x=|C zNA(cOHmRp{|Jb~&_RpaGPF0*)@Qg~DxueARKWxp@k@KNQn$+hWqa*>}fA@K8EyK|8 z%-?!JYr6O59;=$P=Xot5i6;D=)q-AX8~@t$Dtd2)v`(1uA**o5W1_lyGb>Vc6oiPn=G5M{w4lTQgI z^P;R?;dYZi{7~;uyH*@_ujnBDW0{#9ku_oLgn|Po63J}H zLm5EWgq6F{??7aGK9);wEHd6_{H;Z?$uv-5N z%6}XcA%2XA(on;nus#|5mzN^tCyq~^koIh(j8C6GL3ypGsdqVGiDLJ3c>pv4V&7;n zqc;+v*KGM^Rfp0{M;(X>FzF-X;{+R}8$GpvIohm@BsiQX2r9pJk-(pNgB%MFuy!ZU zGijN>UE6rfZ1Ns&@_Sk;NX+C?xX`}!41I4D=bcnNpC|5VMTLv-kTr%VrQTaGt zGYA$X;LglZ`!{;!8_Y7txHc;WG8z+-*=iq@%1^Ifh0x!CMfF@gF4kSDXN#WnJ~H*#=ktN5 zNy?3_?3=zi45kmfDgjEde(rzv##@?filW8LPj75`Rmn~kGIx)zq3Ul9ls-FC4p%Bu z2qUzwcTaW4aDGp=D%U1X7&YL=@!E27^K7Q-N-QZjNmkA+9P*%qZf5+x%5?O!>CkbW z#;YzMVPXCTs!LYE^lc>eDLTd5h{IiyQ6;4q$V@B*u!bjepe>drl6QVJ*M^bEVq)d0 zkTBmw!nIcc%%S2#&-hnRD%0clIv3SW4W1tFnL>!5(TPEIM7wN zig8#;f;J)w9yGxX0td`{v2Uj> z0BnjuAxVZIgUd@z6xXo22r1r+jEMGS`bpKt9D$3aU#9A#U_Ik?b{%&?3~cDEdsOK% zsh&Z)RkUlriVPu=FUy`4k+ybBGu>0w$oae~CDP7%NAkbc7H+fhsq};YIj#?LZT_q* zHGVEtI(078xArW}K;b)^?<@JR|j;6OxC# zV5=e9I;Tt_MfK0Ys^u}^Mh2mnxyAqfgd6@d#Lrunxy>(` z`)6grK^P}Be@+%s9Qd&vGJhic&byEC`!j~bob1ULdDcNR={1{|PB*aupgu@bG;kkh zuCD^A{-@SR^{&QTl^16>p8<@2@XC$(vx7-n?hgqA7aCV*;*AwU5QP^%K z1GM@CZV@FA%C*$Vw{BJ@5GK<;Vx0+T!f4L!7caGL0$mcNp_~%VD@p-^xA3-pJy7k{ zvKNs6tYggb(8k`yHL90%H`X@6Wr(Mw?cUbxf|uuJaQ=YW9IzehEx2pewLQGc87)8j z%nMC`q&CjinUpZ%#TjNsI^=7x$?L<2M=HA!4ss(fT@%O^)L^Xk#{J4AJ{bS#U9zicxZ(yj`uK@^$SA$@T zSK0t%;rN1nB~ba*0+`^HApli4!BE8ejx7MA@283)aNqH&4b1;4_zqPYu`F%4M>?ku zrg>$5hy95DhzK0)+ZVnnu!4ETdnfXb{uuaxqmKMSmdf%w>T5D>ag@03cY1;_x(dbh zF)Oz4SSqAM*l{r{KAlVkFaShg8s6BmK>GT8-XnBN_mjOkCpAu7OlBExu+0AWHeC2SLu4w`9` z&{~k)cP?_G6!LFLY?X<0*W+GIU)DcQeZ?9pGh^ovp-!F}r)0~r6K$0UHKT9hTu-qR zFH5u^_b~Hqf>}#Cm++wOO4J{BF!P)jElXCMm$dnnbC+oSE1o)0aLldw+g~dG6VG`i zLNmCv6y!uvHi__YdA68IYS*zJO?d0E=L!#GFUfCX?+2e;zVad{NYodRxv=nlo}!E> z);VBt;o*fwNud~5Ik0j;=1nJ-j;En1oEnchpmbs54a=2Pq$n?uIY4%y=8ef!m=;YL z?>G=}5$Xu~@tuhrFGX&w^nlHUw`3dx1BBmRey!&mNN#&LxM3m2r0 zv`r}o8qY-jas2}a7qpIyP3eC$XoYK5^c)ca-vQ)kDblkB2P!xC-njyz`IJgUJ>v@p z1UC%cs8dukDR^Ts2UIs~-eKLc1{C!v++#Thj5l1~5YMb_ipvtDF?cJ|8?vWJzgPzm zy%eRf@&oo8-Y01Pm{u~w~vxioO)#u>vc- z8@#8S*H9tRz@)%$#hIA0a~P>Aim>bPvQ-sjsP;v*ZrJuEC4cex(wRi?ej&|;{Uvu( z>BQI1WfIN!C0BGY*Xw58iL8%%p_CyGKYREW(M_@wQy-G5Rja6ae(B`Y4W*M>Kc-G$ zbk5z1Utx~Jy)we1kRZF1x0zyU0a`z!PI{%BXclEo(aQ3Ua|>ZhhPzBsx7b{_NaJ+j z+6}82DNlr3vS4oNM52>7Pl9HF@g&`izLT?)R8XX?2$J~8jlWZHEBN1c&tm=s{gXO3 z?oR%TLN#lei(<}o1>X}6-E!aAzs(sBa{=px>?iqdL8$X&eDap_I&NHf;>YtnC);kM zoy=Pa|CG=Q;pan72JX;(Xa!>diV20%^Cc&9clbUGg7E+)r9ztdl#}s0Y#%zoxO~N# zLd$vJ$r>a(HIraMz7lgG-h9l-@ExYlx1Lx7#ri_6`RbFUJ3=4Eo_GT#$3pJ;oRg_L zTp#+LxNXJDLeKfGldU^|4|7k#wi0O}+I+;x;2p*@t$(bLVnLzOeEG@39lA zVIlK;#>vDT&NH2VT(9Czq2qkp$p)mNEt7vjuaa;f>3qV;=pEMcx3|~;#lAwr`TCQU zJECXCxA*|1z(V2qf|Hp$yl471(zm#G#gD?k`M#5#JJM%nab))2w5GA_1C(m=>=7*u znq1K>jdOO$L=(71NKIj@zwIzuY4u_mr_+t(no3va?Fd>K^x_$3G>zz+(pLZ2;k44} z#nnzP8`(CstghP;>qWExvE|q^ycq_Y7)Ebu`j^em8t>QO?8I9!HZpN^qSAE2G_qz! zfC{UhTfc3@DwyQ}W$f5CLhQ#|P4s~FtJtlK8}art9!C64d8^ZQc&+psaTn8ktLn?+ zo!W8kKmb?V(i*^y@66o4rhs!5xs`^`u7~!gPK1k zZ))23xaoHF=^WaFtSeG~lF2xuX=3&89MOZSD_Vc5&UmHiZ1w&e&V!;WYHQNLxUFep z_2L}WgQhEHYwDlzW7Es(+d0(3SKmm%Nq})e)9C8{`IiSu-)O<9eB+s>4oHYSmH%Q zIyHLL=m*vN)i9EI5^pc&W*7|e`_fBk7|lGDu{UvZ2)^-y?Ikyis-M)_tG-zRpZcNn zQX9t9PmNx?d+{q>b9i=)vI|VO3d|t+>GuK*3mp5o4~VYgypuA#vb4O?Ui<`hek$$e z+)RNbdU*?mXl@z7>3;ORoIBx4dmA?w;0Hf=h~kd^q%@#4PR zTky)e94Nmv*dBfH4xQQcy@3)MivY6}j9Xr>`Jom}Jc4|0{lUF{!o9-6L8N17AoyEx zaM3GE01qSzY&-!ZeQOGCeB}uc5DqRFQv%W4s(~wCIRf~ELkq@dK$f?z;Eq>;0HMAh z!!c$M-mM(C^p!1uw=cwSydI==YYT39 zo>!p&;lLo_F;WoPtu(mgmGzw`FhqE~0Hkzl2?oCMz6%5f_l+5Xm~XYf)vuiIe1V~T z<2xY7TTgHoWNH@r2nrk%29e$>fy*INGw(-8;CLU%@YWIB_R9Y*_!0au76=l)H3Zkc z2EKB?^M8bXj6EQx3*{vttKXYjK)xv31?%cws_6AWlY-`XA_b+CRK9A zAA3=;W6`-|F(KMoH8jh3M3E@NQYNM<*i}wSVLtd?5rwwOw>{1CPE-GLS zoqZ_ZL6{rA9X>jAXaI!nT)`tx%oL9<9bGas z2f}x*;ZY=JRz#%5e@ znT60vqZ5WkL0H$7V0k~LUUb9g`k@sN(KREVoF7duo^T}TuoB4fItHxqs`N@7fEO4k zJZuPZyiNdXkw;M_sk4ojCaTg^mQv`MRTEQf99Z#6#it>S!5)ga7j#?|jc8v2-*TtS!v5sQHT(+!~UN9?3Co9EU zC-Lmh{lT*fOh?h?cL#=;Cd!E>^6L4F{X=S(kWF<5YMMV&hm^cJ4rFbqdgHZ+TrSa@ znhrE=8T?};hl(zi9Wk34|EN7PNL;GUQ}vsuyUY`Esn1-{c=aFt2(2*_xrA@3p^l02 zQbrug^U6)9yB_?2@E5&*6pv{y<8OyhHzMAN0@@G`lNK>Pc!+WH-8)r47eJAaHafn4 z_~k~zJ6S*{pIj-ee0<@M;6~m%T|h6NVkYf){Pqy`M$9{@Tibw~IW1#+;t=OX);q0R z7s7GUR>sc`QEsHXQ@VAw$sN<$#y1X0ZWO&Uy7eHGC+%_kgK2jhf`jGTS=_%t?@15d9Qk7IC7pHEVis=%xjc7}vt~O&au0~Ad@DiqtOiQY+E@Mf$#zf`e z5~7V{OR}y`ZLy|Cb>-3$p^ZXIx~^WF+F6B1nyU37oszk_=ApU)&SEDd5VLn(#J&QO zp|iS}uCl4BqUvVJt0gMCkV_+{GRnr4Q$|5kuYz$d#EPt$MfWpfG_H6|3Ds<})wh&~=rIUmluWkn}wcHl9mGWmSqxr8ZT1_Z8Mvbq~r58uh1YZ&gJW z6@p7agc6?BWOqP9P4+qF6D>};DNWbKA1xW{dKV=R8ZVV^OHijG?umTbB*my25tV~W z7^mOeQ~7jBO5!y}EBBYaoJzPS^XcRjD{7QiE-Vq8%DboY>E)G7YaCbJF2SCPxhHjM z>lZU=WK>Sf(KciFAdr;RDQgv%&RMzRbRx34VPKxxaNyPkF-Z{fS`jn{bxP@1*NIcP z_jHPGMS4hfm7vUxoKm|3J0-WO9MsyX`4{s}ncTT;L~Bn0?)9BYTlD~Cw5o_%g%hcJ z7QzyMN;{NHE`(Hk?f^l^sTE)I|{wEl2?47V%(GKEh)s~CEQ{MY-AJLu)16Af~ zt;On7&U-#S{H@SmKH@!5Od5`rZA<*8`uF)hhW>>@>ZFwkOEjly_XKPOEM?mqWaZp$kz z=A6m+G;NDPj(lG4%>E9$r*>P>vEFl*|1|Gz+6S+vdRyVLj{i=5E9&2@erH*iJK8#m zf4rsyAxV6^m~^rD+}z1mL4}ojKt&{~1lsA}POZnk0b8@|clkadXs2X?HI}D3KCSsB z$EQ7a+diZ{_1j99^=Py3r=fQP&*=UYLh___3A56tC3kbr`2ICQilp^QvoxnEcjM34 z{#8N>1$8sCmZ!kGwP#}gIw7TkdgfWY)0n&AXH5UfUU|d1`dO{h>bs?9LjT%cMZ zS?<%EyQybf|LR_aox00e&(p5Et!IFLeXr6^J?SjkX~f;&Gsas*fV^;B!K~70`Q5@Z z!COs$qHw+8Ec0o`-NZA_TUCHUU)|2E<7wO7#xu!VU4T+wz3?pQX~Ny;GuB(>J2FX$ zu(V?l8iZoYy`{bD2A1?K?fkvGM|+ljOL-^gi7}8KEpAgG=qV4J>nrA-dpRMw3x6+o zSNN#=m<>GbyW4pteX9>8K1Yw>o7{_c`c*=F!J`mZ3Udx62gB484*QO!+OajlX^W7KnmKZge^S0Qf-;^==gO=;N# zggqnucY!lp3Dc6r$-8N&q!F{!&R||-7r};7ikE&-=>mHtNIRh{)@1_tWAd}W!7*V& zqsm#({%Y472aLTCM4I;3rIkF!pCk_^EN>Q#YT(kZD^v+h%c zSlpU}DKTBHTSUywvx@2`fM-y)@dqQ$xhHOVn~~aKS@mBHnj7k)`{S|&|6$#Tvb3dT zZ6HE}Ykw#9${V)Ta06YWtfe%q8>J{6i8?$XiTGD#j6ZBfIX*b2;WmU7780C<#icOaqZ=q9x|DW(1vRY^585<$T3NqH5y5kySM{Mc0;;{Osr&}Im_iA@rb zmgU8V>Sw=GQ)Ujz_ET0Hz}hbXw8XakaUj`QJ2^XxJaikGDR~M(stHzKGR={{z>g#? zt76R27Gu418>-HXL21mK(9$hx)=azsn*A;_5pxB6=6e*Snhk57V~f?`MZ1h~fv&Lo zjgV$uG#T|p{C>MmccP4f3aK+Og6TkyTh5JOePF^xQC@!CM^auMKV8ouFVpG|HQag# zcYh!9P1n~xcyXN|GJ3q>Uy%VDzc7xNsi{`Ih9M6VzvB!1%({f45mu^x6Qlzp;UEpF zRWyrbd1*5R!?uZMIphc=KOGExS4aLPe53{SQYSJ)XLO8{Se_h~^bN+H*pik1EQ+FNd3Ghv4y*MYz zwI?bvTyt&4nhump8c}Y7eFU3ZyLsr#g{fsgYlPdJd8?WZO^0*pM`x zYsy>d*{-WLAgVxFh9CA2gduUJSvbsfHt$F$Il2$-rSY&ThC9&rLS`R^_4roe;Pr37 z3GCfyYDd5y-+*j6>b;x-jV>EnEJtwFlLq#NT8?Ab#p%ZgVwbfXKt%4->lmNYFD-{k+n}ZW+LS=3e8EDdFpGPs6 zJ?))QBtP;um%AIv1{Uk6AKdOemxgRB63KDb*YnvNb}Yzg#ME5G@uEiEMTTfLTSW~ro$U-yi}yY$WEiUoQEkST?M??%UqS1hs)_~4P33)`1DD^AM zahFsgR=TJ3b5~-^KPBK@{L6qZ`=wJgs4)agrO!e>mM!SK{KP@}2nD%fru_OM(m43VddeN&19{meoj#_u51YmP#GxqDdXT{n$-*@|H9yKZ>Yq*1y=3^H-}Wo?S#E z4Uw3o#fp)@pH*;!NSl&w>OrnJ`@wS(1bYe+GPkbO-%1NByV@!Y;6^ z_#11xfx}rNEx3AcSVDGA?_O9#e+UhcqzL?dwL4PYrW2hNv zsGovVPni<40Lin2*Pu-=FnH}wAd_N=WZo}+);t3D4^>ON^5EkvoJv?S=lX8fhxR(g<9<3LL5pjvNU|spBv_7*yHh%Z=3=xF3SY z6J@Xg0h=;$M(cr?*Jm{ruYB|bec8^R_0wO|d2fds30P?eM#Xaf<**D7J+b@%Ols^z zYT>w=PUO6hI+P{498D9=WPgHRW^zSUWrK3zzu2w?yx#LUX>&R>ECgc}Qfq(LnT25y zNU#doQ;|5fLXv{Vn*C}^#1RGW%o23H%xHsT#BofrYVz5A8RNB_AM_rsY-TtsfSi?M z^v!Z06;>a~BKwV23#OrVFg}4Qv(accB;BLYXh0PxeL*(5jA}}tAcfNxm8>}1Kv-K= zY#^y=ywjE50L!jIA2~$9!gc;hT}1%!sl?96K_fRxTjBvA(oNw5Yut%LX*N{GWo|X2 zJ;D@=5fpW8A8&?V74ex*+#oOfZk5{1PQz2`oxuxJ;-;m}$I+3eA7Tf>O;S-#7@z#q z0ByuBr-<)ZEk)L3gG}O!!Tmx3_yC=CRGpWJ)gr4lnACAyi$m&@u4Nms&$wB}YTlg| z$f_&JVn46_R~y#@SGC6p?bl>gTcz~=vkaogeYa&aHZ8HaJ^i+cCD9biQK9-5bqgBGz{mBQqg`nnT z($WJ*%Z6$5#xlEDX-UdPs4|V1Wk`{zv z`!AVy%W&}G+ABFD%1S=vPFU!wRWs7xHgSKN>J*F`{@nO^(vih7U;#B*h@C{rTXh&x zir0I5FZdhYoxkZ6Op`D89+ywWWAX|t78td#w2XUh#sw_nfS9S>Z z5e_ke)NKiC!a&%s4Z;t|;POX(u%jYeT0W~P zufLb%!N!DK$6f;IDs%56n{5E_4I1lq2rhLHUHNn`sWm@F%BgHAg|n5`$^`gZ3K+|_ zVG*aSc~XtFJ2#Cb56@~>05`HtT4(fYTf zCahuLJGIMSJBRO14z9(Md5*=CoYVp~|6Z@P2iRovh#0~KQOl)|(uuh&&0QxDa@sKM zq~x4Fn=omC)Ly>khfZ;uas8?mnIT3TEcNKLIT`M{lJ^tFOO>RpRvx+R0pBpvswtO2 z%8PqB$?f7G=fj)BZ4cghEC?Z)qsk7JfAYGnTZsXF2{~5&Em#2`L2U465sH-QSdd5k zVOMim4rYgAERV|tM(D?lR|D_E{8uf)0}h|>L{G^6yJ$YQyFaFFxxJ(uO5g|K5A5Ne zFZ%0Az|Amu%}HqB0g^s=nk|Fn#b734316K;m<(mW4C*w;O8D{&zz;=lC*H$> zryTeQFd+AruT%0roJrq8v zjZkq!wDTo;0)Eb!BEj5OUzR|DOkuzzDcV1!ZnhJm=`6wa;m1ELOim`38bQLFgT78S zhXa*q@a38SGiYxOEBM>#YO%oT*jbU9M=!@&csm;;pgp<5Yl62Opv4$D$sz z3;)b|mKio98iIy4H0djY)XfVqnyaOnC@SYe1`vrSf z>!EVuXsG3a?P3qR=-H3V@vcvu3TZ0Iec_ob|!H7ij+ z#KGeM#%B18DnKriuT%8-)9iM{LoeFD2w;*A<}KW7EVSkengd0* z>Wi?mOM1K?LaQDp0UB;%o2%u<#-$<3vvkj=tXVU23 z9bbIQ)M~teDAnm=OR5#Rn>NrZ9%Fzg-`-NAdIEu+KStcu`Hp{|)9WCh(3$m+3VYGN zPLwC_I~@XxwBFc|K}Fyzo-Cu&`M~onrO8b#-Qmx?f=;JLK^~;dT8`WPK2fQC;B#GR zqT;F|bdgc(vcvT8@HW8$pLQkJ;=riq-M#w|b4ZVZ`-o9b+uV!?vca6ql~0Z})DZP& zBClSZ(O3c!6BFs3#X8icCzdP@`PTZ0asT_P!k>03<$4OXSG8w?{v>WW@y5JV)RJwP zn&pSPjxhs1lV#dYE3I&wqyB+T6~O}`;yutf z5F7sT8qxch1kKi}fdAsi~qpVq2BlhKj%zKgI65)0qP1dNQ=cwr0tU%+2y8ZQ4i9EzSX6eFW!3BEFd|{f2`|<47eFFNltpR z;y-41BUs^Eh6)Dk`iktpJPYl<1fhA41;CvWSY<%HB9B3NPY4|ZgA-TI#q%Qz!hDt? zra#&EmEmd}dW+$X9qG=${}E~j-VaPZ7ICiIhv1c1aD;~fmtGD%=i? z5um_MTjA%<#r9*k!v%__af^Kvohc}(De)vVj?2FK@a*|Yp(Wh0B2B3!=y71yO;~gE zq%9ct7&88Sv-$ePs{%W9*V>5Yub5OiQkFK8nN3GSiiSxr{6NMNc^-b+ERYdSgGG=7nD1deUvQf>Yk`>iBAUF?1T=`p1k`fU)iqSg^^y#^yg*>-&yKi zEJ}kOAyZ*+KAKx}e?7u$^i?kcSTYp;b(ctqv^V3*pB=4=&PCh!6`$|y3czr)LWbUP zPHRZ*VMaE;i7)fX;h=Z$xJV9#R6aW5i>;pNC*?P2C_BaRJ8R z$mi*vCH2J!$o`cGNy{ITkxi=V2jL}lnEQ`|FYCYB&`y!2j^9c+ z!hY7Ho+3@|--b%ZysxmKb1Bq)-iyoBM=m~ZKJq~aElV|7SL*PRXyY@S=(1Q2B*RYN z+BsnS=yG+vn4YSoM9(IIU-@_ZqwCR?{sLG2>o15^uJ*#6)NbeyMbRWg(lzO&vS%}xZfto&2@e;#H5-h0o!?Fa$4OM(jC@8 zWmxTy)x3h<+`<o-OH?;`p)gqdb9KQjNCg-w7TQbnoY&SjJk-!672Lkb1uN~ zjR3cNxSS}k@3Sf~cBz^Zu}ZMLZRtUEM@#TX`-oAS-Q7yDiGavQ=Ic**ac6?(&F5uN4|oDAZ{122gd zS3=YTpIC=Kk&*K()|&c|#YCDQNN~XPLsb<~vTh+n(?)nM0}k^!!Si9!@frN zATqzhT+%IKRw=Fh_FX-WlgM#16qAD_qChk&m<_^|{|KbQ(#G(eXizRRFIRB03any2 zK<_Sp_p2Cc^0?=ICij;RsYpQo%=F z90#+iXKh!_yzFI5CjOEIy)Ah3D#L&49+A-&#fG?$;$fzKT9sfXM085i*g`Es3l83I zZ|fQkR+$VOQEY4=*f(tNEbwD8`k2kRNe7zJ&iar{m&lKAkD|~*Cc^^oHL-SqAg-NQMNt45-B{L<~1JvYjgMDA+g;C zt1GFG1$Cy>dz%e*V%8`n%InnCv!tVw*$Ltvt*SDbh^+b( z9O?_Xx+ck`ppr~CJ`H@0%gegQm58I&C!%(v^44P~X~%Pvm(#bw&_=Y}Ii$pM8{~U; zWCgXBUIKAfI9qWRtqGPdAT|_UnG34@s(uz1DkJoc-yX0=CM6uz!N$@DrDFXq=k|At z{QN$lI_Qm2rN~5&D37R1mUknmzhz9af94xkY|m|IT>gvyoUKB{(kj3g6j8<*4$uGG zMP8?(C0<81OSz4C*J<0%ZZpq@Znwm5I$r`8@d6zN-@BY`=eK}i1zb&ETvmRp_}L`3 z5$BErhZ(esuK=rP_OlpT&;ImVh^RtvqqHvJsY8n_B0iNHc4C4rMzgIAZBPy(q*3ma zCh>O#jbF;FVn2hbV*lhRwFLaq=fXMpAQK$+ML~<70I^ycP7DR+SxM{%jyc_&X9PM^ zX&XxQ-X)nI?7Ckr$d~2JSTxzm&VD(FdCVpxhAb&H^Kfxu6aGUW32WkP!R}Ew{bojL zOJ`OvtFbs~MPI{lk3&w)fxE6c+Am_dd=4b0(nxQUQ1o34`T6*x+Zc&*NTS`;S2${P$=pj%v2p(Q?f0W7W0N>>!X|njk93J zpoOKm1+14$71mWw907Gh7M{6&WYpHKcx!-Sf4e)va2(8<{l;uKii25k5XnFg>AX_& zCp_iJ!#y?Q?@S6gq!=v1bU20&a9&p`zDtyGgLuC+764ad-kkcJZj*=1Kk`H{8*|t% z_UNe67F4qREK3}1x(htgF1kj#C9FNBHl|12lWL`A8yGmuI^RarDIOOn zp|)UJMACDR*1DO@7J>!g+`UkBoS4jZIugw<#7=PT3OTit%a?tKfRp&mU5U_VBb8kP z+MitLs&fRxxU*C!_>km{>{P>fQxgf##i|;R@Mv+q=ed#HuY|=k$gaf-YRj#U8QVcI zfxq4_*mK{B27JGF*H?q*{mQu-wrIR!zoMW&h?PidzKCqTuKZK!a%$#yAkBFFHCOJo z1TjDOn|lJ{S1v7X7e0UYPLj35g2`O}02v_I4UJ#RJi! zw~+?$)N4IJIcl`u={$Q*q?J?y#vPwyQZKcz(p;!iDkyawuD5n^Z{#Xv#+R z`Cq_@7C)^yFHgmxia0!76AwT2iS292Ya$EOXFgKL44FB9GFa;7_Kc=R8k}Xts%M~} zKh0f0G&lL}HVqYq>w0Z01>w%WXDqV|Tw*SlL)qYkFErf?^=~8SvfJ>CZIP%0#)}cp zRdL#V>O@p!V3TF(64h0MegPm$k zyY&Gh+%o_8UvWWDA0MC4{*$l#DFk*tszfIz}S0Iuijx z4}Nzh7aI%9HOyhlz>V)mpmFm12kdWgmD~I%QfgGqdq6~|XGIz7?bk)9Pg_J%NRY4h zTCdf#c3sfKPV1&r6iZJI!*%xt4O`m?XQhg<7>Ok^bnP-tFUu^IZJ=i}LjNFbZohzBl0ueBVR)QlPN_y_B@R=mW*huzZ? z#5N4R3{hd>Bk6El<02p<$gg=sS-2u!AyZ3=L?!t{JBM@Et=@YbK+ zx`gz(Wg}Q2r--WJPX%E(xr~f+hGr3A?&sR;TTTlhM|fz(I}_2Ai?1P4S3nu5v)E+{ zdc?t5av*Vda;%3FdN`_iTEAe2339}Z0e@k)o3(tWlQ1Q_3vD^&E9Mqu-z8!|GU2h| zAL)RICMqHyr8@~UPa4}N^55%_7wb5V5y8mUZmu-_6fvQM+8(s^R-5#Xaq`*Oti+}C zNhW_sQrCnjfiN$r%)A_RpZR$Y-SZD){Rg;bEwI_Bs%&YHs)U8iy?XVUq{s7>nP~#q zdWIPWVbL(8e_xJgA{DWlYv(Fp;^q?j$gCB|o>fLwsu`4azq@d+j4(*+45s~I-Du8!>J{+p%srC=C z98onLCN<7+E2yp57!X7yU3|VMkRa|NjZh12g>Pd6kT@v{W+A@@uyQ6ckzLnRF!I#kx+kwfn)gQm-`;p2Po@m<_4;3G>LKC-+3A6ZKH$Z{DzvMj@ONSt~zu@RnFBMTK_L9ny>@Q1a`X0|8BbWsn0| zLuzhlH5D*CLNsKPjd8VVI%OQdAfv`^P!TnJ8`l#dm0x^wjFn-=P%4jxoS zavR?qc;F376Y=Ny)ewiJ+)z?fIBN|o=2}=uD&_(P@YYD(KC0e)nSCPXwxVkJ#7kX8 z*UCK@=4OGn$2llVg({$WqYfKpmzztX)hig1^tw8h26p&sv|{uB>OOX#_e)J;g&e83 z9S(f-IT^$F8yvqa2MHL&F$%efkQdY8#Md2jIA5X5n8lAz(ci(&H5caT3h-S;S0P%Q zH6M8u4SdRmdHO_gJ5meqQ`N_w0r(8SWbnD_n_ANb(3&mg_yF6?VX(s-2D{8*u*aO+ z0ADbN!I#Wo5HN>9$Q%#g9&;GnXAXm}n8V-!a~c3&Gl#)9%wZ5Qhe6C77hs<`3_8qV z&}9yT14Y+IX+GowZ2*0%(Ji3wbU)#+iNp7bZj9JJ@IkYG)QH(XX~fi@71c)6U-+P@ zziPzP-!x+CLq#`7)JJ^K)ZaB?>K__0^|5+7k;@GKcyh~BIH2ru`^oT|;`{@Xg-vgG z+GFtE!EhodVk0ACU*rbHog54t49Nu>8Q7e*r3Bb$F|aadfjAC4;T+B!hV06$;w-Ej zP@zONUp6aNEoNCJun@P?J~0MC2A&2^1~vwuMoyrZfYUw(2RHpWqrlAC$?dy; zz5oCi1pt76I@hG`Y-MZstp_jh-9MFYMCzax9$V|XeYXqx^9D*(XTHKKcVXJ_l^1OSvyeAi|0t)?9)@uSqv!T8%2Zu{F#=s%FxlhnAa8tNJ8 z>FF7TAzv`_<4@V%CHW=1fd3BMsW|rcV5B1-x&Aur1}zfNvzLP)kEH}Cxx@N@8~-1> zuA3`9FfgTouZ*u^COiW`I3d_!0ie|r3jbRN0P;PWL4Ya%5nv5~_%HXJpuch2ta1 zF|Z2ax9GD}1W;$#cgrhF#hHy(PATafw!--FG|9jC41s=pV(;>*aG3)s%;2g%P(HW3CgqNOtz+s1nJma zg62H|J?9$YrUT{2U-@-|O>oe*+W*MJ9!oRUP91X{{pV-m-_fvq3BxW&Ho1&}7i9IZ zN1o@3R@!llx3)4z=!uYD1+4rxV@5e;%Qg$yu<9d^)&6Mfz`l)U)%GhoUQ`8dOa9+{ zxWPo65L0;>Z_O#gI)|P6J{>AvAyNaH@;fY(H4IbRh#eu;cCknmd!n=fBn@$n_S_dk z=`Z1&3XxwB%S2sdWq24b9XNJ>u0<%;16?qE)vm$#qlI^&C~*bY{nXq6%?y0twb|{O5jIVm8}UHD%W8lAP(AYGWY^;SI<$|e zFs0pV$Qa7196nuGPzdF?Yb=+s=e($7)16w&7RGmT(9;ilJt;sjXwlM%98$9W9Z^xq-A9TybUWK4#-ti&h3|-o|R7(Ut34I zrdJ=CK!GjD9$yAUOwmOJDbxFZAI}m;FW1w}5G!Y&A^qF(9aMux4HMgvpTwwfpmnjO zUIXRvA;p-(bG-fayu)`LJrNxPtVQDv8ss$3^{7Jh`@saagw;BH0?<7K;7GoLKk^X$ zk^K88{qree1KTiLCuK0pMU9mAvEE13gve*DJb$?P(xv^g_pmeoj>=Ka`i7L#h>|-f) zDovvvE2P$iojPlWZymj7b#m0b zq-o@F9m8+$;aY`+Ebbw$#^k4jpp7>m+y_yiX1}tg)qjt8o&&|vp%E?3R zszVp@TWnj2lKFT$^Gf+eg*IthtTLG*sRsTxmld+N{aoB+f`>A-DDB{GB(p%wJTZ-e z4u#PY3tam^o^)iR0ERh`SD7e=s6qH4)C=PJ!CyBb$DEv;*s)Ojj57JW=Z>r>|(+A{Sg zr6!vu=_lRk?O$3!|MXT7SH;uMsmv@4Ec{zo>m0+|+dSAjo zlpk#J_Uz2PtfwAp^^3oZmKdO1xw3=6*b&0M+$OTD;d(o$3EN@M)@!@G+2v=iOq315 zSf04AU7_+k@bx08eVuZH!}J*=S6@kF>dUS-udv!wVZX?!zu};(uh8hNFlT4wNeh^u zWLeETGejw{@~_-gr5eAjEj3wCWhc<=ue?!BWTOfB=V4jjD6;bYA#b(HNs{U4u#Bq6 zPL^GNau8g%a6{Td0{;7Ja{Gj>^W zwFDEgK{2;wW8Peov9jah-Jbks)MXW(r)Tr@jaxA7$g}H_;w}B6mf`HU!<(IjuaYqq z{qN5iR4Kkh4@T!FV6w85ffS`3+x^PACu^bO80eK>q8RsP{>uKwcIU3_ExFsCv&#_9 z5#P?A9rxYVqtR=*2f4?^yT#i!UL4*tJ|DW#P10^sNnrzs z*cKKhVtsL8-EO*-Xk!Igwtr{oVpc^tITp#5?B>xDa3{o$byw1l#~F3HuEHIppN$R& zo?O{1;YplaPgjk*?)ftQdILD4451&2 zE;^hjPr6dQODiuCwrZcc&U^A~yT7&s9GiEP9Zk|)6WiFjf0Wn<{G}rp;pSI`(N$y^ z4y7tw7{pnaNIS(3X*d!|D^yMYhjaRoZ1EXw(FWCc7>a9IM52jq80En*o<1DwYl$1V zc4}e4M!8)MsjrDtciPL$9!qw5y`u@&fNlq$Ql4|Rqt@Z4W#%W-AueQzZ8pAc)~{_Q zF5slc@1#%I#tgNg4)vjdoTY&Xh8gZh8zkhU$0!S10MmamWY!f}TM;VJ6-lYu%ef&- zP|r#fVZ^$>XpON}6ICb#V3nyX)S9%##dWE?>Uk|2TpQe3} z=CMcav6udF(B^S?={y7sH~a(FA83c#b%5zLTpMak`Z;RPIVf)zRv$Yu6&Hv~FHD`X zO^soQ$3q;g)L>zx$E(}R+!b-fg)d+S8tq8@IY{|F62lZ&Sey2zHU!KrmOzT*gd$)e zcm<70qg=`VKK7GYv?^4sN-AAD;mkqAW{hq$w%tLOd62yX{el$9Vm5nL9AZSU!4$t^ zssmFBhM*SqbEqzLj5~FxEw$=u1GdYL3wHR(DzMcHW^EZ|Z3TvB8OM_g@r@HIgcEk_ znnZgWR(oGY+k`cq3&C8wtgAa9xFy1FU4&$PSj)|~xlzd?Qrygc*esmFEV$SWvOAB< zN8A;n08(T+A!sJz*R&SibjaXz%HT{48KYkkV_Z^gW@U~4l|Gr4A=(;Yuyt+v#Wnbv zAs>%E7)ecB)(x3J54lV4Pq{uxxgm455iGeu4Y__UxnXyoV7JL3w8@YVnC%1M&%-lZ zpQ%%v27!@N!b^*4#oz6TinA(xe>3mnC6P< zquLg)Y_-P1TW|F+Zd6g6@{aDPFsT*r*6?=m9P7do{$+;BEHeat$msPjFl4ohC3Kkg zi{$pwQ1ek6I{h-lF}oilyj?s^O*|6^HX3zpPn5H9q(Dkxlqmne+!N9e5s9R}t>g3P2C|NX23gM_510TBN3Hpdi|uF+FeuK~fS0cg~K zME}PHPywRf?BJVPeX#&wK@I`1p#0zP`9|zFMgXw?%{5;iP(m{d3~;@uZCS}yU)(jf zG+zBupDl2x{dC%4a@w(|b9unEq{DIJK|jj zy^On{sH9MhtFWu(boofeN9P9r8c5rBa4PVsWzx!_*`gIkAVk!oA_vL%QG$kN=Ks}0 zMHv*cS9(vRB-4r4HK1CdmQ2A-HUdEwgdh|IjDUduM!@t{?E!iAMP!8NfH3g|*8^9F zZ1UqH1bfeIQp8gxU=zhF=qj50jZs1~?|jNGE7@=MkCmn}VNp6_n%vCR{K`C{LEee| zk4$x*<%vgInoY6i3DGO&2g?V|hwdxW2c$Y+R*;<%!cvf~1oB@l-o3w&-H%Mr;$C+< zEN!rE-*&x2iYY`|KgVj`V2L@cK<%rLn9C#C2LbEG(=T&13*<+pKL5Fzy8 zX@k)0_^f=j^dZj!M6NO4v9tX!wv(70((=wlRuoq(R!ml!>jLVORO!n@2lZ~$nN{h^ z{fvz?)UzsdR0G+1J;q~Y=oN`v@sBQcYlh3MV5X zx%pNOGvH9G7#XI7 zTq;Ubnu1AMi5xOO@l$e$w3>`19(*+1=uaKpN`evTR^f}H;8;BI?4V_x<)tMBbGy}5 z+xhGAgLkWVmy3uii4VyiaFt(Wk3Pwtyb%t+fBaH_3ooEE<2e-qqx2h^`N17RK7-m8 zR5U|!U%_3St_Y__vT(MbwQzFUe`*C+8mtYr0A>K`g+Gcs? z%^py@fqSRv3L)58DOxY;BiBS(AFxE`0MF<;5$Y80E)jV1zI~z-=@PO{W&C?tdzp46 zyTQY>J5*x-#P6`>E-;h1Wo40Vz3D^fgXmFXVURH-n?nGNA1%OZX>R`V8gdxpY7*f7 zB)>bgr)qh2qC46BNY`>uU_5ubP-n?y}{J5cM7E}?6)~s2%w|T>j|AV*p%Jm?k>z;l{-? z#Jl3==LUqV`*Gn$#~NY-bMD+=5;KuV$6z&TYUC}(&}7z@ndnl{8J}r z^<4WlpF26w!~@-p{ljV_~qMIwQEDc$fSt`l`v9 zpE_B(&v^5ED}FtCTY7r}{R^P@jl&4}?l;;atVd(VEQpVYa145xfS3qr~=1!i|cZjxPm=7d)!3 zp-%7^ytgxWE%!Xk$XkKk1Q!x=6x>s2sPX0yP5h!hjwilmRSdB+&kJZ=7;^RbT3pI*4)NdlV- zECq3_vyq4At<~9Yi<$AxTk&)&$#gH_F{G0_r2ET1`mp+hp?-jJwN}>z(jXcv8>5^H z)Zpr)Kvg7zgGOMCcvB$m_Rv2bf0dQB7kRQK>_2_I17YG!?^Rrv%GFe^Iz1jXE#-!z z9B{7=Z4X$rA(sZzIC(hwHu~*ZJhyW?j*CqnZ5!K z-Vyb&Td#7cua!iOBiI}v6CRfMVdO@5A_jn{e3XZgr%k^{ole8Nib|WVBH(S>C^7Kt zWGOF+;_TObJ;hm!uH)y+Qf^Ryt=FCqVHixG0N8t!U_x3(EETf>Xe4yF2h(%}6?Zh1 ze|e*M3oPXFe@4cFD z#7^#Fx3@RK@9|Oq%`9M147;;^j7{gT#G98t9yH;i0u2UQ{Bn0;@!!- z>FuJIi?}cr3xVgpvA)^es{Zn~rwjgxEwiwwzi-WH4Z)RjK`;I&o#slF>0c@z!-h&E z0l))amV`5g8>-I)?NFS=x7>cxGgR+u{hp9F0Px4E2UHUO^I@)XviOVQ4AHTp1T2o9 zj=;NSJRo=Yg zi4~H95K}{@+C;iT7u~2~Pqfc4(42NZ*8uC*^(a3ZDSg9D=O_I|X)mYWp9`c-X==7_ z(-gZADRk?fVdM0j_jT@{Lk!*)XIg6Yb64%BWtMVamcATnf@|nzYdv(0)+@dsA_c~9 zSSoyiPJbU5XElYRKt5L`OMkAcd{qk)lmRi)PJzN&r=~X?lb=?XFI?-7p1IZ(X-7)d zYnOe3OG8cV>8mykX6Rc1Hf2D9hsCcB6zsPRs}F&^O6Um?o(Vs%2>GqqHy|ZTxgm9a> zEa}`PpO51PQ72-`U5}#tmz3>84zLWGy^M=Ktr!C+e(pAbRJV;Iy?GvB{uR*nGX-9Wc0jL}d?VW@CNqUSw`TNXG`gE(ME`-#8hWn}~E z;gns_;Aph%e@&M*pKR>(V&zTT%uAaLdBe+#n%obxxXNGXC7wEa$<4QkFV#lHRobwuF_OM}@+GXj- zPcU7)H*0;8K+duQ!!QcQQW0$Fnw$0tPB?p&O>*Xqm0cKO`l6%X$zil(PivgJre1G{ z{K3zh?!?Aja!Jxz3tgCwHbt(E#5V0id@R^KWP_gaL;z(T@b=U%Vd*C8q3fb67SN#S zgUiS@i2X$^2I;>%7UNNH-VQwPvyy z6y=3B55%6uHX;_-e25BplJb)sdfFv!*|u|TSVXS>#O~yRuH3EH68j0*2=CkKXT+Ep zIMl~|W8t0j1B0Ww4TfM5sbG=1P+1KYP1p%U5VGg!$a3mL(X2?wU;wF5&3QD2_|6k9 zgEVp?*0KOvl-vbD30_YQq{Ylk!(1AEl>cPFR9tr7W_h!9yM-%#_gh)zTGghOdgwnq zd^|2sZtScf10#9}r)-K7dlCveM{Dsv%#2VJp4%{4jePD05>GuGLZywhZA=k$+3Y#4 zK~oz^>^cGs#Zoq;X0ahs}SjEJgNDpmm|9<}l>xVtLg2Owu(0K9|7QOhWu zI5jZTpPU0?-HH6M{}|ecye%yX#m|=f_8;6{TK}HpzHLAR)cCeKZ?Qt1hWw9T7n($T z$Pv+h!Jh|U(WZ}HiK90#+Ha-VfJVrvT|nkt8r#uyjue?H`Ud0u%vLwA%gngAewLZz ziJiF^C#TD_(~65O2l!yZoUMS2KHpDL-I*&y(CV0gr9~o-6F3IfE&w z7stM_hDD+ib>ndx=?h(KE6oj_xv08p9iDOL+iu~(L19GP!<_B%i=e$RX@~b|gxS^d zv*^pc0I}x>)~A@INmE0^mNqbTB#VoHlmT9-V@UeA%~+XDKJAJuNz*`rBCp#285r}1%K@~nt*S} zf{}yeJh9l{hLLY@3%Q4zLQn_hDtTb-p7(chLx9O59mj}WLO4knqOCy4yyvt(U0pdp znnyimdwX7f?tJ!(#b{VMJ!N-7UWk(DBG2;cYCbD|v_Dh>H#BbFq$jHl+YAL=<09{# z%TIb2ceP_=HH0;lf2HG*KZfyzR3c?8qSxcEIvX6A-v<#4G?5}l)Ltz;@xjr_2(IB{ z-c=24st4p$D6lTnccR_aX5R;ZxoJQ$IK-KZ)cG z{YX$P#L)LX=6JO|pCRo%o`nta0~V^Gn7c)pus?r%PS%8DZDcSk^c0*_4q^eELu0g& z{@F4-9(rqbK6SuEMh)m@UYX0sEYZQY^L#z34;$^!itP1Tf&X}n z<(lqLTk1aS^teEKI$fK~Kv)WPeM|TZQ@3c^Iy=dcG;aPu9M-?kTYrec5RID-TkM6_ zyrq;WSy=SOm*0*o8At&iXO9)kH?}p>B8t6N=O;W0Wfd6#4u(G1a<7*g5-m-!Zb`If z5NLS}Ki4M)b_Qg4S)@AASUt-vtF~XZp*}1wP_9rhdkQIF#9TS4F&S>q+1pB^qlJ4` zYnGXk4;=FE)tr6Voz5GTSZ=<0KJmK|WaqWFbDCO#Vc6AA3;vwcTLTRBBi!kgSp$ZWgA%%NRpTe@{aouSrBoQ zyx$x&2h!~=b#i){DZ;{4Cwlz(b2Ae;XI>4hZ@;_E1*2ts;|DbpvkYV#{Q@1bz$jK7 z#X*nk8tj=K%!@;Z++?2nCCq{71``s>wI@PmMbfj`1hHDDjQZTsjhcz;we5HC)crNx zdN=p375PW0Kdtl?g&ace|F{T97fm$ss1JYe}6zALlZ{( zwScDf^`I78u0&8RMr8As`CeGgCvJ&O?}pjh*Nd{NZr4i`>4I0?_o@7Bp_Z%)XTib> zveg>ZgLcc_c|c&Nl=$&`;ea~Z1?>earV+57m(54Z*7NKLOLSW5zg0Oe_IG^VzW;V{ z-l&F{c%V=DB6qT6r0E|%!(<0W{&e)VwoIX%VqR?g zf9|F;zY5UQ#%$T&l&Z!kzg;OvDi1{6SbJNvB@yO}Lu;1wS%R~no8d3K%I-iRi;31G~Vnn@m)M9#cT#Dtq z87v>6{K{dFS*@xZmRxg*T}828ORliOYeJ4xY`=}hRN4kWcO-(ESB;z+gYh-JFXk5^0Z7~?u^M2t$b^{H*1av@1G@nQ=Js-9{UuG>!5MUn-p8O=r z8nRrafEm&Db@DbLP(Wg3!=AQ-?que$I=%*~TIUy-ckg1L#y^+>zC*tDnf_FQ{+<}v zkzB&3)+W{9`ArCj6D{=*oQY$&;87-zzTS$HNw!mtCT6@NJyj?^n(egi0nNT5nvujI z#ol1?Jx4d~>e~Bab}ifkqtd3z-DnL8%gaz_91kzvOwF)^Wc1VKf`vab>L2VUBDI@- z2;mQ#ldB$4XIUYhc(P|%Y89@l2}KY5l}kg)F!+33^#>jVLytt$<+ps+)8k_sIT7Xt zwUQ`v7p9e?j?B0@>whTEvm?iI%A@ylDdEZSZYh|O`VvCKf)Qi`dj+wF7LiloO6O%} zz!p&&4W$F+Ak7+F+1#CRoTRj%y(37-8uw=vNV+31FNe2FRjVRi2!FWL?VDupFrKmT zStHlHrPX!mkFjT>xuI_a!4+O_T797#jF|MT33qUwrEAAoE$?5v3q(UG=?%a~XS2}- zzZ-%)xtmI$)8b_yzv7(S(X52xs4hU@DBQxH%(Lg021S{9$g&%Rac)~$TMuX$)K~_L zTU!n2J>1UkvKz)rkt6D((lGt*buko1Xzo`3~r;$E6c<~QAYPNPFK`?rv|HAXLM z9hL;O-Dx!erNU-LjfVs5Y(G5jguY)}?P%HH1F5a(NIweGuga>wx>27atxr(uVo6GJ zP1v0rZx7T?Ug}`Uq6HQ04K`$&(TQFfKQj|IX9XvN`gNnQ(BMLX6lpyj?x=&0ha7?6 zb}@PU&URAgB*w^pGqPZuu4uhWaUS1U23X46^BgswQx)`VK|tLw3%l< zb54^1%wy+OmIv`X0sE5^!c(eu(mxF|AVh2ZYO6YEVx?@+2HC>4o<(=Sdu0SjC1P)r!@U0 zb*8;84o@NaaOgG5?9k|Gc1x%)Iwtl{79QJVQmos70+>WoVn?F(^x;;{sRA`FTs}Mv zSi3r3t80la)Nq7>e!p?L#UXiVNtq(r3a;@*axY8RFB^lk${dX)whHD>qq0Qm`?H4R zDmSN@8Xo%kGw%7aR-?14{Oa@Mq*ENz}vBFvd2Xeco@tL~*1>apd*PXhv&)pc$>Me!qfa`My zyJ$<+F~Z;}W#281)kh57#}vUnm}jyWu2=?w?)q#nqyLiXmL`bRQ8nQ_=1TI>!&`)eLfh^WpgV74zB3)u8;v_UiP3 zVb})nGe>r{JNTPeXZ!C7)!jzLU-!AU9v;0p>~YV&A}aYQ;!GY zJp5OueiF@8%CAu^r%W>|kFKMW1Ve7@TIqY-YT?P`J=W+^s5bO9#&A3Gdm+Qgm*e&*&|P53u$up6UztKZb19 z%XqVLP6?NKH^zoU8lhOG9xkl1{`C`oUAa9=K(qW0D3Dbm#aNpf=tB6lfuD0Q?Q!U` z-fziTh%xBp7|L7UY^{Ckz&7*aWF4kvjBggp5TS;59M9&Kh^^$&u%|k5hOt6H3$O;R zUM5!9`Ln6aGi)NCB8tch&nx^I3nIS2;Ws+@JS~9`w8OP3IIWBeYM4Pe&y7eNRMFSb%*|&jD6nL%R?eOUgJQpQV<L=SBWpv5jbvMT@sSu(TQYmv584SG{LpN`@+PcveL`q zU5m6UsRH&I4r9xwOiyZEcmyK{A#XQd1*CTzIu49?Q9>Gyt+Fj@ZvZj`yt zL<&^)(ZB+ecYfmH3}3e`zj85@XB+B2Cs20`*tus)o@2X53mHRN1>Bqv-;LzXwy!Nl zNNE@B9H(LO0lSd?W=}7xNk{%xXWCgvp_VN(KD6k(@Dr83+d4GRMrankX^r~ zGB%Ql3HP>0j~EnjHMG#VatL8~-N&?gWIk%rbF1F6Ez$%i6S?AK`vK-JQ!YResD}TE zKI92Xmu{R&i;ymg}d0bT~=Aa}kLF=aI@FP0-qyXh!de54VyuDj=3~z{z z?i5vZiap;K?9=2cF!t=D>`Y#ANnSrQvNdd^kHR+YQ|eMfWwT)B@VG_!Z%hAX@Rz8j zbd-G@yZb~{&k?Rf9X@M#sCb8u9jqB@awxtQ)M5G`+avD>nB){!-uLVEb&``(*tXoy z4G!7vlaRn_AKYRn)`wCfu&|$`?<`86&J9DlsypASihi$04bPo_@T}}e4fB(>eY3hP zdj_mSY5RNGCM*jI$NXw+%J_dxt4%=nJOnUp#|QUrxS zR44jQ)Q?h(2=!+OcUYg6gzV>f%sOOKJFMAtC&^7WOf9ohg`?+<(mId=YvZo<-Of)6 zZ(RTK2in8ra{b9$#IDc_)jQAA_c;b8A9&+CgFwGw@7*yJEp6G?y=*CjdvpT53@OYx zJr{uP?SuQ#YTKcRc?WJMc>Gyw@%dmw0RObk!@vEw<2EI-cf4^zb7+ryJkqr7cb){p z$%@*g_<=?ImXYDBgg-rck?)@9PL@SmE!t1q;_+640txK@7`!B>h~A-AlfJzKpC@!? zMCg4aUq^cFQ5pI8(6aT;{mhuDFCuAIby>M+SDj9l2bw=_^)!rDbvd7{Rqyd^4H{TP zVB>|s7}u6z$ta2m8DfIzAJ~wSWHsP{70^x?k5G;><;@(HXihxAcTRY7{ZPaFwOk#+ zEX&k1Vsnf&VFK+2*tc7+mExT#B`}9?I=Etis9eb>^4`F5L)_n97Yy05t#KZ|YmqoS zJL0GSl6^v=`2_9&mH+#XtJD#C1cGzot%^aH+c{Oa#^Bg@t;s^H%B^79Se9aIhl|s) z**vn54NYmmv3n;HiSWA8sU)s5pWn=hxvtmpQ(n*!&~t?X8g0gxXr*@+>q_) zhCExHjt$syI;KN$$h>Q}MR0BP^3$0fe6ogeg}{$((dv`tIjD`kEy4n73<+V7hQSuQ zZIJKzp!rCJpYBJ=51)>;1gGNt zkf*fo+N|`F3)-2&#(wm@eO21Pjj*Ka<(0G-Up*WpWr|f^Hi)Xv+#@tXw2Esm_rk^B z^*16)FGNir5?W_M6jGR!`Ix(9lG?i##p2U0VCpxq&v3PynqI6A;y7Q~nTRGER=#l`3Kyo{y{Ph`)n4|j@gYAE z2!kPiM^k>K1AqS)cY{I+#LE7?>xDPkq8pTB@LYDvrAc~atrPz!EVsaIJ49d;AW+sP z4GYu`GR6ArfNo}dA7!5cY6j^JTw|4;tU@bY7TmwzqOmRBe;Wq2_5l*aD zMRvb~fy@zE=57{J8=k=nv-YbLRy|wC4z#o_#+X(BQiT2CzleGxWEFJ|38DFhonfXz zC`b?Sa33Jmsd{#)3iNC;!T6v~# z?2Z@gJ+q?<<;!}{Bx{G*g}yM$%d<%(rg0}G#=|A)`v_Pbw4W^^(aNT^X9oGxrAsY> zNNvQI{C_??xJ>Z8l~=y6Vh5-d@XKjN*EQA{pOT&ll)s(smqJhq=4XpRG$00(ehO(< zo^Z;wJbNorU>yRe{5>1=)m+HUvQbbtjgYY}v zMStpgC3QfYf9>VgiYe08{+?Q{JE(8=*+t=y46Ef>_a#^4Mtz?x=6_&|$MqxzVjuIU zjb)sIy+Y`U1cN(^PS3$c?Z*?wc}HnewU5L*PW@?(CzG!9Qjb3a)4YmQnJ3Az+NFAw*L{jA8!>{<5KU2NFxgr9wWrG`k`h?gso>E z;WNB{e>wTe0ou+EcZmZdPX4%L;VIq^m8Zo@vzCBDzu$U2#_`A3qL&oYXsxLeZ>`N% zYyRQ5s)Kw#`JK2U_{$a3Q2^_13x}%;?ejOzI}(~t;!aHIwIM7}E@*4wnnL-x6BZ~H zBrtL<(3p2b+W)~R?zdCSTA6d_zssec{ipgwg|FK$1GPnHZrHB=)AV|ru88#=2$vURZm>0g-gwx4UWWRQN5lyI>_krO!Xa+P)B(#;P>7J% zf?zCEiZ3zqmaLx&FjOJ8BcT(vo;cx08z{m(-F#Y@%-p8XGn(^#cMokQZX+4ZZ`vre zV;wB5bnLtli#*murar%)iba?CPA}(48h~qC4ChU%rrO?MP1}Ohy5W&lQ`j4w5sbn3xjnF0|{Y@}i>RgGZ-pKkgRD57zGOP9T~&NFgPL%ZeWTs>fuYI?%!q zZQcN<1xaA30jre~^gS6i>6!Dxt)tGJwAEz9?(x^A25>l5HDFpwqWMh0@6qhRaDJJH_)qrrMeDxr-uk{({E2`ZSa#w>!e3FsG3y|!P^{72}gW|u!44<%p7?C|+ zw-Fre=w*)SkIM6Obd?RTt-?nSj?48v_f^QsD%hhP+7_!bN?g^3X2 z{YDN036J<0=S9HGuV2)dH*Fz()te5>wxS{x_Tcv|sYRayv zf{u7rV^OwAj)m-^&Tba|V*z2&aDpgnTl#)VM&@?`qDJBzxRL?z%5p3!MXK7+%16#S z6~o(&*cBTthUlz%F|v%Dee9We3)G(DBxKgcS)&pq2#>XRq8}P0LTYNos+pXe9Yh&t zHe4|zMPrhhL;}`gp~EQJX@;y>FpDi$K34K))k_f3o7k`~=GQb%!2A1_~7S5DXYn z@5obLZ|$^_?#MTqKm7&mh8ais2^1Oe!TZ}l?djF`=GhBa>T{(I^ zq-Lo`7%gkMXnW)tMov#un9~4X=X5783{x1o?ykHGG zQK^idL&cS+jK9gkI)BS}o1?ygTJ$X#Kcp+`23ToYJ)gnOXC}*4gn|Ddl&c2$c>N_= zl$nVq&ax{(jEm)%`6YHVQmpKF*Z1&ak}aS$)@)#5gv)HYix|>cA#4!rC zVly_cbTgJ3vJ%~TKi51~XG};WrrOc$ZUOS$?bs6%q&9$7pTBP896N-3(ev5yM$u?`fN*TiDGgkd~) zmcb2DZs_CHpPHJzcdEZH>*X3)_U79drv6QSxR?3dMz*r}DE)(p?+m{?_kBdYsCRl4 zy_2cElvHvzHIK?s-Vw+8OpOGqhTDHZt$w1e?#|hns`($PGP(p7gVrJ@?S$O@$@*R& zF^pfOZn!9w*A*q%)+?cqtZZ4QY1fE@S1h?#?~uOb8rffLLcHc340Xj;P_jrw{Ue#b zY*vi)qneZx8cjBa2~!>%WpI#cp2nuyN^3ohW>|cer|980;LVY41!IoB5ri@ zB(FLUKt?f~5cY~Oy%*sWd5w>F$1CEDOmRgu|19#&#g(5Gf(45DVwm2!zOOC&bAInU zF~3uxeHsRTwZidHU|kM#xxuDPl^j1HFu#K@I4(cT)0+EbBy!ezQ`xBQ=m%>h-7|6< z2HHAI3|+q}37(n9s>4@JhpxnCVn&6b^$7Y-l0bTmN@)19nvf8J19wuRU@?9VS{W%b z;rQ<}z*o++lPFF=MB|i_QP(33=y&z8hy+ivM_J`OG}fW2qfBJ?c1z9JxMfie#AiVi-)JbTr#R!Gi4sOH-Fiv(>toBIS7i3pdhK3=f>b z4p@|#LF9Ionrt0Z8k|A8#ya1)O&>?pGP;7$C>#J*_YoL9!%)9d_7f;o{MjbxH;1J- zw2a$-A=k6HIGX2C^p2noval_TPImB|)lSqIG~dv|Lt zl2ggj&5Rw#bv_nNF%Y^mYj}~5zux(;^q*~0uopZZLE3V+q?`ji9bDntD?}<+7=HuN z2G+BPgMOIRxYDPzPu-HCR_KUc_>#b2W5?%Trw`9mf`Hv({=%NHsu7fx7g4EKns@7; zYvNI!tgG^)Zwo1IB<2Nz=Cch$1m*!bMsCvECBy#XHpok6%~Y!kk>eM)Q)3&rKO7Gq3H9{uWQ(t9u;z1&Y5 zPMz;jmSJBy|3%dp|Kop#>;w)m`sJM!GxswR+;vn>UQOQf*q=$L-!c0SKA=Za$d}Yk z?iwp^LRPn9O8!rD{=FJ7@rT@3k*h-R`ir^f+CPO{K4AWg9pQfO?6Zy%ldO5gVkZra zL-J+UZ&;s^kzilef%xG$%p8;HneV{9cx)@>MEX5*4OKH{V^El?G?U+CHMo0Qc!!sw$CKUDu_w~W@9mYIPm`4+1$t8^|5YA9sq8#+gV}G{~+4C?t~Y zJS^{vqZfHIe2wo_qi$|SrcB+tY|;DtwAy?4@WaR%{Z~j3UP&*Jz4{}=nQ3{9(Q^k% zB)aZ**E_9lc1Es^4UUwl;r}u-)TQLKL=NlN4zeZ3*x;lUWkr6`VUEt2SUhT-Whluw z(Lon(r~1m3(ud>a%7t+_(4~q6B~Gd~>e*rcR#FkkBZfR3Hls_$>u7-?Nb|VX*EC`Z z9Kdp|Nk$|`_rI&nvEX<5vQeChP4xfy_6YP}WLft~o%a_S;0X1OdW3t()R8u>SX`*l zROwk&e-6KWC!F|IudH+@CCB%`PKn?>uEu@5t#}q(1EVdVG<0y9UP)t4tZ1)6{ZO2j zuUgepkm3^Xr~qdxSJ8zttbsbvr^7Y5dv4xIZZAj0n-5jN$$TgzZf6vOuv;cYzSaWfZb_g?A+IX}dnRUKXmLB4V{F0vYwlZ!8ll5h^%@}|`a z9HOji@c)KRs~uaCq(=saTKwf84CKVYalmHU4ICF%B-7?1TpaS6RA`Gnce-6fz4>Vc zp9{=V54D01XTi6ksotFq9C1-Nz3uYR4nASvK@cZlfcSH{Yb8XD8;&2s-`^L&#t!Oz zN$S|~zW`-Gn!nO^hAZpiH`fb|HmxvePD(Kqd}ng@tlHo?@u+Vpo1E$QxO0>7%xoYP zI5b%~Fq?c4@5B?4id&TTf_`_!mx3)Lo_k|Jo3*)qro`=5)E&oLUyx*27c^>{x>^0q zCR%aCp1c*7%MkI_9Kg1tGBc=91jBGAA6?LdsgkfAA zdsw5E*9_02x9V0`Qkz4*$iczE{S%SM#NG;4DT~XK^E>pvGrGDq?-gtVf-gKtPmMw6 zq_=I|v4yPjI9cad*0uMPZ78fGrGM#K=9>By?;P=yxsPYOUs?s-OsnWw&0MFXU+5}G zP)#G%eo+T-;AL;?Afw4d0$ABs#kNOhxA4fflEuqCGP0aWZw|tGxbot{S&8q>PKCyU zcm$U&blPW!&W5Qrb_Vcj9IuMHe*cAT_wx%62i)$$M104Y)UL+$$R3B;epcJsOdDMJ zl9tl7DAt6d$GS=V;Ei=Gby9&bW>3Q$g^j`AnhRO}^lO(VYO>vo4~WrDqAznW=lnox zuo0!R!Hcv(TWxTDDz`eV-`1h*4Ucm)$jEj=I|ixp#cQibDA%EiH#$xC5b`JQmrD}b z%gNFJDM>h0bw{mR<${E0fBh@FqA_%)^g;Llas&Mc_@Jn%CLNHz#`0OX+^D&!rkaM; zRAc3{B)D3M+~&$7^kY`#pv(T8Tp4SB&o?7bAunko)_3caJG_t2LF+ozK9milgI6L{~ z!81=ypb5#ft_Z1(B3S(PSFhsbQrGaRKY<=s)bQ$ue#QA;fZp8EBt2hKm`QWlD|%dD zlwLMOYbBeIRmo`*hb!oLeV4tbFk<#73t&Cm8!3#&%^{#J%cLJX1rdR7gCM^J(&s4m&L(SY!)g30uwX-vmGL64 z)?*hlmsh&8t?9gfls{DDUZ?*OD@>vPC zJNORtna1zLzw;UDAJKCy@rT;rkErmY41Y|8A7l7)D*R@KKcT|!W%yGn{6U8QsSQ0R z8SW?jl<`wtt)KHk<2k&CXV+_b70*AVz)gzlwfG!a!p%y0@Hw)CTb1-MI%9-y#0$pm zv9o*Zs%JHDL50sT+|{OSkE-o^S=&#^ZA)iiePq8`;l9w;lexh#?Z-fWo5QgUyR?2L zYjbcD-EijECKMOO?PrB?)tgXy!WLw&P0Fmj!nU-X-?!~PHJkEUZ8jQ))gSD9rA@2a zAv{dCu!Og9X+7P}vERu!-`=!7;?fx0-ZZZE^>g)4_#2C78Vm`8aATwX`*~E;~F4&`$ z(8#1KQFI4)X1z({qNN-euH5Cx2F+e)>YS=~1Z6#&{H8!C>hPtjr|-Ab#Du3Xl?Ya| zaZ7TW7#c`9=Qjn*`J}CMFrGLxIB{h;XU069!~QJ(eW1!cu%q76RIA(2((da}MY`G~ z&y9^#ZO6>NhYO#;?_z6&7-{6ddy<2$QASHSP*Zc>{{e%~RkrGx7k;Q=!9ef1sRd~a#dKQcW%jeb?>6#7p8h_*LF?2z}t4r!`s zPi1IXAJ8kchh2Xr&QG{xVg=1=^0ZNI;`O6w2-!mm%U7*trsuLtfqeS#bYZFLOK*MM zgm1+6^ZHo-{OiwJNz`Vu!F;CT>7Pwy&p7LXAzn-0WrgjA4xq8r$OM(F2E!}7gRB?+ zPBX%K^Rn+$_UqtiGWs?(MfH^&FIF1f-FPEX#ol-w+2P>cQ5amoHLz!Fa9dHB8_I4E zW)kO(W|szoi^IXej4Lv>QrLN!c#S`2_NP7GeAqH(31(dRYQ$F-vyS9&eA8x|R_{qx zL#gS!t0odZWSr!az8!?Ht?@=fX;)`xS%1aI@?FiUw>99mz!{}@CTy4XNl{Ezdi>OdOBJs&n)6=|0{qQ#F9i1A5dp(Y;(9?G~@=Mw|rj2&H2|AX0EiRQKsh2xW}x%5meYx#Sl$JS$yRYQ}TZB{QT&3(Ja z=Ira95APPVbZY3&@3iC+om_T-i?d(hGV_SGF3{WM6*)Fyd3*O zI^#!HNq;sc)>3tfCcMRneReXolI&W2$Tb;>%~nDvcBqh9sQAQ9OX>37$!KQtS>>VK z!HO+f3Qo?%^9RmEzY{#(@e7t>Sy%t&{@j+TKelwm(wXmBjmLd-eb18fskbZN11If& zTFXN{i}}J8x$qm{aP42CMlU|Bbr+Xv^&8R8#Pnq6mn=-RhW&6Vb_x$dI}sg9e* z{!GGCH|)9@SEa%=JN>}c^5n(nIlB@f@Z2o zNpAQ+3!5g5SIaal-5h_z?#=Uyf$BmkKl<<6C&#Lj?%c>P?6?T5`CnX zoW9KoI#g~US9B%Sy>rgjAFezF4eYF^U6B+lQ-Y^ z(U0DE^Cx-hrB{yZ-Q@Ld+BPT@0#T}`>kIhqECRQHs}l3eogwMtMSSq ztU81?s-xeb-L-lDN3VOw^jvA--PeEOOuBE9bO*HaAV=lr9Uwn96ZtvYBtN_4avE7y z9Q@SN z1Ri}J*MUC)CvB+kM~SQt!Wa#3cz-3pD9m#0qO3N!vXz@!Y?9(qx;Tl(v!?EGyYIoI z&zDH}e90fdmn8oA*985N7z-zp;ZQ0SYWl=;=n?4O8~9I?_nu|jz8$p@69&WqVLF^0 z7cc2GqFzA)>fpEY-2>UQ-=D@m{P@9x^)G!vOeVz$ZjH7#kKTY@B<*=yolxP&Yq4q* z#G18Kvo%sz&<^$E_Z>Wl_IxptOh!c7my4k^hoj^tn@ zR7xi@rJ#ZVJonc1Ve~BYA6o*cjc+VGj*tC;PE2DIXbhad>4>l{9Y$?)=AJgL;?DV$ z#sN%YA#`BV%DF&c#HKwzLn+ME3597_s_MrSuFMnqilGJzq3M(8OmvvP3&sbp9UeRM zaSfh$$%Mqe@R#te0e<3=OCBO?;9YR-ulT$87<%@D9ISw6ub{g7-_b$zHj?XvpMjr* zpMi`>-{2_rgrT?Pan4a7o(jfGi_`r3J=@A1iJ+Jo8{G0n$?o_KJnNbb&$4dFY5I*i zeMz0Jgli|mb6((&1Fg>!TA#my%GC1#{|muiAovRs{+smxx`uljuSYL%-0APpYXSQU zU~%-q`Ue5Sf4c(z4a*#^jNXlYh!b0SVAsddj;rGz`&j(c=f&H$-xikY>Xy-8(GP*nmk6CNNpzmYl|dh1 z{3O9oO86>D^BQyk*eM^`_&a`2Eca`^69q{fljHdH3V5v3wA}i3bWeRA1?Ool^{@Hq zHrLts!s#{Xy4UnPphJ2d(EK+lUy&YNg^mKBu^hD$+CIWvfxd@62D=^18ywtDc+;eV zP{vB>~w;r6CqyCe%_3h|) z{0T7GaGM=cn>zX~PJwuF1wH!ukvG5jNcP-AhtAC&U4HbYn;u3%MCT=341a`W$@!!|O-T%lr@FPJwHb#c$#!j=2jx zjBNk$AN6PX9~Mq)3xxi|aPJ%0y%^Dvd$o-o0(e!|= zni&lCbUAXf`H^z0-_zX@FPGyT-Jbqfc_crZb67q7xtz=7aTv=+hsRVnP>z@Uy@hVO z=uDrH?=N*}yGs3~m7G(wcNcp7C8_^^V0|EwgM@Ool(|o1L=&VBJ@6T)?-Y_rmtVVz zJCsHh$p9z&DZ3O4D!rcL!?AvEcSo#Tj&*c<`(ve%{7lZ#C3gz?=g7_EM~+}xb1Nl@ z*8CZ1nbvsuK!NqlmCN;eNZ;rfo{3KKKZ3dHY#H5o0*73p(w&>p{N~#<=iy!={dxyl z=AXxzZZPNYJR!0cwpd8Nc{Bg~DJRFZdA9Psm^?n)EFtkQem4K3Qy&LirFga;*5WZT zr!=JYk)E|8m_;*g3Aa_REY%BWjkLGIUCL|u46G-dBW}#&yN%L&_Ym{N$?sI_mi%!& zVC;+`5Q4RmKqO~e|GwA#L*Ey>3SD39`-j)1-t?vqe10}p`}VhMx!KSAKl2&dx2xBW zqTlfM0SB_2vc{e4>BDbnL2HeA>bO-NAF1mr0vIthd)z7_;|(|HW_9=<^o(v!ciV07 z&*^(r&$n~C;rSg>j22y&^c6Kou0gXVzZ;5HY{&jZtyJY1Q-b@clj=g?4ND(+nK0-H zAzov|2;?8JroZ|Iold4o`f{`W>tEMX>ex48SDdl_FX%M?Rj{JwxNRJ*RFxo9;x`Oh z$-FNDBER=>n#+@KK|pEcouIU}8-~BqmlzLAMgOB%f)Q5|iHWB5WJ&5zN2{8%T2jpz zF}K|nK`}YH5DY|c?GF~+BdKIIHM)5;RZ1Am*4RL- zxa|KIV=NrbgnX91WFV9ddC^5Schv2PfH^agD-1jO;%OP@>^AyiF9xqRW-RT)_2-HClg7oo?0YEu(_+ z9f}=F6EVm8lM9Cj2M;eK<v3TcnO3ctR0 zxwja#+oMHq|HP4aDjkbI`l?()FB!dAf2cpycg5$UsYvh^`>U`9cyJjSLr?PeOYfH* z6dCfldED!4|nf(0=yDwu&X z@tKkjzwKpiW=J66n}DJA0nlY_d$z`UZbPm+;g4?a*Hjx6I+A_T$*$1!E;! zA=D8jXP7%AS&T>6O-^2@glzadO;UCSu8xmN0aO}8o;q`wzy0#<+b^&G___;@AHU!_#8s>K^<UEW4vG3thYxqs4^m_qki{$AsGS)C7_$XPbnOG%v4C0DE3W-Sa-z!oi zjl50+QU;Z^Mc1whRfUi>>Jr>mA?Jt=6ud>V-z1s^r`?wG1x?=M2b=qh&UOh=v)yj7 znG8-tT#WaFeC)9ZCX=;GFvdhn&}~AKN|w<5c>nrke3*YL$es~csmF0tCdf(5i@c=W zj^o5($r2qRS{&;Vyu-;$@1T}tRa8-84Gb#9{8YXdRi4H=8Zu!-e7LCBI_Bb@yl8vx zJIs;6cy`BFG%~u&4&Qp_nKz!<9~s|WIw~f{-)^kYzCI6q{Uqrti{#B?5tLWx z0%DcdvfAswOVD1OF_cy({ z)6g7RW@wQyydib+IIbE&_8Zhr(vh{)AzOHBG)bL=TCCApOMx{SdWNLrbz%*{$|gT0 zJ^8VVKV?8a1Hz{@3!tb;Hog`)}yG1&q#H`fk{tI{$pM_m;t2=Chwk zx640bf{!KU+4F{Wme2Jr|&Y&9_9m{s=x^$(Xfm9_pTJ#5M zTk{<~9i9PiYTg}p4F)5Dp_~`Qd|Kbr;Tmv-%0k8#wVjXpW08ynb)am_AM3OA_~PYA zWGF45TRT2th&Tq#fvz9)cq4_7IGC`bYxUQ4haClz90&GU^i^~>e-h@^0I=yEf~}!@ z&{_ObfDJP2Yk+-`TnDQ~!oCXk-cGO~cHLLux^IzthZWdY(U%D}!my)&-AV2pW!T+t z?;Yg2F^1hm?#0)QGwe==O)%_P^g8q|%@kmh4ErTuuOrwL!|LcL+Q*v!n`YQcXd0bE zuo;GZc6|%Fo4b|rWqmj0%ld9~7WZDt7YX|sU|%HH0beBSt8nk_1RG-4eHE_z7P)s= zfo(xwCfEqWjskWkxp$Odcf-ARkn6@6b{Dz#R>~I%yOUuP410FnfZoMDO!*>VzXa@c z1e;=5eSI6+xBfNC7YTc*{s=mUU^5hhHS^i^m(bm4g!s!7+=hctDn=|!CHK%I35Dk` zUS!AH4wM<$x^)Eq1ar9{{PgVEwsmD?>$W|`!QtUbWq5dy_jS&Ok zcK6nu0iP{qj0;1N>Zmo8alQA2$k5i1Cn#7$Zn09d#p6jwh03z80?%%Twj+)6$HwUa zHM>kipmdR7drU zmc%L7vc=_am117OCRj}|n=6y3**ar^Y{Ba$WBXMg_FKSb9qhdZxE8O->0|1ZX9i-Q zWFS(dfzK6dq6rE3Oc5+3T&;DhR+Fv%v^e+=x6Tz`Kd@tBA-%8=xc}P?-h3I_^fk^A zl_iDoCZmtEXk)Ktax>mo@G+=VUKVdRnu`S2uo`Oku;UMyvwmMR60rG90rR)t-|Y+* zM`x?4VGnS|@A3J147N{HXM0M8!Y0BJ=;l$N?@lt`V~x|H<`??X(X+ET)JST!z-1yU zfZHXX*|7*3seUw@Tg*o;paHMn8?cGCj?AS-zb#$XShJo|*&Il_hPJNG_%qg+&n5W# ztg-OV4822xW=kbykNNtR=XRZ8F%sV14gcH$yfp#sEmmqLQ~0{RMraJS(((D`X};GP zaen#F!GyD$pNLNkZ3FB%K6(WXHSAt_>C?x!^3Gz&?6zKN&k6L`$6x{TWs z@E8NOR8ecqx=W?;5*~D4*7{4qXR^d1{;wN)1_%3K%rnDy#I4xgeRlny(7Vw4C4aU? zI(w-p9O60jY^|8fCKB0PvG$oQmli|W!$U)dv%&sL;r?I3{jX#9r@Zu57GyOikH&$Twnhy+6R`Z0aow^2|{Oq`h2wRw%OeHC+={&9d@^yKIf(N>(M#z z95a{ZHk34Mk>hHhd51u!`kd({pUCUXKCjj7EoHYE;yz@z+g;H}cG@i2KjUEkTqoH- zi<14b2=>oalKrzN**}Y5|6C{8KZ}xGGYq&*b;llixoGzyFy0elA%r()FAR1R{QS zh$Tpo7E#;plWDNd~1ss&mmS#TrSGWQ8OFvxqBYa@xznvJ7C_iaG; z{bVi%VXjeMfSr-(V;()Xl5b!{DXaJ8_!`yGw|UZo{^@zm6WWoyGi4K;L!vmGb^j@y z5NjQjh@CUGp8i^IPts@u&P`?u1)8tshu+uarRA z$Fc|&sa&#k@RT`hOGV!Cj+B?Y`a|61=waZ6 ziJRb-xO18!7+Cz<7-0%7Zah!E)tGjhl%nJCg6-mJ(t@Q_7T~jp9fE7rrIJwSIpWbI z@4nENrNcUfHW#2ntgs|Z)*-|eOii&t_zBJ;kBUPk!C*I6E4?2^Q8TK8ePE< zuzHeSlfh^UN0QEDz>+-~3kDO3U@%7Y&s{Kf50JUPiNk5Xit%fl!%_KQV)DVp3XNOT zvH;|mWb)a?yT-N7fyiKaJP?6x{Wz@o86h+=`ja1|;x6YSc-`T)-w*Q!$K2qU6HQag zBr2^D9N%%`9D4`vbkfYQmkh*uuel5D4*l?KZC$2>E~T zd((QmbLMmc*%c%~bKi!(p9H@5ki3Y_)_hlIuy)}L)^1h@x|`KP?ZTTWRW2(Kj6GBW zsR;e;asD%NZ@Yf(qFES(`p<5A$M-)vwTfx@A<=EWh7KpV7Go}p+y+-DCzR1XX7PtN z`P>Gfug4Y^s>Nk!;MSnGLs!&w4iBIzon!BWzWxH%W`Ic7Kpt;NaVDr*Bax9XNVYUR zAn%YIn*ow6O&xQcQt4~@Vjw%|EUh>qG^QZvA3OQL6Y-rz9p4l3_V@HgJmKg_z-O-n zO+wEIKbvxRYc7Ae@c2We9Q+8vA@h5x^-pnXWBj4pHBDVAF2RBa3|!? z%J_JtJTW2diLVBGfwqfB3FS9TKDuwGYDJKu!EoqP7pX^p<))eJ;HjZwV+V-=DlP4- zG>jwx<4SYk+3_;4rs|&{217o_OU6Px_w+^RUn3SbwHBf|W-DO5eKoe#+UjiNN0?lVThGCKWzj*RG7m`yKw&`yiZZ8eyU-MWrGhtHm< zI82G&K9|{G>H)~)2nfkRH;uKr9q9cx{x+Cs3vKff8ZWS=BHSi<_2nr44yif?CvE$! zVr2}`S6irr*q@fRcUEq?DV((hOue>(dwzho7Bu_zm2OO>Iy-WmhRq{{rq2LP$N5=k zhsFL&RHe+KV48Ky88T=zak!16i(D8ByFAPR&<#E60PCCbtw&bSr zAtreLfN8h|=FU%nhF+2r)RTXeoQE!DQAjdzSX~K?c+2ESm$8%YGGx+899V8$$c z^9zng6hhveHC3aI-J!Wm0q%ds1CrRToWrHyS`)( z-TcdMBjFdnt^XLso-2i)E5Y4#AM*&=$3%$EReGUJa>8W0tqpy3nt0+>w>U7>#8=$r z7-ok1+irDGW?^KyEv?_huQ=sC4zzwBWWEzr zFy0@+!s8t5)L74ADK(N+QLUAfP6>IRLZ#EkdHyj?Deq3%9YDw2E@!e9oLU;pCgXV> z`e>KABVRH0B>Sv;mg8e-=gMfI(4S{}>#eY)sE&3uRn=jWnd)e>v>(Ie*!@zSBR5Mx zwZq^2tQ4dq(iHl*McuvFPjabD+?KG#Dw9}Sd$U+u%iC=9c}Xi*Wo7*xyvHVVznRb- z;4+P>)zV1{quEPnwn#6ppHgPmARLwQ$|iOG)IQDu+~5tg%$tTW^}{hgGGn zfsVM_RTi>Ygsdf?+yz#WH|szhmF3NW3D3KPgbjDHn!m5FHx(H$J9lr1j-&;v)nEU{ z@RY@To85k^**IJ*4O74GUFc492Y)BCGrL(#t&JTsZH(?w9%;F9%0ZAzizh%agb2Z zDu2FXRoEnoL&C1?zG!q`c9#IlYLl><-D|bR_P*@zk65jde!ujIW#8)h%{<3H%k`5t z3pn!l#RB(m=@W9w6pk4ZPGEPCz@^Dh+t#S!qi;V6fz3rdfNAN?0*Jh?R4!AF_bT+< zToI^PDcM1IqaT<9;e@L+l%Lx%mv`kS;==>yi1FANgTo{F*`2fby$i#&&3^P;uiey{ zjd>$}e`+`vtR+3#n{U!(e1o23e=Lv;`jdm1vF)ALyi1qz(OT3n7&zZI*~oB}Dw!Bs z%aSb1v18eZ z<0YHZ;s7C}BqWrCvV{u;YAD>>?~$^!rH@C_a&Z&FzO+E05D0x;ps%dA1e(&@*7b$Q zeJw4ebfItyv3$=g|DweX(C0*!^=szLIcH|hoH=vm9AhLpKAvgby37~oF@y#~iB;Xc zWGLkcuILF3g!=q}+*pf&(31mtWPAmTrE|*mvX=7o)3Qi3R43oPNb~}}5_W(%e|YJg zC$_U=k%%lx0yW(VOY}?ja4+;px*`*grE0#Tc9O~hdZe9)WMwK=JNM~rwJ~3{ zRyFN{;|LR+&8jK4OP2+S^i#Aaw;aJzoo9Jo`Sv304jWzWX5Y7cBe-dLMrognC5FGr^-_S;zov<+7Do2EyvPPjn3-#mFV( z8&mA=CsEVLhOlmyIr5Q&FrE~>?nAv+tcXrK>ZZac8}U)G7f>Gc_YDs%`$2FbmhD`V z3$*mENn|^QLBe+WLOpKu>-tSAM>f^h_*%uCyQH?kjk%tw5|cR?+m8y?&#oz0l!HG}x>GTTf@Lch^|lSpSKQzHU2SV=_0krJ9C@-Xb@{ zEvABG-mv~x1BSjccGZ~yg>4}7T0!R3!1gmQd|N0DU1X^mp5AvvkqjPgn_?k}YE)@a z!#%D99@~O!0$lvPahByK^l`$YJU=dZkIb_18s}bZ%=0l$gB&rh_AK|?BA%%|DdMT* zAr9dQ(8t-CphQ)3;-6%asXXc>YCBn8vWkBa$w-A-JmEsE(*pa9SYbt*jH2?!-nwXA zL$kF$+OTT!;+^D!%TpJ%`a11ti>H3MocE2_i?|Mp$n3uAjCB`=ZSCEL9XpU@IQMdS z=7MYQbL`wM?ffT8$eFS@%|(MG2dNC6R`m*AsSLLA_!Ww0sD(=a zJLhtf8WzeLvaq#oHutK$3elY<6}bowWZ<`Nlh zGXCUyQjPenyA(Mtbw~|?hE9Vc;?&7&@$}s*$PJf`XP&)c0uB1QtjRlH8bFQFGas5=p8OO1 zM5W~sX&!zO7s3|!C}xPVo7Vd9&6 z66Hd6+udYeA<0&exWuyrqo7iHvPc-6G{5qSd2$pbhNZ~z^_`;|)~>y=b8;Xe4Wq99 zWfvmPIRok2J60sze?tee(jAW2P$xa_ITvVY#W%rU4j3CJ2^Ha$o*)`Fx9TftCt24j z_6U-A+da!Vg)ECH`jog&r^s|5H*jI))2D0h%{$$?%o1h!nm>o8i+hmE-x>78TO7-J zntObEC;N>CPa(GM)IfSD9LxC(H{U#-PNUB?Ivt^8Q(?5J8C}{T6{nJ(;OSf9D^pG0 z#;Mly2ytFFsQqPzu}bnM%6?jfqWx=s< z86j{fYviHHY*a?D_blmK<|`q)JsDjegQnh$i07EDvss6O+(0*jW`JH9*d2c1S^Ib| zO00m7!xOdfzOfkTdFcDe3*Bqbt;Tv&jmW%T%blCPc^tm=^ zAY!;QPh*5`gmuaa>r_Jc?4mKSDgqsqBmpgt)16Rrs9}EHoj6_DXPL80>HQdxn8s>q zgx;f?j1Fua*|a>fad|j2u(4-(*9JdPmO4gKUT^1$M5y0((f0=nHD{b*%xt`9V(h{b zv*u6lFm$wZ`NNS_+m{!%uZlD_+%rn|ZERis9o3UAE8CY^%H^GsdQ7+C{KPVHEPYo`t=k49^R16^_)~_4G*52%cV9nr#+caYp)NF zTCY84_m}FMqTSLNJEZi+i&u|dw6Vu@`Zh7ylJc||=Kn0oY_D<-5MD=h``tomh?NSF zZ>bs?I-uI3$O*28i+YbL(oNj7N2Uo|7KoBkOSDD4(gB%HnD;r-p<%i>CQ&Yo>%I|A znpclYpIUw7w5LzmFttr8{(aqJb)Qx=q&N{IQY#PeM(rY!+4kzHD(RD5of3Nd3GaC=Kkp+K8wl9(?~NUl8p)3wkQ$Z*bQIUz1vBa zQxnbZO!AzP*E^BP6>%huN@D++*KF7YKN}x~pOvUFJ{U8*tq!}te(1D903&;Mu6v@p zC;jyPlX53boYZsjADA7XSqS0fcsIR!$!-@jZ>k{}2gnr5Hy;Y$h2Dl=>%SX(9?S5H z`D62X*od#L{u%Z{gZNs|0s0m$L+gboc`gv|r9I?b=!WlyFpFnFVishDAz`hS38Nxz zpgt61g$EzmTXd;L2thqYVEeshe&Wye82x;UHGG7`<$O#SW0z{G`u#?vSOhKd-D1AN zcl4}S(L-K-S@!$e+R!7#J}dfO@rv^2iSh?mjSda2S~WN{nnJRYx z?0Ztbe~Ira>kn7dA6VjhQh)F`-w#!OPwYU#E-c~>7;^zZyHUc{2_wHNQbW&na#@~2 zT}Bp|PGm+U3r{^&c#6ScF%PQV(Kr#^UpxVwMV#e?GleVAUoh}pjI`<#wyyX^p-$U32v}F1Gi3r-QdUn%O zm}L$ZME*C-5=DvF19efo^v;|_P3rKpw0PjPp8kf{K}yLpL9Ztm^mv2CpRo7fn+3w_ ze@7-X&EhL8%#-*EBo>75L*UC%9K~M~&K5{Sh<%h_mkQnJExZe6{Q$p1Z&L436a5{h zn0P1QpP;|g4AA68vy@T|#Symz|00*7&lZ1*I*Zq#v*$NFZ+L#gJb`#NwDGFihNE@hF}^FhTbNCK(MA1&Bo*-8BTBc>Tbm9@Kl`{DrrFe7~zW2Stw^tPC2s$4%qu=5Ez}{%J+t+xOOgO-g zah_iFbjm3tljA+}#7z?`(}wiQ3B12}#e-K}^`OAz!wR5h3Y3a*K89Fl5?#tVt2!3( z{kO>Xhz7o2GS6yx%bD|$dgCmt-Zl%H%o zor`Pni)glYEoGB>4*?TRp!3lBt||c zci5#5hK=?hjM3vJ(^Q>#>lpgcNzkc{9+S&rX>u-0pXVGuX-oUgpPen8^V1ze(yI8@ zQ^p;>M&poVEC}MlF<~Fxf<6F=niiI8Cr4V8@F$27iywJpN-kdK>B&(@&At`lhJyxf zW@r1;5H)ha(9j*uC>fVjS6r)DazP}MS8O+5@TVhg*s-=W#pPy;p=CpFcv;-zi7#u- zZ-^Q!&2sV^;X<^tyQfMLF+Bd5@9tg&Mk>5h(TY`l+5}&S*5|n!=*ZVlbKNoPlVYB!)hj zk_TKE<0HMLfhNJ`x@1*IK>to3rF&84o6G- z=Fo=J=@&-Fwhy$e%mjmdpUB2H1kk$SP@lK&oHG)w-uSXGIjqBxko@(VH(s|R?@y0+ zrl*#-MqABx^XGT_nZM%Uh3)8Z(GAkl!*w4P_OO9Vm+rJjx!qE3FjU56EdNxUC(%@I ztGBfDCL4UlT9e%p_trPi&n>o^Qw%3e=CAm|m3`eC2W0~;V0_~GUih3(!)Ftd+l7UL zcwFouK`{ijU|QIfICc(`cVb7F{>#F?ao3&!TgV3g@!yY~i@q7^ z8~_?fGOQf_Dz%4=E*fJ_%O9dFd6pyERWOmqe&8{*omr+Us6YjPfCumljGAp_Id1B!#Ko>+#_ZPiv}#&J{}JZw!_rhC z8n6M7%I3=QYLgW*M>dDr-EWUu4qWDHZ*jJbY#SKZHqz#7X?I=rvNs;Edpd^W@!<}S zJrMW4yvpFtk4%+y%kZCEwf*f(}!Pwv!_XmsS%T+fMPeT{=WhVjDH zI0Ad!dSOkOreRT{%2`xR!@v`A)pAY4#LssOIz^YUkYKR(#;- z9J-_!Mj{%^jT?$D6<;)r^LvRsfI}PLV1kVvJ0L3eG`1+7#%w{d!>b4V>BQn=Q}~Mc zTKui~DKghTyYLSBGd==3Lzfoko6D?*DwdVQM4RA}szsNWSLq-JU+J58bXcBNQN0@G zWGgXoEr-P_Z`WNAcBaOi` zQkD^_zRH5j7BWBW##&W=x%hdF;^aV*4d_D)1W>p&fLx6zGl+U(?4;3(;7Rs&-*`NC znjDQ^uxivd5EUyF(Es$C7(r)7S}wREdHs8 zYPz0S^+XpU*3|IAZ*d+sKwYMv>FNv3L`e_+s9P+Pl;!XtI?rn z6Uat!2mlUaDh@`~^Ckj&ws0;CLJN---&QNx-!HyLffe6l{)x>gHS@P+Jx*0MpmNuHiPr5a4WhVom&>0%Lzi^*&qKHo%=lVb-WBcj{cWghFNu- zu(Leyl`nk>nZ88A4Zzb&gbnC5^nJ1-3t6gfhPdl0yYQQ!qaws7a)SG(NAy?MjuS%$ zc9yNJ9`cH;Oa}t#l@aB=sjJQHZtH5|@6WaR{o%0R-+CFjBSB7=l=rkl&V)i)+2N40 zp-@J4Fx%Cg!ZdmaT}S-a)aZ0(^*R)bP8Z3^ZgRiYB%{ylj}E+){?-0F?)Yx{=l$?~ zREXjXZY+yQnMYaV4o8t>K;ry6?dXq12WIUlNd2j z_;jCIpIljSLjQ+&dq|0a3H6XXfzew5 zh526~eLIEeDF5Y5n2{=%>XWqyBzebf7=d@elOaRQjg3U z4fGD|-hM)}YwG&Z=+GBOPI>5#8~QW(>u!Ji(`>x0Uw8xC@uR?F5A{DKW2cRJztqsk zE#$H-Q#H7n*qk=hG@-QZskWiPS?}#iWt(H8o_cTG-#z6lo)sTTxNDuwbZl*3co)4(;}bV%*=aw7?ugV3 zx_*>(it-SqMuir%{q}XY-@dMWXn1(YKz^Y$Xk+o4#cz&Yb?r5K_FQxARg@1fmL5X8 z@IwI9qOL{6I6>?Zo=@6Zd+|eO%)mbU9w_$%{1EKJpT39WGJ1Lw+n@6oxY$Uh6p1Ix z;@HCHw|Si1chDE`FUXx$E}`nFL^SbT3(PmRt<3dO%k|%~9Ua-xiHT9{OUSK>HeBe* z6}Y_m6~Nl1!ZNBS$@Mx9LwbSJZ6wQq2kpuxlML9yiB_2aBMSq?^Km?g&c!cbn)Mz& zzX_iY(9bO9@7?hELHhaivd@2`xcnV`8EwTcEFEW3l>dIFrw_kSWN~%BjZZ;$;Tr(P zZ>zRhf)ip+MxZ`4zIzovr{nzu z5|`*TW`0?kS?`>)ik_>)2zBf2Xo|8cx0>YrQnK9fVRLzmRiru!Q| zZFAXtzSJPR`J1}PeI!2KD$gT8BmDNe@8TPlF@8LVe}V269aYOc_+S4eI(RugUP0y) zzSpR9)Yw=y7$e6zmgRx`vsMvxgj29P&l;i;N3*jIXR$4m!b9Fz${WgBJwcl{74uSD ze}wLWKDAeYO)rR+!0u(BgB?Men2}oHN6Lt{UQ|Mh>TQSU1M|!{a#yeM&xo2?7i)X8%0^@mE`f*1I!N^mu|$=o4Wd?x$9d! zyyI+7PaBXt>+Cyx@cP*t5$tF0eL>+$XdL7Y%HFzIS9LH|SO8u~NZ36ncmR+t}$ z6c%?QIWV?oG1cRY7Dm(Mc!LFdVd_y`flA7`PB$*NeT#_rHsccSL#5^?5#VP;3*{+F zRVYF6y;EQID(^mfDkx-i=}u46J1=vj$&oUrixT6&yk!LSlN-b}--36D^S%>U7V@Rq zc(8NuNZ}|H9b9g2U*4)__Kq)ZU0B^EvbSB70L1|<(iX8Xx0jmy6dM?%&_zRLb5~oY9?X(<~4~YzI3Xu2WQbM9G3Bl+8a$B z{yL@Y1^>A??O+{kdXaD*dBj~g%)IoKOw>+ck zqnF!B%5+{BpRdbtF)U6j2azf==V#k#_51HTd8&_BVV;d{NAS1cu>#0uw1a#tmdZ6- zGWiDNcPKW~&M`bw7a#6Zch}70l@Ub~KKs-y`c#z&TuZ{gBb~+%o!kHZxn=I-e>drOe>yj8RSlkgrOdT4L za@p!F{K}F5gl+`Ia3iC)OfKitdc2>DUNc+vo1QnV@g!VXt{I4IwiBGTdF*eJE+@)E z5t`K6ZX*^4u_v)LjXP%&MdAdN=Xw%nM+d4>&#htIGG?3ai@L53Ja+KHPmxoMx6^h2 zyPvOs7WGZnf85@LnEF1+5@f2DF19%)eIYOm6io8ix`joA+1UK>^htS_9CmyVYwx+n zRZ11S0;t3`1MoK}S}GuSddLyOwQy&tM?oO39_4b_@r^dtjqjnGS}d_(58U)P=Ah`m zAi63a0ABA%9SDi_L3d*vqUu;TED z8b%OJ&OA2bSzGid;kwRt?558P7JG|e%nqHHmqPlaj z5a*e!lTTJ?pTgL*(NLw2lV_hi9J*th?;s8+1naLSqnH>2qgDaHitSQ;{gob0|F2B6 zLr}QbeW8nifc%`;WFA##Y0I2t_cEjcpXD0v{My~Q-7xIY7Sme~dadra_yFTuj+?|b zrLNyse>1`T=7bxOhYeGrPtzI>KgWm4`84Ehv4V(LN%bB54_HD$bqqil9$Lk2E4T)- z%}~3-`HK$N(zcnUZ?Tnbg}>V=^;vy}X;&*zyS^F$OMkmz^V@hfoH zt>#+`&}NljGZ?FnL;jU^J}krSoj-$is1EgTv((}j*1}m+v)h>7=o)#g7 zSF2{~steO7UvZb`ybST$s5o44dZNDlp6NiUG}aItaie%d#QF0s_s4zxpM?xixFqC> zqQ`DE0?ojBc4ZToc)>9YwBH*JKIs0fA%oV%+c-5KcxA#?`Qjygwe2bSaq03H^{>f##cs6 zPy&L-0qwA%dwmlcv`~9aoNNqWCq;npmU;M&0%h}880EjC1`w;`CYU8a438DJa;@w<%_@q@Bu&Q+1AZ5?T$FF6||ZpM$JC zcW)&A@poVj*KfX0BqPA2;r&i}`h2jtOW2H9xh*~M!3`p2{@KC2l;QQq`nhhQi!yb# z4Owxi#fih-eKoZ$1sz`)0=ht&QC@Pxv7?MMbDb!C+^at5YTq%GQ*~ti+4zAHD;q(d z4}{+98FOz+!ouR{&M<(=tTgqvpJU035ZA?-n9JA)7V7E})h&#s<_R%pn`77_z_54|hCE(_^_QGg=D53!t7laLR3Y}$Y-5_7VO zI*ZD~YZLt>V=VC-Bh{puS@xP@q~B-K1CynWt-F#ZSv;|n^QD027%+14zv);syO-(D zSazdP&YF=Ec8L1HS=-RFAh23`Od_=^?VMb(K2jqOsGgxxc9n?xBU9; zeluG5N|?= zeWG751XW^ae4Emdb10xVqeu+)EqNTqktBjdgts>iK>ddD^nlL)7Nv(yb;x zklo8L0r%R?_=eI}s_PRTrJ+=IYu!3Wgn!=^Fey-Lj&}kyBk= zt0rDd80CEVZ9Fq zu3Mi0`zjE2nwoIT-8q}IpfYPTX=cAK_ExVp!?^d@hNlq0A;(s{?E`KYtbNKt80D(D zFs0yPe?+&IGbto(I~EPe-}Jq|#9l8xo#cJ6GF&gMLrzq)Epk9As73+Ok3gdze z_XwKN4I6(swUlxVJyvTkH%hBM(vi{dJq}MZ$CIF_&OPA%-mAb^$1_3z5N;c!7@H`s zs+q?-Dhr0qu?+JivXq&`?1?ma2PGIg%q^O#=bu)?aCLC2yo1e!AmIBT#j@-$V?qUz zmyD)QbPbPl`fkEe~x&5FF8U=>X z9WFsSg#)qhg$_lIV>YTcNMoEkhYo$S1iu~mqzZ?1iBZmG;-$4Qi4t9g`5R2sRLK?? zaG^rcm5PhSi$gC-vvFag5__f1~>$;ICUKfvJ& zJQZv(h}zJvH)hJX@yo-FVKVnb_}L~OiNkXPEI$t);QE7vhz<)KVxo{>di^hkcMqM6 z8C2}hQV{1EDlUcV4R~v0@%c|){c8r4g&WEKYH^R8oU9!cBkQL37HAt3IibSPqd)rR z*sn0c2(Bt~yM&Xbkw8y7dFAaFT^?fDv5_g4x0r@iJtT35-f&*4=jz&&k zp>!{oMIRJDMR1V^pDoA_*MV<=<|TG~mK56#E8A{q>Vcr$La83|jK5^5KoIK5ilK4* z)y^>aI9jbRF3ncJinVknp_V#=4vl@$w~DzK4}|c+>Ug^8p*rqAc&BW& z#~4W=Hl#vh+0c)=%@cn_so1v>j4oKDx5JF9|` zF@nvuG%`(d!T;qd#UjgW?H#Ey#xM?YqGfuly5{;-={<7_2Rm2qgCR++b?QR=BNS>-oW24$2(EhpCi@h(x{eT&80?p*8CSqyGdD4!Z#^N zp@i9bR;B_DcgUePb_$y}hVeL6DD+5Y-fB9?2f_P$>%o{YKE0hTHFnszTW9nz(InMj zTyA8v^$Fbrj?Cg0ym&P%*vfGZeU>OIXgQ8KMmcI^{F~xoB`RiMWotDHrupLxr?VDT z25}U{t|Z(~#M|hDD`j5viytOgo68XX&#-3O zk~8}cM<3gX2QNoV*QRD#e{D*TDT~`_dlHiPppmmTIX%}QiT;^+vR$}W#sA?Wem0Bd z{gDv=9!*th&o<}zb59=(bLofa5(p~luISbH0n{)ed3@)~326rsAFtLFdSl}0{=u8n zgTv{rtIflbF<_E4oSM&oyi4b9D=n9Y5nm%PtZb(6#}QzzNtey@Xi3sTT=`Qs6Z8q|(G= zhqyWDx%jbdT&6j?2Mg!txi~;#b_|VPw6!r?X%-@@m5$4h=w(22FDQn!vI913lf+zR zf|T{!lu!ONXLw?pC7`~pH=G;oBe$`^)<93{~x6V|nUen{<{`T6Nk|d&_ zP8XI#i!ME>r`)|oHf$q3>88p6HCSAfb)#*@g-KJ}JtAGt{9ci=-l||=Znw;AvwFu| zR!BYjYglSNsrL~N8g@HwQ?Ii&ki8smwmyyHo{;{%C12^3zQ3kG+lKXOoCPK^S8qi`(Jy72?iJ**nwjXz9%3X)v2Zt6pcOIge>1wEBzK0F_(MYz87avp6r+BuLR~d5KX<23Z`>pv!*)+ zG9p|1n=iao7)_EHqTFrm4{yBjKihiVd_%dSfyr9c6B!i^8Ng*(^~P5NCHc(nDpI}J zlq5Z}1_RSu3CSge6B^kGrf}O!;^KOF{Y*?;v1zLJqzLaAH%BNrBk2M1-NB;p0UvjYm&Hr@i zh8Y;WC6&N-Lj zivODpAAj8y|ECAv7xdxx!eMN6F8}AXdxCv~VGrd{;bGV)`=>8ymKAfnanm>))^P#K zyHpB!y2hB545tz0pC&>Kk@QL1(8xm5^jGDk#B$VNTC9mz=7)x`f2RV494?C4Z3}DA z?a@mTKZ4e`*=-Hx$zW1+>nB4}YmAuKT)Kn-g#$D{8$K?7bT0=pR$lG7yTntWdZ}Zd0{W}VWY=AEV4h}@|F2Rh-S8X? zsoQAKz0A)qWC2#*R)_5#Hhn=}8&+xa;f+bpUd9`8gMI~+sgbHEe_jiQv!$n2vjgo-mgHxkm_spE%K zlV%E>=DJ%27b1RNKhd!p?>!A!^>UzZ%WqyrZ*}}UkmP-9=S)ttJu}1c{CF96Xg|Kx z3C;&*30!x8$DrPWuOy4qkWn4i8-TE#l#3h&C~ymfUoh7OXJ;M5kcS8|ejZhXEtLHSk@m=eLr|@bB;t z%7zks^`X81q@oBYS>-`FLe~ulJ;9tTIm*A~rXmF4`UgQj>rxhfLn<-KMV$aK@MK*3}Z$LU}Z zxskHsKr7H{D;5U1K>ibE|G&MaR8x{0{1ldv%FiJv3USLn4fV6yO0)GXw$7f#TOIJ& z6IO|q(gFpVV5BC^M$R-oa@W(-m!Fv8hu_r{mxPT@T;58WivB+F-jP|!U>Zq z!fR~x{h_wF|HEGPt8bJ$k;=ldk_&P@V{m&wu{9`9*?(5$%*MF#GL(bH)%{6E#aa5b z39L%#?!66ZNZ;~qi(NcPIF5mm;zxx!ogk!Sq9${)vl7MaF=mC{tQ_jqx*Lrzu_-|U zK#r>|VrXPr5&gv&1@7(`{H#oK0m8}EbOCbvKsPb(&mJ?1M~NKuGJCo^9C#-C1BN~? zMLwbP5!J*#GnuT&Fgb2fXZW%9m?xU4lq@HWOSW0PWP={by&=9zo79Hn0`x7PL`{^X zu4Dib6#tU81;}ed)dE!!sV#2QUzw%mNo?(UP%sbA9jxeIC~8QLVy3da3&*}0@|CRcf6lXl?jWu_L&CZ)1oiE<`cX@Ci-wPEr{V{(8stG z0Y`EyNEHb|yg2MCPt5ea&d+fM4Rn@5ZZn3=GG(%H4L@wLf92knf=>^=7f^sD&%5(t zQ=}8g{{RKo{Cm+EB0-IybW#f)0VT>lP{DJ*l$`0umLQ+FC0ZHKIgI@TWXD84}_0gCsg8nk5S;mb?pl;>tWEYDpi; z&kX5{Xz!e(g{paOk~65W?MlI#${~mm^NZZvK>YC-9r|Zj^t~(GPixi9K7YS7{Y+X%%t@<=SSN#@K3O~>+bzUOEt}~?_G#$pTP$61XS;YnpIOv!H$=ac9Eu+sXyd^k&)to2z_s%D=1R$X9Yy521t`{59mR`hq+H}5)Bt#uZesP;4_jGmk))UY zIu8$I!S&d{(6gX~#26GJu#hSB0Ilzqzjh7R+j7AW7gX#N@MO8@;>6k1WE~OHi3*$f z>vIL)+bA{2FN+VGvk;ULN3^BU=H{*CyNs> z1LvVSUTn1y1Ph{lGjQ21Qfd=9-)HAx`QwyZq?PX^{Ws2thn5H{7RmE51ifL-Iw(J< zix=GK#ojmjyolCTa44z87D0@Rn!bm44PBOzg(!6v!nY4Cf_|jVXX2-+d*ET+LZJjKU7^M*V934eeU>N3U&~72+^=n5tht*TKe6Q>XF*W(^fUBYk@s zsjr*sGOone{&{^YW?|L*iDLrEpaU`m`1dQ@*La{5{*HgRp~AeUdJjJ79&QHb@lRWo zbe>Yi=(+;k4Z7QbCSg;##6LU-(`Q(lfhZ)?yhHYYJ3*he_lsi(i%OZwLpfPYPmz|T zW_+e{4=}8LHHcJF4)K9-mu71bz+DY>yXJH4nB}R#S{=^u{Ix>m65)CwBs|pN zyJ*t|0|)s+=B|IR`;EuA^f``bTf>(PV#SuSkuhh0~)Fc`Y zNEQosqhRaAG+Gm4I`Lsy|3u`Ea_6#jZQ|G3w0G)p7wcZb%Oq%jRj=pwf!|2M9d6XY zJuo}@K}h)5_!ZEl4q6S*PoZw>8bv_D^KD;UH2Z_;e82)wCaf0)?=sftqFLnYKs?X* z=>10-UwNl%)>d&|kuj3eA8e?$f+Ex$$%zmg7_LxpvM`%`Vm8q(aarU_^z|p>FZmr< z4uj*aWwJBGJHCeBNtWKC@!w8r8&tNLco1>8)B`9aI+LRTg8EC%Q1BI#DXP&}{{w8wiaiQwgfW(427p$j3YCK))Qjx%5+Ml$7u| za+EK2x>~(Zu|{t7mgW1N1^V4`e>q46Hgx<#Q*|>QK8Y%=tm}Svtve&LM$a1vk@cr3qa1I_uHVk2wPmf#g1{>H4dwrr!}R5+nL7uMQ=C^*BiB zS2?O7_RpB_ognAcs4FAPvG>Mh?U}4EssFNqN@S8rq947+H;fUlq^b{LJiB(m)Ot9D z)VRf_FZWqSN@tT(uW_IXv#H?;a+1UED?goZxW#eD@aX(+=VJ+;Zb( z)(bypkj>50bX#s0eEdN*8`oTw#B%q}avOG2XAgXpr|U|u*3ih6eC8Jyh^3K9217RA zQk784zg{z=C+wAX^-!&AHoruAo}0EGtg3j+5X}`?x}ZLsY3XW;d~#RtVMDoC5YDyH ztOCqTM&UBitEH$k%7wLOqtzOR_3PF3*wkz=t1ZEM4Y>^%u-F3E3!>>O$%LA z!;x}#-+b-gGe|;5D0m)C`mn`t?UrBV%+!jTm-tnohqQS*=fg4=!_Tt;Z>~E-omM=2 zla#K>HQZg)VRkI{&cMp-lw%i=MKA}~*#grFea#its<%G#+^+TplB!%~RRJ9Rbu)(a z>P?SI3&d9+?aGEwu35W#(~?G~f$ef(btc;i1#K9Ool-IzeCO&bCl2N7`I^{yO_#28 zC(vvV(C*T6zf^AVr(>edDf3P&$xBDQotb8+OpEptEYUNuuZ(5m6C|DQ{r8j$g+omaZH!a_8O4wu}OoMXBNG!?e<=9U4%5Z)wv>*=>H~lUw+|^tcnad*dxs&=VXJ%Iqq5a*UVyxcR;tLjMYZu*DC!iNa! zwW@&4wlcu=Ic{#sy87!u2Ys_wiW0Nx2gmzan=g8zHP2Cwy)F}TMg347N~!|`D$l}Q zyNIvUtWlSqK&1cVSjN3qSE%P=F9#n5d31!z^}*9*cLc{dOiso4GyrwkCGo9sI2cyggk>K?w0Kx#E237S+mjO?g<{Y%S+?KnHAHc@5Yxe6?37JNk6zTy4BP zmb8ejP!5p4H9}H#0yqWpXn1gS;w3KF8gQ8HzC;y~GH?yRGtgJIQPYEdvYNUK0Nd*9hbG;-uG-hXzX7HkT*pz9D)NZ%?11#j-DkNr9r+0hTBcqv7@HpLefzxJ%UOCp zF$WKUO})pfMQycP;OyP0>q<+V9uf-m{wD zQ96PE25&za_iN0lkT`8~ zY`vi#)W^x}^1UU*x>G;VGTC* z_Vn%oNg&^{vB`SJjZSuNrYWa& zPGFbYD6-E$U2QR@sVCEDI3P7M|KF>vvt{+EW;M~Be;udw72xyke)8Fqo$f~y7V;4g zup_RnmL~qWI9efPL{{8vg{PgmQut^Ewh_l(5N(BGT_{H-8-K2wS#T65!xW(s#9laU z1-FsFoK)b1A<%ukrw{ zr;xqXXHpg^vNdMX{x`EdbkvE4VdT)uNk1s{sQ6S=KcnLeQUA}^k(n2levZZ-+8Nfw zd}0?e-!#oVbr*H*Naa0t7kTZl%{_M)eeEc4v9=4uVGQSXqzk6?wgmSCx?6B|!Nqp| z-qt0_-y%#e#wiP>3(H|f=O(2K&0%`eF@gUCwUkSwk!$jjH;`h1=7G3dltU3w;lR#| zCueH&9yMoz=O%_Xx^z*>mE?K|uZv}NPtTKl_CU{zV<-E0kI#$YsV$NJnEvVnclHGT z>X>(SzkN%hcCqpS`&oqnqiqbVizBsdDp+^li+AYW3xwgw&(mNh_89>7BFG<(cp~zm z`1S{}(C5XGKPdL7@Wt{iD|X-HjOHySwva2Sw0%jz&zCn>5Q0Bm;UMu9l|NbGaPbwM zKXLY;@fDXpb+!=h)t7qV`vsJ|CywDD@)g;9BNMW0C{;O~;c)U5wkM(Xpz;;FC#Cif z_zKw*?@+M&V%`(#aJ>2A-V=O%)cImxF-JIk=wlgvef<97@Bf?NDD1_^JD6Z!;+4ri zD|e6LmC8ROci-X+#Xlw&fMLnsJH~K3`2pK24QB;%De^ww^MTzv<8YJtf!;fPebf1Y z-#be%C+3P0Fh+1Y`T-L#k$VgHfCv~jxLy7D88Eqf`}~0Q-6wD-@RI9_`W+c?ko$`9 z#qli-HTUI8_$>}~`;WNx#qiz#eJBtbA|_faG$JX9ZC1r9)z~z~X_Y)|+C?kBJAv%l zN=qd(zR(awD`PO`+`#K6w>t^jP*6omGfCZ0QAJ)kiQQ0AMP@U}-B43S0bC4zh_fZc znGkQNwF9u82Y>CbP)g zL`x?zxd_`tTrEm7DVk2YIpNN%)sjlZtmYnvX9a_;P&rrO`jc&rtchGtcAE8%eJRhW zdPg*V@#v|)_wSm5N-L*yagIegW@O;vn2Ynl&q-~{Ile)srdE>xT#c#2F0g%KQn=K1B5uRV?r)Xgm{r-MlRi$IFe&ZF723jlVeUU zefc<)V^S_H`TYAMRc-_M#KmKHE|r;t#$#MAjhV#zW6*X*`h>`1bb?^A~9l>ku2hn$;K;>n&nrgGqsHG&1TNS%iW6LS0-SV(&7k!P) zX+lR5ef8vNLq`^UEzM~}M?y_i)X+}p%O*Qbeqa&xL7U%R&N4$Mire&sm zg;8`_af|q}l7G+^4)Wd!u+eV{v_>usdUwi(BKp$pB7!31nMG zMteo5`ji)M;k82$v_Nw$92;!ZGUjzjt@-D+K2?HW|7vUF60GYh2@JmO5Fx~|@ zMHE0P?~0s~QXrOhNlvi^kjuL!rxXB$@XpsS!T^$am+P0L0@1vS^@}xtY~I!SrK`Z7 z-i13w96&nn%AJx{Af9*WPO%4&&%1V~^ce{Dmd9U&2qbwc<1dK?qP!LH7b^f+-m3UZ zXMu2U1wBO!9I|I=yjly3*omL|8s(bMWIQtMUhN~&LWgJ#(Di}offZMNyZ965~Q z@AkvZLdn5(wf9rBxpAXIFYC6MolMEE3OkZ*)7H+Cg%cs~{kGdjq)xCDnWOzI!%%pI zxYs#hVp{Z?>^Y4)^T+iy%os5;crQvaHJWP@FB3jATd0 zyv>Yw-~_Z@#*Mc(2J^A_$Q<2rlbw%!xmXto7MWch)}vP^`$T!r z+xYM^j#q7R*v_|Q41*6Yqw&=T;MlQIWe=K2?I>sTng30xhaLA09)L?2_&_}=WfVZO zc>s+jM@DRQh0s5)i5FkQvt=#Aw?{md<%YWES~PMlo{ucf!J`r+imG?BJ5&J#6zOj4TD+=v#u}Fw zzRa7w==A-5Zgi2mPH)%++;4P=*S7dA>zwA1S3J(`kKxB;?NhSjlKm-Ma!kUC*#Ih8 zx9R_{u24tpZk}GO_;>yj%PE0!AB}cx?68=u*?v}V?#@yRZHDa7X6t3tpl(5fOa7`? z`vU_RCR^fF*Sg{NQD@~|uPmID8|HNU;mcB^+pNfFM8CVpV+o0VNBK{l&6#eMlYL#D z|shpgY|yFw^!da=1fq+WF5H{HJHJHQdZJJIBa-YVm#` z9hh3~usus}<=XCb`m5uLmdAgZ>!8YIO$$)hIMdNMgJh9SGQ%B~?M8oI<&xAm^ZS27 zjw^bU8FZ7&@kwC4%(~t2j#Lj%MU&K1^o)SE1KP>uOweQp8DSQk`~Z zgx|1mfSUzm_d?L09^Y{m2d9OfKaVDsZACol=S-YWQjOK<%E06VKNYgg#IjDD4Vnp> zrfd8cZ94haG8x?d1!NNuZvD@x=m&i2&#;zHG(zhNA1b5 z^3_{>@h(YJoMH)JQWpR{K|HHa$GQIDjC4dCm=&6ZHnu*t9;l1jZb=9r20%J99T^Ae z;ZNmioX8}YC0|=L zIt#&HkWXX`429_6jQ!X4jIvC^;PrjVJJ81e!cv5?98(yABt0h>gnYr%nSz-tY7pSh z6N+`~6D+c9Vx!K{R?jn#zvVP z;I4j`mB~n`>}BBu3)ItS8V0wj>*QMEmGs4Ac`|@B9X} z@D;1xp8SB1nd{eVz>8?w^80-hj<@B>Mrkl^vl!`?dQK={Lj zS2a$kv6zB~0tfc+N$`7YSBQFjbgn386cVU7^!IF|86Q%UvcOB$FP4E1{RdP%HK0gHZv*ON&XCnEy6u%!_{*UbXHWA&5$+)O`4f* z8)c4GPULI}_DP zxXth=GgEJ30}tAz{t3|r)bTp0`uJ`t)x+b-Uzpe3U%=rk*`?J#7uCkPAL<6x8X<#s z4`Vrre#53YQ)P1={R?Ck}cZePlA45L6+5q!>Yy6e5=@pqMKh98X z_dV@@A3=J4`9c0j0w@|0Vh2*UbWW)+ftVOj!=S5odG8I%edn6EeBEV0h>h2^-VV+B zcm0o`ce|Qdyj47lEA?NgXl*)I41~~75Mzi359)KBSsYor)umn-DJBBNpxsH*StD3q z(fp-LhRCaRSOQAcOcLt@^2j3D$y&&d7tTEO%NTsNhQlEn?twVD4o~2VhDfQMZ3ZO``TgL!jh-AUW+KAt@mfz}piB!Ht~+ z5mP_DU&EV_@l&2X@Bjo{PIek|2_Ok^E~5fbC}z_lx1LgxVOWXdaP{;~X@vRA@=G5I z#*#@9UnxbIj44IBGE4f2g78m6aUaA99z+6A^PtHn#ke5z3W|&U$ae19Dyzx7aQN@q zTC45WVK44IU6qVqnX_Q#>)Hy7ryF>mGy~;L!Z%p9Y(Cdfy5c5Y5y|HG8+zLNf$xB3TOgYS5G}7Mq#mJX}cd#4iH?CAeT(3OdC=p;_yr?FtUMy;BseHYn$$US;iJqK zz3a@!bk<|r+!i&oVKEqWR>3o(xSq5ZW7&&&rUKM0OcgBJ_^_@nxMmuZTO%U9u#&sW z)cyc8b=Qu2E2mF6OdlM^$B?nsgR$1>zjaEtvXd0N&aP;{gJt3;$Fl~?vqsLk{;+T+ z%4H1$Il~&gs#%Q}ERTk9XJtI87!JYpXJ|ahD4daN50<$ZFc3p5BDEE>xZbl!cjN~0 zh!y#REji%slxALa`*1u-9E@2o?#y=vbk+ydTbz&_R4#XB$aE)oJSjHYqhRO(usg#D zl!1@BV51Hs*VKJ>obBmlLk4{M2hMKu?M+=*l@>{aHq9b>T^suV}9aJMxrMF ztN?dW2xUJLX;r{e8NiGjL|?quPg*12w4Gf;_gQJ#aA}#&X~nn@^BLD~(YR3anbvRR zxRCRi+-bRdLZ}5y)P+85V$4mtuXVO8?lkH>^<1_fu3@#r^Xqi1$e6%obiRJ)c6}SP zP$~nqb7j3o2j=A68K4K(1lSaJ~1nw-p1{US>9kpsoC*74&fo~nWsn@W2 z^^xt&r9Ez$eql>__$Z8c_e(@Davf~vac-WlI&8=86>le-T4v{}gJsU!!Xp(5j0lYG{W;(@K{JCc$m%75n`e86dUC%ectuVE7N2 zq!*bTsu*{i;vLkL@2mWZh%fqWeb61&0$}z7h3L&z2hm|7sXctuuiu@Hbmtz{zm}Q6)ft^vz3=R+=s`}j3@9N z?$s$}+|L6#^J{*qbHC>?p5PDsiKqB0yPUa*>*0F29M{|Ras6C>SKx|Vi7O2!Eu8JK zy{hDcb_m%thMO<6R&!K1nX`PCOV4S7DT}^dnh-pF~@HK(>GV9bX}F=5$=UJ z8YIZJ9K>wBt=GGf^iuapubc%JY`0=)r|mc9_&2jS!ufPqGuSwnb5W#OG+*%yZK&2C ztW@*YG?fn&chxeJWG<7=L`+3j*^ZCCspYgcw`+4r=xqsL9x~}Je!C-LamvMxlEuo_* zjQK&EfOxbaJC}Omy2MX>a1KO4JbDFGrHp{XF+6~aolS!uiI8H00RlU>20I)Dk2gTT zQ3ZJ505n-@WRAXDCtc*B75#%66X=A5a)s z!EHk>{zdR)LAL)DOD&8XH!()zR*5<-0ly*Hnm2jMB)l5}wowB_Z68ymEo&8S}A^qG3Z>6Fs zhXp>LQrZ@@Vr6kl;!t%i`YygCVaW9AuH4z>R=T~RVq*fwgS~A@+Ht;CWe6lBr|-4| z3C*j{R#>B5Qw3%(D$-Z_Wrka5Px3EnGCmnPQ5Tw~`zPKUx+0tAuX)0umDW{!4L@P` zSmjzM+&M18Lt(O`dT!{xf=e4&;+3V$5lKs<{qDU-U;<7lh@7$G2d!)e>I92TC$LEV z$$OvQv^XTc_R4>qe{I)A>XDX}tNilqPRx1pd4qW5IP`NaKqBA>gkW^$=$EKlc3Vbl za>F{=XN*~A%m#@lE{SCmT`e$TK!j1?6ybFy(dZ;O}|) zCHwo6Fal6-%pGTU^d*GRNf=omJ-^eU^A+FjEJhy4GMbSh;tS1=8X&iQ#bB|RuZm;H4J<0o<6Ffo496`ZijN2&1ky=FG>$?IqEP3D13-IzIMtHIz&w(V(HxTIjV{$nF%sS6nSXm51=B6=e<6$e+w)fB$8ntF3FvXS1Z_@pKahWNB$tfA(j<#NBaZC1t| zmiKVNG>P~ma*f8_9Jy0eX_XDZ^3|BWFAf9*zO>?lwI*A*Rf*32dqX)xv&k==%}j4) z^sfILsXGwC{beF#pT&{6CZt17#S{PhO!8jRiron}JVkHbZZQ_^xfVAe&qsfjp?LDn zr!Vv<)z_caOUINo9@DBiFjD%uLREYh;nU$@p(`&p7TOGMogU;b)6B0Rp&xc-zquV% zVzm9qROag^w` z+z)~7t*!Lj&c0pm%$~lrjn(c0Sawc`jcjZja5zc@EC-5Csx?_)|i-PL!_yxb}4Y%HpY>>j0tI~0YB93*!~UjXr_gOJ7lx?u6rT*l#^**ykz z#SU3(ZfA#oZ}I;Lw*gjSFp#HMGGYu=G*~p^xI2Gy1`D|05fNW(Ks!=HXmqq4i5^Cw z`e9Z9!}$|1YQz<2EC4If-*y36^%@ElO_-nCPLek|ghoPB0{tT}Rsc7@#U@Lg|Fd;6 zh@tX^=S>&A{rut#B@-}AwR>e2! z6{SC&OZ!~A`C|1&n{%^i(Hzci-{GEa_Yxztd-4@`J^TE;(Tmg6QDoHm&KAc6l|hX( z>HN_Th3PkRt-El<9h+<(q`e7p*wC?`9N8T7@m#Mk{b}S@8>ffa4Ps%1XQqxTzdtRL z;j?UTiXHXtVC?{Gpl{WA$vMR3DUOG|djE04^mJcHx~`YJL=9-*uUQiyB!nUHtion2e65pCaesEYq+X9w<@5ABsGXY`<1KJAh&cl%Z| zy}j87#_?~I#pa0-4|jv^h%*paGH^D4gbn~RZ{6xZ4X6|>FHlTGvsia1v@tYjW0>|G zL?q}k?fHAtHD#31CjvGD!bA5 zwr&D&{em-^Mx55g=z@SHjParfU|ZqV0ynS)ID^gNT#!0^NIE{`?NDSV4>%TLJCtbJ z;6tgzQz@x_jqR~JI@c}JjFi*{%Hm23EAyxLP`;f;D2-Xi=t+--n$Rr)%UP(ojFpgXXP!Cyv{F-GeN*6Eq6vPpfY?2hnZ|GB+1cG!2@yPQEw+iFgU@j` ziigH;XyC5rclp+&n%j>j7}g3kDZTf0nGnNL?3@d$_7x+ZsLQq4yyzo7lGu-RJL8e# zdg7?sMt+I$?56}{D+k$jVJDu9wKFHHK5jQ%dn$-JlrgleO|bUnZtpC~dga&`ZyqR? z+`o+2Ss0e-Mrs_FpkJ{_RPW`qP0mP8*E$wvDewFE1U>92zZ*8mDM`1!n|Ry$=&Gis z5nY}KlSR@~NmskiIVTxELzV4RJiEL~yE&-os@-lC&M!Rm<@Pz8F9g-76>W>8aE9&( z9`G)a0s&w^oaw_Er9W}w9I=4LVm>~A1k_o~M{dD<=rk>+1%=VHX$#xOG$Mnga}kLe zU(Y3w3E!UzRnxSH1T7z|HjzXHCi4u_2f6@Lpi`j5dNl)Me{wa1v%ed8U|C4D<`%h# zf4!*OBio)$Lp;!e57K&2xJxen%uO0H$rocVb1F z=8LmauI2F4Vn;M}tfikS)-}$CXE`(`R>$w#I$>JlP#B@Bp&ePOkBeWRk7A(+`k)Uuakd9f+ zv>9mi`j%uLGM(U$wzgbaf);uMnMkG3DBJ01JoG1wKqaA_pow_T2VkMt#etE3Ht=8a z_Tmj8{8qK&gomik;HxG^t6i_j$y^?Lnbp{AxcmC3mY=}-O9xcvB*fV6JR7ko49oE5 zxBvM5;YaqXIfu>>rEZgDD`0?!59hYdTd1dHpZn&nc-DKN(eTwjj$4BvQOj_b^zufKQ` zp7sjZR92h2ID0-$+x<(@=(YMsID3+i8C6Weqq1i%nCz zjq_OLB5xz1I}*m+epwMFY`=%9`8?l@0F)6F=oVlSbrxeZ8c|n^Au_GsMQb=bZoY}h zILrAE%@if2xcKZ2@wBgz+}wA`rogHf&4#O4a9p^ z(6;B4k3_0W*|emlJ(*xrdH3o;*-^-PxaQaR6ErF49-;&x2ln+zq4a!q3uDB;KVWi& zFQNW)-zLP(REv^blzqpp&eq<&=r?x5kR^Tn ze4hMt$EIJqbJYb`Cs+S0ZJ}K*57(hsbM^XP)VLSZrPJHG>mymNKTEcyDYWF}Cq0eO zhf~_CMPH8Wuz24;7Q?U8J6`pX&7a%ce9~Uw!0z3}7g9NV#Au!Dp1n7FB$I5^^eJ*KfxyH)RHBHp{eicr&~irn27L zA}5Wx6V7A-D&Iy@Y4NWdUJ9eQ?8k634^v0cF}IX z6=&we^tZh$4te)Z?Bm*@&yv(GZ9S>dnljty`Z{}FQ|C$WxO8Rehrp9jx40pcvD?)^NR+e@9HPRMgv`^6Clu z0Rdk8w3x>%{jl}&gg6zMbkVhEY>CNrg?gR0tlsb?sL+u2%agqWdV@1wTd{eHZE-M~ zaS`>K?JORP@Z;pQpbi-*vU6Qk8aA`cl^Z4;ZLL1&K4bbI<-gYH$n(654wh33A+ zR{m-UziA=6{FC9@RHgJ>Qx=b?LA*5d`9i>C@L>q<-XC|N5>+Y)aRiVidl~S za@8}lr?hfeDV@!DY)U?JJg7)yw?bESjqKs=t4$m@nk)VKpJtz*b030z@yG@GEASjK zQp5z;GP$8=7hT3aIz=mdfIsx~>))Yfe)75Nsn@$}Bdl^mV8If?G(oif3< ze$L(a<(}%WLPt*S{!1@5dk_ob5j-Fs!SVI(v18)lpCNEhF(gX;w;yHw;8_}rl(vFp zteWBZ`dS+fNoJ{q4I{wJ0Wr|W2&>PCEWVdRP)f(k!&Ry_pCyxWtZlkfm74;LejtZs zxq?+$6Z#j8_Cy*5+&+14@3aTj@*IEA?TiMML-$gWRkBc*i;fp4xY%&QKgDGd4cO&G$aY;skclE#$B;I8|?!dpX)tK*Gov& zcvMO9CZNV||Ey#8p=)4Sltg5Mj*S=Dehq!^_WpO95j=18DrK!Q zS`P2}B4gL-7rXg3&vYAdyUqCI>;IzI;AQgCCVglBd1aAvmxR}3#m#JgA?Oy8SG`(u zZN$U#wL=C9PW2vCmzLS#`&=7*FSpMa2jtH78BeyrV3hZ*M_uZ68HU10gT+o1=M%fU N>i-Ak^d1HP005RYhx7md literal 0 HcmV?d00001 diff --git a/target/doc/SourceCodePro-Semibold.woff b/target/doc/SourceCodePro-Semibold.woff new file mode 100644 index 0000000000000000000000000000000000000000..ca972a11dc428209dd66212e382b884f168e83f7 GIT binary patch literal 55360 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

d?~=$y_z?$}zMRxO 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

-nf}~4k^lgCB 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 d&xU0F2O@Pp9zf@HhMqK>r}n002Tsb2$J2 literal 0 HcmV?d00001 diff --git a/target/doc/SourceSerifPro-Bold.ttf.woff b/target/doc/SourceSerifPro-Bold.ttf.woff new file mode 100644 index 0000000000000000000000000000000000000000..ca254318fe9ea9fc0f3313bc5df7ea5109f16921 GIT binary patch literal 93248 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 z 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 f7WG97r8^C<#}#z-`S23!^JU{=fAN_v-4v@4O literal 0 HcmV?d00001 diff --git a/target/doc/SourceSerifPro-It.ttf.woff b/target/doc/SourceSerifPro-It.ttf.woff new file mode 100644 index 0000000000000000000000000000000000000000..a287bbe6ed3f871376686682bb455d71a13882b2 GIT binary patch literal 36200 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 z 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

=K7)cy&MM-4KyhJcQOumB9&yWI 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

9MHs_oj@6Qz@1rU$v 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 psj%n$fJ$y5H3ZbI{&joRV#LmkS=BE9<$FpQ0 + + + + + +

Redirecting to ../../aho_corasick/enum.MatchKind.html...

+ + + \ No newline at end of file diff --git a/target/doc/aho_corasick/ahocorasick/struct.AhoCorasick.html b/target/doc/aho_corasick/ahocorasick/struct.AhoCorasick.html new file mode 100644 index 0000000..a14d401 --- /dev/null +++ b/target/doc/aho_corasick/ahocorasick/struct.AhoCorasick.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../aho_corasick/struct.AhoCorasick.html...

+ + + \ No newline at end of file diff --git a/target/doc/aho_corasick/ahocorasick/struct.AhoCorasickBuilder.html b/target/doc/aho_corasick/ahocorasick/struct.AhoCorasickBuilder.html new file mode 100644 index 0000000..f6724ed --- /dev/null +++ b/target/doc/aho_corasick/ahocorasick/struct.AhoCorasickBuilder.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../aho_corasick/struct.AhoCorasickBuilder.html...

+ + + \ No newline at end of file diff --git a/target/doc/aho_corasick/ahocorasick/struct.FindIter.html b/target/doc/aho_corasick/ahocorasick/struct.FindIter.html new file mode 100644 index 0000000..e7ddb07 --- /dev/null +++ b/target/doc/aho_corasick/ahocorasick/struct.FindIter.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../aho_corasick/struct.FindIter.html...

+ + + \ No newline at end of file diff --git a/target/doc/aho_corasick/ahocorasick/struct.FindOverlappingIter.html b/target/doc/aho_corasick/ahocorasick/struct.FindOverlappingIter.html new file mode 100644 index 0000000..97af1f5 --- /dev/null +++ b/target/doc/aho_corasick/ahocorasick/struct.FindOverlappingIter.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../aho_corasick/struct.FindOverlappingIter.html...

+ + + \ No newline at end of file diff --git a/target/doc/aho_corasick/ahocorasick/struct.StreamFindIter.html b/target/doc/aho_corasick/ahocorasick/struct.StreamFindIter.html new file mode 100644 index 0000000..074e6a9 --- /dev/null +++ b/target/doc/aho_corasick/ahocorasick/struct.StreamFindIter.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../aho_corasick/struct.StreamFindIter.html...

+ + + \ No newline at end of file diff --git a/target/doc/aho_corasick/all.html b/target/doc/aho_corasick/all.html new file mode 100644 index 0000000..2a4a9bc --- /dev/null +++ b/target/doc/aho_corasick/all.html @@ -0,0 +1,3 @@ +List of all items in this crate

[] + + List of all items

Structs

Enums

Traits

\ No newline at end of file diff --git a/target/doc/aho_corasick/enum.ErrorKind.html b/target/doc/aho_corasick/enum.ErrorKind.html new file mode 100644 index 0000000..919bac9 --- /dev/null +++ b/target/doc/aho_corasick/enum.ErrorKind.html @@ -0,0 +1,40 @@ +aho_corasick::ErrorKind - Rust

[][src]Enum aho_corasick::ErrorKind

pub enum ErrorKind {
+    StateIDOverflow {
+        max: usize,
+    },
+    PremultiplyOverflow {
+        max: usize,
+        requested_max: usize,
+    },
+}

The kind of error that occurred.

+

+ Variants

+StateIDOverflow

An error that occurs when constructing an automaton would require the +use of a state ID that overflows the chosen state ID representation. +For example, if one is using u8 for state IDs and builds a DFA with +257 states, then the last state's ID will be 256 which cannot be +represented with u8.

+

Fields of StateIDOverflow

max: usize

The maximum possible state ID.

+
PremultiplyOverflow

An error that occurs when premultiplication of state IDs is requested +when constructing an Aho-Corasick DFA, but doing so would overflow the +chosen state ID representation.

+

When max == requested_max, then the state ID would overflow usize.

+

Fields of PremultiplyOverflow

max: usize

The maximum possible state id.

+
requested_max: usize

The maximum ID required by premultiplication.

+

Trait Implementations

impl Clone for ErrorKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Debug for ErrorKind[src]

Auto Trait Implementations

impl Send for ErrorKind

impl Sync for ErrorKind

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/aho_corasick/enum.MatchKind.html b/target/doc/aho_corasick/enum.MatchKind.html new file mode 100644 index 0000000..6dd9f63 --- /dev/null +++ b/target/doc/aho_corasick/enum.MatchKind.html @@ -0,0 +1,119 @@ +aho_corasick::MatchKind - Rust

[][src]Enum aho_corasick::MatchKind

pub enum MatchKind {
+    Standard,
+    LeftmostFirst,
+    LeftmostLongest,
+    // some variants omitted
+}

A knob for controlling the match semantics of an Aho-Corasick automaton.

+

There are two generally different ways that Aho-Corasick automatons can +report matches. The first way is the "standard" approach that results from +implementing most textbook explanations of Aho-Corasick. The second way is +to report only the leftmost non-overlapping matches. The leftmost approach +is in turn split into two different ways of resolving ambiguous matches: +leftmost-first and leftmost-longest.

+

The Standard match kind is the default and is the only one that supports +overlapping matches and stream searching. (Trying to find overlapping +or streaming matches using leftmost match semantics will result in a +panic.) The Standard match kind will report matches as they are seen. +When searching for overlapping matches, then all possible matches are +reported. When searching for non-overlapping matches, the first match seen +is reported. For example, for non-overlapping matches, given the patterns +abcd and b and the subject string abcdef, only a match for b is +reported since it is detected first. The abcd match is never reported +since it overlaps with the b match.

+

In contrast, the leftmost match kind always prefers the leftmost match +among all possible matches. Given the same example as above with abcd and +b as patterns and abcdef as the subject string, the leftmost match is +abcd since it begins before the b match, even though the b match is +detected before the abcd match. In this case, the b match is not +reported at all since it overlaps with the abcd match.

+

The difference between leftmost-first and leftmost-longest is in how they +resolve ambiguous matches when there are multiple leftmost matches to +choose from. Leftmost-first always chooses the pattern that was provided +earliest, where as leftmost-longest always chooses the longest matching +pattern. For example, given the patterns a and ab and the subject +string ab, the leftmost-first match is a but the leftmost-longest match +is ab. Conversely, if the patterns were given in reverse order, i.e., +ab and a, then both the leftmost-first and leftmost-longest matches +would be ab. Stated differently, the leftmost-first match depends on the +order in which the patterns were given to the Aho-Corasick automaton. +Because of that, when leftmost-first matching is used, if a pattern A +that appears before a pattern B is a prefix of B, then it is impossible +to ever observe a match of B.

+

If you're not sure which match kind to pick, then stick with the standard +kind, which is the default. In particular, if you need overlapping or +streaming matches, then you must use the standard kind. The leftmost +kinds are useful in specific circumstances. For example, leftmost-first can +be very useful as a way to implement match priority based on the order of +patterns given and leftmost-longest can be useful for dictionary searching +such that only the longest matching words are reported.

+

Relationship with regular expression alternations

+

Understanding match semantics can be a little tricky, and one easy way +to conceptualize non-overlapping matches from an Aho-Corasick automaton +is to think about them as a simple alternation of literals in a regular +expression. For example, let's say we wanted to match the strings +Sam and Samwise, which would turn into the regex Sam|Samwise. It +turns out that regular expression engines have two different ways of +matching this alternation. The first way, leftmost-longest, is commonly +found in POSIX compatible implementations of regular expressions (such as +grep). The second way, leftmost-first, is commonly found in backtracking +implementations such as Perl. (Some regex engines, such as RE2 and Rust's +regex engine do not use backtracking, but still implement leftmost-first +semantics in an effort to match the behavior of dominant backtracking +regex engines such as those found in Perl, Ruby, Python, Javascript and +PHP.)

+

That is, when matching Sam|Samwise against Samwise, a POSIX regex +will match Samwise because it is the longest possible match, but a +Perl-like regex will match Sam since it appears earlier in the +alternation. Indeed, the regex Sam|Samwise in a Perl-like regex engine +will never match Samwise since Sam will always have higher priority. +Conversely, matching the regex Samwise|Sam against Samwise will lead to +a match of Samwise in both POSIX and Perl-like regexes since Samwise is +still longest match, but it also appears earlier than Sam.

+

The "standard" match semantics of Aho-Corasick generally don't correspond +to the match semantics of any large group of regex implementations, so +there's no direct analogy that can be made here. Standard match semantics +are generally useful for overlapping matches, or if you just want to see +matches as they are detected.

+

The main conclusion to draw from this section is that the match semantics +can be tweaked to precisely match either Perl-like regex alternations or +POSIX regex alternations.

+

+ Variants

+Standard

Use standard match semantics, which support overlapping matches. When +used with non-overlapping matches, matches are reported as they are +seen.

+
LeftmostFirst

Use leftmost-first match semantics, which reports leftmost matches. +When there are multiple possible leftmost matches, the match +corresponding to the pattern that appeared earlier when constructing +the automaton is reported.

+

This does not support overlapping matches or stream searching. If +this match kind is used, attempting to find overlapping matches or +stream matches will panic.

+
LeftmostLongest

Use leftmost-longest match semantics, which reports leftmost matches. +When there are multiple possible leftmost matches, the longest match +is chosen.

+

This does not support overlapping matches or stream searching. If +this match kind is used, attempting to find overlapping matches or +stream matches will panic.

+

Trait Implementations

impl PartialEq<MatchKind> for MatchKind[src]

#[must_use] +
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests for !=.

+

impl Clone for MatchKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Default for MatchKind[src]

The default match kind is MatchKind::Standard.

+

impl Eq for MatchKind[src]

impl Copy for MatchKind[src]

impl Debug for MatchKind[src]

Auto Trait Implementations

impl Send for MatchKind

impl Sync for MatchKind

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/aho_corasick/error/enum.ErrorKind.html b/target/doc/aho_corasick/error/enum.ErrorKind.html new file mode 100644 index 0000000..b5ff16e --- /dev/null +++ b/target/doc/aho_corasick/error/enum.ErrorKind.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../aho_corasick/enum.ErrorKind.html...

+ + + \ No newline at end of file diff --git a/target/doc/aho_corasick/error/struct.Error.html b/target/doc/aho_corasick/error/struct.Error.html new file mode 100644 index 0000000..ec608fc --- /dev/null +++ b/target/doc/aho_corasick/error/struct.Error.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../aho_corasick/struct.Error.html...

+ + + \ No newline at end of file diff --git a/target/doc/aho_corasick/index.html b/target/doc/aho_corasick/index.html new file mode 100644 index 0000000..866cabc --- /dev/null +++ b/target/doc/aho_corasick/index.html @@ -0,0 +1,166 @@ +aho_corasick - Rust

[][src]Crate aho_corasick

A library for finding occurrences of many patterns at once. This library +provides multiple pattern search principally through an implementation of the +Aho-Corasick algorithm, +which builds a fast finite state machine for executing searches in linear time.

+

Additionally, this library provides a number of configuration options for +building the automaton that permit controlling the space versus time trade +off. Other features include simple ASCII case insensitive matching, finding +overlapping matches, replacements, searching streams and even searching and +replacing text in streams.

+

Finally, unlike all other (known) Aho-Corasick implementations, this one +supports enabling +leftmost-first +or +leftmost-longest +match semantics, using a (seemingly) novel alternative construction algorithm. +For more details on what match semantics means, see the +MatchKind +type.

+

Overview

+

This section gives a brief overview of the primary types in this crate:

+
    +
  • AhoCorasick is the primary type and represents +an Aho-Corasick automaton. This is the type you use to execute searches.
  • +
  • AhoCorasickBuilder can be used to build +an Aho-Corasick automaton, and supports configuring a number of options.
  • +
  • Match represents a single match reported by an +Aho-Corasick automaton. Each match has two pieces of information: the pattern +that matched and the start and end byte offsets corresponding to the position +in the haystack at which it matched.
  • +
+

Example: basic searching

+

This example shows how to search for occurrences of multiple patterns +simultaneously. Each match includes the pattern that matched along with the +byte offsets of the match.

+ +
+use aho_corasick::AhoCorasick;
+
+let patterns = &["apple", "maple", "Snapple"];
+let haystack = "Nobody likes maple in their apple flavored Snapple.";
+
+let ac = AhoCorasick::new(patterns);
+let mut matches = vec![];
+for mat in ac.find_iter(haystack) {
+    matches.push((mat.pattern(), mat.start(), mat.end()));
+}
+assert_eq!(matches, vec![
+    (1, 13, 18),
+    (0, 28, 33),
+    (2, 43, 50),
+]);
+

Example: case insensitivity

+

This is like the previous example, but matches Snapple case insensitively +using AhoCorasickBuilder:

+ +
+use aho_corasick::AhoCorasickBuilder;
+
+let patterns = &["apple", "maple", "snapple"];
+let haystack = "Nobody likes maple in their apple flavored Snapple.";
+
+let ac = AhoCorasickBuilder::new()
+    .ascii_case_insensitive(true)
+    .build(patterns);
+let mut matches = vec![];
+for mat in ac.find_iter(haystack) {
+    matches.push((mat.pattern(), mat.start(), mat.end()));
+}
+assert_eq!(matches, vec![
+    (1, 13, 18),
+    (0, 28, 33),
+    (2, 43, 50),
+]);
+

Example: replacing matches in a stream

+

This example shows how to execute a search and replace on a stream without +loading the entire stream into memory first.

+ +
+use aho_corasick::AhoCorasick;
+
+let patterns = &["fox", "brown", "quick"];
+let replace_with = &["sloth", "grey", "slow"];
+
+// In a real example, these might be `std::fs::File`s instead. All you need to
+// do is supply a pair of `std::io::Read` and `std::io::Write` implementations.
+let rdr = "The quick brown fox.";
+let mut wtr = vec![];
+
+let ac = AhoCorasick::new(patterns);
+ac.stream_replace_all(rdr.as_bytes(), &mut wtr, replace_with)?;
+assert_eq!(b"The slow grey sloth.".to_vec(), wtr);
+

Example: finding the leftmost first match

+

In the textbook description of Aho-Corasick, its formulation is typically +structured such that it reports all possible matches, even when they overlap +with another. In many cases, overlapping matches may not be desired, such as +the case of finding all successive non-overlapping matches like you might with +a standard regular expression.

+

Unfortunately the "obvious" way to modify the Aho-Corasick algorithm to do +this doesn't always work in the expected way, since it will report matches as +soon as they are seen. For example, consider matching the regex Samwise|Sam +against the text Samwise. Most regex engines (that are Perl-like, or +non-POSIX) will report Samwise as a match, but the standard Aho-Corasick +algorithm modified for reporting non-overlapping matches will report Sam.

+

A novel contribution of this library is the ability to change the match +semantics of Aho-Corasick (without additional search time overhead) such that +Samwise is reported instead. For example, here's the standard approach:

+ +
+use aho_corasick::AhoCorasick;
+
+let patterns = &["Samwise", "Sam"];
+let haystack = "Samwise";
+
+let ac = AhoCorasick::new(patterns);
+let mat = ac.find(haystack).expect("should have a match");
+assert_eq!("Sam", &haystack[mat.start()..mat.end()]);
+

And now here's the leftmost-first version, which matches how a Perl-like +regex will work:

+ +
+use aho_corasick::{AhoCorasickBuilder, MatchKind};
+
+let patterns = &["Samwise", "Sam"];
+let haystack = "Samwise";
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::LeftmostFirst)
+    .build(patterns);
+let mat = ac.find(haystack).expect("should have a match");
+assert_eq!("Samwise", &haystack[mat.start()..mat.end()]);
+

In addition to leftmost-first semantics, this library also supports +leftmost-longest semantics, which match the POSIX behavior of a regular +expression alternation. See +MatchKind +for more details.

+

Prefilters

+

While an Aho-Corasick automaton can perform admirably when compared to more +naive solutions, it is generally slower than more specialized algorithms that +are accelerated using vector instructions such as SIMD.

+

For that reason, this library will internally use a "prefilter" to attempt +to accelerate searches when possible. Currently, this library has fairly +limited implementation that only applies when there are 3 or fewer unique +starting bytes among all patterns in an automaton.

+

In the future, it is intended for this prefilter to grow more sophisticated +by pushing applicable optimizations from the +regex +crate (and other places) down into this library.

+

While a prefilter is generally good to have on by default since it works well +in the common case, it can lead to less predictable or even sub-optimal +performance in some cases. For that reason, prefilters can be disabled via +AhoCorasickBuilder::prefilter.

+

Structs

+
AhoCorasick

An automaton for searching multiple strings in linear time.

+
AhoCorasickBuilder

A builder for configuring an Aho-Corasick automaton.

+
Error

An error that occurred during the construction of an Aho-Corasick +automaton.

+
FindIter

An iterator of non-overlapping matches in a particular haystack.

+
FindOverlappingIter

An iterator of overlapping matches in a particular haystack.

+
Match

A representation of a match reported by an Aho-Corasick automaton.

+
StreamFindIter

An iterator that reports Aho-Corasick matches in a stream.

+

Enums

+
ErrorKind

The kind of error that occurred.

+
MatchKind

A knob for controlling the match semantics of an Aho-Corasick automaton.

+

Traits

+
StateID

A trait describing the representation of an automaton's state identifier.

+
\ No newline at end of file diff --git a/target/doc/aho_corasick/sidebar-items.js b/target/doc/aho_corasick/sidebar-items.js new file mode 100644 index 0000000..6daed18 --- /dev/null +++ b/target/doc/aho_corasick/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"enum":[["ErrorKind","The kind of error that occurred."],["MatchKind","A knob for controlling the match semantics of an Aho-Corasick automaton."]],"struct":[["AhoCorasick","An automaton for searching multiple strings in linear time."],["AhoCorasickBuilder","A builder for configuring an Aho-Corasick automaton."],["Error","An error that occurred during the construction of an Aho-Corasick automaton."],["FindIter","An iterator of non-overlapping matches in a particular haystack."],["FindOverlappingIter","An iterator of overlapping matches in a particular haystack."],["Match","A representation of a match reported by an Aho-Corasick automaton."],["StreamFindIter","An iterator that reports Aho-Corasick matches in a stream."]],"trait":[["StateID","A trait describing the representation of an automaton's state identifier."]]}); \ No newline at end of file diff --git a/target/doc/aho_corasick/state_id/trait.StateID.html b/target/doc/aho_corasick/state_id/trait.StateID.html new file mode 100644 index 0000000..b173524 --- /dev/null +++ b/target/doc/aho_corasick/state_id/trait.StateID.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../aho_corasick/trait.StateID.html...

+ + + \ No newline at end of file diff --git a/target/doc/aho_corasick/struct.AhoCorasick.html b/target/doc/aho_corasick/struct.AhoCorasick.html new file mode 100644 index 0000000..4bd3b7e --- /dev/null +++ b/target/doc/aho_corasick/struct.AhoCorasick.html @@ -0,0 +1,646 @@ +aho_corasick::AhoCorasick - Rust

[][src]Struct aho_corasick::AhoCorasick

pub struct AhoCorasick<S: StateID = usize> { /* fields omitted */ }

An automaton for searching multiple strings in linear time.

+

The AhoCorasick type supports a few basic ways of constructing an +automaton, including +AhoCorasick::new +and +AhoCorasick::new_auto_configured. +However, there are a fair number of configurable options that can be set +by using +AhoCorasickBuilder +instead. Such options include, but are not limited to, how matches are +determined, simple case insensitivity, whether to use a DFA or not and +various knobs for controlling the space-vs-time trade offs taken when +building the automaton.

+

If you aren't sure where to start, try beginning with +AhoCorasick::new_auto_configured.

+

Resource usage

+

Aho-Corasick automatons are always constructed in O(p) time, where p +is the combined length of all patterns being searched. With that said, +building an automaton can be fairly costly because of high constant +factors, particularly when enabling the +DFA +option (which is disabled by default). For this reason, it's generally a +good idea to build an automaton once and reuse it as much as possible.

+

Aho-Corasick automatons can also use a fair bit of memory. To get a +concrete idea of how much memory is being used, try using the +AhoCorasick::heap_bytes +method.

+

Examples

+

This example shows how to search for occurrences of multiple patterns +simultaneously in a case insensitive fashion. Each match includes the +pattern that matched along with the byte offsets of the match.

+ +
+use aho_corasick::AhoCorasickBuilder;
+
+let patterns = &["apple", "maple", "snapple"];
+let haystack = "Nobody likes maple in their apple flavored Snapple.";
+
+let ac = AhoCorasickBuilder::new()
+    .ascii_case_insensitive(true)
+    .build(patterns);
+let mut matches = vec![];
+for mat in ac.find_iter(haystack) {
+    matches.push((mat.pattern(), mat.start(), mat.end()));
+}
+assert_eq!(matches, vec![
+    (1, 13, 18),
+    (0, 28, 33),
+    (2, 43, 50),
+]);
+

This example shows how to replace matches with some other string:

+ +
+use aho_corasick::AhoCorasick;
+
+let patterns = &["fox", "brown", "quick"];
+let haystack = "The quick brown fox.";
+let replace_with = &["sloth", "grey", "slow"];
+
+let ac = AhoCorasick::new(patterns);
+let result = ac.replace_all(haystack, replace_with);
+assert_eq!(result, "The slow grey sloth.");
+

Methods

impl AhoCorasick[src]

pub fn new<I, P>(patterns: I) -> AhoCorasick where
    I: IntoIterator<Item = P>,
    P: AsRef<[u8]>, 
[src]

Create a new Aho-Corasick automaton using the default configuration.

+

The default configuration optimizes for less space usage, but at the +expense of longer search times. To change the configuration, use +AhoCorasickBuilder +for fine-grained control, or +AhoCorasick::new_auto_configured +for automatic configuration if you aren't sure which settings to pick.

+

This uses the default +MatchKind::Standard +match semantics, which reports a match as soon as it is found. This +corresponds to the standard match semantics supported by textbook +descriptions of the Aho-Corasick algorithm.

+

Examples

+

Basic usage:

+ +
+use aho_corasick::AhoCorasick;
+
+let ac = AhoCorasick::new(&[
+    "foo", "bar", "baz",
+]);
+assert_eq!(Some(1), ac.find("xxx bar xxx").map(|m| m.pattern()));
+

pub fn new_auto_configured<B>(patterns: &[B]) -> AhoCorasick where
    B: AsRef<[u8]>, 
[src]

Build an Aho-Corasick automaton with an automatically determined +configuration.

+

Specifically, this requires a slice of patterns instead of an iterator +since the configuration is determined by looking at the patterns before +constructing the automaton. The idea here is to balance space and time +automatically. That is, when searching a small number of patterns, this +will attempt to use the fastest possible configuration since the total +space required will be small anyway. As the number of patterns grows, +this will fall back to slower configurations that use less space.

+

If you want auto configuration but with match semantics different from +the default MatchKind::Standard, then use +AhoCorasickBuilder::auto_configure.

+

Examples

+

Basic usage is just like new, except you must provide a slice:

+ +
+use aho_corasick::AhoCorasick;
+
+let ac = AhoCorasick::new_auto_configured(&[
+    "foo", "bar", "baz",
+]);
+assert_eq!(Some(1), ac.find("xxx bar xxx").map(|m| m.pattern()));
+

impl<S: StateID> AhoCorasick<S>[src]

pub fn is_match<B: AsRef<[u8]>>(&self, haystack: B) -> bool[src]

Returns true if and only if this automaton matches the haystack at any +position.

+

haystack may be any type that is cheaply convertible to a &[u8]. +This includes, but is not limited to, String, &str, Vec<u8>, and +&[u8] itself.

+

Examples

+

Basic usage:

+ +
+use aho_corasick::AhoCorasick;
+
+let ac = AhoCorasick::new(&[
+    "foo", "bar", "quux", "baz",
+]);
+assert!(ac.is_match("xxx bar xxx"));
+assert!(!ac.is_match("xxx qux xxx"));
+

pub fn earliest_find<B: AsRef<[u8]>>(&self, haystack: B) -> Option<Match>[src]

Returns the location of the first detected match in haystack.

+

This method has the same behavior regardless of the +MatchKind +of this automaton.

+

haystack may be any type that is cheaply convertible to a &[u8]. +This includes, but is not limited to, String, &str, Vec<u8>, and +&[u8] itself.

+

Examples

+

Basic usage:

+ +
+use aho_corasick::AhoCorasick;
+
+let ac = AhoCorasick::new(&[
+    "abc", "b",
+]);
+let mat = ac.earliest_find("abcd").expect("should have match");
+assert_eq!(1, mat.pattern());
+assert_eq!((1, 2), (mat.start(), mat.end()));
+

pub fn find<B: AsRef<[u8]>>(&self, haystack: B) -> Option<Match>[src]

Returns the location of the first match according to the match +semantics that this automaton was constructed with.

+

When using MatchKind::Standard, this corresponds precisely to the +same behavior as +earliest_find. +Otherwise, match semantics correspond to either +leftmost-first +or +leftmost-longest.

+

haystack may be any type that is cheaply convertible to a &[u8]. +This includes, but is not limited to, String, &str, Vec<u8>, and +&[u8] itself.

+

Examples

+

Basic usage, with standard semantics:

+ +
+use aho_corasick::{AhoCorasickBuilder, MatchKind};
+
+let patterns = &["b", "abc", "abcd"];
+let haystack = "abcd";
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::Standard) // default, not necessary
+    .build(patterns);
+let mat = ac.find(haystack).expect("should have a match");
+assert_eq!("b", &haystack[mat.start()..mat.end()]);
+

Now with leftmost-first semantics:

+ +
+use aho_corasick::{AhoCorasickBuilder, MatchKind};
+
+let patterns = &["b", "abc", "abcd"];
+let haystack = "abcd";
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::LeftmostFirst)
+    .build(patterns);
+let mat = ac.find(haystack).expect("should have a match");
+assert_eq!("abc", &haystack[mat.start()..mat.end()]);
+

And finally, leftmost-longest semantics:

+ +
+use aho_corasick::{AhoCorasickBuilder, MatchKind};
+
+let patterns = &["b", "abc", "abcd"];
+let haystack = "abcd";
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::LeftmostLongest)
+    .build(patterns);
+let mat = ac.find(haystack).expect("should have a match");
+assert_eq!("abcd", &haystack[mat.start()..mat.end()]);
+

Important traits for FindIter<'a, 'b, S>
pub fn find_iter<'a, 'b, B: ?Sized + AsRef<[u8]>>(
    &'a self,
    haystack: &'b B
) -> FindIter<'a, 'b, S>
[src]

Returns an iterator of non-overlapping matches, using the match +semantics that this automaton was constructed with.

+

haystack may be any type that is cheaply convertible to a &[u8]. +This includes, but is not limited to, String, &str, Vec<u8>, and +&[u8] itself.

+

Examples

+

Basic usage, with standard semantics:

+ +
+use aho_corasick::{AhoCorasickBuilder, MatchKind};
+
+let patterns = &["append", "appendage", "app"];
+let haystack = "append the app to the appendage";
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::Standard) // default, not necessary
+    .build(patterns);
+let matches: Vec<usize> = ac
+    .find_iter(haystack)
+    .map(|mat| mat.pattern())
+    .collect();
+assert_eq!(vec![2, 2, 2], matches);
+

Now with leftmost-first semantics:

+ +
+use aho_corasick::{AhoCorasickBuilder, MatchKind};
+
+let patterns = &["append", "appendage", "app"];
+let haystack = "append the app to the appendage";
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::LeftmostFirst)
+    .build(patterns);
+let matches: Vec<usize> = ac
+    .find_iter(haystack)
+    .map(|mat| mat.pattern())
+    .collect();
+assert_eq!(vec![0, 2, 0], matches);
+

And finally, leftmost-longest semantics:

+ +
+use aho_corasick::{AhoCorasickBuilder, MatchKind};
+
+let patterns = &["append", "appendage", "app"];
+let haystack = "append the app to the appendage";
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::LeftmostLongest)
+    .build(patterns);
+let matches: Vec<usize> = ac
+    .find_iter(haystack)
+    .map(|mat| mat.pattern())
+    .collect();
+assert_eq!(vec![0, 2, 1], matches);
+

Important traits for FindOverlappingIter<'a, 'b, S>
pub fn find_overlapping_iter<'a, 'b, B: ?Sized + AsRef<[u8]>>(
    &'a self,
    haystack: &'b B
) -> FindOverlappingIter<'a, 'b, S>
[src]

Returns an iterator of overlapping matches in the given haystack.

+

Overlapping matches can only be detected using +MatchKind::Standard semantics. If this automaton was constructed with +leftmost semantics, then this method will panic. To determine whether +this will panic at runtime, use the +AhoCorasick::supports_overlapping +method.

+

haystack may be any type that is cheaply convertible to a &[u8]. +This includes, but is not limited to, String, &str, Vec<u8>, and +&[u8] itself.

+

Panics

+

This panics when AhoCorasick::supports_overlapping returns false. +That is, this panics when this automaton's match semantics are not +MatchKind::Standard.

+

Examples

+

Basic usage, with standard semantics:

+ +
+use aho_corasick::AhoCorasick;
+
+let patterns = &["append", "appendage", "app"];
+let haystack = "append the app to the appendage";
+
+let ac = AhoCorasick::new(patterns);
+let matches: Vec<usize> = ac
+    .find_overlapping_iter(haystack)
+    .map(|mat| mat.pattern())
+    .collect();
+assert_eq!(vec![2, 0, 2, 2, 0, 1], matches);
+

pub fn replace_all<B>(&self, haystack: &str, replace_with: &[B]) -> String where
    B: AsRef<str>, 
[src]

Replace all matches with a corresponding value in the replace_with +slice given. Matches correspond to the same matches as reported by +find_iter.

+

Replacements are determined by the index of the matching pattern. +For example, if the pattern with index 2 is found, then it is +replaced by replace_with[2].

+

Panics

+

This panics when replace_with.len() does not equal the total number +of patterns that are matched by this automaton.

+

Examples

+

Basic usage:

+ +
+use aho_corasick::{AhoCorasickBuilder, MatchKind};
+
+let patterns = &["append", "appendage", "app"];
+let haystack = "append the app to the appendage";
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::LeftmostFirst)
+    .build(patterns);
+let result = ac.replace_all(haystack, &["x", "y", "z"]);
+assert_eq!("x the z to the xage", result);
+

pub fn replace_all_bytes<B>(
    &self,
    haystack: &[u8],
    replace_with: &[B]
) -> Vec<u8> where
    B: AsRef<[u8]>, 
[src]

Replace all matches using raw bytes with a corresponding value in the +replace_with slice given. Matches correspond to the same matches as +reported by find_iter.

+

Replacements are determined by the index of the matching pattern. +For example, if the pattern with index 2 is found, then it is +replaced by replace_with[2].

+

Panics

+

This panics when replace_with.len() does not equal the total number +of patterns that are matched by this automaton.

+

Examples

+

Basic usage:

+ +
+use aho_corasick::{AhoCorasickBuilder, MatchKind};
+
+let patterns = &["append", "appendage", "app"];
+let haystack = b"append the app to the appendage";
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::LeftmostFirst)
+    .build(patterns);
+let result = ac.replace_all_bytes(haystack, &["x", "y", "z"]);
+assert_eq!(b"x the z to the xage".to_vec(), result);
+

pub fn replace_all_with<F>(
    &self,
    haystack: &str,
    dst: &mut String,
    replace_with: F
) where
    F: FnMut(&Match, &str, &mut String) -> bool
[src]

Replace all matches using a closure called on each match. +Matches correspond to the same matches as reported by +find_iter.

+

The closure accepts three parameters: the match found, the text of +the match and a string buffer with which to write the replaced text +(if any). If the closure returns true, then it continues to the next +match. If the closure returns false, then searching is stopped.

+

Examples

+

Basic usage:

+ +
+use aho_corasick::{AhoCorasickBuilder, MatchKind};
+
+let patterns = &["append", "appendage", "app"];
+let haystack = "append the app to the appendage";
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::LeftmostFirst)
+    .build(patterns);
+let mut result = String::new();
+ac.replace_all_with(haystack, &mut result, |mat, _, dst| {
+    dst.push_str(&mat.pattern().to_string());
+    true
+});
+assert_eq!("0 the 2 to the 0age", result);
+

pub fn replace_all_with_bytes<F>(
    &self,
    haystack: &[u8],
    dst: &mut Vec<u8>,
    replace_with: F
) where
    F: FnMut(&Match, &[u8], &mut Vec<u8>) -> bool
[src]

Replace all matches using raw bytes with a closure called on each +match. Matches correspond to the same matches as reported by +find_iter.

+

The closure accepts three parameters: the match found, the text of +the match and a byte buffer with which to write the replaced text +(if any). If the closure returns true, then it continues to the next +match. If the closure returns false, then searching is stopped.

+

Examples

+

Basic usage:

+ +
+use aho_corasick::{AhoCorasickBuilder, MatchKind};
+
+let patterns = &["append", "appendage", "app"];
+let haystack = b"append the app to the appendage";
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::LeftmostFirst)
+    .build(patterns);
+let mut result = vec![];
+ac.replace_all_with_bytes(haystack, &mut result, |mat, _, dst| {
+    dst.extend(mat.pattern().to_string().bytes());
+    true
+});
+assert_eq!(b"0 the 2 to the 0age".to_vec(), result);
+

Important traits for StreamFindIter<'a, R, S>
pub fn stream_find_iter<'a, R: Read>(
    &'a self,
    rdr: R
) -> StreamFindIter<'a, R, S>
[src]

Returns an iterator of non-overlapping matches in the given +stream. Matches correspond to the same matches as reported by +find_iter.

+

The matches yielded by this iterator use absolute position offsets in +the stream given, where the first byte has index 0. Matches are +yieled until the stream is exhausted.

+

Each item yielded by the iterator is an io::Result<Match>, where an +error is yielded if there was a problem reading from the reader given.

+

When searching a stream, an internal buffer is used. Therefore, callers +should avoiding providing a buffered reader, if possible.

+

Searching a stream requires that the automaton was built with +MatchKind::Standard semantics. If this automaton was constructed +with leftmost semantics, then this method will panic. To determine +whether this will panic at runtime, use the +AhoCorasick::supports_stream +method.

+

Memory usage

+

In general, searching streams will use a constant amount of memory for +its internal buffer. The one requirement is that the internal buffer +must be at least the size of the longest possible match. In most use +cases, the default buffer size will be much larger than any individual +match.

+

Panics

+

This panics when AhoCorasick::supports_stream returns false. +That is, this panics when this automaton's match semantics are not +MatchKind::Standard. This restriction may be lifted in the future.

+

Examples

+

Basic usage:

+ +
+use aho_corasick::AhoCorasick;
+
+let patterns = &["append", "appendage", "app"];
+let haystack = "append the app to the appendage";
+
+let ac = AhoCorasick::new(patterns);
+let mut matches = vec![];
+for result in ac.stream_find_iter(haystack.as_bytes()) {
+    let mat = result?;
+    matches.push(mat.pattern());
+}
+assert_eq!(vec![2, 2, 2], matches);
+

pub fn stream_replace_all<R, W, B>(
    &self,
    rdr: R,
    wtr: W,
    replace_with: &[B]
) -> Result<()> where
    R: Read,
    W: Write,
    B: AsRef<[u8]>, 
[src]

Search for and replace all matches of this automaton in +the given reader, and write the replacements to the given +writer. Matches correspond to the same matches as reported by +find_iter.

+

Replacements are determined by the index of the matching pattern. +For example, if the pattern with index 2 is found, then it is +replaced by replace_with[2].

+

After all matches are replaced, the writer is not flushed.

+

If there was a problem reading from the given reader or writing to the +given writer, then the corresponding io::Error is returned and all +replacement is stopped.

+

When searching a stream, an internal buffer is used. Therefore, callers +should avoiding providing a buffered reader, if possible. However, +callers may want to provide a buffered writer.

+

Searching a stream requires that the automaton was built with +MatchKind::Standard semantics. If this automaton was constructed +with leftmost semantics, then this method will panic. To determine +whether this will panic at runtime, use the +AhoCorasick::supports_stream +method.

+

Memory usage

+

In general, searching streams will use a constant amount of memory for +its internal buffer. The one requirement is that the internal buffer +must be at least the size of the longest possible match. In most use +cases, the default buffer size will be much larger than any individual +match.

+

Panics

+

This panics when AhoCorasick::supports_stream returns false. +That is, this panics when this automaton's match semantics are not +MatchKind::Standard. This restriction may be lifted in the future.

+

Examples

+

Basic usage:

+ +
+use aho_corasick::AhoCorasick;
+
+let patterns = &["fox", "brown", "quick"];
+let haystack = "The quick brown fox.";
+let replace_with = &["sloth", "grey", "slow"];
+
+let ac = AhoCorasick::new(patterns);
+let mut result = vec![];
+ac.stream_replace_all(haystack.as_bytes(), &mut result, replace_with)?;
+assert_eq!(b"The slow grey sloth.".to_vec(), result);
+

pub fn stream_replace_all_with<R, W, F>(
    &self,
    rdr: R,
    wtr: W,
    replace_with: F
) -> Result<()> where
    R: Read,
    W: Write,
    F: FnMut(&Match, &[u8], &mut W) -> Result<()>, 
[src]

Search the given reader and replace all matches of this automaton +using the given closure. The result is written to the given +writer. Matches correspond to the same matches as reported by +find_iter.

+

The closure accepts three parameters: the match found, the text of +the match and the writer with which to write the replaced text +(if any). If the closure returns true, then it continues to the next +match. If the closure returns false, then searching is stopped.

+

After all matches are replaced, the writer is not flushed.

+

If there was a problem reading from the given reader or writing to the +given writer, then the corresponding io::Error is returned and all +replacement is stopped.

+

When searching a stream, an internal buffer is used. Therefore, callers +should avoiding providing a buffered reader, if possible. However, +callers may want to provide a buffered writer.

+

Searching a stream requires that the automaton was built with +MatchKind::Standard semantics. If this automaton was constructed +with leftmost semantics, then this method will panic. To determine +whether this will panic at runtime, use the +AhoCorasick::supports_stream +method.

+

Memory usage

+

In general, searching streams will use a constant amount of memory for +its internal buffer. The one requirement is that the internal buffer +must be at least the size of the longest possible match. In most use +cases, the default buffer size will be much larger than any individual +match.

+

Panics

+

This panics when AhoCorasick::supports_stream returns false. +That is, this panics when this automaton's match semantics are not +MatchKind::Standard. This restriction may be lifted in the future.

+

Examples

+

Basic usage:

+ +
+use std::io::Write;
+use aho_corasick::AhoCorasick;
+
+let patterns = &["fox", "brown", "quick"];
+let haystack = "The quick brown fox.";
+
+let ac = AhoCorasick::new(patterns);
+let mut result = vec![];
+ac.stream_replace_all_with(
+    haystack.as_bytes(),
+    &mut result,
+    |mat, _, wtr| {
+        wtr.write_all(mat.pattern().to_string().as_bytes())
+    },
+)?;
+assert_eq!(b"The 2 1 0.".to_vec(), result);
+

pub fn match_kind(&self) -> &MatchKind[src]

Returns the match kind used by this automaton.

+

Examples

+

Basic usage:

+ +
+use aho_corasick::{AhoCorasick, MatchKind};
+
+let ac = AhoCorasick::new(&[
+    "foo", "bar", "quux", "baz",
+]);
+assert_eq!(&MatchKind::Standard, ac.match_kind());
+

pub fn max_pattern_len(&self) -> usize[src]

Returns the length of the longest pattern matched by this automaton.

+

Examples

+

Basic usage:

+ +
+use aho_corasick::AhoCorasick;
+
+let ac = AhoCorasick::new(&[
+    "foo", "bar", "quux", "baz",
+]);
+assert_eq!(4, ac.max_pattern_len());
+

pub fn pattern_count(&self) -> usize[src]

Return the total number of patterns matched by this automaton.

+

This includes patterns that may never participate in a match. For +example, if +MatchKind::LeftmostFirst +match semantics are used, and the patterns Sam and Samwise were +used to build the automaton, then Samwise can never participate in a +match because Sam will always take priority.

+

Examples

+

Basic usage:

+ +
+use aho_corasick::AhoCorasick;
+
+let ac = AhoCorasick::new(&[
+    "foo", "bar", "baz",
+]);
+assert_eq!(3, ac.pattern_count());
+

pub fn supports_overlapping(&self) -> bool[src]

Returns true if and only if this automaton supports reporting +overlapping matches.

+

If this returns false and overlapping matches are requested, then it +will result in a panic.

+

Since leftmost matching is inherently incompatible with overlapping +matches, only +MatchKind::Standard +supports overlapping matches. This is unlikely to change in the future.

+

Examples

+

Basic usage:

+ +
+use aho_corasick::{AhoCorasickBuilder, MatchKind};
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::Standard)
+    .build(&["foo", "bar", "baz"]);
+assert!(ac.supports_overlapping());
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::LeftmostFirst)
+    .build(&["foo", "bar", "baz"]);
+assert!(!ac.supports_overlapping());
+

pub fn supports_stream(&self) -> bool[src]

Returns true if and only if this automaton supports stream searching.

+

If this returns false and stream searching (or replacing) is attempted, +then it will result in a panic.

+

Currently, only +MatchKind::Standard +supports streaming. This may be expanded in the future.

+

Examples

+

Basic usage:

+ +
+use aho_corasick::{AhoCorasickBuilder, MatchKind};
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::Standard)
+    .build(&["foo", "bar", "baz"]);
+assert!(ac.supports_stream());
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::LeftmostFirst)
+    .build(&["foo", "bar", "baz"]);
+assert!(!ac.supports_stream());
+

pub fn heap_bytes(&self) -> usize[src]

Returns the total amount of heap used by this automaton, in units of +bytes.

+

Examples

+

This example shows the difference in heap usage between a few +configurations:

+ +
This example is not tested
+use aho_corasick::{AhoCorasickBuilder, MatchKind};
+
+let ac = AhoCorasickBuilder::new()
+    .dfa(false) // default
+    .build(&["foo", "bar", "baz"]);
+assert_eq!(10_336, ac.heap_bytes());
+
+let ac = AhoCorasickBuilder::new()
+    .dfa(false) // default
+    .ascii_case_insensitive(true)
+    .build(&["foo", "bar", "baz"]);
+assert_eq!(10_384, ac.heap_bytes());
+
+let ac = AhoCorasickBuilder::new()
+    .dfa(true)
+    .byte_classes(false)
+    .build(&["foo", "bar", "baz"]);
+assert_eq!(20_768, ac.heap_bytes());
+
+let ac = AhoCorasickBuilder::new()
+    .dfa(true)
+    .byte_classes(true) // default
+    .build(&["foo", "bar", "baz"]);
+assert_eq!(1_248, ac.heap_bytes());
+
+let ac = AhoCorasickBuilder::new()
+    .dfa(true)
+    .ascii_case_insensitive(true)
+    .build(&["foo", "bar", "baz"]);
+assert_eq!(1_248, ac.heap_bytes());
+

Trait Implementations

impl<S: Clone + StateID> Clone for AhoCorasick<S>[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl<S: Debug + StateID> Debug for AhoCorasick<S>[src]

Auto Trait Implementations

impl<S> Send for AhoCorasick<S> where
    S: Send

impl<S> Sync for AhoCorasick<S> where
    S: Sync

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/aho_corasick/struct.AhoCorasickBuilder.html b/target/doc/aho_corasick/struct.AhoCorasickBuilder.html new file mode 100644 index 0000000..3270e71 --- /dev/null +++ b/target/doc/aho_corasick/struct.AhoCorasickBuilder.html @@ -0,0 +1,256 @@ +aho_corasick::AhoCorasickBuilder - Rust

[][src]Struct aho_corasick::AhoCorasickBuilder

pub struct AhoCorasickBuilder { /* fields omitted */ }

A builder for configuring an Aho-Corasick automaton.

+

Methods

impl AhoCorasickBuilder[src]

pub fn new() -> AhoCorasickBuilder[src]

Create a new builder for configuring an Aho-Corasick automaton.

+

If you don't need fine grained configuration or aren't sure which knobs +to set, try using +AhoCorasick::new_auto_configured +instead.

+

pub fn build<I, P>(&self, patterns: I) -> AhoCorasick where
    I: IntoIterator<Item = P>,
    P: AsRef<[u8]>, 
[src]

Build an Aho-Corasick automaton using the configuration set on this +builder.

+

A builder may be reused to create more automatons.

+

This method will use the default for representing internal state +identifiers, which is usize. This guarantees that building the +automaton will succeed and is generally a good default, but can make +the size of the automaton 2-8 times bigger than it needs to be, +depending on your target platform.

+

Examples

+

Basic usage:

+ +
+use aho_corasick::AhoCorasickBuilder;
+
+let patterns = &["foo", "bar", "baz"];
+let ac = AhoCorasickBuilder::new()
+    .build(patterns);
+assert_eq!(Some(1), ac.find("xxx bar xxx").map(|m| m.pattern()));
+

pub fn build_with_size<S, I, P>(
    &self,
    patterns: I
) -> Result<AhoCorasick<S>, Error> where
    S: StateID,
    I: IntoIterator<Item = P>,
    P: AsRef<[u8]>, 
[src]

Build an Aho-Corasick automaton using the configuration set on this +builder with a specific state identifier representation. This only has +an effect when the dfa option is enabled.

+

Generally, the choices for a state identifier representation are +u8, u16, u32, u64 or usize, with usize being the default. +The advantage of choosing a smaller state identifier representation +is that the automaton produced will be smaller. This might be +beneficial for just generally using less space, or might even allow it +to fit more of the automaton in your CPU's cache, leading to overall +better search performance.

+

Unlike the standard build method, this can report an error if the +state identifier representation cannot support the size of the +automaton.

+

Note that the state identifier representation is determined by the +S type variable. This requires a type hint of some sort, either +by specifying the return type or using the turbofish, e.g., +build_with_size::<u16, _, _>(...).

+

Examples

+

Basic usage:

+ +
+use aho_corasick::{AhoCorasick, AhoCorasickBuilder};
+
+let patterns = &["foo", "bar", "baz"];
+let ac: AhoCorasick<u8> = AhoCorasickBuilder::new()
+    .build_with_size(patterns)?;
+assert_eq!(Some(1), ac.find("xxx bar xxx").map(|m| m.pattern()));
+

Or alternatively, with turbofish:

+ +
+use aho_corasick::AhoCorasickBuilder;
+
+let patterns = &["foo", "bar", "baz"];
+let ac = AhoCorasickBuilder::new()
+    .build_with_size::<u8, _, _>(patterns)?;
+assert_eq!(Some(1), ac.find("xxx bar xxx").map(|m| m.pattern()));
+

pub fn auto_configure<B: AsRef<[u8]>>(
    &mut self,
    patterns: &[B]
) -> &mut AhoCorasickBuilder
[src]

Automatically configure the settings on this builder according to the +patterns that will be used to construct the automaton.

+

The idea here is to balance space and time automatically. That is, when +searching a small number of patterns, this will attempt to use the +fastest possible configuration since the total space required will be +small anyway. As the number of patterns grows, this will fall back to +slower configurations that use less space.

+

This is guaranteed to never set match_kind, but any other option may +be overridden.

+

Examples

+

Basic usage:

+ +
+use aho_corasick::AhoCorasickBuilder;
+
+let patterns = &["foo", "bar", "baz"];
+let ac = AhoCorasickBuilder::new()
+    .auto_configure(patterns)
+    .build(patterns);
+assert_eq!(Some(1), ac.find("xxx bar xxx").map(|m| m.pattern()));
+

pub fn match_kind(&mut self, kind: MatchKind) -> &mut AhoCorasickBuilder[src]

Set the desired match semantics.

+

The default is MatchKind::Standard, which corresponds to the match +semantics supported by the standard textbook description of the +Aho-Corasick algorithm. Namely, matches are reported as soon as they +are found. Moreover, this is the only way to get overlapping matches +or do stream searching.

+

The other kinds of match semantics that are supported are +MatchKind::LeftmostFirst and MatchKind::LeftmostLongest. The former +corresponds to the match you would get if you were to try to match +each pattern at each position in the haystack in the same order that +you give to the automaton. That is, it returns the leftmost match +corresponding the earliest pattern given to the automaton. The latter +corresponds to finding the longest possible match among all leftmost +matches.

+

For more details on match semantics, see the +documentation for MatchKind.

+

Examples

+

In these examples, we demonstrate the differences between match +semantics for a particular set of patterns in a specific order: +b, abc, abcd.

+

Standard semantics:

+ +
+use aho_corasick::{AhoCorasickBuilder, MatchKind};
+
+let patterns = &["b", "abc", "abcd"];
+let haystack = "abcd";
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::Standard) // default, not necessary
+    .build(patterns);
+let mat = ac.find(haystack).expect("should have a match");
+assert_eq!("b", &haystack[mat.start()..mat.end()]);
+

Leftmost-first semantics:

+ +
+use aho_corasick::{AhoCorasickBuilder, MatchKind};
+
+let patterns = &["b", "abc", "abcd"];
+let haystack = "abcd";
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::LeftmostFirst)
+    .build(patterns);
+let mat = ac.find(haystack).expect("should have a match");
+assert_eq!("abc", &haystack[mat.start()..mat.end()]);
+

Leftmost-longest semantics:

+ +
+use aho_corasick::{AhoCorasickBuilder, MatchKind};
+
+let patterns = &["b", "abc", "abcd"];
+let haystack = "abcd";
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::LeftmostLongest)
+    .build(patterns);
+let mat = ac.find(haystack).expect("should have a match");
+assert_eq!("abcd", &haystack[mat.start()..mat.end()]);
+

pub fn ascii_case_insensitive(&mut self, yes: bool) -> &mut AhoCorasickBuilder[src]

Enable ASCII-aware case insensitive matching.

+

When this option is enabled, searching will be performed without +respect to case for ASCII letters (a-z and A-Z) only.

+

Enabling this option does not change the search algorithm, but it may +increase the size of the automaton.

+

NOTE: In the future, support for full Unicode case insensitivity +may be added, but ASCII case insensitivity is comparatively much +simpler to add.

+

Examples

+

Basic usage:

+ +
+use aho_corasick::AhoCorasickBuilder;
+
+let patterns = &["FOO", "bAr", "BaZ"];
+let haystack = "foo bar baz";
+
+let ac = AhoCorasickBuilder::new()
+    .ascii_case_insensitive(true)
+    .build(patterns);
+assert_eq!(3, ac.find_iter(haystack).count());
+

pub fn dense_depth(&mut self, depth: usize) -> &mut AhoCorasickBuilder[src]

Set the limit on how many NFA states use a dense representation for +their transitions.

+

A dense representation uses more space, but supports faster access to +transitions at search time. Thus, this setting permits the control of a +space vs time trade off when using the NFA variant of Aho-Corasick.

+

This limit is expressed in terms of the depth of a state, i.e., the +number of transitions from the starting state of the NFA. The idea is +that most of the time searching will be spent near the starting state +of the automaton, so states near the start state should use a dense +representation. States further away from the start state would then use +a sparse representation, which uses less space but is slower to access +transitions at search time.

+

By default, this is set to a low but non-zero number.

+

This setting has no effect if the dfa option is enabled.

+

pub fn dfa(&mut self, yes: bool) -> &mut AhoCorasickBuilder[src]

Compile the standard Aho-Corasick automaton into a deterministic finite +automaton (DFA).

+

When this is disabled (which is the default), then a non-deterministic +finite automaton (NFA) is used instead.

+

The main benefit to a DFA is that it can execute searches more quickly +than a DFA (perhaps 2-4 times as fast). The main drawback is that the +DFA uses more space and can take much longer to build.

+

Enabling this option does not change the time complexity for +constructing the Aho-Corasick automaton (which is O(p) where +p is the total number of patterns being compiled). Enabling this +option does however reduce the time complexity of non-overlapping +searches from O(n + p) to O(n), where n is the length of the +haystack.

+

In general, it's a good idea to enable this if you're searching a +small number of fairly short patterns (~1000), or if you want the +fastest possible search without regard to compilation time or space +usage.

+

pub fn prefilter(&mut self, yes: bool) -> &mut AhoCorasickBuilder[src]

Enable heuristic prefilter optimizations.

+

When enabled, searching will attempt to quickly skip to match +candidates using specialized literal search routines. A prefilter +cannot always be used, and is generally treated as a heuristic. It +can be useful to disable this if the prefilter is observed to be +sub-optimal for a particular workload.

+

This is enabled by default.

+

pub fn byte_classes(&mut self, yes: bool) -> &mut AhoCorasickBuilder[src]

Shrink the size of the transition alphabet by mapping bytes to their +equivalence classes. This only has an effect when the dfa option is +enabled.

+

When enabled, each a DFA will use a map from all possible bytes +to their corresponding equivalence class. Each equivalence class +represents a set of bytes that does not discriminate between a match +and a non-match in the DFA. For example, the patterns bar and baz +have at least five equivalence classes: singleton sets of b, a, r +and z, and a final set that contains every other byte.

+

The advantage of this map is that the size of the transition table can +be reduced drastically from #states * 256 * sizeof(id) to +#states * k * sizeof(id) where k is the number of equivalence +classes. As a result, total space usage can decrease substantially. +Moreover, since a smaller alphabet is used, compilation becomes faster +as well.

+

The disadvantage of this map is that every byte searched must be +passed through this map before it can be used to determine the next +transition. This has a small match time performance cost. However, if +the DFA is otherwise very large without byte classes, then using byte +classes can greatly improve memory locality and thus lead to better +overall performance.

+

This option is enabled by default.

+

pub fn premultiply(&mut self, yes: bool) -> &mut AhoCorasickBuilder[src]

Premultiply state identifiers in the transition table. This only has +an effect when the dfa option is enabled.

+

When enabled, state identifiers are premultiplied to point to their +corresponding row in the transition table. That is, given the ith +state, its corresponding premultiplied identifier is i * k where k +is the alphabet size of the automaton. (The alphabet size is at most +256, but is in practice smaller if byte classes is enabled.)

+

When state identifiers are not premultiplied, then the identifier of +the ith state is i.

+

The advantage of premultiplying state identifiers is that is saves a +multiplication instruction per byte when searching with a DFA. This has +been observed to lead to a 20% performance benefit in micro-benchmarks.

+

The primary disadvantage of premultiplying state identifiers is +that they require a larger integer size to represent. For example, +if the DFA has 200 states, then its premultiplied form requires 16 +bits to represent every possible state identifier, where as its +non-premultiplied form only requires 8 bits.

+

This option is enabled by default.

+

Trait Implementations

impl Clone for AhoCorasickBuilder[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Default for AhoCorasickBuilder[src]

impl Debug for AhoCorasickBuilder[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/aho_corasick/struct.Error.html b/target/doc/aho_corasick/struct.Error.html new file mode 100644 index 0000000..0586679 --- /dev/null +++ b/target/doc/aho_corasick/struct.Error.html @@ -0,0 +1,26 @@ +aho_corasick::Error - Rust

[][src]Struct aho_corasick::Error

pub struct Error { /* fields omitted */ }

An error that occurred during the construction of an Aho-Corasick +automaton.

+

Methods

impl Error[src]

pub fn kind(&self) -> &ErrorKind[src]

Return the kind of this error.

+

Trait Implementations

impl Clone for Error[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Display for Error[src]

impl Debug for Error[src]

impl Error for Error[src]

fn cause(&self) -> Option<&dyn Error>1.0.0[src]

Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

+

The lower-level cause of this error, if any. Read more

+

fn source(&self) -> Option<&(dyn Error + 'static)>1.30.0[src]

The lower-level source of this error, if any. Read more

+

Auto Trait Implementations

impl Send for Error

impl Sync for Error

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/aho_corasick/struct.FindIter.html b/target/doc/aho_corasick/struct.FindIter.html new file mode 100644 index 0000000..0b8b508 --- /dev/null +++ b/target/doc/aho_corasick/struct.FindIter.html @@ -0,0 +1,89 @@ +aho_corasick::FindIter - Rust

[][src]Struct aho_corasick::FindIter

pub struct FindIter<'a, 'b, S: 'a + StateID> { /* fields omitted */ }

An iterator of non-overlapping matches in a particular haystack.

+

This iterator yields matches according to the +MatchKind +used by this automaton.

+

This iterator is constructed via the +AhoCorasick::find_iter +method.

+

The type variable S refers to the representation used for state +identifiers. (By default, this is usize.)

+

The lifetime 'a refers to the lifetime of the AhoCorasick automaton.

+

The lifetime 'b refers to the lifetime of the haystack being searched.

+

Trait Implementations

impl<'a, 'b, S: StateID> Iterator for FindIter<'a, 'b, S>[src]

type Item = Match

The type of the elements being iterated over.

+

fn size_hint(&self) -> (usize, Option<usize>)1.0.0[src]

Returns the bounds on the remaining length of the iterator. Read more

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

impl<'a, 'b, S: Debug + 'a + StateID> Debug for FindIter<'a, 'b, S>[src]

Auto Trait Implementations

impl<'a, 'b, S> Send for FindIter<'a, 'b, S> where
    S: Send + Sync

impl<'a, 'b, S> Sync for FindIter<'a, 'b, S> where
    S: Sync

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/aho_corasick/struct.FindOverlappingIter.html b/target/doc/aho_corasick/struct.FindOverlappingIter.html new file mode 100644 index 0000000..010e4a0 --- /dev/null +++ b/target/doc/aho_corasick/struct.FindOverlappingIter.html @@ -0,0 +1,88 @@ +aho_corasick::FindOverlappingIter - Rust

[][src]Struct aho_corasick::FindOverlappingIter

pub struct FindOverlappingIter<'a, 'b, S: 'a + StateID> { /* fields omitted */ }

An iterator of overlapping matches in a particular haystack.

+

This iterator will report all possible matches in a particular haystack, +even when the matches overlap.

+

This iterator is constructed via the +AhoCorasick::find_overlapping_iter +method.

+

The type variable S refers to the representation used for state +identifiers. (By default, this is usize.)

+

The lifetime 'a refers to the lifetime of the AhoCorasick automaton.

+

The lifetime 'b refers to the lifetime of the haystack being searched.

+

Trait Implementations

impl<'a, 'b, S: StateID> Iterator for FindOverlappingIter<'a, 'b, S>[src]

type Item = Match

The type of the elements being iterated over.

+

fn size_hint(&self) -> (usize, Option<usize>)1.0.0[src]

Returns the bounds on the remaining length of the iterator. Read more

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

impl<'a, 'b, S: Debug + 'a + StateID> Debug for FindOverlappingIter<'a, 'b, S>[src]

Auto Trait Implementations

impl<'a, 'b, S> Send for FindOverlappingIter<'a, 'b, S> where
    S: Send + Sync

impl<'a, 'b, S> Sync for FindOverlappingIter<'a, 'b, S> where
    S: Sync

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/aho_corasick/struct.Match.html b/target/doc/aho_corasick/struct.Match.html new file mode 100644 index 0000000..5da98ef --- /dev/null +++ b/target/doc/aho_corasick/struct.Match.html @@ -0,0 +1,49 @@ +aho_corasick::Match - Rust

[][src]Struct aho_corasick::Match

pub struct Match { /* fields omitted */ }

A representation of a match reported by an Aho-Corasick automaton.

+

A match has two essential pieces of information: the identifier of the +pattern that matched, along with the start and end offsets of the match +in the haystack.

+

Examples

+

Basic usage:

+ +
+use aho_corasick::AhoCorasick;
+
+let ac = AhoCorasick::new(&[
+    "foo", "bar", "baz",
+]);
+let mat = ac.find("xxx bar xxx").expect("should have a match");
+assert_eq!(1, mat.pattern());
+assert_eq!(4, mat.start());
+assert_eq!(7, mat.end());
+

Methods

impl Match[src]

pub fn pattern(&self) -> usize[src]

Returns the identifier of the pattern that matched.

+

The identifier of a pattern is derived from the position in which it +was originally inserted into the corresponding automaton. The first +pattern has identifier 0, and each subsequent pattern is 1, 2 +and so on.

+

pub fn start(&self) -> usize[src]

The starting position of the match.

+

pub fn end(&self) -> usize[src]

The ending position of the match.

+

pub fn is_empty(&self) -> bool[src]

Returns true if and only if this match is empty. That is, when +start() == end().

+

An empty match can only be returned when the empty string was among +the patterns used to build the Aho-Corasick automaton.

+

Trait Implementations

impl PartialEq<Match> for Match[src]

impl Clone for Match[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Match[src]

impl Debug for Match[src]

impl Hash for Match[src]

fn hash_slice<H>(data: &[Self], state: &mut H) where
    H: Hasher
1.3.0[src]

Feeds a slice of this type into the given [Hasher]. Read more

+

Auto Trait Implementations

impl Send for Match

impl Sync for Match

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/aho_corasick/struct.StreamFindIter.html b/target/doc/aho_corasick/struct.StreamFindIter.html new file mode 100644 index 0000000..9c20087 --- /dev/null +++ b/target/doc/aho_corasick/struct.StreamFindIter.html @@ -0,0 +1,90 @@ +aho_corasick::StreamFindIter - Rust

[][src]Struct aho_corasick::StreamFindIter

pub struct StreamFindIter<'a, R, S: 'a + StateID> { /* fields omitted */ }

An iterator that reports Aho-Corasick matches in a stream.

+

This iterator yields elements of type io::Result<Match>, where an error +is reported if there was a problem reading from the underlying stream. +The iterator terminates only when the underlying stream reaches EOF.

+

This iterator is constructed via the +AhoCorasick::stream_find_iter +method.

+

The type variable R refers to the io::Read stream that is being read +from.

+

The type variable S refers to the representation used for state +identifiers. (By default, this is usize.)

+

The lifetime 'a refers to the lifetime of the AhoCorasick automaton.

+

Trait Implementations

impl<'a, R: Read, S: StateID> Iterator for StreamFindIter<'a, R, S>[src]

type Item = Result<Match>

The type of the elements being iterated over.

+

fn size_hint(&self) -> (usize, Option<usize>)1.0.0[src]

Returns the bounds on the remaining length of the iterator. Read more

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

impl<'a, R: Debug, S: Debug + 'a + StateID> Debug for StreamFindIter<'a, R, S>[src]

Auto Trait Implementations

impl<'a, R, S> Send for StreamFindIter<'a, R, S> where
    R: Send,
    S: Send + Sync

impl<'a, R, S> Sync for StreamFindIter<'a, R, S> where
    R: Sync,
    S: Sync

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/aho_corasick/trait.StateID.html b/target/doc/aho_corasick/trait.StateID.html new file mode 100644 index 0000000..89f9169 --- /dev/null +++ b/target/doc/aho_corasick/trait.StateID.html @@ -0,0 +1,43 @@ +aho_corasick::StateID - Rust

[][src]Trait aho_corasick::StateID

pub unsafe trait StateID: Sealed + Clone + Copy + Debug + Eq + Hash + PartialEq + PartialOrd + Ord {
+    fn from_usize(n: usize) -> Self;
+
fn to_usize(self) -> usize; +
fn max_id() -> usize; +}

A trait describing the representation of an automaton's state identifier.

+

The purpose of this trait is to safely express both the possible state +identifier representations that can be used in an automaton and to convert +between state identifier representations and types that can be used to +efficiently index memory (such as usize).

+

In general, one should not need to implement this trait explicitly. Indeed, +for now, this trait is sealed such that it cannot be implemented by any +other type. In particular, this crate provides implementations for u8, +u16, u32, u64 and usize. (u32 and u64 are only provided for +targets that can represent all corresponding values in a usize.)

+

Safety

+

This trait is unsafe because the correctness of its implementations may be +relied upon by other unsafe code. For example, one possible way to +implement this trait incorrectly would be to return a maximum identifier +in max_id that is greater than the real maximum identifier. This will +likely result in wrap-on-overflow semantics in release mode, which can in +turn produce incorrect state identifiers. Those state identifiers may then +in turn access out-of-bounds memory in an automaton's search routine, where +bounds checks are explicitly elided for performance reasons.

+
+

Required methods

fn from_usize(n: usize) -> Self

Convert from a usize to this implementation's representation.

+

Implementors may assume that n <= Self::max_id. That is, implementors +do not need to check whether n can fit inside this implementation's +representation.

+

fn to_usize(self) -> usize

Convert this implementation's representation to a usize.

+

Implementors must not return a usize value greater than +Self::max_id and must not permit overflow when converting between the +implementor's representation and usize. In general, the preferred +way for implementors to achieve this is to simply not provide +implementations of StateID that cannot fit into the target platform's +usize.

+

fn max_id() -> usize

Return the maximum state identifier supported by this representation.

+

Implementors must return a correct bound. Doing otherwise may result +in memory unsafety.

+
Loading content... +

Implementations on Foreign Types

impl StateID for usize[src]

impl StateID for u8[src]

impl StateID for u16[src]

impl StateID for u32[src]

impl StateID for u64[src]

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/aliases.js b/target/doc/aliases.js new file mode 100644 index 0000000..30cd9e2 --- /dev/null +++ b/target/doc/aliases.js @@ -0,0 +1,17 @@ +var ALIASES = {}; +ALIASES["aho_corasick"] = {}; +ALIASES["c2_chacha"] = {}; +ALIASES["cfg_if"] = {}; +ALIASES["getrandom"] = {}; +ALIASES["lazy_static"] = {}; +ALIASES["memchr"] = {}; +ALIASES["owoify"] = {}; +ALIASES["ppv_lite86"] = {}; +ALIASES["rand"] = {}; +ALIASES["rand_chacha"] = {}; +ALIASES["rand_core"] = {}; +ALIASES["regex"] = {}; +ALIASES["regex_syntax"] = {}; +ALIASES["thread_local"] = {}; +ALIASES["ucd_util"] = {}; +ALIASES["utf8_ranges"] = {}; diff --git a/target/doc/brush.svg b/target/doc/brush.svg new file mode 100644 index 0000000..072264a --- /dev/null +++ b/target/doc/brush.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/target/doc/c2_chacha/all.html b/target/doc/c2_chacha/all.html new file mode 100644 index 0000000..09427d2 --- /dev/null +++ b/target/doc/c2_chacha/all.html @@ -0,0 +1,3 @@ +List of all items in this crate

[] + + List of all items

Structs

Traits

\ No newline at end of file diff --git a/target/doc/c2_chacha/guts/index.html b/target/doc/c2_chacha/guts/index.html new file mode 100644 index 0000000..7dd0cb1 --- /dev/null +++ b/target/doc/c2_chacha/guts/index.html @@ -0,0 +1,3 @@ +c2_chacha::guts - Rust

[][src]Module c2_chacha::guts

Structs

+
ChaCha
State

Traits

+
Machine
\ No newline at end of file diff --git a/target/doc/c2_chacha/guts/sidebar-items.js b/target/doc/c2_chacha/guts/sidebar-items.js new file mode 100644 index 0000000..fe17ac6 --- /dev/null +++ b/target/doc/c2_chacha/guts/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["ChaCha",""],["State",""]],"trait":[["Machine",""]]}); \ No newline at end of file diff --git a/target/doc/c2_chacha/guts/struct.ChaCha.html b/target/doc/c2_chacha/guts/struct.ChaCha.html new file mode 100644 index 0000000..a587738 --- /dev/null +++ b/target/doc/c2_chacha/guts/struct.ChaCha.html @@ -0,0 +1,18 @@ +c2_chacha::guts::ChaCha - Rust

[][src]Struct c2_chacha::guts::ChaCha

pub struct ChaCha { /* fields omitted */ }

Methods

impl ChaCha[src]

pub fn new(key: &[u8; 32], nonce: &[u8]) -> Self[src]

pub fn refill4(&mut self, drounds: u32, out: &mut [u8; 256])[src]

Produce 4 blocks of output, advancing the state

+

pub fn refill(&mut self, drounds: u32, out: &mut [u8; 64])[src]

Produce a block of output, advancing the state

+

pub fn set_stream_param(&mut self, param: u32, value: u64)[src]

pub fn get_stream_param(&self, param: u32) -> u64[src]

Trait Implementations

impl Clone for ChaCha[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

Auto Trait Implementations

impl Send for ChaCha

impl Sync for ChaCha

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/c2_chacha/guts/struct.State.html b/target/doc/c2_chacha/guts/struct.State.html new file mode 100644 index 0000000..124618d --- /dev/null +++ b/target/doc/c2_chacha/guts/struct.State.html @@ -0,0 +1,16 @@ +c2_chacha::guts::State - Rust

[][src]Struct c2_chacha::guts::State

pub struct State<V> { /* fields omitted */ }

Trait Implementations

impl<V: Clone> Clone for State<V>[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

Auto Trait Implementations

impl<V> Send for State<V> where
    V: Send

impl<V> Sync for State<V> where
    V: Sync

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/c2_chacha/guts/trait.Machine.html b/target/doc/c2_chacha/guts/trait.Machine.html new file mode 100644 index 0000000..c815460 --- /dev/null +++ b/target/doc/c2_chacha/guts/trait.Machine.html @@ -0,0 +1,29 @@ +c2_chacha::guts::Machine - Rust

[][src]Trait c2_chacha::guts::Machine

pub trait Machine: Copy {
+    type u32x4: u32x4<Self>;
+    type u64x2: u64x2<Self>;
+    type u128x1: u128x1<Self>;
+    type u32x4x2: u32x4x2<Self>;
+    type u64x2x2: u64x2x2<Self>;
+    type u64x4: u64x4<Self>;
+    type u128x2: u128x2<Self>;
+    type u32x4x4: u32x4x4<Self>;
+    type u64x2x4: u64x2x4<Self>;
+    type u128x4: u128x4<Self>;
+    unsafe fn instance() -> Self;
+
+    fn unpack<S, V>(self, s: S) -> V
    where
        V: Store<S>
, + { ... } +
fn vec<V, A>(self, a: A) -> V
    where
        V: MultiLane<A>
, + { ... } +
fn read_le<V>(self, input: &[u8]) -> V
    where
        V: StoreBytes
, + { ... } +
fn read_be<V>(self, input: &[u8]) -> V
    where
        V: StoreBytes
, + { ... } +}
+

Associated Types

type u32x4: u32x4<Self>

type u64x2: u64x2<Self>

type u128x1: u128x1<Self>

type u32x4x2: u32x4x2<Self>

type u64x2x2: u64x2x2<Self>

type u64x4: u64x4<Self>

type u128x2: u128x2<Self>

type u32x4x4: u32x4x4<Self>

type u64x2x4: u64x2x4<Self>

type u128x4: u128x4<Self>

Loading content... +

Required methods

unsafe fn instance() -> Self

Loading content... +

Provided methods

fn unpack<S, V>(self, s: S) -> V where
    V: Store<S>, 

fn vec<V, A>(self, a: A) -> V where
    V: MultiLane<A>, 

fn read_le<V>(self, input: &[u8]) -> V where
    V: StoreBytes

fn read_be<V>(self, input: &[u8]) -> V where
    V: StoreBytes

Loading content... +

Implementations on Foreign Types

impl<S3, S4, NI> Machine for SseMachine<S3, S4, NI> where
    NI: Copy,
    S3: Copy,
    S4: Copy,
    u128x1_sse2<S3, S4, NI>: Swap64,
    u64x2_sse2<S3, S4, NI>: BSwap,
    u64x2_sse2<S3, S4, NI>: RotateEachWord32,
    u64x2_sse2<S3, S4, NI>: MultiLane<[u64; 2]>,
    u64x2_sse2<S3, S4, NI>: Vec2<u64>,
    u32x4_sse2<S3, S4, NI>: BSwap,
    u32x4_sse2<S3, S4, NI>: RotateEachWord32,
    u32x4_sse2<S3, S4, NI>: MultiLane<[u32; 4]>,
    u32x4_sse2<S3, S4, NI>: Vec4<u32>,
    x2<u64x2_sse2<S3, S4, NI>, G1>: BSwap,
    x2<u64x2_sse2<S3, S4, NI>, G1>: Words4,
    u128x1_sse2<S3, S4, NI>: BSwap,
    x2<u128x1_sse2<S3, S4, NI>, G0>: Into<x2<u64x2_sse2<S3, S4, NI>, G0>>,
    x2<u128x1_sse2<S3, S4, NI>, G0>: Into<x2<u64x2_sse2<S3, S4, NI>, G1>>,
    x2<u128x1_sse2<S3, S4, NI>, G0>: Into<x2<u32x4_sse2<S3, S4, NI>, G0>>,
    x4<u128x1_sse2<S3, S4, NI>>: Into<x4<u64x2_sse2<S3, S4, NI>>>,
    x4<u128x1_sse2<S3, S4, NI>>: Into<x4<u32x4_sse2<S3, S4, NI>>>, 
[src]

type u32x4 = u32x4_sse2<S3, S4, NI>

type u64x2 = u64x2_sse2<S3, S4, NI>

type u128x1 = u128x1_sse2<S3, S4, NI>

type u32x4x2 = x2<u32x4_sse2<S3, S4, NI>, G0>

type u64x2x2 = x2<u64x2_sse2<S3, S4, NI>, G0>

type u64x4 = x2<u64x2_sse2<S3, S4, NI>, G1>

type u128x2 = x2<u128x1_sse2<S3, S4, NI>, G0>

type u32x4x4 = x4<u32x4_sse2<S3, S4, NI>>

type u64x2x4 = x4<u64x2_sse2<S3, S4, NI>>

type u128x4 = x4<u128x1_sse2<S3, S4, NI>>

fn unpack<S, V>(self, s: S) -> V where
    V: Store<S>, 
[src]

fn vec<V, A>(self, a: A) -> V where
    V: MultiLane<A>, 
[src]

fn read_le<V>(self, input: &[u8]) -> V where
    V: StoreBytes
[src]

fn read_be<V>(self, input: &[u8]) -> V where
    V: StoreBytes
[src]

impl<NI> Machine for Avx2Machine<NI> where
    NI: Copy,
    u128x1_sse2<YesS3, YesS4, NI>: BSwap,
    u128x1_sse2<YesS3, YesS4, NI>: Swap64,
    u64x2_sse2<YesS3, YesS4, NI>: BSwap,
    u64x2_sse2<YesS3, YesS4, NI>: RotateEachWord32,
    u64x2_sse2<YesS3, YesS4, NI>: MultiLane<[u64; 2]>,
    u64x2_sse2<YesS3, YesS4, NI>: Vec2<u64>,
    u32x4_sse2<YesS3, YesS4, NI>: BSwap,
    u32x4_sse2<YesS3, YesS4, NI>: RotateEachWord32,
    u32x4_sse2<YesS3, YesS4, NI>: MultiLane<[u32; 4]>,
    u32x4_sse2<YesS3, YesS4, NI>: Vec4<u32>,
    x2<u64x2_sse2<YesS3, YesS4, NI>, G1>: BSwap,
    x2<u64x2_sse2<YesS3, YesS4, NI>, G1>: Words4
[src]

type u32x4 = u32x4_sse2<YesS3, YesS4, NI>

type u64x2 = u64x2_sse2<YesS3, YesS4, NI>

type u128x1 = u128x1_sse2<YesS3, YesS4, NI>

type u32x4x2 = x2<u32x4_sse2<YesS3, YesS4, NI>, G0>

type u64x2x2 = x2<u64x2_sse2<YesS3, YesS4, NI>, G0>

type u64x4 = x2<u64x2_sse2<YesS3, YesS4, NI>, G1>

type u128x2 = x2<u128x1_sse2<YesS3, YesS4, NI>, G0>

type u32x4x4 = u32x4x4_avx2<NI>

type u64x2x4 = x4<u64x2_sse2<YesS3, YesS4, NI>>

type u128x4 = x4<u128x1_sse2<YesS3, YesS4, NI>>

fn unpack<S, V>(self, s: S) -> V where
    V: Store<S>, 
[src]

fn vec<V, A>(self, a: A) -> V where
    V: MultiLane<A>, 
[src]

fn read_le<V>(self, input: &[u8]) -> V where
    V: StoreBytes
[src]

fn read_be<V>(self, input: &[u8]) -> V where
    V: StoreBytes
[src]

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/c2_chacha/index.html b/target/doc/c2_chacha/index.html new file mode 100644 index 0000000..d8460f9 --- /dev/null +++ b/target/doc/c2_chacha/index.html @@ -0,0 +1,28 @@ +c2_chacha - Rust

[][src]Crate c2_chacha

Pure Rust ChaCha with SIMD optimizations.

+

Stream-cipher usage:

+ +
+extern crate c2_chacha;
+
+use c2_chacha::stream_cipher::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek};
+use c2_chacha::{ChaCha20, ChaCha12};
+
+let key = b"very secret key-the most secret.";
+let iv = b"my nonce";
+let plaintext = b"The quick brown fox jumps over the lazy dog.";
+
+let mut buffer = plaintext.to_vec();
+// create cipher instance
+let mut cipher = ChaCha20::new_var(key, iv).unwrap();
+// apply keystream (encrypt)
+cipher.apply_keystream(&mut buffer);
+// and decrypt it back
+cipher.seek(0);
+cipher.apply_keystream(&mut buffer);
+// stream ciphers can be used with streaming messages
+let mut cipher = ChaCha12::new_var(key, iv).unwrap();
+for chunk in buffer.chunks_mut(3) {
+    cipher.apply_keystream(chunk);
+}
+

Modules

+
guts
\ No newline at end of file diff --git a/target/doc/c2_chacha/sidebar-items.js b/target/doc/c2_chacha/sidebar-items.js new file mode 100644 index 0000000..ea58fe3 --- /dev/null +++ b/target/doc/c2_chacha/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"mod":[["guts",""]]}); \ No newline at end of file diff --git a/target/doc/cfg_if/all.html b/target/doc/cfg_if/all.html new file mode 100644 index 0000000..b4c79f3 --- /dev/null +++ b/target/doc/cfg_if/all.html @@ -0,0 +1,3 @@ +List of all items in this crate

[] + + List of all items

Macros

\ No newline at end of file diff --git a/target/doc/cfg_if/index.html b/target/doc/cfg_if/index.html new file mode 100644 index 0000000..43b04d7 --- /dev/null +++ b/target/doc/cfg_if/index.html @@ -0,0 +1,25 @@ +cfg_if - Rust

[][src]Crate cfg_if

A macro for defining #[cfg] if-else statements.

+

The macro provided by this crate, cfg_if, is similar to the if/elif C +preprocessor macro by allowing definition of a cascade of #[cfg] cases, +emitting the implementation which matches first.

+

This allows you to conveniently provide a long list #[cfg]'d blocks of code +without having to rewrite each clause multiple times.

+

Example

+
+#[macro_use]
+extern crate cfg_if;
+
+cfg_if! {
+    if #[cfg(unix)] {
+        fn foo() { /* unix specific functionality */ }
+    } else if #[cfg(target_pointer_width = "32")] {
+        fn foo() { /* non-unix, 32-bit functionality */ }
+    } else {
+        fn foo() { /* fallback implementation */ }
+    }
+}
+
+

Macros

+
cfg_if

The main macro provided by this crate. See crate documentation for more +information.

+
\ No newline at end of file diff --git a/target/doc/cfg_if/macro.cfg_if!.html b/target/doc/cfg_if/macro.cfg_if!.html new file mode 100644 index 0000000..36f9a6d --- /dev/null +++ b/target/doc/cfg_if/macro.cfg_if!.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to macro.cfg_if.html...

+ + + \ No newline at end of file diff --git a/target/doc/cfg_if/macro.cfg_if.html b/target/doc/cfg_if/macro.cfg_if.html new file mode 100644 index 0000000..d80c207 --- /dev/null +++ b/target/doc/cfg_if/macro.cfg_if.html @@ -0,0 +1,20 @@ +cfg_if::cfg_if - Rust

[][src]Macro cfg_if::cfg_if

+macro_rules! cfg_if {
+    ($(
+        if #[cfg($($meta:meta),*)] { $($it:item)* }
+    ) else * else {
+        $($it2:item)*
+    }) => { ... };
+    (
+        if #[cfg($($i_met:meta),*)] { $($i_it:item)* }
+        $(
+            else if #[cfg($($e_met:meta),*)] { $($e_it:item)* }
+        )*
+    ) => { ... };
+    (@__items ($($not:meta,)*) ; ) => { ... };
+    (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => { ... };
+    (@__apply $m:meta, $($it:item)*) => { ... };
+}
+

The main macro provided by this crate. See crate documentation for more +information.

+
\ No newline at end of file diff --git a/target/doc/cfg_if/sidebar-items.js b/target/doc/cfg_if/sidebar-items.js new file mode 100644 index 0000000..dbc0f91 --- /dev/null +++ b/target/doc/cfg_if/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"macro":[["cfg_if","The main macro provided by this crate. See crate documentation for more information."]]}); \ No newline at end of file diff --git a/target/doc/dark.css b/target/doc/dark.css new file mode 100644 index 0000000..0f090c4 --- /dev/null +++ b/target/doc/dark.css @@ -0,0 +1 @@ +body{background-color:#353535;color:#ddd;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){color:#ddd;}h1.fqn{border-bottom-color:#d2d2d2;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){border-bottom-color:#d2d2d2;}.in-band{background-color:#353535;}.invisible{background:rgba(0,0,0,0);}.docblock code,.docblock-short code{background-color:#2A2A2A;}pre{background-color:#2A2A2A;}.sidebar{background-color:#505050;}.sidebar .current{background-color:#333;}.source .sidebar{background-color:#353535;}.sidebar .location{border-color:#fff;background:#575757;color:#DDD;}.sidebar .version{border-bottom-color:#DDD;}.sidebar-title{border-top-color:#777;border-bottom-color:#777;}.block a:hover{background:#444;}.line-numbers span{color:#3B91E2;}.line-numbers .line-highlighted{background-color:#0a042f !important;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom-color:#DDD;}.docblock table,.docblock table td,.docblock table th{border-color:#ddd;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#ddd;}.content .highlighted{color:#eee !important;background-color:#616161;}.content .highlighted a,.content .highlighted span{color:#eee !important;}.content .highlighted.trait{background-color:#013191;}.content .highlighted.traitalias{background-color:#013191;}.content .highlighted.mod,.content .highlighted.externcrate{background-color:#afc6e4;}.content .highlighted.mod{background-color:#803a1b;}.content .highlighted.externcrate{background-color:#396bac;}.content .highlighted.enum{background-color:#5b4e68;}.content .highlighted.struct{background-color:#194e9f;}.content .highlighted.union{background-color:#b7bd49;}.content .highlighted.fn,.content .highlighted.method,.content .highlighted.tymethod{background-color:#4950ed;}.content .highlighted.type{background-color:#38902c;}.content .highlighted.foreigntype{background-color:#b200d6;}.content .highlighted.attr,.content .highlighted.derive,.content .highlighted.macro{background-color:#217d1c;}.content .highlighted.constant,.content .highlighted.static{background-color:#0063cc;}.content .highlighted.primitive{background-color:#00708a;}.content .highlighted.keyword{background-color:#884719;}.content span.enum,.content a.enum,.block a.current.enum{color:#82b089;}.content span.struct,.content a.struct,.block a.current.struct{color:#2dbfb8;}.content span.type,.content a.type,.block a.current.type{color:#ff7f00;}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{color:#dd7de8;}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{color:#09bd00;}.content span.union,.content a.union,.block a.current.union{color:#a6ae37;}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{color:#82a5c9;}.content span.primitive,.content a.primitive,.block a.current.primitive{color:#43aec7;}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{color:#bda000;}.content span.trait,.content a.trait,.block a.current.trait{color:#b78cf2;}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{color:#b397da;}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{color:#2BAB63;}.content span.keyword,.content a.keyword,.block a.current.keyword{color:#de5249;}pre.rust .comment{color:#8d8d8b;}pre.rust .doccomment{color:#8ca375;}nav{border-bottom-color:#4e4e4e;}nav.main .current{border-top-color:#eee;border-bottom-color:#eee;}nav.main .separator{border-color:#eee;}a{color:#ddd;}.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),.docblock-short a:not(.srclink):not(.test-arrow),.stability a{color:#D2991D;}.stab.internal a{color:#304FFE;}a.test-arrow{color:#dedede;}.collapse-toggle{color:#999;}#crate-search{color:#111;background-color:#f0f0f0;border-color:#000;box-shadow:0 0 0 1px #000,0 0 0 2px transparent;}.search-input{color:#111;background-color:#f0f0f0;box-shadow:0 0 0 1px #000,0 0 0 2px transparent;}.search-input:focus{border-color:#008dfd;}#crate-search+.search-input:focus{box-shadow:0 0 8px 4px #078dd8;}.module-item .stab{color:#ddd;}.stab.unstable{background:#FFF5D6;border-color:#FFC600;color:#2f2f2f;}.stab.internal{background:#FFB9B3;border-color:#B71C1C;color:#2f2f2f;}.stab.deprecated{background:#F3DFFF;border-color:#7F0087;color:#2f2f2f;}.stab.portability{background:#C4ECFF;border-color:#7BA5DB;color:#2f2f2f;}.stab.portability>code{color:#ddd;}#help>div{background:#4d4d4d;border-color:#bfbfbf;}#help dt{border-color:#bfbfbf;background:rgba(0,0,0,0);color:black;}.since{color:grey;}tr.result span.primitive::after,tr.result span.keyword::after{color:#ddd;}.line-numbers :target{background-color:transparent;}pre.rust .kw{color:#ab8ac1;}pre.rust .kw-2,pre.rust .prelude-ty{color:#769acb;}pre.rust .number,pre.rust .string{color:#83a300;}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{color:#ee6868;}pre.rust .macro,pre.rust .macro-nonterminal{color:#3E999F;}pre.rust .lifetime{color:#d97f26;}pre.rust .question-mark{color:#ff9011;}.example-wrap>pre.line-number{border-color:#4a4949;}a.test-arrow{background-color:rgba(78,139,202,0.2);}a.test-arrow:hover{background-color:#4e8bca;}.toggle-label{color:#999;}:target>code,:target>.in-band{background-color:#494a3d;}pre.compile_fail{border-left:2px solid rgba(255,0,0,.6);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.6);}.information>.compile_fail:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:rgba(255,142,0,1);}.search-failed a{color:#0089ff;}.tooltip .tooltiptext{background-color:black;color:#fff;}.tooltip .tooltiptext::after{border-color:transparent black transparent transparent;}.important-traits .tooltip .tooltiptext{background-color:white;color:black;border-color:black;}#titles>div:not(.selected){background-color:#252525;border-top-color:#252525;}#titles>div:hover,#titles>div.selected{border-top-color:#0089ff;}#titles>div>div.count{color:#888;}.modal{background-color:rgba(0,0,0,0.3);}.modal-content{background-color:#272727;border-color:#999;}.modal-content>.close{background-color:#272727;border-color:#999;}.modal-content>.close:hover{background-color:#ff1f1f;color:white;}.modal-content>.whiter{background-color:#272727;}.modal-content>.close:hover+.whiter{background-color:#ff1f1f;}@media (max-width:700px){.sidebar-menu{background-color:#505050;border-bottom-color:#e0e0e0;border-right-color:#e0e0e0;}.sidebar-elems{background-color:#505050;border-right-color:#000;}#sidebar-filler{background-color:#505050;border-bottom-color:#e0e0e0;}}kbd{color:#000;background-color:#fafbfc;border-color:#d1d5da;border-bottom-color:#c6cbd1;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu{border-color:#e0e0e0;background:#f0f0f0;}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus{border-color:#ffb900;}#theme-choices{border-color:#e0e0e0;background-color:#353535;}#theme-choices>button:not(:first-child){border-top-color:#e0e0e0;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:#4e4e4e;}@media (max-width:700px){#theme-picker{background:#f0f0f0;}}#all-types{background-color:#505050;}#all-types:hover{background-color:#606060;}.search-results td span.alias{color:#fff;}.search-results td span.grey{color:#ccc;}#sidebar-toggle{background-color:#565656;}#sidebar-toggle:hover{background-color:#676767;}#source-sidebar{background-color:#565656;}#source-sidebar>.title{border-bottom-color:#ccc;}div.files>a:hover,div.name:hover{background-color:#444;}div.files>.selected{background-color:#333;} \ No newline at end of file diff --git a/target/doc/down-arrow.svg b/target/doc/down-arrow.svg new file mode 100644 index 0000000..c0f59f0 --- /dev/null +++ b/target/doc/down-arrow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/target/doc/favicon.ico b/target/doc/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..b8ad23769ac8d06eb5973bfb3d2acbf385240f98 GIT binary patch literal 23229 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 of all items in this crate

[] + + List of all items

Structs

Functions

\ No newline at end of file diff --git a/target/doc/getrandom/error/struct.Error.html b/target/doc/getrandom/error/struct.Error.html new file mode 100644 index 0000000..20453a6 --- /dev/null +++ b/target/doc/getrandom/error/struct.Error.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../getrandom/struct.Error.html...

+ + + \ No newline at end of file diff --git a/target/doc/getrandom/fn.getrandom.html b/target/doc/getrandom/fn.getrandom.html new file mode 100644 index 0000000..46f7cb9 --- /dev/null +++ b/target/doc/getrandom/fn.getrandom.html @@ -0,0 +1,9 @@ +getrandom::getrandom - Rust

[][src]Function getrandom::getrandom

pub fn getrandom(dest: &mut [u8]) -> Result<(), Error>

Fill dest with random bytes from the system's preferred random number +source.

+

This function returns an error on any failure, including partial reads. We +make no guarantees regarding the contents of dest on error.

+

Blocking is possible, at least during early boot; see module documentation.

+

In general, getrandom will be fast enough for interactive usage, though +significantly slower than a user-space CSPRNG; for the latter consider +rand::thread_rng.

+
\ No newline at end of file diff --git a/target/doc/getrandom/index.html b/target/doc/getrandom/index.html new file mode 100644 index 0000000..f42b733 --- /dev/null +++ b/target/doc/getrandom/index.html @@ -0,0 +1,64 @@ +getrandom - Rust

[][src]Crate getrandom

Interface to the random number generator of the operating system.

+

Platform sources

+ + + + + + + + + + + + + + + + + + +
OSinterface
Linux, Androidgetrandom system call if available, otherwise /dev/urandom after reading from /dev/random once
WindowsRtlGenRandom
macOSgetentropy() if available, otherwise /dev/random (identical to /dev/urandom)
iOSSecRandomCopyBytes
FreeBSDgetrandom() if available, otherwise kern.arandom
OpenBSDgetentropy
NetBSD/dev/urandom after reading from /dev/random once
Dragonfly BSD/dev/random
Solaris, illumosgetrandom system call if available, otherwise /dev/random
Fuchsia OScprng_draw
Redoxrand:
CloudABIcloudabi_sys_random_get
Haiku/dev/random (identical to /dev/urandom)
L4RE, SGX, UEFIRDRAND
HermitRDRAND as sys_rand is currently broken.
Web browsersCrypto.getRandomValues (see Support for WebAssembly and ams.js)
Node.jscrypto.randomBytes (see Support for WebAssembly and ams.js)
WASI__wasi_random_get
+

Getrandom doesn't have a blanket implementation for all Unix-like operating +systems that reads from /dev/urandom. This ensures all supported operating +systems are using the recommended interface and respect maximum buffer +sizes.

+

Support for WebAssembly and ams.js

+

The three Emscripten targets asmjs-unknown-emscripten, +wasm32-unknown-emscripten and wasm32-experimental-emscripten use +Emscripten's emulation of /dev/random on web browsers and Node.js.

+

The bare WASM target wasm32-unknown-unknown tries to call the javascript +methods directly, using either stdweb or wasm-bindgen depending on what +features are activated for this crate. Note that if both features are +enabled wasm-bindgen will be used. If neither feature is enabled, +getrandom will always fail.

+

The WASI target wasm32-wasi uses the __wasi_random_get function defined +by the WASI standard.

+

Early boot

+

It is possible that early in the boot process the OS hasn't had enough time +yet to collect entropy to securely seed its RNG, especially on virtual +machines.

+

Some operating systems always block the thread until the RNG is securely +seeded. This can take anywhere from a few seconds to more than a minute. +Others make a best effort to use a seed from before the shutdown and don't +document much.

+

A few, Linux, NetBSD and Solaris, offer a choice between blocking and +getting an error; in these cases we always choose to block.

+

On Linux (when the genrandom system call is not available) and on NetBSD +reading from /dev/urandom never blocks, even when the OS hasn't collected +enough entropy yet. To avoid returning low-entropy bytes, we first read from +/dev/random and only switch to /dev/urandom once this has succeeded.

+

Error handling

+

We always choose failure over returning insecure "random" bytes. In general, +on supported platforms, failure is highly unlikely, though not impossible. +If an error does occur, then it is likely that it will occur on every call to +getrandom, hence after the first successful call one can be reasonably +confident that no errors will occur.

+

On unsupported platforms, getrandom always fails. See the [Error] type +for more information on what data is returned on failure.

+

Structs

+
Error

A small and no_std compatible error type.

+

Functions

+
getrandom

Fill dest with random bytes from the system's preferred random number +source.

+
\ No newline at end of file diff --git a/target/doc/getrandom/sidebar-items.js b/target/doc/getrandom/sidebar-items.js new file mode 100644 index 0000000..a6e84ce --- /dev/null +++ b/target/doc/getrandom/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"fn":[["getrandom","Fill `dest` with random bytes from the system's preferred random number source."]],"struct":[["Error","A small and `no_std` compatible error type."]]}); \ No newline at end of file diff --git a/target/doc/getrandom/struct.Error.html b/target/doc/getrandom/struct.Error.html new file mode 100644 index 0000000..d752d10 --- /dev/null +++ b/target/doc/getrandom/struct.Error.html @@ -0,0 +1,46 @@ +getrandom::Error - Rust

[][src]Struct getrandom::Error

pub struct Error(_);

A small and no_std compatible error type.

+

The [Error::raw_os_error()] will indicate if the error is from the OS, and +if so, which error code the OS gave the application. If such an error is +encountered, please consult with your system documentation.

+

Internally this type is a NonZeroU32, with certain values reserved for +certain purposes, see [Error::INTERNAL_START] and [Error::CUSTOM_START].

+

Methods

impl Error[src]

pub const UNKNOWN: Error[src]

Deprecated since 0.1.7

pub const UNAVAILABLE: Error[src]

Deprecated since 0.1.7

pub const INTERNAL_START: u32[src]

Codes below this point represent OS Errors (i.e. positive i32 values). +Codes at or above this point, but below [Error::CUSTOM_START] are +reserved for use by the rand and getrandom crates.

+

pub const CUSTOM_START: u32[src]

Codes at or above this point can be used by users to define their own +custom errors.

+

pub fn raw_os_error(&self) -> Option<i32>[src]

Extract the raw OS error code (if this error came from the OS)

+

This method is identical to std::io::Error::raw_os_error(), except +that it works in no_std contexts. If this method returns None, the +error value can still be formatted via the Diplay implementation.

+

pub fn code(&self) -> NonZeroU32[src]

Extract the bare error code.

+

This code can either come from the underlying OS, or be a custom error. +Use [Error::raw_os_error()] to disambiguate.

+

Trait Implementations

impl PartialEq<Error> for Error[src]

impl Eq for Error[src]

impl From<NonZeroU32> for Error[src]

impl From<Error> for Error[src]

impl From<Error> for Error[src]

impl Display for Error[src]

impl Debug for Error[src]

impl Copy for Error[src]

impl Clone for Error[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Error for Error[src]

fn description(&self) -> &str1.0.0[src]

This method is soft-deprecated. Read more

+

fn cause(&self) -> Option<&dyn Error>1.0.0[src]

Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

+

The lower-level cause of this error, if any. Read more

+

fn source(&self) -> Option<&(dyn Error + 'static)>1.30.0[src]

The lower-level source of this error, if any. Read more

+

Auto Trait Implementations

impl Send for Error

impl Sync for Error

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/implementors/aho_corasick/trait.StateID.js b/target/doc/implementors/aho_corasick/trait.StateID.js new file mode 100644 index 0000000..d87c946 --- /dev/null +++ b/target/doc/implementors/aho_corasick/trait.StateID.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["aho_corasick"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/c2_chacha/guts/trait.Machine.js b/target/doc/implementors/c2_chacha/guts/trait.Machine.js new file mode 100644 index 0000000..c1151a4 --- /dev/null +++ b/target/doc/implementors/c2_chacha/guts/trait.Machine.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["c2_chacha"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/clone/trait.Clone.js b/target/doc/implementors/core/clone/trait.Clone.js new file mode 100644 index 0000000..598282f --- /dev/null +++ b/target/doc/implementors/core/clone/trait.Clone.js @@ -0,0 +1,19 @@ +(function() {var implementors = {}; +implementors["aho_corasick"] = [{text:"impl<S: Clone + StateID> Clone for AhoCorasick<S>",synthetic:false,types:["aho_corasick::ahocorasick::AhoCorasick"]},{text:"impl Clone for AhoCorasickBuilder",synthetic:false,types:["aho_corasick::ahocorasick::AhoCorasickBuilder"]},{text:"impl Clone for MatchKind",synthetic:false,types:["aho_corasick::ahocorasick::MatchKind"]},{text:"impl Clone for Error",synthetic:false,types:["aho_corasick::error::Error"]},{text:"impl Clone for ErrorKind",synthetic:false,types:["aho_corasick::error::ErrorKind"]},{text:"impl Clone for Match",synthetic:false,types:["aho_corasick::Match"]},]; +implementors["c2_chacha"] = [{text:"impl Clone for ChaCha",synthetic:false,types:["c2_chacha::guts::ChaCha"]},{text:"impl<V: Clone> Clone for State<V>",synthetic:false,types:["c2_chacha::guts::State"]},]; +implementors["getrandom"] = [{text:"impl Clone for Error",synthetic:false,types:["getrandom::error::Error"]},]; +implementors["ppv_lite86"] = [{text:"impl Clone for YesS3",synthetic:false,types:["ppv_lite86::x86_64::YesS3"]},{text:"impl Clone for NoS3",synthetic:false,types:["ppv_lite86::x86_64::NoS3"]},{text:"impl Clone for YesS4",synthetic:false,types:["ppv_lite86::x86_64::YesS4"]},{text:"impl Clone for NoS4",synthetic:false,types:["ppv_lite86::x86_64::NoS4"]},{text:"impl Clone for YesA1",synthetic:false,types:["ppv_lite86::x86_64::YesA1"]},{text:"impl Clone for NoA1",synthetic:false,types:["ppv_lite86::x86_64::NoA1"]},{text:"impl Clone for YesA2",synthetic:false,types:["ppv_lite86::x86_64::YesA2"]},{text:"impl Clone for NoA2",synthetic:false,types:["ppv_lite86::x86_64::NoA2"]},{text:"impl Clone for YesNI",synthetic:false,types:["ppv_lite86::x86_64::YesNI"]},{text:"impl Clone for NoNI",synthetic:false,types:["ppv_lite86::x86_64::NoNI"]},{text:"impl<S3: Clone, S4: Clone, NI: Clone> Clone for SseMachine<S3, S4, NI>",synthetic:false,types:["ppv_lite86::x86_64::SseMachine"]},{text:"impl<NI: Clone> Clone for Avx2Machine<NI>",synthetic:false,types:["ppv_lite86::x86_64::Avx2Machine"]},{text:"impl Clone for vec128_storage",synthetic:false,types:["ppv_lite86::x86_64::vec128_storage"]},{text:"impl Clone for vec256_storage",synthetic:false,types:["ppv_lite86::x86_64::vec256_storage"]},{text:"impl Clone for vec512_storage",synthetic:false,types:["ppv_lite86::x86_64::vec512_storage"]},]; +implementors["rand"] = [{text:"impl<X: Clone + SampleUniform> Clone for Uniform<X> where
    X::Sampler: Clone
",synthetic:false,types:["rand::distributions::uniform::Uniform"]},{text:"impl<X: Clone> Clone for UniformInt<X>",synthetic:false,types:["rand::distributions::uniform::UniformInt"]},{text:"impl<X: Clone> Clone for UniformFloat<X>",synthetic:false,types:["rand::distributions::uniform::UniformFloat"]},{text:"impl Clone for UniformDuration",synthetic:false,types:["rand::distributions::uniform::UniformDuration"]},{text:"impl Clone for Bernoulli",synthetic:false,types:["rand::distributions::bernoulli::Bernoulli"]},{text:"impl Clone for BernoulliError",synthetic:false,types:["rand::distributions::bernoulli::BernoulliError"]},{text:"impl<W: Weight> Clone for WeightedIndex<W> where
    Uniform<W>: Clone
",synthetic:false,types:["rand::distributions::weighted::alias_method::WeightedIndex"]},{text:"impl<X: Clone + SampleUniform + PartialOrd> Clone for WeightedIndex<X> where
    X::Sampler: Clone
",synthetic:false,types:["rand::distributions::weighted::WeightedIndex"]},{text:"impl Clone for WeightedError",synthetic:false,types:["rand::distributions::weighted::WeightedError"]},{text:"impl Clone for UnitSphereSurface",synthetic:false,types:["rand::distributions::unit_sphere::UnitSphereSurface"]},{text:"impl Clone for UnitCircle",synthetic:false,types:["rand::distributions::unit_circle::UnitCircle"]},{text:"impl Clone for Gamma",synthetic:false,types:["rand::distributions::gamma::Gamma"]},{text:"impl Clone for ChiSquared",synthetic:false,types:["rand::distributions::gamma::ChiSquared"]},{text:"impl Clone for FisherF",synthetic:false,types:["rand::distributions::gamma::FisherF"]},{text:"impl Clone for StudentT",synthetic:false,types:["rand::distributions::gamma::StudentT"]},{text:"impl Clone for Beta",synthetic:false,types:["rand::distributions::gamma::Beta"]},{text:"impl Clone for StandardNormal",synthetic:false,types:["rand::distributions::normal::StandardNormal"]},{text:"impl Clone for Normal",synthetic:false,types:["rand::distributions::normal::Normal"]},{text:"impl Clone for LogNormal",synthetic:false,types:["rand::distributions::normal::LogNormal"]},{text:"impl Clone for Exp1",synthetic:false,types:["rand::distributions::exponential::Exp1"]},{text:"impl Clone for Exp",synthetic:false,types:["rand::distributions::exponential::Exp"]},{text:"impl Clone for Pareto",synthetic:false,types:["rand::distributions::pareto::Pareto"]},{text:"impl Clone for Poisson",synthetic:false,types:["rand::distributions::poisson::Poisson"]},{text:"impl Clone for Binomial",synthetic:false,types:["rand::distributions::binomial::Binomial"]},{text:"impl Clone for Cauchy",synthetic:false,types:["rand::distributions::cauchy::Cauchy"]},{text:"impl Clone for Dirichlet",synthetic:false,types:["rand::distributions::dirichlet::Dirichlet"]},{text:"impl Clone for Triangular",synthetic:false,types:["rand::distributions::triangular::Triangular"]},{text:"impl Clone for Weibull",synthetic:false,types:["rand::distributions::weibull::Weibull"]},{text:"impl Clone for OpenClosed01",synthetic:false,types:["rand::distributions::float::OpenClosed01"]},{text:"impl Clone for Open01",synthetic:false,types:["rand::distributions::float::Open01"]},{text:"impl Clone for Standard",synthetic:false,types:["rand::distributions::Standard"]},{text:"impl<R, Rsdr> Clone for ReseedingRng<R, Rsdr> where
    R: BlockRngCore + SeedableRng + Clone,
    Rsdr: RngCore + Clone
",synthetic:false,types:["rand::rngs::adapter::reseeding::ReseedingRng"]},{text:"impl Clone for StepRng",synthetic:false,types:["rand::rngs::mock::StepRng"]},{text:"impl Clone for StdRng",synthetic:false,types:["rand::rngs::std::StdRng"]},{text:"impl Clone for ThreadRng",synthetic:false,types:["rand::rngs::thread::ThreadRng"]},{text:"impl Clone for OsRng",synthetic:false,types:["rand::rngs::os::OsRng"]},{text:"impl Clone for IndexVec",synthetic:false,types:["rand::seq::index::IndexVec"]},{text:"impl Clone for IndexVecIntoIter",synthetic:false,types:["rand::seq::index::IndexVecIntoIter"]},]; +implementors["rand_chacha"] = [{text:"impl Clone for ChaCha20Core",synthetic:false,types:["rand_chacha::chacha::ChaCha20Core"]},{text:"impl Clone for ChaCha20Rng",synthetic:false,types:["rand_chacha::chacha::ChaCha20Rng"]},{text:"impl Clone for ChaCha12Core",synthetic:false,types:["rand_chacha::chacha::ChaCha12Core"]},{text:"impl Clone for ChaCha12Rng",synthetic:false,types:["rand_chacha::chacha::ChaCha12Rng"]},{text:"impl Clone for ChaCha8Core",synthetic:false,types:["rand_chacha::chacha::ChaCha8Core"]},{text:"impl Clone for ChaCha8Rng",synthetic:false,types:["rand_chacha::chacha::ChaCha8Rng"]},]; +implementors["rand_core"] = [{text:"impl<R: Clone + BlockRngCore + ?Sized> Clone for BlockRng<R> where
    R::Results: Clone
",synthetic:false,types:["rand_core::block::BlockRng"]},{text:"impl<R: Clone + BlockRngCore + ?Sized> Clone for BlockRng64<R> where
    R::Results: Clone
",synthetic:false,types:["rand_core::block::BlockRng64"]},]; +implementors["regex"] = [{text:"impl Clone for Error",synthetic:false,types:["regex::error::Error"]},{text:"impl<'t> Clone for Match<'t>",synthetic:false,types:["regex::re_bytes::Match"]},{text:"impl Clone for Regex",synthetic:false,types:["regex::re_bytes::Regex"]},{text:"impl Clone for CaptureLocations",synthetic:false,types:["regex::re_bytes::CaptureLocations"]},{text:"impl Clone for RegexSet",synthetic:false,types:["regex::re_set::unicode::RegexSet"]},{text:"impl Clone for SetMatches",synthetic:false,types:["regex::re_set::unicode::SetMatches"]},{text:"impl<'a> Clone for SetMatchesIter<'a>",synthetic:false,types:["regex::re_set::unicode::SetMatchesIter"]},{text:"impl Clone for RegexSet",synthetic:false,types:["regex::re_set::bytes::RegexSet"]},{text:"impl Clone for SetMatches",synthetic:false,types:["regex::re_set::bytes::SetMatches"]},{text:"impl<'a> Clone for SetMatchesIter<'a>",synthetic:false,types:["regex::re_set::bytes::SetMatchesIter"]},{text:"impl<'t> Clone for Match<'t>",synthetic:false,types:["regex::re_unicode::Match"]},{text:"impl Clone for Regex",synthetic:false,types:["regex::re_unicode::Regex"]},{text:"impl Clone for CaptureLocations",synthetic:false,types:["regex::re_unicode::CaptureLocations"]},]; +implementors["regex_syntax"] = [{text:"impl Clone for ParserBuilder",synthetic:false,types:["regex_syntax::ast::parse::ParserBuilder"]},{text:"impl Clone for Parser",synthetic:false,types:["regex_syntax::ast::parse::Parser"]},{text:"impl Clone for Error",synthetic:false,types:["regex_syntax::ast::Error"]},{text:"impl Clone for ErrorKind",synthetic:false,types:["regex_syntax::ast::ErrorKind"]},{text:"impl Clone for Span",synthetic:false,types:["regex_syntax::ast::Span"]},{text:"impl Clone for Position",synthetic:false,types:["regex_syntax::ast::Position"]},{text:"impl Clone for WithComments",synthetic:false,types:["regex_syntax::ast::WithComments"]},{text:"impl Clone for Comment",synthetic:false,types:["regex_syntax::ast::Comment"]},{text:"impl Clone for Ast",synthetic:false,types:["regex_syntax::ast::Ast"]},{text:"impl Clone for Alternation",synthetic:false,types:["regex_syntax::ast::Alternation"]},{text:"impl Clone for Concat",synthetic:false,types:["regex_syntax::ast::Concat"]},{text:"impl Clone for Literal",synthetic:false,types:["regex_syntax::ast::Literal"]},{text:"impl Clone for LiteralKind",synthetic:false,types:["regex_syntax::ast::LiteralKind"]},{text:"impl Clone for SpecialLiteralKind",synthetic:false,types:["regex_syntax::ast::SpecialLiteralKind"]},{text:"impl Clone for HexLiteralKind",synthetic:false,types:["regex_syntax::ast::HexLiteralKind"]},{text:"impl Clone for Class",synthetic:false,types:["regex_syntax::ast::Class"]},{text:"impl Clone for ClassPerl",synthetic:false,types:["regex_syntax::ast::ClassPerl"]},{text:"impl Clone for ClassPerlKind",synthetic:false,types:["regex_syntax::ast::ClassPerlKind"]},{text:"impl Clone for ClassAscii",synthetic:false,types:["regex_syntax::ast::ClassAscii"]},{text:"impl Clone for ClassAsciiKind",synthetic:false,types:["regex_syntax::ast::ClassAsciiKind"]},{text:"impl Clone for ClassUnicode",synthetic:false,types:["regex_syntax::ast::ClassUnicode"]},{text:"impl Clone for ClassUnicodeKind",synthetic:false,types:["regex_syntax::ast::ClassUnicodeKind"]},{text:"impl Clone for ClassUnicodeOpKind",synthetic:false,types:["regex_syntax::ast::ClassUnicodeOpKind"]},{text:"impl Clone for ClassBracketed",synthetic:false,types:["regex_syntax::ast::ClassBracketed"]},{text:"impl Clone for ClassSet",synthetic:false,types:["regex_syntax::ast::ClassSet"]},{text:"impl Clone for ClassSetItem",synthetic:false,types:["regex_syntax::ast::ClassSetItem"]},{text:"impl Clone for ClassSetRange",synthetic:false,types:["regex_syntax::ast::ClassSetRange"]},{text:"impl Clone for ClassSetUnion",synthetic:false,types:["regex_syntax::ast::ClassSetUnion"]},{text:"impl Clone for ClassSetBinaryOp",synthetic:false,types:["regex_syntax::ast::ClassSetBinaryOp"]},{text:"impl Clone for ClassSetBinaryOpKind",synthetic:false,types:["regex_syntax::ast::ClassSetBinaryOpKind"]},{text:"impl Clone for Assertion",synthetic:false,types:["regex_syntax::ast::Assertion"]},{text:"impl Clone for AssertionKind",synthetic:false,types:["regex_syntax::ast::AssertionKind"]},{text:"impl Clone for Repetition",synthetic:false,types:["regex_syntax::ast::Repetition"]},{text:"impl Clone for RepetitionOp",synthetic:false,types:["regex_syntax::ast::RepetitionOp"]},{text:"impl Clone for RepetitionKind",synthetic:false,types:["regex_syntax::ast::RepetitionKind"]},{text:"impl Clone for RepetitionRange",synthetic:false,types:["regex_syntax::ast::RepetitionRange"]},{text:"impl Clone for Group",synthetic:false,types:["regex_syntax::ast::Group"]},{text:"impl Clone for GroupKind",synthetic:false,types:["regex_syntax::ast::GroupKind"]},{text:"impl Clone for CaptureName",synthetic:false,types:["regex_syntax::ast::CaptureName"]},{text:"impl Clone for SetFlags",synthetic:false,types:["regex_syntax::ast::SetFlags"]},{text:"impl Clone for Flags",synthetic:false,types:["regex_syntax::ast::Flags"]},{text:"impl Clone for FlagsItem",synthetic:false,types:["regex_syntax::ast::FlagsItem"]},{text:"impl Clone for FlagsItemKind",synthetic:false,types:["regex_syntax::ast::FlagsItemKind"]},{text:"impl Clone for Flag",synthetic:false,types:["regex_syntax::ast::Flag"]},{text:"impl Clone for Error",synthetic:false,types:["regex_syntax::error::Error"]},{text:"impl Clone for Literals",synthetic:false,types:["regex_syntax::hir::literal::Literals"]},{text:"impl Clone for Literal",synthetic:false,types:["regex_syntax::hir::literal::Literal"]},{text:"impl Clone for TranslatorBuilder",synthetic:false,types:["regex_syntax::hir::translate::TranslatorBuilder"]},{text:"impl Clone for Translator",synthetic:false,types:["regex_syntax::hir::translate::Translator"]},{text:"impl Clone for Error",synthetic:false,types:["regex_syntax::hir::Error"]},{text:"impl Clone for ErrorKind",synthetic:false,types:["regex_syntax::hir::ErrorKind"]},{text:"impl Clone for Hir",synthetic:false,types:["regex_syntax::hir::Hir"]},{text:"impl Clone for HirKind",synthetic:false,types:["regex_syntax::hir::HirKind"]},{text:"impl Clone for Literal",synthetic:false,types:["regex_syntax::hir::Literal"]},{text:"impl Clone for Class",synthetic:false,types:["regex_syntax::hir::Class"]},{text:"impl Clone for ClassUnicode",synthetic:false,types:["regex_syntax::hir::ClassUnicode"]},{text:"impl Clone for ClassUnicodeRange",synthetic:false,types:["regex_syntax::hir::ClassUnicodeRange"]},{text:"impl Clone for ClassBytes",synthetic:false,types:["regex_syntax::hir::ClassBytes"]},{text:"impl Clone for ClassBytesRange",synthetic:false,types:["regex_syntax::hir::ClassBytesRange"]},{text:"impl Clone for Anchor",synthetic:false,types:["regex_syntax::hir::Anchor"]},{text:"impl Clone for WordBoundary",synthetic:false,types:["regex_syntax::hir::WordBoundary"]},{text:"impl Clone for Group",synthetic:false,types:["regex_syntax::hir::Group"]},{text:"impl Clone for GroupKind",synthetic:false,types:["regex_syntax::hir::GroupKind"]},{text:"impl Clone for Repetition",synthetic:false,types:["regex_syntax::hir::Repetition"]},{text:"impl Clone for RepetitionKind",synthetic:false,types:["regex_syntax::hir::RepetitionKind"]},{text:"impl Clone for RepetitionRange",synthetic:false,types:["regex_syntax::hir::RepetitionRange"]},{text:"impl Clone for ParserBuilder",synthetic:false,types:["regex_syntax::parser::ParserBuilder"]},{text:"impl Clone for Parser",synthetic:false,types:["regex_syntax::parser::Parser"]},]; +implementors["utf8_ranges"] = [{text:"impl Clone for Utf8Sequence",synthetic:false,types:["utf8_ranges::Utf8Sequence"]},{text:"impl Clone for Utf8Range",synthetic:false,types:["utf8_ranges::Utf8Range"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/cmp/trait.Eq.js b/target/doc/implementors/core/cmp/trait.Eq.js new file mode 100644 index 0000000..bcc846a --- /dev/null +++ b/target/doc/implementors/core/cmp/trait.Eq.js @@ -0,0 +1,15 @@ +(function() {var implementors = {}; +implementors["aho_corasick"] = [{text:"impl Eq for MatchKind",synthetic:false,types:["aho_corasick::ahocorasick::MatchKind"]},{text:"impl Eq for Match",synthetic:false,types:["aho_corasick::Match"]},]; +implementors["getrandom"] = [{text:"impl Eq for Error",synthetic:false,types:["getrandom::error::Error"]},]; +implementors["rand"] = [{text:"impl Eq for BernoulliError",synthetic:false,types:["rand::distributions::bernoulli::BernoulliError"]},{text:"impl Eq for WeightedError",synthetic:false,types:["rand::distributions::weighted::WeightedError"]},]; +implementors["regex"] = [{text:"impl<'t> Eq for Match<'t>",synthetic:false,types:["regex::re_bytes::Match"]},{text:"impl<'t> Eq for Match<'t>",synthetic:false,types:["regex::re_unicode::Match"]},]; +implementors["regex_syntax"] = [{text:"impl Eq for Error",synthetic:false,types:["regex_syntax::ast::Error"]},{text:"impl Eq for ErrorKind",synthetic:false,types:["regex_syntax::ast::ErrorKind"]},{text:"impl Eq for Span",synthetic:false,types:["regex_syntax::ast::Span"]},{text:"impl Eq for Position",synthetic:false,types:["regex_syntax::ast::Position"]},{text:"impl Eq for WithComments",synthetic:false,types:["regex_syntax::ast::WithComments"]},{text:"impl Eq for Comment",synthetic:false,types:["regex_syntax::ast::Comment"]},{text:"impl Eq for Ast",synthetic:false,types:["regex_syntax::ast::Ast"]},{text:"impl Eq for Alternation",synthetic:false,types:["regex_syntax::ast::Alternation"]},{text:"impl Eq for Concat",synthetic:false,types:["regex_syntax::ast::Concat"]},{text:"impl Eq for Literal",synthetic:false,types:["regex_syntax::ast::Literal"]},{text:"impl Eq for LiteralKind",synthetic:false,types:["regex_syntax::ast::LiteralKind"]},{text:"impl Eq for SpecialLiteralKind",synthetic:false,types:["regex_syntax::ast::SpecialLiteralKind"]},{text:"impl Eq for HexLiteralKind",synthetic:false,types:["regex_syntax::ast::HexLiteralKind"]},{text:"impl Eq for Class",synthetic:false,types:["regex_syntax::ast::Class"]},{text:"impl Eq for ClassPerl",synthetic:false,types:["regex_syntax::ast::ClassPerl"]},{text:"impl Eq for ClassPerlKind",synthetic:false,types:["regex_syntax::ast::ClassPerlKind"]},{text:"impl Eq for ClassAscii",synthetic:false,types:["regex_syntax::ast::ClassAscii"]},{text:"impl Eq for ClassAsciiKind",synthetic:false,types:["regex_syntax::ast::ClassAsciiKind"]},{text:"impl Eq for ClassUnicode",synthetic:false,types:["regex_syntax::ast::ClassUnicode"]},{text:"impl Eq for ClassUnicodeKind",synthetic:false,types:["regex_syntax::ast::ClassUnicodeKind"]},{text:"impl Eq for ClassUnicodeOpKind",synthetic:false,types:["regex_syntax::ast::ClassUnicodeOpKind"]},{text:"impl Eq for ClassBracketed",synthetic:false,types:["regex_syntax::ast::ClassBracketed"]},{text:"impl Eq for ClassSet",synthetic:false,types:["regex_syntax::ast::ClassSet"]},{text:"impl Eq for ClassSetItem",synthetic:false,types:["regex_syntax::ast::ClassSetItem"]},{text:"impl Eq for ClassSetRange",synthetic:false,types:["regex_syntax::ast::ClassSetRange"]},{text:"impl Eq for ClassSetUnion",synthetic:false,types:["regex_syntax::ast::ClassSetUnion"]},{text:"impl Eq for ClassSetBinaryOp",synthetic:false,types:["regex_syntax::ast::ClassSetBinaryOp"]},{text:"impl Eq for ClassSetBinaryOpKind",synthetic:false,types:["regex_syntax::ast::ClassSetBinaryOpKind"]},{text:"impl Eq for Assertion",synthetic:false,types:["regex_syntax::ast::Assertion"]},{text:"impl Eq for AssertionKind",synthetic:false,types:["regex_syntax::ast::AssertionKind"]},{text:"impl Eq for Repetition",synthetic:false,types:["regex_syntax::ast::Repetition"]},{text:"impl Eq for RepetitionOp",synthetic:false,types:["regex_syntax::ast::RepetitionOp"]},{text:"impl Eq for RepetitionKind",synthetic:false,types:["regex_syntax::ast::RepetitionKind"]},{text:"impl Eq for RepetitionRange",synthetic:false,types:["regex_syntax::ast::RepetitionRange"]},{text:"impl Eq for Group",synthetic:false,types:["regex_syntax::ast::Group"]},{text:"impl Eq for GroupKind",synthetic:false,types:["regex_syntax::ast::GroupKind"]},{text:"impl Eq for CaptureName",synthetic:false,types:["regex_syntax::ast::CaptureName"]},{text:"impl Eq for SetFlags",synthetic:false,types:["regex_syntax::ast::SetFlags"]},{text:"impl Eq for Flags",synthetic:false,types:["regex_syntax::ast::Flags"]},{text:"impl Eq for FlagsItem",synthetic:false,types:["regex_syntax::ast::FlagsItem"]},{text:"impl Eq for FlagsItemKind",synthetic:false,types:["regex_syntax::ast::FlagsItemKind"]},{text:"impl Eq for Flag",synthetic:false,types:["regex_syntax::ast::Flag"]},{text:"impl Eq for Error",synthetic:false,types:["regex_syntax::error::Error"]},{text:"impl Eq for Literals",synthetic:false,types:["regex_syntax::hir::literal::Literals"]},{text:"impl Eq for Literal",synthetic:false,types:["regex_syntax::hir::literal::Literal"]},{text:"impl Eq for Error",synthetic:false,types:["regex_syntax::hir::Error"]},{text:"impl Eq for ErrorKind",synthetic:false,types:["regex_syntax::hir::ErrorKind"]},{text:"impl Eq for Hir",synthetic:false,types:["regex_syntax::hir::Hir"]},{text:"impl Eq for HirKind",synthetic:false,types:["regex_syntax::hir::HirKind"]},{text:"impl Eq for Literal",synthetic:false,types:["regex_syntax::hir::Literal"]},{text:"impl Eq for Class",synthetic:false,types:["regex_syntax::hir::Class"]},{text:"impl Eq for ClassUnicode",synthetic:false,types:["regex_syntax::hir::ClassUnicode"]},{text:"impl Eq for ClassUnicodeRange",synthetic:false,types:["regex_syntax::hir::ClassUnicodeRange"]},{text:"impl Eq for ClassBytes",synthetic:false,types:["regex_syntax::hir::ClassBytes"]},{text:"impl Eq for ClassBytesRange",synthetic:false,types:["regex_syntax::hir::ClassBytesRange"]},{text:"impl Eq for Anchor",synthetic:false,types:["regex_syntax::hir::Anchor"]},{text:"impl Eq for WordBoundary",synthetic:false,types:["regex_syntax::hir::WordBoundary"]},{text:"impl Eq for Group",synthetic:false,types:["regex_syntax::hir::Group"]},{text:"impl Eq for GroupKind",synthetic:false,types:["regex_syntax::hir::GroupKind"]},{text:"impl Eq for Repetition",synthetic:false,types:["regex_syntax::hir::Repetition"]},{text:"impl Eq for RepetitionKind",synthetic:false,types:["regex_syntax::hir::RepetitionKind"]},{text:"impl Eq for RepetitionRange",synthetic:false,types:["regex_syntax::hir::RepetitionRange"]},]; +implementors["utf8_ranges"] = [{text:"impl Eq for Utf8Sequence",synthetic:false,types:["utf8_ranges::Utf8Sequence"]},{text:"impl Eq for Utf8Range",synthetic:false,types:["utf8_ranges::Utf8Range"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/cmp/trait.Ord.js b/target/doc/implementors/core/cmp/trait.Ord.js new file mode 100644 index 0000000..f64bf57 --- /dev/null +++ b/target/doc/implementors/core/cmp/trait.Ord.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["regex_syntax"] = [{text:"impl Ord for Span",synthetic:false,types:["regex_syntax::ast::Span"]},{text:"impl Ord for Position",synthetic:false,types:["regex_syntax::ast::Position"]},{text:"impl Ord for Literal",synthetic:false,types:["regex_syntax::hir::literal::Literal"]},{text:"impl Ord for ClassUnicodeRange",synthetic:false,types:["regex_syntax::hir::ClassUnicodeRange"]},{text:"impl Ord for ClassBytesRange",synthetic:false,types:["regex_syntax::hir::ClassBytesRange"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/cmp/trait.PartialEq.js b/target/doc/implementors/core/cmp/trait.PartialEq.js new file mode 100644 index 0000000..104034a --- /dev/null +++ b/target/doc/implementors/core/cmp/trait.PartialEq.js @@ -0,0 +1,15 @@ +(function() {var implementors = {}; +implementors["aho_corasick"] = [{text:"impl PartialEq<MatchKind> for MatchKind",synthetic:false,types:["aho_corasick::ahocorasick::MatchKind"]},{text:"impl PartialEq<Match> for Match",synthetic:false,types:["aho_corasick::Match"]},]; +implementors["getrandom"] = [{text:"impl PartialEq<Error> for Error",synthetic:false,types:["getrandom::error::Error"]},]; +implementors["rand"] = [{text:"impl PartialEq<BernoulliError> for BernoulliError",synthetic:false,types:["rand::distributions::bernoulli::BernoulliError"]},{text:"impl PartialEq<WeightedError> for WeightedError",synthetic:false,types:["rand::distributions::weighted::WeightedError"]},{text:"impl PartialEq<IndexVec> for IndexVec",synthetic:false,types:["rand::seq::index::IndexVec"]},]; +implementors["regex"] = [{text:"impl PartialEq<Error> for Error",synthetic:false,types:["regex::error::Error"]},{text:"impl<'t> PartialEq<Match<'t>> for Match<'t>",synthetic:false,types:["regex::re_bytes::Match"]},{text:"impl<'t> PartialEq<Match<'t>> for Match<'t>",synthetic:false,types:["regex::re_unicode::Match"]},]; +implementors["regex_syntax"] = [{text:"impl PartialEq<Error> for Error",synthetic:false,types:["regex_syntax::ast::Error"]},{text:"impl PartialEq<ErrorKind> for ErrorKind",synthetic:false,types:["regex_syntax::ast::ErrorKind"]},{text:"impl PartialEq<Span> for Span",synthetic:false,types:["regex_syntax::ast::Span"]},{text:"impl PartialEq<Position> for Position",synthetic:false,types:["regex_syntax::ast::Position"]},{text:"impl PartialEq<WithComments> for WithComments",synthetic:false,types:["regex_syntax::ast::WithComments"]},{text:"impl PartialEq<Comment> for Comment",synthetic:false,types:["regex_syntax::ast::Comment"]},{text:"impl PartialEq<Ast> for Ast",synthetic:false,types:["regex_syntax::ast::Ast"]},{text:"impl PartialEq<Alternation> for Alternation",synthetic:false,types:["regex_syntax::ast::Alternation"]},{text:"impl PartialEq<Concat> for Concat",synthetic:false,types:["regex_syntax::ast::Concat"]},{text:"impl PartialEq<Literal> for Literal",synthetic:false,types:["regex_syntax::ast::Literal"]},{text:"impl PartialEq<LiteralKind> for LiteralKind",synthetic:false,types:["regex_syntax::ast::LiteralKind"]},{text:"impl PartialEq<SpecialLiteralKind> for SpecialLiteralKind",synthetic:false,types:["regex_syntax::ast::SpecialLiteralKind"]},{text:"impl PartialEq<HexLiteralKind> for HexLiteralKind",synthetic:false,types:["regex_syntax::ast::HexLiteralKind"]},{text:"impl PartialEq<Class> for Class",synthetic:false,types:["regex_syntax::ast::Class"]},{text:"impl PartialEq<ClassPerl> for ClassPerl",synthetic:false,types:["regex_syntax::ast::ClassPerl"]},{text:"impl PartialEq<ClassPerlKind> for ClassPerlKind",synthetic:false,types:["regex_syntax::ast::ClassPerlKind"]},{text:"impl PartialEq<ClassAscii> for ClassAscii",synthetic:false,types:["regex_syntax::ast::ClassAscii"]},{text:"impl PartialEq<ClassAsciiKind> for ClassAsciiKind",synthetic:false,types:["regex_syntax::ast::ClassAsciiKind"]},{text:"impl PartialEq<ClassUnicode> for ClassUnicode",synthetic:false,types:["regex_syntax::ast::ClassUnicode"]},{text:"impl PartialEq<ClassUnicodeKind> for ClassUnicodeKind",synthetic:false,types:["regex_syntax::ast::ClassUnicodeKind"]},{text:"impl PartialEq<ClassUnicodeOpKind> for ClassUnicodeOpKind",synthetic:false,types:["regex_syntax::ast::ClassUnicodeOpKind"]},{text:"impl PartialEq<ClassBracketed> for ClassBracketed",synthetic:false,types:["regex_syntax::ast::ClassBracketed"]},{text:"impl PartialEq<ClassSet> for ClassSet",synthetic:false,types:["regex_syntax::ast::ClassSet"]},{text:"impl PartialEq<ClassSetItem> for ClassSetItem",synthetic:false,types:["regex_syntax::ast::ClassSetItem"]},{text:"impl PartialEq<ClassSetRange> for ClassSetRange",synthetic:false,types:["regex_syntax::ast::ClassSetRange"]},{text:"impl PartialEq<ClassSetUnion> for ClassSetUnion",synthetic:false,types:["regex_syntax::ast::ClassSetUnion"]},{text:"impl PartialEq<ClassSetBinaryOp> for ClassSetBinaryOp",synthetic:false,types:["regex_syntax::ast::ClassSetBinaryOp"]},{text:"impl PartialEq<ClassSetBinaryOpKind> for ClassSetBinaryOpKind",synthetic:false,types:["regex_syntax::ast::ClassSetBinaryOpKind"]},{text:"impl PartialEq<Assertion> for Assertion",synthetic:false,types:["regex_syntax::ast::Assertion"]},{text:"impl PartialEq<AssertionKind> for AssertionKind",synthetic:false,types:["regex_syntax::ast::AssertionKind"]},{text:"impl PartialEq<Repetition> for Repetition",synthetic:false,types:["regex_syntax::ast::Repetition"]},{text:"impl PartialEq<RepetitionOp> for RepetitionOp",synthetic:false,types:["regex_syntax::ast::RepetitionOp"]},{text:"impl PartialEq<RepetitionKind> for RepetitionKind",synthetic:false,types:["regex_syntax::ast::RepetitionKind"]},{text:"impl PartialEq<RepetitionRange> for RepetitionRange",synthetic:false,types:["regex_syntax::ast::RepetitionRange"]},{text:"impl PartialEq<Group> for Group",synthetic:false,types:["regex_syntax::ast::Group"]},{text:"impl PartialEq<GroupKind> for GroupKind",synthetic:false,types:["regex_syntax::ast::GroupKind"]},{text:"impl PartialEq<CaptureName> for CaptureName",synthetic:false,types:["regex_syntax::ast::CaptureName"]},{text:"impl PartialEq<SetFlags> for SetFlags",synthetic:false,types:["regex_syntax::ast::SetFlags"]},{text:"impl PartialEq<Flags> for Flags",synthetic:false,types:["regex_syntax::ast::Flags"]},{text:"impl PartialEq<FlagsItem> for FlagsItem",synthetic:false,types:["regex_syntax::ast::FlagsItem"]},{text:"impl PartialEq<FlagsItemKind> for FlagsItemKind",synthetic:false,types:["regex_syntax::ast::FlagsItemKind"]},{text:"impl PartialEq<Flag> for Flag",synthetic:false,types:["regex_syntax::ast::Flag"]},{text:"impl PartialEq<Error> for Error",synthetic:false,types:["regex_syntax::error::Error"]},{text:"impl PartialEq<Literals> for Literals",synthetic:false,types:["regex_syntax::hir::literal::Literals"]},{text:"impl PartialEq<Literal> for Literal",synthetic:false,types:["regex_syntax::hir::literal::Literal"]},{text:"impl PartialEq<Error> for Error",synthetic:false,types:["regex_syntax::hir::Error"]},{text:"impl PartialEq<ErrorKind> for ErrorKind",synthetic:false,types:["regex_syntax::hir::ErrorKind"]},{text:"impl PartialEq<Hir> for Hir",synthetic:false,types:["regex_syntax::hir::Hir"]},{text:"impl PartialEq<HirKind> for HirKind",synthetic:false,types:["regex_syntax::hir::HirKind"]},{text:"impl PartialEq<Literal> for Literal",synthetic:false,types:["regex_syntax::hir::Literal"]},{text:"impl PartialEq<Class> for Class",synthetic:false,types:["regex_syntax::hir::Class"]},{text:"impl PartialEq<ClassUnicode> for ClassUnicode",synthetic:false,types:["regex_syntax::hir::ClassUnicode"]},{text:"impl PartialEq<ClassUnicodeRange> for ClassUnicodeRange",synthetic:false,types:["regex_syntax::hir::ClassUnicodeRange"]},{text:"impl PartialEq<ClassBytes> for ClassBytes",synthetic:false,types:["regex_syntax::hir::ClassBytes"]},{text:"impl PartialEq<ClassBytesRange> for ClassBytesRange",synthetic:false,types:["regex_syntax::hir::ClassBytesRange"]},{text:"impl PartialEq<Anchor> for Anchor",synthetic:false,types:["regex_syntax::hir::Anchor"]},{text:"impl PartialEq<WordBoundary> for WordBoundary",synthetic:false,types:["regex_syntax::hir::WordBoundary"]},{text:"impl PartialEq<Group> for Group",synthetic:false,types:["regex_syntax::hir::Group"]},{text:"impl PartialEq<GroupKind> for GroupKind",synthetic:false,types:["regex_syntax::hir::GroupKind"]},{text:"impl PartialEq<Repetition> for Repetition",synthetic:false,types:["regex_syntax::hir::Repetition"]},{text:"impl PartialEq<RepetitionKind> for RepetitionKind",synthetic:false,types:["regex_syntax::hir::RepetitionKind"]},{text:"impl PartialEq<RepetitionRange> for RepetitionRange",synthetic:false,types:["regex_syntax::hir::RepetitionRange"]},]; +implementors["utf8_ranges"] = [{text:"impl PartialEq<Utf8Sequence> for Utf8Sequence",synthetic:false,types:["utf8_ranges::Utf8Sequence"]},{text:"impl PartialEq<Utf8Range> for Utf8Range",synthetic:false,types:["utf8_ranges::Utf8Range"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/cmp/trait.PartialOrd.js b/target/doc/implementors/core/cmp/trait.PartialOrd.js new file mode 100644 index 0000000..147ef14 --- /dev/null +++ b/target/doc/implementors/core/cmp/trait.PartialOrd.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["regex_syntax"] = [{text:"impl PartialOrd<Span> for Span",synthetic:false,types:["regex_syntax::ast::Span"]},{text:"impl PartialOrd<Position> for Position",synthetic:false,types:["regex_syntax::ast::Position"]},{text:"impl PartialOrd<Literal> for Literal",synthetic:false,types:["regex_syntax::hir::literal::Literal"]},{text:"impl PartialOrd<ClassUnicodeRange> for ClassUnicodeRange",synthetic:false,types:["regex_syntax::hir::ClassUnicodeRange"]},{text:"impl PartialOrd<ClassBytesRange> for ClassBytesRange",synthetic:false,types:["regex_syntax::hir::ClassBytesRange"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/convert/trait.AsRef.js b/target/doc/implementors/core/convert/trait.AsRef.js new file mode 100644 index 0000000..7b1c661 --- /dev/null +++ b/target/doc/implementors/core/convert/trait.AsRef.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["regex_syntax"] = [{text:"impl AsRef<[u8]> for Literal",synthetic:false,types:["regex_syntax::hir::literal::Literal"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/convert/trait.From.js b/target/doc/implementors/core/convert/trait.From.js new file mode 100644 index 0000000..11387ca --- /dev/null +++ b/target/doc/implementors/core/convert/trait.From.js @@ -0,0 +1,15 @@ +(function() {var implementors = {}; +implementors["getrandom"] = [{text:"impl From<NonZeroU32> for Error",synthetic:false,types:["getrandom::error::Error"]},{text:"impl From<Error> for Error",synthetic:false,types:["getrandom::error::Error"]},{text:"impl From<Error> for Error",synthetic:false,types:["std::io::error::Error"]},]; +implementors["rand"] = [{text:"impl<X: SampleUniform> From<Range<X>> for Uniform<X>",synthetic:false,types:["rand::distributions::uniform::Uniform"]},{text:"impl<X: SampleUniform> From<RangeInclusive<X>> for Uniform<X>",synthetic:false,types:["rand::distributions::uniform::Uniform"]},{text:"impl From<Vec<u32>> for IndexVec",synthetic:false,types:["rand::seq::index::IndexVec"]},{text:"impl From<Vec<usize>> for IndexVec",synthetic:false,types:["rand::seq::index::IndexVec"]},]; +implementors["rand_chacha"] = [{text:"impl From<ChaCha20Core> for ChaCha20Rng",synthetic:false,types:["rand_chacha::chacha::ChaCha20Rng"]},{text:"impl From<ChaCha12Core> for ChaCha12Rng",synthetic:false,types:["rand_chacha::chacha::ChaCha12Rng"]},{text:"impl From<ChaCha8Core> for ChaCha8Rng",synthetic:false,types:["rand_chacha::chacha::ChaCha8Rng"]},]; +implementors["rand_core"] = [{text:"impl From<NonZeroU32> for Error",synthetic:false,types:["rand_core::error::Error"]},{text:"impl From<Error> for Error",synthetic:false,types:["rand_core::error::Error"]},{text:"impl From<Error> for Error",synthetic:false,types:["std::io::error::Error"]},]; +implementors["regex"] = [{text:"impl<'t> From<Match<'t>> for &'t str",synthetic:false,types:[]},]; +implementors["regex_syntax"] = [{text:"impl From<Error> for Error",synthetic:false,types:["regex_syntax::error::Error"]},{text:"impl From<Error> for Error",synthetic:false,types:["regex_syntax::error::Error"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/convert/trait.Into.js b/target/doc/implementors/core/convert/trait.Into.js new file mode 100644 index 0000000..f7aa13a --- /dev/null +++ b/target/doc/implementors/core/convert/trait.Into.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["ppv_lite86"] = [{text:"impl<'a> Into<&'a [u32; 4]> for &'a vec128_storage",synthetic:false,types:["ppv_lite86::x86_64::vec128_storage"]},{text:"impl Into<vec128_storage> for [u32; 4]",synthetic:false,types:[]},{text:"impl Into<vec256_storage> for [u64; 4]",synthetic:false,types:[]},{text:"impl Into<[u32; 4]> for vec128_storage",synthetic:false,types:["ppv_lite86::x86_64::vec128_storage"]},{text:"impl Into<[u64; 2]> for vec128_storage",synthetic:false,types:["ppv_lite86::x86_64::vec128_storage"]},{text:"impl Into<[u128; 1]> for vec128_storage",synthetic:false,types:["ppv_lite86::x86_64::vec128_storage"]},{text:"impl Into<[u32; 8]> for vec256_storage",synthetic:false,types:["ppv_lite86::x86_64::vec256_storage"]},{text:"impl Into<[u64; 4]> for vec256_storage",synthetic:false,types:["ppv_lite86::x86_64::vec256_storage"]},{text:"impl Into<[u128; 2]> for vec256_storage",synthetic:false,types:["ppv_lite86::x86_64::vec256_storage"]},{text:"impl Into<[u32; 16]> for vec512_storage",synthetic:false,types:["ppv_lite86::x86_64::vec512_storage"]},{text:"impl Into<[u64; 8]> for vec512_storage",synthetic:false,types:["ppv_lite86::x86_64::vec512_storage"]},{text:"impl Into<[u128; 4]> for vec512_storage",synthetic:false,types:["ppv_lite86::x86_64::vec512_storage"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/default/trait.Default.js b/target/doc/implementors/core/default/trait.Default.js new file mode 100644 index 0000000..bfb6a16 --- /dev/null +++ b/target/doc/implementors/core/default/trait.Default.js @@ -0,0 +1,14 @@ +(function() {var implementors = {}; +implementors["aho_corasick"] = [{text:"impl Default for AhoCorasickBuilder",synthetic:false,types:["aho_corasick::ahocorasick::AhoCorasickBuilder"]},{text:"impl Default for MatchKind",synthetic:false,types:["aho_corasick::ahocorasick::MatchKind"]},]; +implementors["ppv_lite86"] = [{text:"impl Default for vec128_storage",synthetic:false,types:["ppv_lite86::x86_64::vec128_storage"]},{text:"impl Default for vec256_storage",synthetic:false,types:["ppv_lite86::x86_64::vec256_storage"]},{text:"impl Default for vec512_storage",synthetic:false,types:["ppv_lite86::x86_64::vec512_storage"]},]; +implementors["rand"] = [{text:"impl Default for EntropyRng",synthetic:false,types:["rand::rngs::entropy::EntropyRng"]},{text:"impl Default for ThreadRng",synthetic:false,types:["rand::rngs::thread::ThreadRng"]},{text:"impl Default for OsRng",synthetic:false,types:["rand::rngs::os::OsRng"]},]; +implementors["regex_syntax"] = [{text:"impl Default for ParserBuilder",synthetic:false,types:["regex_syntax::ast::parse::ParserBuilder"]},{text:"impl Default for TranslatorBuilder",synthetic:false,types:["regex_syntax::hir::translate::TranslatorBuilder"]},{text:"impl Default for ClassUnicodeRange",synthetic:false,types:["regex_syntax::hir::ClassUnicodeRange"]},{text:"impl Default for ClassBytesRange",synthetic:false,types:["regex_syntax::hir::ClassBytesRange"]},{text:"impl Default for ParserBuilder",synthetic:false,types:["regex_syntax::parser::ParserBuilder"]},]; +implementors["thread_local"] = [{text:"impl<T: ?Sized + Send> Default for ThreadLocal<T>",synthetic:false,types:["thread_local::ThreadLocal"]},{text:"impl<T: ?Sized + Send> Default for CachedThreadLocal<T>",synthetic:false,types:["thread_local::CachedThreadLocal"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/fmt/trait.Debug.js b/target/doc/implementors/core/fmt/trait.Debug.js new file mode 100644 index 0000000..cb81947 --- /dev/null +++ b/target/doc/implementors/core/fmt/trait.Debug.js @@ -0,0 +1,18 @@ +(function() {var implementors = {}; +implementors["aho_corasick"] = [{text:"impl<S: Debug + StateID> Debug for AhoCorasick<S>",synthetic:false,types:["aho_corasick::ahocorasick::AhoCorasick"]},{text:"impl<'a, 'b, S: Debug + 'a + StateID> Debug for FindIter<'a, 'b, S>",synthetic:false,types:["aho_corasick::ahocorasick::FindIter"]},{text:"impl<'a, 'b, S: Debug + 'a + StateID> Debug for FindOverlappingIter<'a, 'b, S>",synthetic:false,types:["aho_corasick::ahocorasick::FindOverlappingIter"]},{text:"impl<'a, R: Debug, S: Debug + 'a + StateID> Debug for StreamFindIter<'a, R, S>",synthetic:false,types:["aho_corasick::ahocorasick::StreamFindIter"]},{text:"impl Debug for AhoCorasickBuilder",synthetic:false,types:["aho_corasick::ahocorasick::AhoCorasickBuilder"]},{text:"impl Debug for MatchKind",synthetic:false,types:["aho_corasick::ahocorasick::MatchKind"]},{text:"impl Debug for Error",synthetic:false,types:["aho_corasick::error::Error"]},{text:"impl Debug for ErrorKind",synthetic:false,types:["aho_corasick::error::ErrorKind"]},{text:"impl Debug for Match",synthetic:false,types:["aho_corasick::Match"]},]; +implementors["getrandom"] = [{text:"impl Debug for Error",synthetic:false,types:["getrandom::error::Error"]},]; +implementors["rand"] = [{text:"impl<X: Debug + SampleUniform> Debug for Uniform<X> where
    X::Sampler: Debug
",synthetic:false,types:["rand::distributions::uniform::Uniform"]},{text:"impl<X: Debug> Debug for UniformInt<X>",synthetic:false,types:["rand::distributions::uniform::UniformInt"]},{text:"impl<X: Debug> Debug for UniformFloat<X>",synthetic:false,types:["rand::distributions::uniform::UniformFloat"]},{text:"impl Debug for UniformDuration",synthetic:false,types:["rand::distributions::uniform::UniformDuration"]},{text:"impl Debug for Bernoulli",synthetic:false,types:["rand::distributions::bernoulli::Bernoulli"]},{text:"impl Debug for BernoulliError",synthetic:false,types:["rand::distributions::bernoulli::BernoulliError"]},{text:"impl<W: Weight> Debug for WeightedIndex<W> where
    W: Debug,
    Uniform<W>: Debug
",synthetic:false,types:["rand::distributions::weighted::alias_method::WeightedIndex"]},{text:"impl<X: Debug + SampleUniform + PartialOrd> Debug for WeightedIndex<X> where
    X::Sampler: Debug
",synthetic:false,types:["rand::distributions::weighted::WeightedIndex"]},{text:"impl Debug for WeightedError",synthetic:false,types:["rand::distributions::weighted::WeightedError"]},{text:"impl Debug for UnitSphereSurface",synthetic:false,types:["rand::distributions::unit_sphere::UnitSphereSurface"]},{text:"impl Debug for UnitCircle",synthetic:false,types:["rand::distributions::unit_circle::UnitCircle"]},{text:"impl Debug for Gamma",synthetic:false,types:["rand::distributions::gamma::Gamma"]},{text:"impl Debug for ChiSquared",synthetic:false,types:["rand::distributions::gamma::ChiSquared"]},{text:"impl Debug for FisherF",synthetic:false,types:["rand::distributions::gamma::FisherF"]},{text:"impl Debug for StudentT",synthetic:false,types:["rand::distributions::gamma::StudentT"]},{text:"impl Debug for Beta",synthetic:false,types:["rand::distributions::gamma::Beta"]},{text:"impl Debug for StandardNormal",synthetic:false,types:["rand::distributions::normal::StandardNormal"]},{text:"impl Debug for Normal",synthetic:false,types:["rand::distributions::normal::Normal"]},{text:"impl Debug for LogNormal",synthetic:false,types:["rand::distributions::normal::LogNormal"]},{text:"impl Debug for Exp1",synthetic:false,types:["rand::distributions::exponential::Exp1"]},{text:"impl Debug for Exp",synthetic:false,types:["rand::distributions::exponential::Exp"]},{text:"impl Debug for Pareto",synthetic:false,types:["rand::distributions::pareto::Pareto"]},{text:"impl Debug for Poisson",synthetic:false,types:["rand::distributions::poisson::Poisson"]},{text:"impl Debug for Binomial",synthetic:false,types:["rand::distributions::binomial::Binomial"]},{text:"impl Debug for Cauchy",synthetic:false,types:["rand::distributions::cauchy::Cauchy"]},{text:"impl Debug for Dirichlet",synthetic:false,types:["rand::distributions::dirichlet::Dirichlet"]},{text:"impl Debug for Triangular",synthetic:false,types:["rand::distributions::triangular::Triangular"]},{text:"impl Debug for Weibull",synthetic:false,types:["rand::distributions::weibull::Weibull"]},{text:"impl Debug for OpenClosed01",synthetic:false,types:["rand::distributions::float::OpenClosed01"]},{text:"impl Debug for Open01",synthetic:false,types:["rand::distributions::float::Open01"]},{text:"impl Debug for Alphanumeric",synthetic:false,types:["rand::distributions::other::Alphanumeric"]},{text:"impl<D: Debug, R: Debug, T: Debug> Debug for DistIter<D, R, T>",synthetic:false,types:["rand::distributions::DistIter"]},{text:"impl Debug for Standard",synthetic:false,types:["rand::distributions::Standard"]},{text:"impl<R: Debug> Debug for ReadRng<R>",synthetic:false,types:["rand::rngs::adapter::read::ReadRng"]},{text:"impl Debug for ReadError",synthetic:false,types:["rand::rngs::adapter::read::ReadError"]},{text:"impl<R: Debug, Rsdr: Debug> Debug for ReseedingRng<R, Rsdr> where
    R: BlockRngCore + SeedableRng,
    Rsdr: RngCore
",synthetic:false,types:["rand::rngs::adapter::reseeding::ReseedingRng"]},{text:"impl Debug for EntropyRng",synthetic:false,types:["rand::rngs::entropy::EntropyRng"]},{text:"impl Debug for StepRng",synthetic:false,types:["rand::rngs::mock::StepRng"]},{text:"impl Debug for StdRng",synthetic:false,types:["rand::rngs::std::StdRng"]},{text:"impl Debug for ThreadRng",synthetic:false,types:["rand::rngs::thread::ThreadRng"]},{text:"impl Debug for OsRng",synthetic:false,types:["rand::rngs::os::OsRng"]},{text:"impl Debug for IndexVec",synthetic:false,types:["rand::seq::index::IndexVec"]},{text:"impl<'a> Debug for IndexVecIter<'a>",synthetic:false,types:["rand::seq::index::IndexVecIter"]},{text:"impl Debug for IndexVecIntoIter",synthetic:false,types:["rand::seq::index::IndexVecIntoIter"]},{text:"impl<'a, S: Debug + ?Sized + 'a, T: Debug + 'a> Debug for SliceChooseIter<'a, S, T>",synthetic:false,types:["rand::seq::SliceChooseIter"]},]; +implementors["rand_chacha"] = [{text:"impl Debug for ChaCha20Core",synthetic:false,types:["rand_chacha::chacha::ChaCha20Core"]},{text:"impl Debug for ChaCha20Rng",synthetic:false,types:["rand_chacha::chacha::ChaCha20Rng"]},{text:"impl Debug for ChaCha12Core",synthetic:false,types:["rand_chacha::chacha::ChaCha12Core"]},{text:"impl Debug for ChaCha12Rng",synthetic:false,types:["rand_chacha::chacha::ChaCha12Rng"]},{text:"impl Debug for ChaCha8Core",synthetic:false,types:["rand_chacha::chacha::ChaCha8Core"]},{text:"impl Debug for ChaCha8Rng",synthetic:false,types:["rand_chacha::chacha::ChaCha8Rng"]},]; +implementors["rand_core"] = [{text:"impl Debug for Error",synthetic:false,types:["rand_core::error::Error"]},{text:"impl<R: BlockRngCore + Debug> Debug for BlockRng<R>",synthetic:false,types:["rand_core::block::BlockRng"]},{text:"impl<R: BlockRngCore + Debug> Debug for BlockRng64<R>",synthetic:false,types:["rand_core::block::BlockRng64"]},]; +implementors["regex"] = [{text:"impl Debug for Error",synthetic:false,types:["regex::error::Error"]},{text:"impl<'t> Debug for Match<'t>",synthetic:false,types:["regex::re_bytes::Match"]},{text:"impl Debug for Regex",synthetic:false,types:["regex::re_bytes::Regex"]},{text:"impl Debug for CaptureLocations",synthetic:false,types:["regex::re_bytes::CaptureLocations"]},{text:"impl<'t> Debug for Captures<'t>",synthetic:false,types:["regex::re_bytes::Captures"]},{text:"impl<'a, R: Debug + ?Sized + 'a> Debug for ReplacerRef<'a, R>",synthetic:false,types:["regex::re_bytes::ReplacerRef"]},{text:"impl Debug for SetMatches",synthetic:false,types:["regex::re_set::unicode::SetMatches"]},{text:"impl Debug for RegexSet",synthetic:false,types:["regex::re_set::unicode::RegexSet"]},{text:"impl Debug for SetMatches",synthetic:false,types:["regex::re_set::bytes::SetMatches"]},{text:"impl Debug for RegexSet",synthetic:false,types:["regex::re_set::bytes::RegexSet"]},{text:"impl<'t> Debug for Match<'t>",synthetic:false,types:["regex::re_unicode::Match"]},{text:"impl Debug for Regex",synthetic:false,types:["regex::re_unicode::Regex"]},{text:"impl Debug for CaptureLocations",synthetic:false,types:["regex::re_unicode::CaptureLocations"]},{text:"impl<'t> Debug for Captures<'t>",synthetic:false,types:["regex::re_unicode::Captures"]},{text:"impl<'a, R: Debug + ?Sized + 'a> Debug for ReplacerRef<'a, R>",synthetic:false,types:["regex::re_unicode::ReplacerRef"]},]; +implementors["regex_syntax"] = [{text:"impl Debug for ParserBuilder",synthetic:false,types:["regex_syntax::ast::parse::ParserBuilder"]},{text:"impl Debug for Parser",synthetic:false,types:["regex_syntax::ast::parse::Parser"]},{text:"impl Debug for Printer",synthetic:false,types:["regex_syntax::ast::print::Printer"]},{text:"impl Debug for Error",synthetic:false,types:["regex_syntax::ast::Error"]},{text:"impl Debug for ErrorKind",synthetic:false,types:["regex_syntax::ast::ErrorKind"]},{text:"impl Debug for Span",synthetic:false,types:["regex_syntax::ast::Span"]},{text:"impl Debug for Position",synthetic:false,types:["regex_syntax::ast::Position"]},{text:"impl Debug for WithComments",synthetic:false,types:["regex_syntax::ast::WithComments"]},{text:"impl Debug for Comment",synthetic:false,types:["regex_syntax::ast::Comment"]},{text:"impl Debug for Ast",synthetic:false,types:["regex_syntax::ast::Ast"]},{text:"impl Debug for Alternation",synthetic:false,types:["regex_syntax::ast::Alternation"]},{text:"impl Debug for Concat",synthetic:false,types:["regex_syntax::ast::Concat"]},{text:"impl Debug for Literal",synthetic:false,types:["regex_syntax::ast::Literal"]},{text:"impl Debug for LiteralKind",synthetic:false,types:["regex_syntax::ast::LiteralKind"]},{text:"impl Debug for SpecialLiteralKind",synthetic:false,types:["regex_syntax::ast::SpecialLiteralKind"]},{text:"impl Debug for HexLiteralKind",synthetic:false,types:["regex_syntax::ast::HexLiteralKind"]},{text:"impl Debug for Class",synthetic:false,types:["regex_syntax::ast::Class"]},{text:"impl Debug for ClassPerl",synthetic:false,types:["regex_syntax::ast::ClassPerl"]},{text:"impl Debug for ClassPerlKind",synthetic:false,types:["regex_syntax::ast::ClassPerlKind"]},{text:"impl Debug for ClassAscii",synthetic:false,types:["regex_syntax::ast::ClassAscii"]},{text:"impl Debug for ClassAsciiKind",synthetic:false,types:["regex_syntax::ast::ClassAsciiKind"]},{text:"impl Debug for ClassUnicode",synthetic:false,types:["regex_syntax::ast::ClassUnicode"]},{text:"impl Debug for ClassUnicodeKind",synthetic:false,types:["regex_syntax::ast::ClassUnicodeKind"]},{text:"impl Debug for ClassUnicodeOpKind",synthetic:false,types:["regex_syntax::ast::ClassUnicodeOpKind"]},{text:"impl Debug for ClassBracketed",synthetic:false,types:["regex_syntax::ast::ClassBracketed"]},{text:"impl Debug for ClassSet",synthetic:false,types:["regex_syntax::ast::ClassSet"]},{text:"impl Debug for ClassSetItem",synthetic:false,types:["regex_syntax::ast::ClassSetItem"]},{text:"impl Debug for ClassSetRange",synthetic:false,types:["regex_syntax::ast::ClassSetRange"]},{text:"impl Debug for ClassSetUnion",synthetic:false,types:["regex_syntax::ast::ClassSetUnion"]},{text:"impl Debug for ClassSetBinaryOp",synthetic:false,types:["regex_syntax::ast::ClassSetBinaryOp"]},{text:"impl Debug for ClassSetBinaryOpKind",synthetic:false,types:["regex_syntax::ast::ClassSetBinaryOpKind"]},{text:"impl Debug for Assertion",synthetic:false,types:["regex_syntax::ast::Assertion"]},{text:"impl Debug for AssertionKind",synthetic:false,types:["regex_syntax::ast::AssertionKind"]},{text:"impl Debug for Repetition",synthetic:false,types:["regex_syntax::ast::Repetition"]},{text:"impl Debug for RepetitionOp",synthetic:false,types:["regex_syntax::ast::RepetitionOp"]},{text:"impl Debug for RepetitionKind",synthetic:false,types:["regex_syntax::ast::RepetitionKind"]},{text:"impl Debug for RepetitionRange",synthetic:false,types:["regex_syntax::ast::RepetitionRange"]},{text:"impl Debug for Group",synthetic:false,types:["regex_syntax::ast::Group"]},{text:"impl Debug for GroupKind",synthetic:false,types:["regex_syntax::ast::GroupKind"]},{text:"impl Debug for CaptureName",synthetic:false,types:["regex_syntax::ast::CaptureName"]},{text:"impl Debug for SetFlags",synthetic:false,types:["regex_syntax::ast::SetFlags"]},{text:"impl Debug for Flags",synthetic:false,types:["regex_syntax::ast::Flags"]},{text:"impl Debug for FlagsItem",synthetic:false,types:["regex_syntax::ast::FlagsItem"]},{text:"impl Debug for FlagsItemKind",synthetic:false,types:["regex_syntax::ast::FlagsItemKind"]},{text:"impl Debug for Flag",synthetic:false,types:["regex_syntax::ast::Flag"]},{text:"impl Debug for Error",synthetic:false,types:["regex_syntax::error::Error"]},{text:"impl Debug for Literals",synthetic:false,types:["regex_syntax::hir::literal::Literals"]},{text:"impl Debug for Literal",synthetic:false,types:["regex_syntax::hir::literal::Literal"]},{text:"impl Debug for Printer",synthetic:false,types:["regex_syntax::hir::print::Printer"]},{text:"impl Debug for TranslatorBuilder",synthetic:false,types:["regex_syntax::hir::translate::TranslatorBuilder"]},{text:"impl Debug for Translator",synthetic:false,types:["regex_syntax::hir::translate::Translator"]},{text:"impl Debug for Error",synthetic:false,types:["regex_syntax::hir::Error"]},{text:"impl Debug for ErrorKind",synthetic:false,types:["regex_syntax::hir::ErrorKind"]},{text:"impl Debug for Hir",synthetic:false,types:["regex_syntax::hir::Hir"]},{text:"impl Debug for HirKind",synthetic:false,types:["regex_syntax::hir::HirKind"]},{text:"impl Debug for Literal",synthetic:false,types:["regex_syntax::hir::Literal"]},{text:"impl Debug for Class",synthetic:false,types:["regex_syntax::hir::Class"]},{text:"impl Debug for ClassUnicode",synthetic:false,types:["regex_syntax::hir::ClassUnicode"]},{text:"impl<'a> Debug for ClassUnicodeIter<'a>",synthetic:false,types:["regex_syntax::hir::ClassUnicodeIter"]},{text:"impl Debug for ClassUnicodeRange",synthetic:false,types:["regex_syntax::hir::ClassUnicodeRange"]},{text:"impl Debug for ClassBytes",synthetic:false,types:["regex_syntax::hir::ClassBytes"]},{text:"impl<'a> Debug for ClassBytesIter<'a>",synthetic:false,types:["regex_syntax::hir::ClassBytesIter"]},{text:"impl Debug for ClassBytesRange",synthetic:false,types:["regex_syntax::hir::ClassBytesRange"]},{text:"impl Debug for Anchor",synthetic:false,types:["regex_syntax::hir::Anchor"]},{text:"impl Debug for WordBoundary",synthetic:false,types:["regex_syntax::hir::WordBoundary"]},{text:"impl Debug for Group",synthetic:false,types:["regex_syntax::hir::Group"]},{text:"impl Debug for GroupKind",synthetic:false,types:["regex_syntax::hir::GroupKind"]},{text:"impl Debug for Repetition",synthetic:false,types:["regex_syntax::hir::Repetition"]},{text:"impl Debug for RepetitionKind",synthetic:false,types:["regex_syntax::hir::RepetitionKind"]},{text:"impl Debug for RepetitionRange",synthetic:false,types:["regex_syntax::hir::RepetitionRange"]},{text:"impl Debug for ParserBuilder",synthetic:false,types:["regex_syntax::parser::ParserBuilder"]},{text:"impl Debug for Parser",synthetic:false,types:["regex_syntax::parser::Parser"]},]; +implementors["thread_local"] = [{text:"impl<T: ?Sized + Send + Debug> Debug for ThreadLocal<T>",synthetic:false,types:["thread_local::ThreadLocal"]},{text:"impl<T: ?Sized + Send + Debug> Debug for CachedThreadLocal<T>",synthetic:false,types:["thread_local::CachedThreadLocal"]},]; +implementors["utf8_ranges"] = [{text:"impl Debug for Utf8Sequence",synthetic:false,types:["utf8_ranges::Utf8Sequence"]},{text:"impl Debug for Utf8Range",synthetic:false,types:["utf8_ranges::Utf8Range"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/fmt/trait.Display.js b/target/doc/implementors/core/fmt/trait.Display.js new file mode 100644 index 0000000..227a7cc --- /dev/null +++ b/target/doc/implementors/core/fmt/trait.Display.js @@ -0,0 +1,15 @@ +(function() {var implementors = {}; +implementors["aho_corasick"] = [{text:"impl Display for Error",synthetic:false,types:["aho_corasick::error::Error"]},]; +implementors["getrandom"] = [{text:"impl Display for Error",synthetic:false,types:["getrandom::error::Error"]},]; +implementors["rand"] = [{text:"impl Display for WeightedError",synthetic:false,types:["rand::distributions::weighted::WeightedError"]},{text:"impl Display for ReadError",synthetic:false,types:["rand::rngs::adapter::read::ReadError"]},]; +implementors["rand_core"] = [{text:"impl Display for Error",synthetic:false,types:["rand_core::error::Error"]},]; +implementors["regex"] = [{text:"impl Display for Error",synthetic:false,types:["regex::error::Error"]},{text:"impl Display for Regex",synthetic:false,types:["regex::re_bytes::Regex"]},{text:"impl Display for Regex",synthetic:false,types:["regex::re_unicode::Regex"]},]; +implementors["regex_syntax"] = [{text:"impl Display for Error",synthetic:false,types:["regex_syntax::ast::Error"]},{text:"impl Display for ErrorKind",synthetic:false,types:["regex_syntax::ast::ErrorKind"]},{text:"impl Display for Ast",synthetic:false,types:["regex_syntax::ast::Ast"]},{text:"impl Display for Error",synthetic:false,types:["regex_syntax::error::Error"]},{text:"impl Display for Error",synthetic:false,types:["regex_syntax::hir::Error"]},{text:"impl Display for ErrorKind",synthetic:false,types:["regex_syntax::hir::ErrorKind"]},{text:"impl Display for Hir",synthetic:false,types:["regex_syntax::hir::Hir"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/hash/trait.Hash.js b/target/doc/implementors/core/hash/trait.Hash.js new file mode 100644 index 0000000..a56c2c1 --- /dev/null +++ b/target/doc/implementors/core/hash/trait.Hash.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["aho_corasick"] = [{text:"impl Hash for Match",synthetic:false,types:["aho_corasick::Match"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/iter/traits/collect/trait.IntoIterator.js b/target/doc/implementors/core/iter/traits/collect/trait.IntoIterator.js new file mode 100644 index 0000000..0c426ec --- /dev/null +++ b/target/doc/implementors/core/iter/traits/collect/trait.IntoIterator.js @@ -0,0 +1,12 @@ +(function() {var implementors = {}; +implementors["regex"] = [{text:"impl IntoIterator for SetMatches",synthetic:false,types:["regex::re_set::unicode::SetMatches"]},{text:"impl<'a> IntoIterator for &'a SetMatches",synthetic:false,types:["regex::re_set::unicode::SetMatches"]},{text:"impl IntoIterator for SetMatches",synthetic:false,types:["regex::re_set::bytes::SetMatches"]},{text:"impl<'a> IntoIterator for &'a SetMatches",synthetic:false,types:["regex::re_set::bytes::SetMatches"]},]; +implementors["thread_local"] = [{text:"impl<T: ?Sized + Send> IntoIterator for ThreadLocal<T>",synthetic:false,types:["thread_local::ThreadLocal"]},{text:"impl<'a, T: ?Sized + Send + 'a> IntoIterator for &'a mut ThreadLocal<T>",synthetic:false,types:["thread_local::ThreadLocal"]},{text:"impl<T: ?Sized + Send> IntoIterator for CachedThreadLocal<T>",synthetic:false,types:["thread_local::CachedThreadLocal"]},{text:"impl<'a, T: ?Sized + Send + 'a> IntoIterator for &'a mut CachedThreadLocal<T>",synthetic:false,types:["thread_local::CachedThreadLocal"]},]; +implementors["utf8_ranges"] = [{text:"impl<'a> IntoIterator for &'a Utf8Sequence",synthetic:false,types:["utf8_ranges::Utf8Sequence"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/iter/traits/double_ended/trait.DoubleEndedIterator.js b/target/doc/implementors/core/iter/traits/double_ended/trait.DoubleEndedIterator.js new file mode 100644 index 0000000..81006f4 --- /dev/null +++ b/target/doc/implementors/core/iter/traits/double_ended/trait.DoubleEndedIterator.js @@ -0,0 +1,11 @@ +(function() {var implementors = {}; +implementors["memchr"] = [{text:"impl<'a> DoubleEndedIterator for Memchr<'a>",synthetic:false,types:["memchr::iter::Memchr"]},{text:"impl<'a> DoubleEndedIterator for Memchr2<'a>",synthetic:false,types:["memchr::iter::Memchr2"]},{text:"impl<'a> DoubleEndedIterator for Memchr3<'a>",synthetic:false,types:["memchr::iter::Memchr3"]},]; +implementors["regex"] = [{text:"impl DoubleEndedIterator for SetMatchesIntoIter",synthetic:false,types:["regex::re_set::unicode::SetMatchesIntoIter"]},{text:"impl<'a> DoubleEndedIterator for SetMatchesIter<'a>",synthetic:false,types:["regex::re_set::unicode::SetMatchesIter"]},{text:"impl DoubleEndedIterator for SetMatchesIntoIter",synthetic:false,types:["regex::re_set::bytes::SetMatchesIntoIter"]},{text:"impl<'a> DoubleEndedIterator for SetMatchesIter<'a>",synthetic:false,types:["regex::re_set::bytes::SetMatchesIter"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/iter/traits/exact_size/trait.ExactSizeIterator.js b/target/doc/implementors/core/iter/traits/exact_size/trait.ExactSizeIterator.js new file mode 100644 index 0000000..c9b96a2 --- /dev/null +++ b/target/doc/implementors/core/iter/traits/exact_size/trait.ExactSizeIterator.js @@ -0,0 +1,11 @@ +(function() {var implementors = {}; +implementors["rand"] = [{text:"impl<'a> ExactSizeIterator for IndexVecIter<'a>",synthetic:false,types:["rand::seq::index::IndexVecIter"]},{text:"impl ExactSizeIterator for IndexVecIntoIter",synthetic:false,types:["rand::seq::index::IndexVecIntoIter"]},{text:"impl<'a, S: Index<usize, Output = T> + ?Sized + 'a, T: 'a> ExactSizeIterator for SliceChooseIter<'a, S, T>",synthetic:false,types:["rand::seq::SliceChooseIter"]},]; +implementors["thread_local"] = [{text:"impl<'a, T: ?Sized + Send + 'a> ExactSizeIterator for IterMut<'a, T>",synthetic:false,types:["thread_local::IterMut"]},{text:"impl<T: ?Sized + Send> ExactSizeIterator for IntoIter<T>",synthetic:false,types:["thread_local::IntoIter"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/iter/traits/iterator/trait.Iterator.js b/target/doc/implementors/core/iter/traits/iterator/trait.Iterator.js new file mode 100644 index 0000000..f55ef2c --- /dev/null +++ b/target/doc/implementors/core/iter/traits/iterator/trait.Iterator.js @@ -0,0 +1,16 @@ +(function() {var implementors = {}; +implementors["aho_corasick"] = [{text:"impl<'a, 'b, S: StateID> Iterator for FindIter<'a, 'b, S>",synthetic:false,types:["aho_corasick::ahocorasick::FindIter"]},{text:"impl<'a, 'b, S: StateID> Iterator for FindOverlappingIter<'a, 'b, S>",synthetic:false,types:["aho_corasick::ahocorasick::FindOverlappingIter"]},{text:"impl<'a, R: Read, S: StateID> Iterator for StreamFindIter<'a, R, S>",synthetic:false,types:["aho_corasick::ahocorasick::StreamFindIter"]},]; +implementors["memchr"] = [{text:"impl<'a> Iterator for Memchr<'a>",synthetic:false,types:["memchr::iter::Memchr"]},{text:"impl<'a> Iterator for Memchr2<'a>",synthetic:false,types:["memchr::iter::Memchr2"]},{text:"impl<'a> Iterator for Memchr3<'a>",synthetic:false,types:["memchr::iter::Memchr3"]},]; +implementors["rand"] = [{text:"impl<D, R, T> Iterator for DistIter<D, R, T> where
    D: Distribution<T>,
    R: Rng
",synthetic:false,types:["rand::distributions::DistIter"]},{text:"impl<'a> Iterator for IndexVecIter<'a>",synthetic:false,types:["rand::seq::index::IndexVecIter"]},{text:"impl Iterator for IndexVecIntoIter",synthetic:false,types:["rand::seq::index::IndexVecIntoIter"]},{text:"impl<'a, S: Index<usize, Output = T> + ?Sized + 'a, T: 'a> Iterator for SliceChooseIter<'a, S, T>",synthetic:false,types:["rand::seq::SliceChooseIter"]},]; +implementors["regex"] = [{text:"impl<'r, 't> Iterator for Matches<'r, 't>",synthetic:false,types:["regex::re_bytes::Matches"]},{text:"impl<'r, 't> Iterator for CaptureMatches<'r, 't>",synthetic:false,types:["regex::re_bytes::CaptureMatches"]},{text:"impl<'r, 't> Iterator for Split<'r, 't>",synthetic:false,types:["regex::re_bytes::Split"]},{text:"impl<'r, 't> Iterator for SplitN<'r, 't>",synthetic:false,types:["regex::re_bytes::SplitN"]},{text:"impl<'r> Iterator for CaptureNames<'r>",synthetic:false,types:["regex::re_bytes::CaptureNames"]},{text:"impl<'c, 't> Iterator for SubCaptureMatches<'c, 't>",synthetic:false,types:["regex::re_bytes::SubCaptureMatches"]},{text:"impl Iterator for SetMatchesIntoIter",synthetic:false,types:["regex::re_set::unicode::SetMatchesIntoIter"]},{text:"impl<'a> Iterator for SetMatchesIter<'a>",synthetic:false,types:["regex::re_set::unicode::SetMatchesIter"]},{text:"impl Iterator for SetMatchesIntoIter",synthetic:false,types:["regex::re_set::bytes::SetMatchesIntoIter"]},{text:"impl<'a> Iterator for SetMatchesIter<'a>",synthetic:false,types:["regex::re_set::bytes::SetMatchesIter"]},{text:"impl<'r> Iterator for CaptureNames<'r>",synthetic:false,types:["regex::re_unicode::CaptureNames"]},{text:"impl<'r, 't> Iterator for Split<'r, 't>",synthetic:false,types:["regex::re_unicode::Split"]},{text:"impl<'r, 't> Iterator for SplitN<'r, 't>",synthetic:false,types:["regex::re_unicode::SplitN"]},{text:"impl<'c, 't> Iterator for SubCaptureMatches<'c, 't>",synthetic:false,types:["regex::re_unicode::SubCaptureMatches"]},{text:"impl<'r, 't> Iterator for CaptureMatches<'r, 't>",synthetic:false,types:["regex::re_unicode::CaptureMatches"]},{text:"impl<'r, 't> Iterator for Matches<'r, 't>",synthetic:false,types:["regex::re_unicode::Matches"]},]; +implementors["regex_syntax"] = [{text:"impl<'a> Iterator for ClassUnicodeIter<'a>",synthetic:false,types:["regex_syntax::hir::ClassUnicodeIter"]},{text:"impl<'a> Iterator for ClassBytesIter<'a>",synthetic:false,types:["regex_syntax::hir::ClassBytesIter"]},]; +implementors["thread_local"] = [{text:"impl<'a, T: ?Sized + Send + 'a> Iterator for IterMut<'a, T>",synthetic:false,types:["thread_local::IterMut"]},{text:"impl<T: ?Sized + Send> Iterator for IntoIter<T>",synthetic:false,types:["thread_local::IntoIter"]},]; +implementors["utf8_ranges"] = [{text:"impl Iterator for Utf8Sequences",synthetic:false,types:["utf8_ranges::Utf8Sequences"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/iter/traits/marker/trait.FusedIterator.js b/target/doc/implementors/core/iter/traits/marker/trait.FusedIterator.js new file mode 100644 index 0000000..2186958 --- /dev/null +++ b/target/doc/implementors/core/iter/traits/marker/trait.FusedIterator.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["rand"] = [{text:"impl<D, R, T> FusedIterator for DistIter<D, R, T> where
    D: Distribution<T>,
    R: Rng
",synthetic:false,types:["rand::distributions::DistIter"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/marker/trait.Copy.js b/target/doc/implementors/core/marker/trait.Copy.js new file mode 100644 index 0000000..dd990a8 --- /dev/null +++ b/target/doc/implementors/core/marker/trait.Copy.js @@ -0,0 +1,16 @@ +(function() {var implementors = {}; +implementors["aho_corasick"] = [{text:"impl Copy for MatchKind",synthetic:false,types:["aho_corasick::ahocorasick::MatchKind"]},]; +implementors["getrandom"] = [{text:"impl Copy for Error",synthetic:false,types:["getrandom::error::Error"]},]; +implementors["ppv_lite86"] = [{text:"impl Copy for YesS3",synthetic:false,types:["ppv_lite86::x86_64::YesS3"]},{text:"impl Copy for NoS3",synthetic:false,types:["ppv_lite86::x86_64::NoS3"]},{text:"impl Copy for YesS4",synthetic:false,types:["ppv_lite86::x86_64::YesS4"]},{text:"impl Copy for NoS4",synthetic:false,types:["ppv_lite86::x86_64::NoS4"]},{text:"impl Copy for YesA1",synthetic:false,types:["ppv_lite86::x86_64::YesA1"]},{text:"impl Copy for NoA1",synthetic:false,types:["ppv_lite86::x86_64::NoA1"]},{text:"impl Copy for YesA2",synthetic:false,types:["ppv_lite86::x86_64::YesA2"]},{text:"impl Copy for NoA2",synthetic:false,types:["ppv_lite86::x86_64::NoA2"]},{text:"impl Copy for YesNI",synthetic:false,types:["ppv_lite86::x86_64::YesNI"]},{text:"impl Copy for NoNI",synthetic:false,types:["ppv_lite86::x86_64::NoNI"]},{text:"impl<S3: Copy, S4: Copy, NI: Copy> Copy for SseMachine<S3, S4, NI>",synthetic:false,types:["ppv_lite86::x86_64::SseMachine"]},{text:"impl<NI: Copy> Copy for Avx2Machine<NI>",synthetic:false,types:["ppv_lite86::x86_64::Avx2Machine"]},{text:"impl Copy for vec128_storage",synthetic:false,types:["ppv_lite86::x86_64::vec128_storage"]},{text:"impl Copy for vec256_storage",synthetic:false,types:["ppv_lite86::x86_64::vec256_storage"]},{text:"impl Copy for vec512_storage",synthetic:false,types:["ppv_lite86::x86_64::vec512_storage"]},]; +implementors["rand"] = [{text:"impl<X: Copy + SampleUniform> Copy for Uniform<X> where
    X::Sampler: Copy
",synthetic:false,types:["rand::distributions::uniform::Uniform"]},{text:"impl<X: Copy> Copy for UniformInt<X>",synthetic:false,types:["rand::distributions::uniform::UniformInt"]},{text:"impl<X: Copy> Copy for UniformFloat<X>",synthetic:false,types:["rand::distributions::uniform::UniformFloat"]},{text:"impl Copy for UniformDuration",synthetic:false,types:["rand::distributions::uniform::UniformDuration"]},{text:"impl Copy for Bernoulli",synthetic:false,types:["rand::distributions::bernoulli::Bernoulli"]},{text:"impl Copy for BernoulliError",synthetic:false,types:["rand::distributions::bernoulli::BernoulliError"]},{text:"impl Copy for WeightedError",synthetic:false,types:["rand::distributions::weighted::WeightedError"]},{text:"impl Copy for UnitSphereSurface",synthetic:false,types:["rand::distributions::unit_sphere::UnitSphereSurface"]},{text:"impl Copy for UnitCircle",synthetic:false,types:["rand::distributions::unit_circle::UnitCircle"]},{text:"impl Copy for Gamma",synthetic:false,types:["rand::distributions::gamma::Gamma"]},{text:"impl Copy for ChiSquared",synthetic:false,types:["rand::distributions::gamma::ChiSquared"]},{text:"impl Copy for FisherF",synthetic:false,types:["rand::distributions::gamma::FisherF"]},{text:"impl Copy for StudentT",synthetic:false,types:["rand::distributions::gamma::StudentT"]},{text:"impl Copy for Beta",synthetic:false,types:["rand::distributions::gamma::Beta"]},{text:"impl Copy for StandardNormal",synthetic:false,types:["rand::distributions::normal::StandardNormal"]},{text:"impl Copy for Normal",synthetic:false,types:["rand::distributions::normal::Normal"]},{text:"impl Copy for LogNormal",synthetic:false,types:["rand::distributions::normal::LogNormal"]},{text:"impl Copy for Exp1",synthetic:false,types:["rand::distributions::exponential::Exp1"]},{text:"impl Copy for Exp",synthetic:false,types:["rand::distributions::exponential::Exp"]},{text:"impl Copy for Pareto",synthetic:false,types:["rand::distributions::pareto::Pareto"]},{text:"impl Copy for Poisson",synthetic:false,types:["rand::distributions::poisson::Poisson"]},{text:"impl Copy for Binomial",synthetic:false,types:["rand::distributions::binomial::Binomial"]},{text:"impl Copy for Cauchy",synthetic:false,types:["rand::distributions::cauchy::Cauchy"]},{text:"impl Copy for Triangular",synthetic:false,types:["rand::distributions::triangular::Triangular"]},{text:"impl Copy for Weibull",synthetic:false,types:["rand::distributions::weibull::Weibull"]},{text:"impl Copy for OpenClosed01",synthetic:false,types:["rand::distributions::float::OpenClosed01"]},{text:"impl Copy for Open01",synthetic:false,types:["rand::distributions::float::Open01"]},{text:"impl Copy for Standard",synthetic:false,types:["rand::distributions::Standard"]},{text:"impl Copy for ThreadRng",synthetic:false,types:["rand::rngs::thread::ThreadRng"]},{text:"impl Copy for OsRng",synthetic:false,types:["rand::rngs::os::OsRng"]},]; +implementors["regex"] = [{text:"impl<'t> Copy for Match<'t>",synthetic:false,types:["regex::re_bytes::Match"]},{text:"impl<'t> Copy for Match<'t>",synthetic:false,types:["regex::re_unicode::Match"]},]; +implementors["regex_syntax"] = [{text:"impl Copy for Span",synthetic:false,types:["regex_syntax::ast::Span"]},{text:"impl Copy for Position",synthetic:false,types:["regex_syntax::ast::Position"]},{text:"impl Copy for ClassSetBinaryOpKind",synthetic:false,types:["regex_syntax::ast::ClassSetBinaryOpKind"]},{text:"impl Copy for Flag",synthetic:false,types:["regex_syntax::ast::Flag"]},{text:"impl Copy for ClassUnicodeRange",synthetic:false,types:["regex_syntax::hir::ClassUnicodeRange"]},{text:"impl Copy for ClassBytesRange",synthetic:false,types:["regex_syntax::hir::ClassBytesRange"]},]; +implementors["utf8_ranges"] = [{text:"impl Copy for Utf8Sequence",synthetic:false,types:["utf8_ranges::Utf8Sequence"]},{text:"impl Copy for Utf8Range",synthetic:false,types:["utf8_ranges::Utf8Range"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/marker/trait.Send.js b/target/doc/implementors/core/marker/trait.Send.js new file mode 100644 index 0000000..b8e2036 --- /dev/null +++ b/target/doc/implementors/core/marker/trait.Send.js @@ -0,0 +1,21 @@ +(function() {var implementors = {}; +implementors["aho_corasick"] = [{text:"impl<S> Send for AhoCorasick<S> where
    S: Send
",synthetic:true,types:["aho_corasick::ahocorasick::AhoCorasick"]},{text:"impl Send for AhoCorasickBuilder",synthetic:true,types:["aho_corasick::ahocorasick::AhoCorasickBuilder"]},{text:"impl<'a, 'b, S> Send for FindIter<'a, 'b, S> where
    S: Send + Sync
",synthetic:true,types:["aho_corasick::ahocorasick::FindIter"]},{text:"impl<'a, 'b, S> Send for FindOverlappingIter<'a, 'b, S> where
    S: Send + Sync
",synthetic:true,types:["aho_corasick::ahocorasick::FindOverlappingIter"]},{text:"impl<'a, R, S> Send for StreamFindIter<'a, R, S> where
    R: Send,
    S: Send + Sync
",synthetic:true,types:["aho_corasick::ahocorasick::StreamFindIter"]},{text:"impl Send for Error",synthetic:true,types:["aho_corasick::error::Error"]},{text:"impl Send for Match",synthetic:true,types:["aho_corasick::Match"]},{text:"impl Send for MatchKind",synthetic:true,types:["aho_corasick::ahocorasick::MatchKind"]},{text:"impl Send for ErrorKind",synthetic:true,types:["aho_corasick::error::ErrorKind"]},]; +implementors["c2_chacha"] = [{text:"impl Send for ChaCha",synthetic:true,types:["c2_chacha::guts::ChaCha"]},{text:"impl<V> Send for State<V> where
    V: Send
",synthetic:true,types:["c2_chacha::guts::State"]},]; +implementors["getrandom"] = [{text:"impl Send for Error",synthetic:true,types:["getrandom::error::Error"]},]; +implementors["memchr"] = [{text:"impl<'a> Send for Memchr<'a>",synthetic:true,types:["memchr::iter::Memchr"]},{text:"impl<'a> Send for Memchr2<'a>",synthetic:true,types:["memchr::iter::Memchr2"]},{text:"impl<'a> Send for Memchr3<'a>",synthetic:true,types:["memchr::iter::Memchr3"]},]; +implementors["ppv_lite86"] = [{text:"impl Send for YesS3",synthetic:true,types:["ppv_lite86::x86_64::YesS3"]},{text:"impl Send for NoS3",synthetic:true,types:["ppv_lite86::x86_64::NoS3"]},{text:"impl Send for YesS4",synthetic:true,types:["ppv_lite86::x86_64::YesS4"]},{text:"impl Send for NoS4",synthetic:true,types:["ppv_lite86::x86_64::NoS4"]},{text:"impl Send for YesA1",synthetic:true,types:["ppv_lite86::x86_64::YesA1"]},{text:"impl Send for NoA1",synthetic:true,types:["ppv_lite86::x86_64::NoA1"]},{text:"impl Send for YesA2",synthetic:true,types:["ppv_lite86::x86_64::YesA2"]},{text:"impl Send for NoA2",synthetic:true,types:["ppv_lite86::x86_64::NoA2"]},{text:"impl Send for YesNI",synthetic:true,types:["ppv_lite86::x86_64::YesNI"]},{text:"impl Send for NoNI",synthetic:true,types:["ppv_lite86::x86_64::NoNI"]},{text:"impl<S3, S4, NI> Send for SseMachine<S3, S4, NI> where
    NI: Send,
    S3: Send,
    S4: Send
",synthetic:true,types:["ppv_lite86::x86_64::SseMachine"]},{text:"impl<NI> Send for Avx2Machine<NI> where
    NI: Send
",synthetic:true,types:["ppv_lite86::x86_64::Avx2Machine"]},{text:"impl Send for vec128_storage",synthetic:true,types:["ppv_lite86::x86_64::vec128_storage"]},{text:"impl Send for vec256_storage",synthetic:true,types:["ppv_lite86::x86_64::vec256_storage"]},{text:"impl Send for vec512_storage",synthetic:true,types:["ppv_lite86::x86_64::vec512_storage"]},]; +implementors["rand"] = [{text:"impl Send for Alphanumeric",synthetic:true,types:["rand::distributions::other::Alphanumeric"]},{text:"impl<X> Send for Uniform<X> where
    <X as SampleUniform>::Sampler: Send
",synthetic:true,types:["rand::distributions::uniform::Uniform"]},{text:"impl Send for OpenClosed01",synthetic:true,types:["rand::distributions::float::OpenClosed01"]},{text:"impl Send for Open01",synthetic:true,types:["rand::distributions::float::Open01"]},{text:"impl Send for Bernoulli",synthetic:true,types:["rand::distributions::bernoulli::Bernoulli"]},{text:"impl Send for UnitSphereSurface",synthetic:true,types:["rand::distributions::unit_sphere::UnitSphereSurface"]},{text:"impl Send for UnitCircle",synthetic:true,types:["rand::distributions::unit_circle::UnitCircle"]},{text:"impl Send for Gamma",synthetic:true,types:["rand::distributions::gamma::Gamma"]},{text:"impl Send for ChiSquared",synthetic:true,types:["rand::distributions::gamma::ChiSquared"]},{text:"impl Send for FisherF",synthetic:true,types:["rand::distributions::gamma::FisherF"]},{text:"impl Send for StudentT",synthetic:true,types:["rand::distributions::gamma::StudentT"]},{text:"impl Send for Beta",synthetic:true,types:["rand::distributions::gamma::Beta"]},{text:"impl Send for Normal",synthetic:true,types:["rand::distributions::normal::Normal"]},{text:"impl Send for LogNormal",synthetic:true,types:["rand::distributions::normal::LogNormal"]},{text:"impl Send for StandardNormal",synthetic:true,types:["rand::distributions::normal::StandardNormal"]},{text:"impl Send for Exp",synthetic:true,types:["rand::distributions::exponential::Exp"]},{text:"impl Send for Exp1",synthetic:true,types:["rand::distributions::exponential::Exp1"]},{text:"impl Send for Pareto",synthetic:true,types:["rand::distributions::pareto::Pareto"]},{text:"impl Send for Poisson",synthetic:true,types:["rand::distributions::poisson::Poisson"]},{text:"impl Send for Binomial",synthetic:true,types:["rand::distributions::binomial::Binomial"]},{text:"impl Send for Cauchy",synthetic:true,types:["rand::distributions::cauchy::Cauchy"]},{text:"impl Send for Dirichlet",synthetic:true,types:["rand::distributions::dirichlet::Dirichlet"]},{text:"impl Send for Triangular",synthetic:true,types:["rand::distributions::triangular::Triangular"]},{text:"impl Send for Weibull",synthetic:true,types:["rand::distributions::weibull::Weibull"]},{text:"impl<D, R, T> Send for DistIter<D, R, T> where
    D: Send,
    R: Send,
    T: Send
",synthetic:true,types:["rand::distributions::DistIter"]},{text:"impl Send for Standard",synthetic:true,types:["rand::distributions::Standard"]},{text:"impl Send for BernoulliError",synthetic:true,types:["rand::distributions::bernoulli::BernoulliError"]},{text:"impl<X> Send for UniformInt<X> where
    X: Send
",synthetic:true,types:["rand::distributions::uniform::UniformInt"]},{text:"impl<X> Send for UniformFloat<X> where
    X: Send
",synthetic:true,types:["rand::distributions::uniform::UniformFloat"]},{text:"impl Send for UniformDuration",synthetic:true,types:["rand::distributions::uniform::UniformDuration"]},{text:"impl<X> Send for WeightedIndex<X> where
    X: Send,
    <X as SampleUniform>::Sampler: Send
",synthetic:true,types:["rand::distributions::weighted::WeightedIndex"]},{text:"impl Send for WeightedError",synthetic:true,types:["rand::distributions::weighted::WeightedError"]},{text:"impl<W> Send for WeightedIndex<W> where
    W: Send,
    <W as SampleUniform>::Sampler: Send
",synthetic:true,types:["rand::distributions::weighted::alias_method::WeightedIndex"]},{text:"impl Send for EntropyRng",synthetic:true,types:["rand::rngs::entropy::EntropyRng"]},{text:"impl Send for StdRng",synthetic:true,types:["rand::rngs::std::StdRng"]},{text:"impl !Send for ThreadRng",synthetic:true,types:["rand::rngs::thread::ThreadRng"]},{text:"impl Send for OsRng",synthetic:true,types:["rand::rngs::os::OsRng"]},{text:"impl<R> Send for ReadRng<R> where
    R: Send
",synthetic:true,types:["rand::rngs::adapter::read::ReadRng"]},{text:"impl Send for ReadError",synthetic:true,types:["rand::rngs::adapter::read::ReadError"]},{text:"impl<R, Rsdr> Send for ReseedingRng<R, Rsdr> where
    R: Send,
    Rsdr: Send,
    <R as BlockRngCore>::Results: Send
",synthetic:true,types:["rand::rngs::adapter::reseeding::ReseedingRng"]},{text:"impl Send for StepRng",synthetic:true,types:["rand::rngs::mock::StepRng"]},{text:"impl<'a, S: ?Sized, T> Send for SliceChooseIter<'a, S, T> where
    S: Sync,
    T: Send
",synthetic:true,types:["rand::seq::SliceChooseIter"]},{text:"impl Send for IndexVec",synthetic:true,types:["rand::seq::index::IndexVec"]},{text:"impl<'a> Send for IndexVecIter<'a>",synthetic:true,types:["rand::seq::index::IndexVecIter"]},{text:"impl Send for IndexVecIntoIter",synthetic:true,types:["rand::seq::index::IndexVecIntoIter"]},]; +implementors["rand_chacha"] = [{text:"impl Send for ChaCha12Core",synthetic:true,types:["rand_chacha::chacha::ChaCha12Core"]},{text:"impl Send for ChaCha12Rng",synthetic:true,types:["rand_chacha::chacha::ChaCha12Rng"]},{text:"impl Send for ChaCha20Core",synthetic:true,types:["rand_chacha::chacha::ChaCha20Core"]},{text:"impl Send for ChaCha20Rng",synthetic:true,types:["rand_chacha::chacha::ChaCha20Rng"]},{text:"impl Send for ChaCha8Core",synthetic:true,types:["rand_chacha::chacha::ChaCha8Core"]},{text:"impl Send for ChaCha8Rng",synthetic:true,types:["rand_chacha::chacha::ChaCha8Rng"]},]; +implementors["rand_core"] = [{text:"impl Send for Error",synthetic:true,types:["rand_core::error::Error"]},{text:"impl<R: ?Sized> Send for BlockRng<R> where
    R: Send,
    <R as BlockRngCore>::Results: Send
",synthetic:true,types:["rand_core::block::BlockRng"]},{text:"impl<R: ?Sized> Send for BlockRng64<R> where
    R: Send,
    <R as BlockRngCore>::Results: Send
",synthetic:true,types:["rand_core::block::BlockRng64"]},]; +implementors["regex"] = [{text:"impl Send for RegexBuilder",synthetic:true,types:["regex::re_builder::unicode::RegexBuilder"]},{text:"impl Send for RegexSetBuilder",synthetic:true,types:["regex::re_builder::set_unicode::RegexSetBuilder"]},{text:"impl Send for RegexSet",synthetic:true,types:["regex::re_set::unicode::RegexSet"]},{text:"impl Send for SetMatches",synthetic:true,types:["regex::re_set::unicode::SetMatches"]},{text:"impl Send for SetMatchesIntoIter",synthetic:true,types:["regex::re_set::unicode::SetMatchesIntoIter"]},{text:"impl<'a> Send for SetMatchesIter<'a>",synthetic:true,types:["regex::re_set::unicode::SetMatchesIter"]},{text:"impl Send for Regex",synthetic:true,types:["regex::re_unicode::Regex"]},{text:"impl<'t> Send for Match<'t>",synthetic:true,types:["regex::re_unicode::Match"]},{text:"impl<'t> Send for Captures<'t>",synthetic:true,types:["regex::re_unicode::Captures"]},{text:"impl<'r> Send for CaptureNames<'r>",synthetic:true,types:["regex::re_unicode::CaptureNames"]},{text:"impl<'r, 't> !Send for Matches<'r, 't>",synthetic:true,types:["regex::re_unicode::Matches"]},{text:"impl<'r, 't> !Send for CaptureMatches<'r, 't>",synthetic:true,types:["regex::re_unicode::CaptureMatches"]},{text:"impl<'c, 't> Send for SubCaptureMatches<'c, 't>",synthetic:true,types:["regex::re_unicode::SubCaptureMatches"]},{text:"impl Send for CaptureLocations",synthetic:true,types:["regex::re_unicode::CaptureLocations"]},{text:"impl<'a, R: ?Sized> Send for ReplacerRef<'a, R> where
    R: Send
",synthetic:true,types:["regex::re_unicode::ReplacerRef"]},{text:"impl<'t> Send for NoExpand<'t>",synthetic:true,types:["regex::re_unicode::NoExpand"]},{text:"impl<'r, 't> !Send for Split<'r, 't>",synthetic:true,types:["regex::re_unicode::Split"]},{text:"impl<'r, 't> !Send for SplitN<'r, 't>",synthetic:true,types:["regex::re_unicode::SplitN"]},{text:"impl Send for Error",synthetic:true,types:["regex::error::Error"]},{text:"impl Send for RegexBuilder",synthetic:true,types:["regex::re_builder::bytes::RegexBuilder"]},{text:"impl Send for RegexSetBuilder",synthetic:true,types:["regex::re_builder::set_bytes::RegexSetBuilder"]},{text:"impl<'t> Send for Match<'t>",synthetic:true,types:["regex::re_bytes::Match"]},{text:"impl Send for Regex",synthetic:true,types:["regex::re_bytes::Regex"]},{text:"impl<'r, 't> !Send for Matches<'r, 't>",synthetic:true,types:["regex::re_bytes::Matches"]},{text:"impl<'r, 't> !Send for CaptureMatches<'r, 't>",synthetic:true,types:["regex::re_bytes::CaptureMatches"]},{text:"impl<'r, 't> !Send for Split<'r, 't>",synthetic:true,types:["regex::re_bytes::Split"]},{text:"impl<'r, 't> !Send for SplitN<'r, 't>",synthetic:true,types:["regex::re_bytes::SplitN"]},{text:"impl<'r> Send for CaptureNames<'r>",synthetic:true,types:["regex::re_bytes::CaptureNames"]},{text:"impl Send for CaptureLocations",synthetic:true,types:["regex::re_bytes::CaptureLocations"]},{text:"impl<'t> Send for Captures<'t>",synthetic:true,types:["regex::re_bytes::Captures"]},{text:"impl<'c, 't> Send for SubCaptureMatches<'c, 't>",synthetic:true,types:["regex::re_bytes::SubCaptureMatches"]},{text:"impl<'a, R: ?Sized> Send for ReplacerRef<'a, R> where
    R: Send
",synthetic:true,types:["regex::re_bytes::ReplacerRef"]},{text:"impl<'t> Send for NoExpand<'t>",synthetic:true,types:["regex::re_bytes::NoExpand"]},{text:"impl Send for RegexSet",synthetic:true,types:["regex::re_set::bytes::RegexSet"]},{text:"impl Send for SetMatches",synthetic:true,types:["regex::re_set::bytes::SetMatches"]},{text:"impl Send for SetMatchesIntoIter",synthetic:true,types:["regex::re_set::bytes::SetMatchesIntoIter"]},{text:"impl<'a> Send for SetMatchesIter<'a>",synthetic:true,types:["regex::re_set::bytes::SetMatchesIter"]},]; +implementors["regex_syntax"] = [{text:"impl Send for Parser",synthetic:true,types:["regex_syntax::parser::Parser"]},{text:"impl Send for ParserBuilder",synthetic:true,types:["regex_syntax::parser::ParserBuilder"]},{text:"impl Send for Error",synthetic:true,types:["regex_syntax::error::Error"]},{text:"impl Send for Error",synthetic:true,types:["regex_syntax::ast::Error"]},{text:"impl Send for Span",synthetic:true,types:["regex_syntax::ast::Span"]},{text:"impl Send for Position",synthetic:true,types:["regex_syntax::ast::Position"]},{text:"impl Send for WithComments",synthetic:true,types:["regex_syntax::ast::WithComments"]},{text:"impl Send for Comment",synthetic:true,types:["regex_syntax::ast::Comment"]},{text:"impl Send for Alternation",synthetic:true,types:["regex_syntax::ast::Alternation"]},{text:"impl Send for Concat",synthetic:true,types:["regex_syntax::ast::Concat"]},{text:"impl Send for Literal",synthetic:true,types:["regex_syntax::ast::Literal"]},{text:"impl Send for ClassPerl",synthetic:true,types:["regex_syntax::ast::ClassPerl"]},{text:"impl Send for ClassAscii",synthetic:true,types:["regex_syntax::ast::ClassAscii"]},{text:"impl Send for ClassUnicode",synthetic:true,types:["regex_syntax::ast::ClassUnicode"]},{text:"impl Send for ClassBracketed",synthetic:true,types:["regex_syntax::ast::ClassBracketed"]},{text:"impl Send for ClassSetRange",synthetic:true,types:["regex_syntax::ast::ClassSetRange"]},{text:"impl Send for ClassSetUnion",synthetic:true,types:["regex_syntax::ast::ClassSetUnion"]},{text:"impl Send for ClassSetBinaryOp",synthetic:true,types:["regex_syntax::ast::ClassSetBinaryOp"]},{text:"impl Send for Assertion",synthetic:true,types:["regex_syntax::ast::Assertion"]},{text:"impl Send for Repetition",synthetic:true,types:["regex_syntax::ast::Repetition"]},{text:"impl Send for RepetitionOp",synthetic:true,types:["regex_syntax::ast::RepetitionOp"]},{text:"impl Send for Group",synthetic:true,types:["regex_syntax::ast::Group"]},{text:"impl Send for CaptureName",synthetic:true,types:["regex_syntax::ast::CaptureName"]},{text:"impl Send for SetFlags",synthetic:true,types:["regex_syntax::ast::SetFlags"]},{text:"impl Send for Flags",synthetic:true,types:["regex_syntax::ast::Flags"]},{text:"impl Send for FlagsItem",synthetic:true,types:["regex_syntax::ast::FlagsItem"]},{text:"impl Send for ErrorKind",synthetic:true,types:["regex_syntax::ast::ErrorKind"]},{text:"impl Send for Ast",synthetic:true,types:["regex_syntax::ast::Ast"]},{text:"impl Send for LiteralKind",synthetic:true,types:["regex_syntax::ast::LiteralKind"]},{text:"impl Send for SpecialLiteralKind",synthetic:true,types:["regex_syntax::ast::SpecialLiteralKind"]},{text:"impl Send for HexLiteralKind",synthetic:true,types:["regex_syntax::ast::HexLiteralKind"]},{text:"impl Send for Class",synthetic:true,types:["regex_syntax::ast::Class"]},{text:"impl Send for ClassPerlKind",synthetic:true,types:["regex_syntax::ast::ClassPerlKind"]},{text:"impl Send for ClassAsciiKind",synthetic:true,types:["regex_syntax::ast::ClassAsciiKind"]},{text:"impl Send for ClassUnicodeKind",synthetic:true,types:["regex_syntax::ast::ClassUnicodeKind"]},{text:"impl Send for ClassUnicodeOpKind",synthetic:true,types:["regex_syntax::ast::ClassUnicodeOpKind"]},{text:"impl Send for ClassSet",synthetic:true,types:["regex_syntax::ast::ClassSet"]},{text:"impl Send for ClassSetItem",synthetic:true,types:["regex_syntax::ast::ClassSetItem"]},{text:"impl Send for ClassSetBinaryOpKind",synthetic:true,types:["regex_syntax::ast::ClassSetBinaryOpKind"]},{text:"impl Send for AssertionKind",synthetic:true,types:["regex_syntax::ast::AssertionKind"]},{text:"impl Send for RepetitionKind",synthetic:true,types:["regex_syntax::ast::RepetitionKind"]},{text:"impl Send for RepetitionRange",synthetic:true,types:["regex_syntax::ast::RepetitionRange"]},{text:"impl Send for GroupKind",synthetic:true,types:["regex_syntax::ast::GroupKind"]},{text:"impl Send for FlagsItemKind",synthetic:true,types:["regex_syntax::ast::FlagsItemKind"]},{text:"impl Send for Flag",synthetic:true,types:["regex_syntax::ast::Flag"]},{text:"impl Send for ParserBuilder",synthetic:true,types:["regex_syntax::ast::parse::ParserBuilder"]},{text:"impl Send for Parser",synthetic:true,types:["regex_syntax::ast::parse::Parser"]},{text:"impl Send for Printer",synthetic:true,types:["regex_syntax::ast::print::Printer"]},{text:"impl Send for Error",synthetic:true,types:["regex_syntax::hir::Error"]},{text:"impl Send for Hir",synthetic:true,types:["regex_syntax::hir::Hir"]},{text:"impl Send for ClassUnicode",synthetic:true,types:["regex_syntax::hir::ClassUnicode"]},{text:"impl<'a> Send for ClassUnicodeIter<'a>",synthetic:true,types:["regex_syntax::hir::ClassUnicodeIter"]},{text:"impl Send for ClassUnicodeRange",synthetic:true,types:["regex_syntax::hir::ClassUnicodeRange"]},{text:"impl Send for ClassBytes",synthetic:true,types:["regex_syntax::hir::ClassBytes"]},{text:"impl<'a> Send for ClassBytesIter<'a>",synthetic:true,types:["regex_syntax::hir::ClassBytesIter"]},{text:"impl Send for ClassBytesRange",synthetic:true,types:["regex_syntax::hir::ClassBytesRange"]},{text:"impl Send for Group",synthetic:true,types:["regex_syntax::hir::Group"]},{text:"impl Send for Repetition",synthetic:true,types:["regex_syntax::hir::Repetition"]},{text:"impl Send for ErrorKind",synthetic:true,types:["regex_syntax::hir::ErrorKind"]},{text:"impl Send for HirKind",synthetic:true,types:["regex_syntax::hir::HirKind"]},{text:"impl Send for Literal",synthetic:true,types:["regex_syntax::hir::Literal"]},{text:"impl Send for Class",synthetic:true,types:["regex_syntax::hir::Class"]},{text:"impl Send for Anchor",synthetic:true,types:["regex_syntax::hir::Anchor"]},{text:"impl Send for WordBoundary",synthetic:true,types:["regex_syntax::hir::WordBoundary"]},{text:"impl Send for GroupKind",synthetic:true,types:["regex_syntax::hir::GroupKind"]},{text:"impl Send for RepetitionKind",synthetic:true,types:["regex_syntax::hir::RepetitionKind"]},{text:"impl Send for RepetitionRange",synthetic:true,types:["regex_syntax::hir::RepetitionRange"]},{text:"impl Send for Literals",synthetic:true,types:["regex_syntax::hir::literal::Literals"]},{text:"impl Send for Literal",synthetic:true,types:["regex_syntax::hir::literal::Literal"]},{text:"impl Send for Printer",synthetic:true,types:["regex_syntax::hir::print::Printer"]},{text:"impl Send for TranslatorBuilder",synthetic:true,types:["regex_syntax::hir::translate::TranslatorBuilder"]},{text:"impl Send for Translator",synthetic:true,types:["regex_syntax::hir::translate::Translator"]},]; +implementors["thread_local"] = [{text:"impl<T: ?Sized> Send for ThreadLocal<T>",synthetic:true,types:["thread_local::ThreadLocal"]},{text:"impl<'a, T> !Send for IterMut<'a, T>",synthetic:true,types:["thread_local::IterMut"]},{text:"impl<T> !Send for IntoIter<T>",synthetic:true,types:["thread_local::IntoIter"]},{text:"impl<T: ?Sized> Send for CachedThreadLocal<T>",synthetic:true,types:["thread_local::CachedThreadLocal"]},]; +implementors["utf8_ranges"] = [{text:"impl Send for Utf8Range",synthetic:true,types:["utf8_ranges::Utf8Range"]},{text:"impl Send for Utf8Sequences",synthetic:true,types:["utf8_ranges::Utf8Sequences"]},{text:"impl Send for Utf8Sequence",synthetic:true,types:["utf8_ranges::Utf8Sequence"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/marker/trait.Sync.js b/target/doc/implementors/core/marker/trait.Sync.js new file mode 100644 index 0000000..f237f7e --- /dev/null +++ b/target/doc/implementors/core/marker/trait.Sync.js @@ -0,0 +1,21 @@ +(function() {var implementors = {}; +implementors["aho_corasick"] = [{text:"impl<S> Sync for AhoCorasick<S> where
    S: Sync
",synthetic:true,types:["aho_corasick::ahocorasick::AhoCorasick"]},{text:"impl Sync for AhoCorasickBuilder",synthetic:true,types:["aho_corasick::ahocorasick::AhoCorasickBuilder"]},{text:"impl<'a, 'b, S> Sync for FindIter<'a, 'b, S> where
    S: Sync
",synthetic:true,types:["aho_corasick::ahocorasick::FindIter"]},{text:"impl<'a, 'b, S> Sync for FindOverlappingIter<'a, 'b, S> where
    S: Sync
",synthetic:true,types:["aho_corasick::ahocorasick::FindOverlappingIter"]},{text:"impl<'a, R, S> Sync for StreamFindIter<'a, R, S> where
    R: Sync,
    S: Sync
",synthetic:true,types:["aho_corasick::ahocorasick::StreamFindIter"]},{text:"impl Sync for Error",synthetic:true,types:["aho_corasick::error::Error"]},{text:"impl Sync for Match",synthetic:true,types:["aho_corasick::Match"]},{text:"impl Sync for MatchKind",synthetic:true,types:["aho_corasick::ahocorasick::MatchKind"]},{text:"impl Sync for ErrorKind",synthetic:true,types:["aho_corasick::error::ErrorKind"]},]; +implementors["c2_chacha"] = [{text:"impl Sync for ChaCha",synthetic:true,types:["c2_chacha::guts::ChaCha"]},{text:"impl<V> Sync for State<V> where
    V: Sync
",synthetic:true,types:["c2_chacha::guts::State"]},]; +implementors["getrandom"] = [{text:"impl Sync for Error",synthetic:true,types:["getrandom::error::Error"]},]; +implementors["memchr"] = [{text:"impl<'a> Sync for Memchr<'a>",synthetic:true,types:["memchr::iter::Memchr"]},{text:"impl<'a> Sync for Memchr2<'a>",synthetic:true,types:["memchr::iter::Memchr2"]},{text:"impl<'a> Sync for Memchr3<'a>",synthetic:true,types:["memchr::iter::Memchr3"]},]; +implementors["ppv_lite86"] = [{text:"impl Sync for YesS3",synthetic:true,types:["ppv_lite86::x86_64::YesS3"]},{text:"impl Sync for NoS3",synthetic:true,types:["ppv_lite86::x86_64::NoS3"]},{text:"impl Sync for YesS4",synthetic:true,types:["ppv_lite86::x86_64::YesS4"]},{text:"impl Sync for NoS4",synthetic:true,types:["ppv_lite86::x86_64::NoS4"]},{text:"impl Sync for YesA1",synthetic:true,types:["ppv_lite86::x86_64::YesA1"]},{text:"impl Sync for NoA1",synthetic:true,types:["ppv_lite86::x86_64::NoA1"]},{text:"impl Sync for YesA2",synthetic:true,types:["ppv_lite86::x86_64::YesA2"]},{text:"impl Sync for NoA2",synthetic:true,types:["ppv_lite86::x86_64::NoA2"]},{text:"impl Sync for YesNI",synthetic:true,types:["ppv_lite86::x86_64::YesNI"]},{text:"impl Sync for NoNI",synthetic:true,types:["ppv_lite86::x86_64::NoNI"]},{text:"impl<S3, S4, NI> Sync for SseMachine<S3, S4, NI> where
    NI: Sync,
    S3: Sync,
    S4: Sync
",synthetic:true,types:["ppv_lite86::x86_64::SseMachine"]},{text:"impl<NI> Sync for Avx2Machine<NI> where
    NI: Sync
",synthetic:true,types:["ppv_lite86::x86_64::Avx2Machine"]},{text:"impl Sync for vec128_storage",synthetic:true,types:["ppv_lite86::x86_64::vec128_storage"]},{text:"impl Sync for vec256_storage",synthetic:true,types:["ppv_lite86::x86_64::vec256_storage"]},{text:"impl Sync for vec512_storage",synthetic:true,types:["ppv_lite86::x86_64::vec512_storage"]},]; +implementors["rand"] = [{text:"impl Sync for Alphanumeric",synthetic:true,types:["rand::distributions::other::Alphanumeric"]},{text:"impl<X> Sync for Uniform<X> where
    <X as SampleUniform>::Sampler: Sync
",synthetic:true,types:["rand::distributions::uniform::Uniform"]},{text:"impl Sync for OpenClosed01",synthetic:true,types:["rand::distributions::float::OpenClosed01"]},{text:"impl Sync for Open01",synthetic:true,types:["rand::distributions::float::Open01"]},{text:"impl Sync for Bernoulli",synthetic:true,types:["rand::distributions::bernoulli::Bernoulli"]},{text:"impl Sync for UnitSphereSurface",synthetic:true,types:["rand::distributions::unit_sphere::UnitSphereSurface"]},{text:"impl Sync for UnitCircle",synthetic:true,types:["rand::distributions::unit_circle::UnitCircle"]},{text:"impl Sync for Gamma",synthetic:true,types:["rand::distributions::gamma::Gamma"]},{text:"impl Sync for ChiSquared",synthetic:true,types:["rand::distributions::gamma::ChiSquared"]},{text:"impl Sync for FisherF",synthetic:true,types:["rand::distributions::gamma::FisherF"]},{text:"impl Sync for StudentT",synthetic:true,types:["rand::distributions::gamma::StudentT"]},{text:"impl Sync for Beta",synthetic:true,types:["rand::distributions::gamma::Beta"]},{text:"impl Sync for Normal",synthetic:true,types:["rand::distributions::normal::Normal"]},{text:"impl Sync for LogNormal",synthetic:true,types:["rand::distributions::normal::LogNormal"]},{text:"impl Sync for StandardNormal",synthetic:true,types:["rand::distributions::normal::StandardNormal"]},{text:"impl Sync for Exp",synthetic:true,types:["rand::distributions::exponential::Exp"]},{text:"impl Sync for Exp1",synthetic:true,types:["rand::distributions::exponential::Exp1"]},{text:"impl Sync for Pareto",synthetic:true,types:["rand::distributions::pareto::Pareto"]},{text:"impl Sync for Poisson",synthetic:true,types:["rand::distributions::poisson::Poisson"]},{text:"impl Sync for Binomial",synthetic:true,types:["rand::distributions::binomial::Binomial"]},{text:"impl Sync for Cauchy",synthetic:true,types:["rand::distributions::cauchy::Cauchy"]},{text:"impl Sync for Dirichlet",synthetic:true,types:["rand::distributions::dirichlet::Dirichlet"]},{text:"impl Sync for Triangular",synthetic:true,types:["rand::distributions::triangular::Triangular"]},{text:"impl Sync for Weibull",synthetic:true,types:["rand::distributions::weibull::Weibull"]},{text:"impl<D, R, T> Sync for DistIter<D, R, T> where
    D: Sync,
    R: Sync,
    T: Sync
",synthetic:true,types:["rand::distributions::DistIter"]},{text:"impl Sync for Standard",synthetic:true,types:["rand::distributions::Standard"]},{text:"impl Sync for BernoulliError",synthetic:true,types:["rand::distributions::bernoulli::BernoulliError"]},{text:"impl<X> Sync for UniformInt<X> where
    X: Sync
",synthetic:true,types:["rand::distributions::uniform::UniformInt"]},{text:"impl<X> Sync for UniformFloat<X> where
    X: Sync
",synthetic:true,types:["rand::distributions::uniform::UniformFloat"]},{text:"impl Sync for UniformDuration",synthetic:true,types:["rand::distributions::uniform::UniformDuration"]},{text:"impl<X> Sync for WeightedIndex<X> where
    X: Sync,
    <X as SampleUniform>::Sampler: Sync
",synthetic:true,types:["rand::distributions::weighted::WeightedIndex"]},{text:"impl Sync for WeightedError",synthetic:true,types:["rand::distributions::weighted::WeightedError"]},{text:"impl<W> Sync for WeightedIndex<W> where
    W: Sync,
    <W as SampleUniform>::Sampler: Sync
",synthetic:true,types:["rand::distributions::weighted::alias_method::WeightedIndex"]},{text:"impl Sync for EntropyRng",synthetic:true,types:["rand::rngs::entropy::EntropyRng"]},{text:"impl Sync for StdRng",synthetic:true,types:["rand::rngs::std::StdRng"]},{text:"impl !Sync for ThreadRng",synthetic:true,types:["rand::rngs::thread::ThreadRng"]},{text:"impl Sync for OsRng",synthetic:true,types:["rand::rngs::os::OsRng"]},{text:"impl<R> Sync for ReadRng<R> where
    R: Sync
",synthetic:true,types:["rand::rngs::adapter::read::ReadRng"]},{text:"impl Sync for ReadError",synthetic:true,types:["rand::rngs::adapter::read::ReadError"]},{text:"impl<R, Rsdr> Sync for ReseedingRng<R, Rsdr> where
    R: Sync,
    Rsdr: Sync,
    <R as BlockRngCore>::Results: Sync
",synthetic:true,types:["rand::rngs::adapter::reseeding::ReseedingRng"]},{text:"impl Sync for StepRng",synthetic:true,types:["rand::rngs::mock::StepRng"]},{text:"impl<'a, S: ?Sized, T> Sync for SliceChooseIter<'a, S, T> where
    S: Sync,
    T: Sync
",synthetic:true,types:["rand::seq::SliceChooseIter"]},{text:"impl Sync for IndexVec",synthetic:true,types:["rand::seq::index::IndexVec"]},{text:"impl<'a> Sync for IndexVecIter<'a>",synthetic:true,types:["rand::seq::index::IndexVecIter"]},{text:"impl Sync for IndexVecIntoIter",synthetic:true,types:["rand::seq::index::IndexVecIntoIter"]},]; +implementors["rand_chacha"] = [{text:"impl Sync for ChaCha12Core",synthetic:true,types:["rand_chacha::chacha::ChaCha12Core"]},{text:"impl Sync for ChaCha12Rng",synthetic:true,types:["rand_chacha::chacha::ChaCha12Rng"]},{text:"impl Sync for ChaCha20Core",synthetic:true,types:["rand_chacha::chacha::ChaCha20Core"]},{text:"impl Sync for ChaCha20Rng",synthetic:true,types:["rand_chacha::chacha::ChaCha20Rng"]},{text:"impl Sync for ChaCha8Core",synthetic:true,types:["rand_chacha::chacha::ChaCha8Core"]},{text:"impl Sync for ChaCha8Rng",synthetic:true,types:["rand_chacha::chacha::ChaCha8Rng"]},]; +implementors["rand_core"] = [{text:"impl Sync for Error",synthetic:true,types:["rand_core::error::Error"]},{text:"impl<R: ?Sized> Sync for BlockRng<R> where
    R: Sync,
    <R as BlockRngCore>::Results: Sync
",synthetic:true,types:["rand_core::block::BlockRng"]},{text:"impl<R: ?Sized> Sync for BlockRng64<R> where
    R: Sync,
    <R as BlockRngCore>::Results: Sync
",synthetic:true,types:["rand_core::block::BlockRng64"]},]; +implementors["regex"] = [{text:"impl Sync for RegexBuilder",synthetic:true,types:["regex::re_builder::unicode::RegexBuilder"]},{text:"impl Sync for RegexSetBuilder",synthetic:true,types:["regex::re_builder::set_unicode::RegexSetBuilder"]},{text:"impl Sync for RegexSet",synthetic:true,types:["regex::re_set::unicode::RegexSet"]},{text:"impl Sync for SetMatches",synthetic:true,types:["regex::re_set::unicode::SetMatches"]},{text:"impl Sync for SetMatchesIntoIter",synthetic:true,types:["regex::re_set::unicode::SetMatchesIntoIter"]},{text:"impl<'a> Sync for SetMatchesIter<'a>",synthetic:true,types:["regex::re_set::unicode::SetMatchesIter"]},{text:"impl Sync for Regex",synthetic:true,types:["regex::re_unicode::Regex"]},{text:"impl<'t> Sync for Match<'t>",synthetic:true,types:["regex::re_unicode::Match"]},{text:"impl<'t> Sync for Captures<'t>",synthetic:true,types:["regex::re_unicode::Captures"]},{text:"impl<'r> Sync for CaptureNames<'r>",synthetic:true,types:["regex::re_unicode::CaptureNames"]},{text:"impl<'r, 't> !Sync for Matches<'r, 't>",synthetic:true,types:["regex::re_unicode::Matches"]},{text:"impl<'r, 't> !Sync for CaptureMatches<'r, 't>",synthetic:true,types:["regex::re_unicode::CaptureMatches"]},{text:"impl<'c, 't> Sync for SubCaptureMatches<'c, 't>",synthetic:true,types:["regex::re_unicode::SubCaptureMatches"]},{text:"impl Sync for CaptureLocations",synthetic:true,types:["regex::re_unicode::CaptureLocations"]},{text:"impl<'a, R: ?Sized> Sync for ReplacerRef<'a, R> where
    R: Sync
",synthetic:true,types:["regex::re_unicode::ReplacerRef"]},{text:"impl<'t> Sync for NoExpand<'t>",synthetic:true,types:["regex::re_unicode::NoExpand"]},{text:"impl<'r, 't> !Sync for Split<'r, 't>",synthetic:true,types:["regex::re_unicode::Split"]},{text:"impl<'r, 't> !Sync for SplitN<'r, 't>",synthetic:true,types:["regex::re_unicode::SplitN"]},{text:"impl Sync for Error",synthetic:true,types:["regex::error::Error"]},{text:"impl Sync for RegexBuilder",synthetic:true,types:["regex::re_builder::bytes::RegexBuilder"]},{text:"impl Sync for RegexSetBuilder",synthetic:true,types:["regex::re_builder::set_bytes::RegexSetBuilder"]},{text:"impl<'t> Sync for Match<'t>",synthetic:true,types:["regex::re_bytes::Match"]},{text:"impl Sync for Regex",synthetic:true,types:["regex::re_bytes::Regex"]},{text:"impl<'r, 't> !Sync for Matches<'r, 't>",synthetic:true,types:["regex::re_bytes::Matches"]},{text:"impl<'r, 't> !Sync for CaptureMatches<'r, 't>",synthetic:true,types:["regex::re_bytes::CaptureMatches"]},{text:"impl<'r, 't> !Sync for Split<'r, 't>",synthetic:true,types:["regex::re_bytes::Split"]},{text:"impl<'r, 't> !Sync for SplitN<'r, 't>",synthetic:true,types:["regex::re_bytes::SplitN"]},{text:"impl<'r> Sync for CaptureNames<'r>",synthetic:true,types:["regex::re_bytes::CaptureNames"]},{text:"impl Sync for CaptureLocations",synthetic:true,types:["regex::re_bytes::CaptureLocations"]},{text:"impl<'t> Sync for Captures<'t>",synthetic:true,types:["regex::re_bytes::Captures"]},{text:"impl<'c, 't> Sync for SubCaptureMatches<'c, 't>",synthetic:true,types:["regex::re_bytes::SubCaptureMatches"]},{text:"impl<'a, R: ?Sized> Sync for ReplacerRef<'a, R> where
    R: Sync
",synthetic:true,types:["regex::re_bytes::ReplacerRef"]},{text:"impl<'t> Sync for NoExpand<'t>",synthetic:true,types:["regex::re_bytes::NoExpand"]},{text:"impl Sync for RegexSet",synthetic:true,types:["regex::re_set::bytes::RegexSet"]},{text:"impl Sync for SetMatches",synthetic:true,types:["regex::re_set::bytes::SetMatches"]},{text:"impl Sync for SetMatchesIntoIter",synthetic:true,types:["regex::re_set::bytes::SetMatchesIntoIter"]},{text:"impl<'a> Sync for SetMatchesIter<'a>",synthetic:true,types:["regex::re_set::bytes::SetMatchesIter"]},]; +implementors["regex_syntax"] = [{text:"impl !Sync for Parser",synthetic:true,types:["regex_syntax::parser::Parser"]},{text:"impl Sync for ParserBuilder",synthetic:true,types:["regex_syntax::parser::ParserBuilder"]},{text:"impl Sync for Error",synthetic:true,types:["regex_syntax::error::Error"]},{text:"impl Sync for Error",synthetic:true,types:["regex_syntax::ast::Error"]},{text:"impl Sync for Span",synthetic:true,types:["regex_syntax::ast::Span"]},{text:"impl Sync for Position",synthetic:true,types:["regex_syntax::ast::Position"]},{text:"impl Sync for WithComments",synthetic:true,types:["regex_syntax::ast::WithComments"]},{text:"impl Sync for Comment",synthetic:true,types:["regex_syntax::ast::Comment"]},{text:"impl Sync for Alternation",synthetic:true,types:["regex_syntax::ast::Alternation"]},{text:"impl Sync for Concat",synthetic:true,types:["regex_syntax::ast::Concat"]},{text:"impl Sync for Literal",synthetic:true,types:["regex_syntax::ast::Literal"]},{text:"impl Sync for ClassPerl",synthetic:true,types:["regex_syntax::ast::ClassPerl"]},{text:"impl Sync for ClassAscii",synthetic:true,types:["regex_syntax::ast::ClassAscii"]},{text:"impl Sync for ClassUnicode",synthetic:true,types:["regex_syntax::ast::ClassUnicode"]},{text:"impl Sync for ClassBracketed",synthetic:true,types:["regex_syntax::ast::ClassBracketed"]},{text:"impl Sync for ClassSetRange",synthetic:true,types:["regex_syntax::ast::ClassSetRange"]},{text:"impl Sync for ClassSetUnion",synthetic:true,types:["regex_syntax::ast::ClassSetUnion"]},{text:"impl Sync for ClassSetBinaryOp",synthetic:true,types:["regex_syntax::ast::ClassSetBinaryOp"]},{text:"impl Sync for Assertion",synthetic:true,types:["regex_syntax::ast::Assertion"]},{text:"impl Sync for Repetition",synthetic:true,types:["regex_syntax::ast::Repetition"]},{text:"impl Sync for RepetitionOp",synthetic:true,types:["regex_syntax::ast::RepetitionOp"]},{text:"impl Sync for Group",synthetic:true,types:["regex_syntax::ast::Group"]},{text:"impl Sync for CaptureName",synthetic:true,types:["regex_syntax::ast::CaptureName"]},{text:"impl Sync for SetFlags",synthetic:true,types:["regex_syntax::ast::SetFlags"]},{text:"impl Sync for Flags",synthetic:true,types:["regex_syntax::ast::Flags"]},{text:"impl Sync for FlagsItem",synthetic:true,types:["regex_syntax::ast::FlagsItem"]},{text:"impl Sync for ErrorKind",synthetic:true,types:["regex_syntax::ast::ErrorKind"]},{text:"impl Sync for Ast",synthetic:true,types:["regex_syntax::ast::Ast"]},{text:"impl Sync for LiteralKind",synthetic:true,types:["regex_syntax::ast::LiteralKind"]},{text:"impl Sync for SpecialLiteralKind",synthetic:true,types:["regex_syntax::ast::SpecialLiteralKind"]},{text:"impl Sync for HexLiteralKind",synthetic:true,types:["regex_syntax::ast::HexLiteralKind"]},{text:"impl Sync for Class",synthetic:true,types:["regex_syntax::ast::Class"]},{text:"impl Sync for ClassPerlKind",synthetic:true,types:["regex_syntax::ast::ClassPerlKind"]},{text:"impl Sync for ClassAsciiKind",synthetic:true,types:["regex_syntax::ast::ClassAsciiKind"]},{text:"impl Sync for ClassUnicodeKind",synthetic:true,types:["regex_syntax::ast::ClassUnicodeKind"]},{text:"impl Sync for ClassUnicodeOpKind",synthetic:true,types:["regex_syntax::ast::ClassUnicodeOpKind"]},{text:"impl Sync for ClassSet",synthetic:true,types:["regex_syntax::ast::ClassSet"]},{text:"impl Sync for ClassSetItem",synthetic:true,types:["regex_syntax::ast::ClassSetItem"]},{text:"impl Sync for ClassSetBinaryOpKind",synthetic:true,types:["regex_syntax::ast::ClassSetBinaryOpKind"]},{text:"impl Sync for AssertionKind",synthetic:true,types:["regex_syntax::ast::AssertionKind"]},{text:"impl Sync for RepetitionKind",synthetic:true,types:["regex_syntax::ast::RepetitionKind"]},{text:"impl Sync for RepetitionRange",synthetic:true,types:["regex_syntax::ast::RepetitionRange"]},{text:"impl Sync for GroupKind",synthetic:true,types:["regex_syntax::ast::GroupKind"]},{text:"impl Sync for FlagsItemKind",synthetic:true,types:["regex_syntax::ast::FlagsItemKind"]},{text:"impl Sync for Flag",synthetic:true,types:["regex_syntax::ast::Flag"]},{text:"impl Sync for ParserBuilder",synthetic:true,types:["regex_syntax::ast::parse::ParserBuilder"]},{text:"impl !Sync for Parser",synthetic:true,types:["regex_syntax::ast::parse::Parser"]},{text:"impl Sync for Printer",synthetic:true,types:["regex_syntax::ast::print::Printer"]},{text:"impl Sync for Error",synthetic:true,types:["regex_syntax::hir::Error"]},{text:"impl Sync for Hir",synthetic:true,types:["regex_syntax::hir::Hir"]},{text:"impl Sync for ClassUnicode",synthetic:true,types:["regex_syntax::hir::ClassUnicode"]},{text:"impl<'a> Sync for ClassUnicodeIter<'a>",synthetic:true,types:["regex_syntax::hir::ClassUnicodeIter"]},{text:"impl Sync for ClassUnicodeRange",synthetic:true,types:["regex_syntax::hir::ClassUnicodeRange"]},{text:"impl Sync for ClassBytes",synthetic:true,types:["regex_syntax::hir::ClassBytes"]},{text:"impl<'a> Sync for ClassBytesIter<'a>",synthetic:true,types:["regex_syntax::hir::ClassBytesIter"]},{text:"impl Sync for ClassBytesRange",synthetic:true,types:["regex_syntax::hir::ClassBytesRange"]},{text:"impl Sync for Group",synthetic:true,types:["regex_syntax::hir::Group"]},{text:"impl Sync for Repetition",synthetic:true,types:["regex_syntax::hir::Repetition"]},{text:"impl Sync for ErrorKind",synthetic:true,types:["regex_syntax::hir::ErrorKind"]},{text:"impl Sync for HirKind",synthetic:true,types:["regex_syntax::hir::HirKind"]},{text:"impl Sync for Literal",synthetic:true,types:["regex_syntax::hir::Literal"]},{text:"impl Sync for Class",synthetic:true,types:["regex_syntax::hir::Class"]},{text:"impl Sync for Anchor",synthetic:true,types:["regex_syntax::hir::Anchor"]},{text:"impl Sync for WordBoundary",synthetic:true,types:["regex_syntax::hir::WordBoundary"]},{text:"impl Sync for GroupKind",synthetic:true,types:["regex_syntax::hir::GroupKind"]},{text:"impl Sync for RepetitionKind",synthetic:true,types:["regex_syntax::hir::RepetitionKind"]},{text:"impl Sync for RepetitionRange",synthetic:true,types:["regex_syntax::hir::RepetitionRange"]},{text:"impl Sync for Literals",synthetic:true,types:["regex_syntax::hir::literal::Literals"]},{text:"impl Sync for Literal",synthetic:true,types:["regex_syntax::hir::literal::Literal"]},{text:"impl Sync for Printer",synthetic:true,types:["regex_syntax::hir::print::Printer"]},{text:"impl Sync for TranslatorBuilder",synthetic:true,types:["regex_syntax::hir::translate::TranslatorBuilder"]},{text:"impl !Sync for Translator",synthetic:true,types:["regex_syntax::hir::translate::Translator"]},]; +implementors["thread_local"] = [{text:"impl<'a, T> !Sync for IterMut<'a, T>",synthetic:true,types:["thread_local::IterMut"]},{text:"impl<T> !Sync for IntoIter<T>",synthetic:true,types:["thread_local::IntoIter"]},{text:"impl<T: ?Sized + Send> Sync for ThreadLocal<T>",synthetic:false,types:["thread_local::ThreadLocal"]},{text:"impl<T: ?Sized + Send> Sync for CachedThreadLocal<T>",synthetic:false,types:["thread_local::CachedThreadLocal"]},]; +implementors["utf8_ranges"] = [{text:"impl Sync for Utf8Range",synthetic:true,types:["utf8_ranges::Utf8Range"]},{text:"impl Sync for Utf8Sequences",synthetic:true,types:["utf8_ranges::Utf8Sequences"]},{text:"impl Sync for Utf8Sequence",synthetic:true,types:["utf8_ranges::Utf8Sequence"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/ops/deref/trait.Deref.js b/target/doc/implementors/core/ops/deref/trait.Deref.js new file mode 100644 index 0000000..2638ce9 --- /dev/null +++ b/target/doc/implementors/core/ops/deref/trait.Deref.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["regex_syntax"] = [{text:"impl Deref for Literal",synthetic:false,types:["regex_syntax::hir::literal::Literal"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/ops/deref/trait.DerefMut.js b/target/doc/implementors/core/ops/deref/trait.DerefMut.js new file mode 100644 index 0000000..354dab7 --- /dev/null +++ b/target/doc/implementors/core/ops/deref/trait.DerefMut.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["regex_syntax"] = [{text:"impl DerefMut for Literal",synthetic:false,types:["regex_syntax::hir::literal::Literal"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/ops/drop/trait.Drop.js b/target/doc/implementors/core/ops/drop/trait.Drop.js new file mode 100644 index 0000000..016ef8e --- /dev/null +++ b/target/doc/implementors/core/ops/drop/trait.Drop.js @@ -0,0 +1,11 @@ +(function() {var implementors = {}; +implementors["regex_syntax"] = [{text:"impl Drop for Ast",synthetic:false,types:["regex_syntax::ast::Ast"]},{text:"impl Drop for ClassSet",synthetic:false,types:["regex_syntax::ast::ClassSet"]},{text:"impl Drop for Hir",synthetic:false,types:["regex_syntax::hir::Hir"]},]; +implementors["thread_local"] = [{text:"impl<T: ?Sized + Send> Drop for ThreadLocal<T>",synthetic:false,types:["thread_local::ThreadLocal"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/ops/index/trait.Index.js b/target/doc/implementors/core/ops/index/trait.Index.js new file mode 100644 index 0000000..3e192e6 --- /dev/null +++ b/target/doc/implementors/core/ops/index/trait.Index.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["regex"] = [{text:"impl<'t> Index<usize> for Captures<'t>",synthetic:false,types:["regex::re_bytes::Captures"]},{text:"impl<'t, 'i> Index<&'i str> for Captures<'t>",synthetic:false,types:["regex::re_bytes::Captures"]},{text:"impl<'t> Index<usize> for Captures<'t>",synthetic:false,types:["regex::re_unicode::Captures"]},{text:"impl<'t, 'i> Index<&'i str> for Captures<'t>",synthetic:false,types:["regex::re_unicode::Captures"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/core/str/trait.FromStr.js b/target/doc/implementors/core/str/trait.FromStr.js new file mode 100644 index 0000000..17f89fc --- /dev/null +++ b/target/doc/implementors/core/str/trait.FromStr.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["regex"] = [{text:"impl FromStr for Regex",synthetic:false,types:["regex::re_bytes::Regex"]},{text:"impl FromStr for Regex",synthetic:false,types:["regex::re_unicode::Regex"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/owoify/trait.OwOifiable.js b/target/doc/implementors/owoify/trait.OwOifiable.js new file mode 100644 index 0000000..7475ebd --- /dev/null +++ b/target/doc/implementors/owoify/trait.OwOifiable.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["owoify"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/ppv_lite86/trait.Machine.js b/target/doc/implementors/ppv_lite86/trait.Machine.js new file mode 100644 index 0000000..1db41c7 --- /dev/null +++ b/target/doc/implementors/ppv_lite86/trait.Machine.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["ppv_lite86"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/ppv_lite86/trait.Store.js b/target/doc/implementors/ppv_lite86/trait.Store.js new file mode 100644 index 0000000..1db41c7 --- /dev/null +++ b/target/doc/implementors/ppv_lite86/trait.Store.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["ppv_lite86"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/ppv_lite86/trait.VZip.js b/target/doc/implementors/ppv_lite86/trait.VZip.js new file mode 100644 index 0000000..1db41c7 --- /dev/null +++ b/target/doc/implementors/ppv_lite86/trait.VZip.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["ppv_lite86"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/rand/distributions/trait.Distribution.js b/target/doc/implementors/rand/distributions/trait.Distribution.js new file mode 100644 index 0000000..4a757ff --- /dev/null +++ b/target/doc/implementors/rand/distributions/trait.Distribution.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["rand"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/rand/distributions/uniform/trait.SampleBorrow.js b/target/doc/implementors/rand/distributions/uniform/trait.SampleBorrow.js new file mode 100644 index 0000000..4a757ff --- /dev/null +++ b/target/doc/implementors/rand/distributions/uniform/trait.SampleBorrow.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["rand"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/rand/distributions/uniform/trait.SampleUniform.js b/target/doc/implementors/rand/distributions/uniform/trait.SampleUniform.js new file mode 100644 index 0000000..4a757ff --- /dev/null +++ b/target/doc/implementors/rand/distributions/uniform/trait.SampleUniform.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["rand"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/rand/distributions/uniform/trait.UniformSampler.js b/target/doc/implementors/rand/distributions/uniform/trait.UniformSampler.js new file mode 100644 index 0000000..4a757ff --- /dev/null +++ b/target/doc/implementors/rand/distributions/uniform/trait.UniformSampler.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["rand"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/rand/distributions/weighted/alias_method/trait.Weight.js b/target/doc/implementors/rand/distributions/weighted/alias_method/trait.Weight.js new file mode 100644 index 0000000..4a757ff --- /dev/null +++ b/target/doc/implementors/rand/distributions/weighted/alias_method/trait.Weight.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["rand"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/rand/seq/trait.IteratorRandom.js b/target/doc/implementors/rand/seq/trait.IteratorRandom.js new file mode 100644 index 0000000..4a757ff --- /dev/null +++ b/target/doc/implementors/rand/seq/trait.IteratorRandom.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["rand"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/rand/seq/trait.SliceRandom.js b/target/doc/implementors/rand/seq/trait.SliceRandom.js new file mode 100644 index 0000000..4a757ff --- /dev/null +++ b/target/doc/implementors/rand/seq/trait.SliceRandom.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["rand"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/rand/trait.AsByteSliceMut.js b/target/doc/implementors/rand/trait.AsByteSliceMut.js new file mode 100644 index 0000000..4a757ff --- /dev/null +++ b/target/doc/implementors/rand/trait.AsByteSliceMut.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["rand"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/rand/trait.CryptoRng.js b/target/doc/implementors/rand/trait.CryptoRng.js new file mode 100644 index 0000000..d124cd5 --- /dev/null +++ b/target/doc/implementors/rand/trait.CryptoRng.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["rand"] = [{text:"impl<R, Rsdr> CryptoRng for ReseedingRng<R, Rsdr> where
    R: BlockRngCore + SeedableRng + CryptoRng,
    Rsdr: RngCore + CryptoRng
",synthetic:false,types:["rand::rngs::adapter::reseeding::ReseedingRng"]},{text:"impl CryptoRng for EntropyRng",synthetic:false,types:["rand::rngs::entropy::EntropyRng"]},{text:"impl CryptoRng for StdRng",synthetic:false,types:["rand::rngs::std::StdRng"]},{text:"impl CryptoRng for ThreadRng",synthetic:false,types:["rand::rngs::thread::ThreadRng"]},{text:"impl CryptoRng for OsRng",synthetic:false,types:["rand::rngs::os::OsRng"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/rand/trait.Rng.js b/target/doc/implementors/rand/trait.Rng.js new file mode 100644 index 0000000..4a757ff --- /dev/null +++ b/target/doc/implementors/rand/trait.Rng.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["rand"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/rand/trait.RngCore.js b/target/doc/implementors/rand/trait.RngCore.js new file mode 100644 index 0000000..4ef9d83 --- /dev/null +++ b/target/doc/implementors/rand/trait.RngCore.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["rand"] = [{text:"impl<R: Read> RngCore for ReadRng<R>",synthetic:false,types:["rand::rngs::adapter::read::ReadRng"]},{text:"impl<R, Rsdr: RngCore> RngCore for ReseedingRng<R, Rsdr> where
    R: BlockRngCore<Item = u32> + SeedableRng,
    <R as BlockRngCore>::Results: AsRef<[u32]> + AsMut<[u32]>, 
",synthetic:false,types:["rand::rngs::adapter::reseeding::ReseedingRng"]},{text:"impl RngCore for EntropyRng",synthetic:false,types:["rand::rngs::entropy::EntropyRng"]},{text:"impl RngCore for StepRng",synthetic:false,types:["rand::rngs::mock::StepRng"]},{text:"impl RngCore for StdRng",synthetic:false,types:["rand::rngs::std::StdRng"]},{text:"impl RngCore for ThreadRng",synthetic:false,types:["rand::rngs::thread::ThreadRng"]},{text:"impl RngCore for OsRng",synthetic:false,types:["rand::rngs::os::OsRng"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/rand/trait.SeedableRng.js b/target/doc/implementors/rand/trait.SeedableRng.js new file mode 100644 index 0000000..55d5189 --- /dev/null +++ b/target/doc/implementors/rand/trait.SeedableRng.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["rand"] = [{text:"impl SeedableRng for StdRng",synthetic:false,types:["rand::rngs::std::StdRng"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/rand_core/block/trait.BlockRngCore.js b/target/doc/implementors/rand_core/block/trait.BlockRngCore.js new file mode 100644 index 0000000..0cb3c88 --- /dev/null +++ b/target/doc/implementors/rand_core/block/trait.BlockRngCore.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["rand_chacha"] = [{text:"impl BlockRngCore for ChaCha20Core",synthetic:false,types:["rand_chacha::chacha::ChaCha20Core"]},{text:"impl BlockRngCore for ChaCha12Core",synthetic:false,types:["rand_chacha::chacha::ChaCha12Core"]},{text:"impl BlockRngCore for ChaCha8Core",synthetic:false,types:["rand_chacha::chacha::ChaCha8Core"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/rand_core/trait.CryptoRng.js b/target/doc/implementors/rand_core/trait.CryptoRng.js new file mode 100644 index 0000000..fc08697 --- /dev/null +++ b/target/doc/implementors/rand_core/trait.CryptoRng.js @@ -0,0 +1,11 @@ +(function() {var implementors = {}; +implementors["rand_chacha"] = [{text:"impl CryptoRng for ChaCha20Rng",synthetic:false,types:["rand_chacha::chacha::ChaCha20Rng"]},{text:"impl CryptoRng for ChaCha12Rng",synthetic:false,types:["rand_chacha::chacha::ChaCha12Rng"]},{text:"impl CryptoRng for ChaCha8Rng",synthetic:false,types:["rand_chacha::chacha::ChaCha8Rng"]},]; +implementors["rand_core"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/rand_core/trait.RngCore.js b/target/doc/implementors/rand_core/trait.RngCore.js new file mode 100644 index 0000000..087010b --- /dev/null +++ b/target/doc/implementors/rand_core/trait.RngCore.js @@ -0,0 +1,11 @@ +(function() {var implementors = {}; +implementors["rand_chacha"] = [{text:"impl RngCore for ChaCha20Rng",synthetic:false,types:["rand_chacha::chacha::ChaCha20Rng"]},{text:"impl RngCore for ChaCha12Rng",synthetic:false,types:["rand_chacha::chacha::ChaCha12Rng"]},{text:"impl RngCore for ChaCha8Rng",synthetic:false,types:["rand_chacha::chacha::ChaCha8Rng"]},]; +implementors["rand_core"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/rand_core/trait.SeedableRng.js b/target/doc/implementors/rand_core/trait.SeedableRng.js new file mode 100644 index 0000000..ae9e694 --- /dev/null +++ b/target/doc/implementors/rand_core/trait.SeedableRng.js @@ -0,0 +1,11 @@ +(function() {var implementors = {}; +implementors["rand_chacha"] = [{text:"impl SeedableRng for ChaCha20Core",synthetic:false,types:["rand_chacha::chacha::ChaCha20Core"]},{text:"impl SeedableRng for ChaCha20Rng",synthetic:false,types:["rand_chacha::chacha::ChaCha20Rng"]},{text:"impl SeedableRng for ChaCha12Core",synthetic:false,types:["rand_chacha::chacha::ChaCha12Core"]},{text:"impl SeedableRng for ChaCha12Rng",synthetic:false,types:["rand_chacha::chacha::ChaCha12Rng"]},{text:"impl SeedableRng for ChaCha8Core",synthetic:false,types:["rand_chacha::chacha::ChaCha8Core"]},{text:"impl SeedableRng for ChaCha8Rng",synthetic:false,types:["rand_chacha::chacha::ChaCha8Rng"]},]; +implementors["rand_core"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/regex/bytes/trait.Replacer.js b/target/doc/implementors/regex/bytes/trait.Replacer.js new file mode 100644 index 0000000..3e5703b --- /dev/null +++ b/target/doc/implementors/regex/bytes/trait.Replacer.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["regex"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/regex/trait.Replacer.js b/target/doc/implementors/regex/trait.Replacer.js new file mode 100644 index 0000000..3e5703b --- /dev/null +++ b/target/doc/implementors/regex/trait.Replacer.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["regex"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/std/error/trait.Error.js b/target/doc/implementors/std/error/trait.Error.js new file mode 100644 index 0000000..55d8b9d --- /dev/null +++ b/target/doc/implementors/std/error/trait.Error.js @@ -0,0 +1,15 @@ +(function() {var implementors = {}; +implementors["aho_corasick"] = [{text:"impl Error for Error",synthetic:false,types:["aho_corasick::error::Error"]},]; +implementors["getrandom"] = [{text:"impl Error for Error",synthetic:false,types:["getrandom::error::Error"]},]; +implementors["rand"] = [{text:"impl Error for WeightedError",synthetic:false,types:["rand::distributions::weighted::WeightedError"]},{text:"impl Error for ReadError",synthetic:false,types:["rand::rngs::adapter::read::ReadError"]},]; +implementors["rand_core"] = [{text:"impl Error for Error",synthetic:false,types:["rand_core::error::Error"]},]; +implementors["regex"] = [{text:"impl Error for Error",synthetic:false,types:["regex::error::Error"]},]; +implementors["regex_syntax"] = [{text:"impl Error for Error",synthetic:false,types:["regex_syntax::ast::Error"]},{text:"impl Error for Error",synthetic:false,types:["regex_syntax::error::Error"]},{text:"impl Error for Error",synthetic:false,types:["regex_syntax::hir::Error"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/std/io/trait.Read.js b/target/doc/implementors/std/io/trait.Read.js new file mode 100644 index 0000000..d27fb63 --- /dev/null +++ b/target/doc/implementors/std/io/trait.Read.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["rand_core"] = [{text:"impl Read for dyn RngCore",synthetic:false,types:["rand_core::RngCore"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/implementors/std/panic/trait.UnwindSafe.js b/target/doc/implementors/std/panic/trait.UnwindSafe.js new file mode 100644 index 0000000..8804a88 --- /dev/null +++ b/target/doc/implementors/std/panic/trait.UnwindSafe.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["thread_local"] = [{text:"impl<T: ?Sized + Send + UnwindSafe> UnwindSafe for ThreadLocal<T>",synthetic:false,types:["thread_local::ThreadLocal"]},{text:"impl<T: ?Sized + Send + UnwindSafe> UnwindSafe for CachedThreadLocal<T>",synthetic:false,types:["thread_local::CachedThreadLocal"]},]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/target/doc/lazy_static/all.html b/target/doc/lazy_static/all.html new file mode 100644 index 0000000..f371fde --- /dev/null +++ b/target/doc/lazy_static/all.html @@ -0,0 +1,3 @@ +List of all items in this crate

[] + + List of all items

Traits

Macros

Functions

\ No newline at end of file diff --git a/target/doc/lazy_static/fn.initialize.html b/target/doc/lazy_static/fn.initialize.html new file mode 100644 index 0000000..cae038a --- /dev/null +++ b/target/doc/lazy_static/fn.initialize.html @@ -0,0 +1,20 @@ +lazy_static::initialize - Rust

[][src]Function lazy_static::initialize

pub fn initialize<T: LazyStatic>(lazy: &T)

Takes a shared reference to a lazy static and initializes +it if it has not been already.

+

This can be used to control the initialization point of a lazy static.

+

Example:

+ +
+#[macro_use]
+extern crate lazy_static;
+
+lazy_static! {
+    static ref BUFFER: Vec<u8> = (0..255).collect();
+}
+
+fn main() {
+    lazy_static::initialize(&BUFFER);
+
+    // ...
+    work_with_initialized_data(&BUFFER);
+}
+
\ No newline at end of file diff --git a/target/doc/lazy_static/index.html b/target/doc/lazy_static/index.html new file mode 100644 index 0000000..cdb3215 --- /dev/null +++ b/target/doc/lazy_static/index.html @@ -0,0 +1,77 @@ +lazy_static - Rust

[][src]Crate lazy_static

A macro for declaring lazily evaluated statics.

+

Using this macro, it is possible to have statics that require code to be +executed at runtime in order to be initialized. +This includes anything requiring heap allocations, like vectors or hash maps, +as well as anything that requires function calls to be computed.

+

Syntax

+
This example is not tested
+lazy_static! {
+    [pub] static ref NAME_1: TYPE_1 = EXPR_1;
+    [pub] static ref NAME_2: TYPE_2 = EXPR_2;
+    ...
+    [pub] static ref NAME_N: TYPE_N = EXPR_N;
+}
+

Attributes (including doc comments) are supported as well:

+ +
+lazy_static! {
+    /// This is an example for using doc comment attributes
+    static ref EXAMPLE: u8 = 42;
+}
+

Semantics

+

For a given static ref NAME: TYPE = EXPR;, the macro generates a unique type that +implements Deref<TYPE> and stores it in a static with name NAME. (Attributes end up +attaching to this type.)

+

On first deref, EXPR gets evaluated and stored internally, such that all further derefs +can return a reference to the same object. Note that this can lead to deadlocks +if you have multiple lazy statics that depend on each other in their initialization.

+

Apart from the lazy initialization, the resulting "static ref" variables +have generally the same properties as regular "static" variables:

+
    +
  • Any type in them needs to fulfill the Sync trait.
  • +
  • If the type has a destructor, then it will not run when the process exits.
  • +
+

Example

+

Using the macro:

+ +
+#[macro_use]
+extern crate lazy_static;
+
+use std::collections::HashMap;
+
+lazy_static! {
+    static ref HASHMAP: HashMap<u32, &'static str> = {
+        let mut m = HashMap::new();
+        m.insert(0, "foo");
+        m.insert(1, "bar");
+        m.insert(2, "baz");
+        m
+    };
+    static ref COUNT: usize = HASHMAP.len();
+    static ref NUMBER: u32 = times_two(21);
+}
+
+fn times_two(n: u32) -> u32 { n * 2 }
+
+fn main() {
+    println!("The map has {} entries.", *COUNT);
+    println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());
+    println!("A expensive calculation on a static results in: {}.", *NUMBER);
+}
+

Implementation details

+

The Deref implementation uses a hidden static variable that is guarded by an atomic check on each access.

+

Cargo features

+

This crate provides two cargo features:

+
    +
  • spin_no_std: This allows using this crate in a no-std environment, by depending on the standalone spin crate.
  • +
+

Both features depend on unstable language features, which means +no guarantees can be made about them in regard to SemVer stability.

+

Macros

+
lazy_static

Traits

+
LazyStatic

Support trait for enabling a few common operation on lazy static values.

+

Functions

+
initialize

Takes a shared reference to a lazy static and initializes +it if it has not been already.

+
\ No newline at end of file diff --git a/target/doc/lazy_static/macro.lazy_static!.html b/target/doc/lazy_static/macro.lazy_static!.html new file mode 100644 index 0000000..d556a77 --- /dev/null +++ b/target/doc/lazy_static/macro.lazy_static!.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to macro.lazy_static.html...

+ + + \ No newline at end of file diff --git a/target/doc/lazy_static/macro.lazy_static.html b/target/doc/lazy_static/macro.lazy_static.html new file mode 100644 index 0000000..63a2acf --- /dev/null +++ b/target/doc/lazy_static/macro.lazy_static.html @@ -0,0 +1,8 @@ +lazy_static::lazy_static - Rust

[][src]Macro lazy_static::lazy_static

+macro_rules! lazy_static {
+    ($(#[$attr:meta])* static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { ... };
+    ($(#[$attr:meta])* pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { ... };
+    ($(#[$attr:meta])* pub ($($vis:tt)+) static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { ... };
+    () => { ... };
+}
+
\ No newline at end of file diff --git a/target/doc/lazy_static/sidebar-items.js b/target/doc/lazy_static/sidebar-items.js new file mode 100644 index 0000000..4b10a8e --- /dev/null +++ b/target/doc/lazy_static/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"fn":[["initialize","Takes a shared reference to a lazy static and initializes it if it has not been already."]],"macro":[["lazy_static",""]],"trait":[["LazyStatic","Support trait for enabling a few common operation on lazy static values."]]}); \ No newline at end of file diff --git a/target/doc/lazy_static/trait.LazyStatic.html b/target/doc/lazy_static/trait.LazyStatic.html new file mode 100644 index 0000000..42ef51a --- /dev/null +++ b/target/doc/lazy_static/trait.LazyStatic.html @@ -0,0 +1,7 @@ +lazy_static::LazyStatic - Rust

[][src]Trait lazy_static::LazyStatic

pub trait LazyStatic { }

Support trait for enabling a few common operation on lazy static values.

+

This is implemented by each defined lazy static, and +used by the free functions in this crate.

+
+

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/light.css b/target/doc/light.css new file mode 100644 index 0000000..52bbbce --- /dev/null +++ b/target/doc/light.css @@ -0,0 +1 @@ + body{background-color:white;color:black;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){color:black;}h1.fqn{border-bottom-color:#D5D5D5;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){border-bottom-color:#DDDDDD;}.in-band{background-color:white;}.invisible{background:rgba(0,0,0,0);}.docblock code,.docblock-short code{background-color:#F5F5F5;}pre{background-color:#F5F5F5;}.sidebar{background-color:#F1F1F1;}.sidebar .current{background-color:#fff;}.source .sidebar{background-color:#fff;}.sidebar .location{border-color:#000;background-color:#fff;color:#333;}.sidebar .version{border-bottom-color:#DDD;}.sidebar-title{border-top-color:#777;border-bottom-color:#777;}.block a:hover{background:#F5F5F5;}.line-numbers span{color:#c67e2d;}.line-numbers .line-highlighted{background-color:#f6fdb0 !important;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom-color:#ddd;}.docblock table,.docblock table td,.docblock table th{border-color:#ddd;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#4E4C4C;}.content .highlighted{color:#000 !important;background-color:#ccc;}.content .highlighted a,.content .highlighted span{color:#000 !important;}.content .highlighted.trait{background-color:#c7b6ff;}.content .highlighted.traitalias{background-color:#c7b6ff;}.content .highlighted.mod,.content .highlighted.externcrate{background-color:#afc6e4;}.content .highlighted.enum{background-color:#b4d1b9;}.content .highlighted.struct{background-color:#e7b1a0;}.content .highlighted.union{background-color:#b7bd49;}.content .highlighted.fn,.content .highlighted.method,.content .highlighted.tymethod{background-color:#c6afb3;}.content .highlighted.type{background-color:#ffc891;}.content .highlighted.foreigntype{background-color:#f5c4ff;}.content .highlighted.attr,.content .highlighted.derive,.content .highlighted.macro{background-color:#8ce488;}.content .highlighted.constant,.content .highlighted.static{background-color:#c3e0ff;}.content .highlighted.primitive{background-color:#9aecff;}.content .highlighted.keyword{background-color:#f99650;}.content span.enum,.content a.enum,.block a.current.enum{color:#508157;}.content span.struct,.content a.struct,.block a.current.struct{color:#ad448e;}.content span.type,.content a.type,.block a.current.type{color:#ba5d00;}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{color:#cd00e2;}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{color:#068000;}.content span.union,.content a.union,.block a.current.union{color:#767b27;}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{color:#546e8a;}.content span.primitive,.content a.primitive,.block a.current.primitive{color:#2c8093;}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{color:#4d76ae;}.content span.trait,.content a.trait,.block a.current.trait{color:#7c5af3;}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{color:#6841f1;}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{color:#9a6e31;}.content span.keyword,.content a.keyword,.block a.current.keyword{color:#de5249;}pre.rust .comment{color:#8E908C;}pre.rust .doccomment{color:#4D4D4C;}nav{border-bottom-color:#e0e0e0;}nav.main .current{border-top-color:#000;border-bottom-color:#000;}nav.main .separator{border:1px solid #000;}a{color:#000;}.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),.docblock-short a:not(.srclink):not(.test-arrow),.stability a{color:#3873AD;}.stab.internal a{color:#304FFE;}a.test-arrow{color:#f5f5f5;}.collapse-toggle{color:#999;}#crate-search{color:#555;background-color:white;border-color:#e0e0e0;box-shadow:0 0 0 1px #e0e0e0,0 0 0 2px transparent;}.search-input{color:#555;background-color:white;box-shadow:0 0 0 1px #e0e0e0,0 0 0 2px transparent;}.search-input:focus{border-color:#66afe9;}#crate-search+.search-input:focus{box-shadow:0 0 8px #078dd8;}.module-item .stab{color:#000;}.stab.unstable{background:#FFF5D6;border-color:#FFC600;}.stab.internal{background:#FFB9B3;border-color:#B71C1C;}.stab.deprecated{background:#F3DFFF;border-color:#7F0087;}.stab.portability{background:#C4ECFF;border-color:#7BA5DB;}.stab.portability>code{color:#000;}#help>div{background:#e9e9e9;border-color:#bfbfbf;}.since{color:grey;}tr.result span.primitive::after,tr.result span.keyword::after{color:black;}.line-numbers :target{background-color:transparent;}pre.rust .kw{color:#8959A8;}pre.rust .kw-2,pre.rust .prelude-ty{color:#4271AE;}pre.rust .number,pre.rust .string{color:#718C00;}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{color:#C82829;}pre.rust .macro,pre.rust .macro-nonterminal{color:#3E999F;}pre.rust .lifetime{color:#B76514;}pre.rust .question-mark{color:#ff9011;}.example-wrap>pre.line-number{border-color:#c7c7c7;}a.test-arrow{background-color:rgba(78,139,202,0.2);}a.test-arrow:hover{background-color:#4e8bca;}.toggle-label{color:#999;}:target>code,:target>.in-band{background:#FDFFD3;}pre.compile_fail{border-left:2px solid rgba(255,0,0,.4);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.4);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.3);}.information>.compile_fail:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.3);}.information>.ignore:hover{color:rgba(255,142,0,1);}.search-failed a{color:#0089ff;}.tooltip .tooltiptext{background-color:black;color:#fff;}.tooltip .tooltiptext::after{border-color:transparent black transparent transparent;}.important-traits .tooltip .tooltiptext{background-color:white;color:black;border-color:black;}#titles>div:not(.selected){background-color:#e6e6e6;border-top-color:#e6e6e6;}#titles>div:hover,#titles>div.selected{border-top-color:#0089ff;}#titles>div>div.count{color:#888;}.modal{background-color:rgba(0,0,0,0.3);}.modal-content{background-color:#eee;border-color:#999;}.modal-content>.close{background-color:#eee;border-color:#999;}.modal-content>.close:hover{background-color:#ff1f1f;color:white;}.modal-content>.whiter{background-color:#eee;}.modal-content>.close:hover+.whiter{background-color:#ff1f1f;}@media (max-width:700px){.sidebar-menu{background-color:#F1F1F1;border-bottom-color:#e0e0e0;border-right-color:#e0e0e0;}.sidebar-elems{background-color:#F1F1F1;border-right-color:#000;}#sidebar-filler{background-color:#F1F1F1;border-bottom-color:#e0e0e0;}}kbd{color:#000;background-color:#fafbfc;border-color:#d1d5da;border-bottom-color:#c6cbd1;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu{border-color:#e0e0e0;background-color:#fff;}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus{border-color:#717171;}#theme-choices{border-color:#ccc;background-color:#fff;}#theme-choices>button:not(:first-child){border-top-color:#e0e0e0;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:#eee;}@media (max-width:700px){#theme-picker{background:#fff;}}#all-types{background-color:#fff;}#all-types:hover{background-color:#f9f9f9;}.search-results td span.alias{color:#000;}.search-results td span.grey{color:#999;}#sidebar-toggle{background-color:#F1F1F1;}#sidebar-toggle:hover{background-color:#E0E0E0;}#source-sidebar{background-color:#F1F1F1;}#source-sidebar>.title{border-bottom-color:#ccc;}div.files>a:hover,div.name:hover{background-color:#E0E0E0;}div.files>.selected{background-color:#fff;} \ No newline at end of file diff --git a/target/doc/main.js b/target/doc/main.js new file mode 100644 index 0000000..48744b5 --- /dev/null +++ b/target/doc/main.js @@ -0,0 +1,95 @@ +if(!String.prototype.startsWith){String.prototype.startsWith=function(searchString,position){position=position||0;return this.indexOf(searchString,position)===position;};}if(!String.prototype.endsWith){String.prototype.endsWith=function(suffix,length){var l=length||this.length;return this.indexOf(suffix,l-suffix.length)!==-1;};}if(!DOMTokenList.prototype.add){DOMTokenList.prototype.add=function(className){if(className&&!hasClass(this,className)){if(this.className&&this.className.length>0){this.className+=" "+className;}else{this.className=className;}}};}if(!DOMTokenList.prototype.remove){DOMTokenList.prototype.remove=function(className){if(className&&this.className){this.className=(" "+this.className+" ").replace(" "+className+" "," ").trim();}};}(function(){"use strict";var itemTypes=["mod","externcrate","import","struct","enum","fn","type","static","trait","impl","tymethod","method","structfield","variant","macro","primitive","associatedtype","constant","associatedconstant","union","foreigntype","keyword","existential","attr","derive","traitalias"];var search_input=document.getElementsByClassName("search-input")[0];var currentTab=0;var titleBeforeSearch=document.title;function getPageId(){var id=document.location.href.split("#")[1];if(id){return id.split("?")[0].split("&")[0];}return null;}function showSidebar(){var elems=document.getElementsByClassName("sidebar-elems")[0];if(elems){addClass(elems,"show-it");}var sidebar=document.getElementsByClassName("sidebar")[0];if(sidebar){addClass(sidebar,"mobile");var filler=document.getElementById("sidebar-filler");if(!filler){var div=document.createElement("div");div.id="sidebar-filler";sidebar.appendChild(div);}}var themePicker=document.getElementsByClassName("theme-picker");if(themePicker&&themePicker.length>0){themePicker[0].style.display="none";}}function hideSidebar(){var elems=document.getElementsByClassName("sidebar-elems")[0];if(elems){removeClass(elems,"show-it");}var sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"mobile");var filler=document.getElementById("sidebar-filler");if(filler){filler.remove();}document.getElementsByTagName("body")[0].style.marginTop="";var themePicker=document.getElementsByClassName("theme-picker");if(themePicker&&themePicker.length>0){themePicker[0].style.display=null;}}var TY_PRIMITIVE=itemTypes.indexOf("primitive");var TY_KEYWORD=itemTypes.indexOf("keyword");onEachLazy(document.getElementsByClassName("js-only"),function(e){removeClass(e,"js-only");});function getQueryStringParams(){var params={};window.location.search.substring(1).split("&").map(function(s){var pair=s.split("=");params[decodeURIComponent(pair[0])]=typeof pair[1]==="undefined"?null:decodeURIComponent(pair[1]);});return params;}function browserSupportsHistoryApi(){return window.history&&typeof window.history.pushState==="function";}var main=document.getElementById("main");function highlightSourceLines(ev){hideSidebar();var elem;var search=document.getElementById("search");var i,from,to,match=window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);if(match){from=parseInt(match[1],10);to=Math.min(50000,parseInt(match[2]||match[1],10));from=Math.min(from,to);elem=document.getElementById(from);if(!elem){return;}if(ev===null){var x=document.getElementById(from);if(x){x.scrollIntoView();}}onEachLazy(document.getElementsByClassName("line-numbers"),function(e){onEachLazy(e.getElementsByTagName("span"),function(i_e){removeClass(i_e,"line-highlighted");});});for(i=from;i<=to;++i){addClass(document.getElementById(i),"line-highlighted");}}else if(ev!==null&&search&&!hasClass(search,"hidden")&&ev.newURL){addClass(search,"hidden");removeClass(main,"hidden");var hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(browserSupportsHistoryApi()){history.replaceState(hash,"","?search=#"+hash);}elem=document.getElementById(hash);if(elem){elem.scrollIntoView();}}}function expandSection(id){var elem=document.getElementById(id);if(elem&&isHidden(elem)){var h3=elem.parentNode.previousElementSibling;if(h3&&h3.tagName!=="H3"){h3=h3.previousElementSibling;}if(h3){var collapses=h3.getElementsByClassName("collapse-toggle");if(collapses.length>0){collapseDocs(collapses[0],"show");}}}}highlightSourceLines(null);window.onhashchange=highlightSourceLines;function getVirtualKey(ev){if("key"in ev&&typeof ev.key!="undefined"){return ev.key;}var c=ev.charCode||ev.keyCode;if(c==27){return"Escape";}return String.fromCharCode(c);}function displayHelp(display,ev,help){if(display===true){if(hasClass(help,"hidden")){ev.preventDefault();removeClass(help,"hidden");addClass(document.body,"blur");}}else if(hasClass(help,"hidden")===false){ev.preventDefault();addClass(help,"hidden");removeClass(document.body,"blur");}}function handleEscape(ev,help){hideModal();var search=document.getElementById("search");if(hasClass(help,"hidden")===false){displayHelp(false,ev,help);}else if(hasClass(search,"hidden")===false){ev.preventDefault();addClass(search,"hidden");removeClass(main,"hidden");document.title=titleBeforeSearch;}defocusSearchBar();}function handleShortcut(ev){if(ev.ctrlKey||ev.altKey||ev.metaKey){return;}var help=document.getElementById("help");if(document.activeElement.tagName==="INPUT"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev,help);break;}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev,help);break;case"s":case"S":displayHelp(false,ev,help);hideModal();ev.preventDefault();focusSearchBar();break;case"+":case"-":ev.preventDefault();toggleAllDocs();break;case"?":if(ev.shiftKey){hideModal();displayHelp(true,ev,help);}break;}}}function findParentElement(elem,tagName){do{if(elem&&elem.tagName===tagName){return elem;}elem=elem.parentNode;}while(elem);return null;}document.onkeypress=handleShortcut;document.onkeydown=handleShortcut;document.onclick=function(ev){if(hasClass(ev.target,"collapse-toggle")){collapseDocs(ev.target,"toggle");}else if(hasClass(ev.target.parentNode,"collapse-toggle")){collapseDocs(ev.target.parentNode,"toggle");}else if(ev.target.tagName==="SPAN"&&hasClass(ev.target.parentNode,"line-numbers")){var prev_id=0;var set_fragment=function(name){if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);window.hashchange();}else{location.replace("#"+name);}};var cur_id=parseInt(ev.target.id,10);if(ev.shiftKey&&prev_id){if(prev_id>cur_id){var tmp=prev_id;prev_id=cur_id;cur_id=tmp;}set_fragment(prev_id+"-"+cur_id);}else{prev_id=cur_id;set_fragment(cur_id);}}else if(hasClass(document.getElementById("help"),"hidden")===false){addClass(document.getElementById("help"),"hidden");removeClass(document.body,"blur");}else{var a=findParentElement(ev.target,"A");if(a&&a.hash){expandSection(a.hash.replace(/^#/,""));}}};var x=document.getElementsByClassName("version-selector");if(x.length>0){x[0].onchange=function(){var i,match,url=document.location.href,stripped="",len=rootPath.match(/\.\.\//g).length+1;for(i=0;i-1){var obj=searchIndex[results[i].id];obj.lev=results[i].lev;if(isType!==true||obj.type){var res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=obj.displayPath+obj.name;obj.fullPath+="|"+obj.ty;obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break;}}}}return out;}function sortResults(results,isType){var ar=[];for(var entry in results){if(results.hasOwnProperty(entry)){ar.push(results[entry]);}}results=ar;var i;var nresults=results.length;for(i=0;ib?+1:-1);}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b;}a=aaa.index;b=bbb.index;if(a!==b){return a-b;}if((aaa.item.ty===TY_PRIMITIVE&&bbb.item.ty!==TY_KEYWORD)||(aaa.item.ty===TY_KEYWORD&&bbb.item.ty!==TY_PRIMITIVE)){return-1;}if((bbb.item.ty===TY_PRIMITIVE&&aaa.item.ty!==TY_PRIMITIVE)||(bbb.item.ty===TY_KEYWORD&&aaa.item.ty!==TY_KEYWORD)){return 1;}a=(aaa.item.desc==="");b=(bbb.item.desc==="");if(a!==b){return a-b;}a=aaa.item.ty;b=bbb.item.ty;if(a!==b){return a-b;}a=aaa.item.path;b=bbb.item.path;if(a!==b){return(a>b?+1:-1);}return 0;});var length=results.length;for(i=0;i"));return{name:val.substring(0,val.indexOf("<")),generics:values.split(/\s*,\s*/),};}return{name:val,generics:[],};}function checkGenerics(obj,val){var lev_distance=MAX_LEV_DISTANCE+1;if(val.generics.length>0){if(obj.length>GENERICS_DATA&&obj[GENERICS_DATA].length>=val.generics.length){var elems=obj[GENERICS_DATA].slice(0);var total=0;var done=0;var vlength=val.generics.length;for(var y=0;yGENERICS_DATA&&obj[GENERICS_DATA].length>=val.generics.length){var elems=obj[GENERICS_DATA].slice(0);var allFound=true;for(var y=0;allFound===true&&yGENERICS_DATA&&obj[GENERICS_DATA].length!==0){var tmp_lev=checkGenerics(obj,val);if(tmp_lev<=MAX_LEV_DISTANCE){return tmp_lev;}}else{return 0;}}if(literalSearch===true){if(obj.length>GENERICS_DATA&&obj[GENERICS_DATA].length>0){var length=obj[GENERICS_DATA].length;for(x=0;x GENERICS_DATA && obj[GENERICS_DATA].length > 0) { + // We can check if the type we're looking for is inside the generics! + var olength = obj[GENERICS_DATA].length; + for (x = 0; x < olength; ++x) { + lev_distance = Math.min(levenshtein(obj[GENERICS_DATA][x], val.name), + lev_distance); + } + } + // Now whatever happens, the returned distance is "less good" so we should mark it + // as such, and so we add 1 to the distance to make it "less good". + return lev_distance + 1; + } + + function findArg(obj, val, literalSearch) { + var lev_distance = MAX_LEV_DISTANCE + 1; + + if (obj && obj.type && obj.type[INPUTS_DATA] && + obj.type[INPUTS_DATA].length > 0) { + var length = obj.type[INPUTS_DATA].length; + for (var i = 0; i < length; i++) { + var tmp = checkType(obj.type[INPUTS_DATA][i], val, literalSearch); + if (literalSearch === true && tmp === true) { + return true; + } + lev_distance = Math.min(tmp, lev_distance); + if (lev_distance === 0) { + return 0; + } + } + } + return literalSearch === true ? false : lev_distance; + } + + function checkReturned(obj, val, literalSearch) { + var lev_distance = MAX_LEV_DISTANCE + 1; + + if (obj && obj.type && obj.type.length > OUTPUT_DATA) { + var ret = obj.type[OUTPUT_DATA]; + if (!obj.type[OUTPUT_DATA].length) { + ret = [ret]; + } + for (var x = 0; x < ret.length; ++x) { + var r = ret[x]; + if (typeof r === "string") { + r = [r]; + } + var tmp = checkType(r, val, literalSearch); + if (literalSearch === true) { + if (tmp === true) { + return true; + } + continue; + } + lev_distance = Math.min(tmp, lev_distance); + if (lev_distance === 0) { + return 0; + } + } + } + return literalSearch === true ? false : lev_distance; + } + + function checkPath(contains, lastElem, ty) { + if (contains.length === 0) { + return 0; + } + var ret_lev = MAX_LEV_DISTANCE + 1; + var path = ty.path.split("::"); + + if (ty.parent && ty.parent.name) { + path.push(ty.parent.name.toLowerCase()); + } + + var length = path.length; + var clength = contains.length; + if (clength > length) { + return MAX_LEV_DISTANCE + 1; + } + for (var i = 0; i < length; ++i) { + if (i + clength > length) { + break; + } + var lev_total = 0; + var aborted = false; + for (var x = 0; x < clength; ++x) { + var lev = levenshtein(path[i + x], contains[x]); + if (lev > MAX_LEV_DISTANCE) { + aborted = true; + break; + } + lev_total += lev; + } + if (aborted === false) { + ret_lev = Math.min(ret_lev, Math.round(lev_total /clength));}}return ret_lev;}function typePassesFilter(filter,type){if(filter<0)return true;if(filter===type)return true;var name=itemTypes[type];switch(itemTypes[filter]){case"constant":return(name=="associatedconstant");case"fn":return(name=="method"||name=="tymethod");case"type":return(name=="primitive"||name=="keyword");}return false;}function generateId(ty){if(ty.parent&&ty.parent.name){return itemTypes[ty.ty]+ty.path+ty.parent.name+ty.name;}return itemTypes[ty.ty]+ty.path+ty.name;}var nSearchWords=searchWords.length;var i;var ty;var fullId;var returned;var in_args;if((val.charAt(0)==="\""||val.charAt(0)==="'")&&val.charAt(val.length-1)===val.charAt(0)){val=extractGenerics(val.substr(1,val.length-2));for(i=0;i")>-1){var trimmer=function(s){return s.trim();};var parts=val.split("->").map(trimmer);var input=parts[0];var inputs=input.split(",").map(trimmer).sort();for(i=0;iOUTPUT_DATA?type[OUTPUT_DATA].name:"";returned=checkReturned(ty,output,true);if(output.name==="*"||returned===true){in_args=false;var is_module=false;if(input==="*"){is_module=true;}else{var allFound=true;for(var it=0;allFound===true&&it1?paths.length-1:1);for(j=0;j1){lev=checkPath(contains,paths[paths.length-1],ty);if(lev>MAX_LEV_DISTANCE){continue;}else if(lev>0){lev_add=1;}}returned=MAX_LEV_DISTANCE+1;in_args=MAX_LEV_DISTANCE+1;var index=-1;lev=MAX_LEV_DISTANCE+1;fullId=generateId(ty);if(searchWords[j].indexOf(split[i])>-1||searchWords[j].indexOf(val)>-1||searchWords[j].replace(/_/g,"").indexOf(val)>-1){if(typePassesFilter(typeFilter,ty.ty)&&results[fullId]===undefined){index=searchWords[j].replace(/_/g,"").indexOf(val);}}if((lev=levenshtein(searchWords[j],val))<=MAX_LEV_DISTANCE){if(typePassesFilter(typeFilter,ty.ty)===false){lev=MAX_LEV_DISTANCE+1;}else{lev+=1;}}if((in_args=findArg(ty,valGenerics))<=MAX_LEV_DISTANCE){if(typePassesFilter(typeFilter,ty.ty)===false){in_args=MAX_LEV_DISTANCE+1;}}if((returned=checkReturned(ty,valGenerics))<=MAX_LEV_DISTANCE){if(typePassesFilter(typeFilter,ty.ty)===false){returned=MAX_LEV_DISTANCE+1;}}lev+=lev_add;if(lev>0&&val.length>3&&searchWords[j].indexOf(val)>-1){if(val.length<6){lev-=1;}else{lev=0;}}if(in_args<=MAX_LEV_DISTANCE){if(results_in_args[fullId]===undefined){results_in_args[fullId]={id:j,index:index,lev:in_args,};}results_in_args[fullId].lev=Math.min(results_in_args[fullId].lev,in_args);}if(returned<=MAX_LEV_DISTANCE){if(results_returned[fullId]===undefined){results_returned[fullId]={id:j,index:index,lev:returned,};}results_returned[fullId].lev=Math.min(results_returned[fullId].lev,returned);}if(index!==-1||lev<=MAX_LEV_DISTANCE){if(index!==-1&&paths.length<2){lev=0;}else if(searchWords[j]===val){lev=-1;}if(results[fullId]===undefined){results[fullId]={id:j,index:index,lev:lev,};}results[fullId].lev=Math.min(results[fullId].lev,lev);}}}var ret={"in_args":sortResults(results_in_args,true),"returned":sortResults(results_returned,true),"others":sortResults(results),};if(ALIASES&&ALIASES[window.currentCrate]&&ALIASES[window.currentCrate][query.raw]){var aliases=ALIASES[window.currentCrate][query.raw];for(i=0;iMAX_RESULTS){ret.others.pop();}}}return ret;}function validateResult(name,path,keys,parent){for(var i=0;i-1||path.indexOf(keys[i])>-1||(parent!==undefined&&parent.name.toLowerCase().indexOf(keys[i])>-1)||levenshtein(name,keys[i])<=MAX_LEV_DISTANCE)){return false;}}return true;}function getQuery(raw){var matches,type,query;query=raw;matches=query.match(/^(fn|mod|struct|enum|trait|type|const|macro)\s*:\s*/i);if(matches){type=matches[1].replace(/^const$/,"constant");query=query.substring(matches[0].length);}return{raw:raw,query:query,type:type,id:query+type};}function initSearchNav(){var hoverTimeout;var click_func=function(e){var el=e.target;while(el.tagName!=="TR"){el=el.parentNode;}var dst=e.target.getElementsByTagName("a");if(dst.length<1){return;}dst=dst[0];if(window.location.pathname===dst.pathname){addClass(document.getElementById("search"),"hidden");removeClass(main,"hidden");document.location.href=dst.href;}};var mouseover_func=function(e){var el=e.target;while(el.tagName!=="TR"){el=el.parentNode;}clearTimeout(hoverTimeout);hoverTimeout=setTimeout(function(){onEachLazy(document.getElementsByClassName("search-results"),function(e){onEachLazy(e.getElementsByClassName("result"),function(i_e){removeClass(i_e,"highlighted");});});addClass(el,"highlighted");},20);};onEachLazy(document.getElementsByClassName("search-results"),function(e){onEachLazy(e.getElementsByClassName("result"),function(i_e){i_e.onclick=click_func;i_e.onmouseover=mouseover_func;});});search_input.onkeydown=function(e){var actives=[[],[],[]];var current=0;onEachLazy(document.getElementById("results").childNodes,function(e){onEachLazy(e.getElementsByClassName("highlighted"),function(e){actives[current].push(e);});current+=1;});if(e.which===38){if(!actives[currentTab].length||!actives[currentTab][0].previousElementSibling){return;}addClass(actives[currentTab][0].previousElementSibling,"highlighted");removeClass(actives[currentTab][0],"highlighted");}else if(e.which===40){if(!actives[currentTab].length){var results=document.getElementById("results").childNodes;if(results.length>0){var res=results[currentTab].getElementsByClassName("result");if(res.length>0){addClass(res[0],"highlighted");}}}else if(actives[currentTab][0].nextElementSibling){addClass(actives[currentTab][0].nextElementSibling,"highlighted");removeClass(actives[currentTab][0],"highlighted");}}else if(e.which===13){if(actives[currentTab].length){document.location.href=actives[currentTab][0].getElementsByTagName("a")[0].href;}}else if(e.which===9){if(e.shiftKey){printTab(currentTab>0?currentTab-1:2);}else{printTab(currentTab>1?0:currentTab+1);}e.preventDefault();}else if(e.which===16){}else if(e.which===27){removeClass(actives[currentTab][0],"highlighted");search_input.value="";defocusSearchBar();}else if(actives[currentTab].length>0){removeClass(actives[currentTab][0],"highlighted");}};}function buildHrefAndPath(item){var displayPath;var href;var type=itemTypes[item.ty];var name=item.name;if(type==="mod"){displayPath=item.path+"::";href=rootPath+item.path.replace(/::/g,"/")+"/"+name+"/index.html";}else if(type==="primitive"||type==="keyword"){displayPath="";href=rootPath+item.path.replace(/::/g,"/")+"/"+type+"."+name+".html";}else if(type==="externcrate"){displayPath="";href=rootPath+name+"/index.html";}else if(item.parent!==undefined){var myparent=item.parent;var anchor="#"+type+"."+name;var parentType=itemTypes[myparent.ty];if(parentType==="primitive"){displayPath=myparent.name+"::";}else{displayPath=item.path+"::"+myparent.name+"::";}href=rootPath+item.path.replace(/::/g,"/")+"/"+parentType+"."+myparent.name+".html"+anchor;}else{displayPath=item.path+"::";href=rootPath+item.path.replace(/::/g,"/")+"/"+type+"."+name+".html";}return[displayPath,href];}function escape(content){var h1=document.createElement("h1");h1.textContent=content;return h1.innerHTML;}function pathSplitter(path){var tmp=""+path.replace(/::/g,"::");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6);}return tmp;}function addTab(array,query,display){var extraStyle="";if(display===false){extraStyle=" style=\"display: none;\"";}var output="";var duplicates={};var length=0;if(array.length>0){output="";array.forEach(function(item){var name,type;name=item.name;type=itemTypes[item.ty];if(item.is_alias!==true){if(duplicates[item.fullPath]){return;}duplicates[item.fullPath]=true;}length+=1;output+="";});output+="
"+""+(item.is_alias===true?(""+item.alias+"  - see "):"")+item.displayPath+""+name+""+""+""+escape(item.desc)+" 
";}else{output="
No results :(
"+"Try on DuckDuckGo?

"+"Or try looking in one of these:
";}return[output,length];}function makeTabHeader(tabNb,text,nbElems){if(currentTab===tabNb){return"
"+text+"
("+nbElems+")
";}return"
"+text+"
("+nbElems+")
";}function showResults(results){if(results.others.length===1&&getCurrentValue("rustdoc-go-to-only-result")==="true"){var elem=document.createElement("a");elem.href=results.others[0].href;elem.style.display="none";document.body.appendChild(elem);elem.click();}var query=getQuery(search_input.value);currentResults=query.id;var ret_others=addTab(results.others,query);var ret_in_args=addTab(results.in_args,query,false);var ret_returned=addTab(results.returned,query,false);var output="

Results for "+escape(query.query)+(query.type?" (type: "+escape(query.type)+")":"")+"

"+"
"+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+"
"+ret_others[0]+ret_in_args[0]+ret_returned[0]+"
";addClass(main,"hidden");var search=document.getElementById("search");removeClass(search,"hidden");search.innerHTML=output;var tds=search.getElementsByTagName("td");var td_width=0;if(tds.length>0){td_width=tds[0].offsetWidth;}var width=search.offsetWidth-40-td_width;onEachLazy(search.getElementsByClassName("desc"),function(e){e.style.width=width+"px";});initSearchNav();var elems=document.getElementById("titles").childNodes;elems[0].onclick=function(){printTab(0);};elems[1].onclick=function(){printTab(1);};elems[2].onclick=function(){printTab(2);};printTab(currentTab);}function execSearch(query,searchWords,filterCrates){function getSmallest(arrays,positions,notDuplicates){var start=null;for(var it=0;itpositions[it]&&(start===null||start>arrays[it][positions[it]].lev)&&!notDuplicates[arrays[it][positions[it]].fullPath]){start=arrays[it][positions[it]].lev;}}return start;}function mergeArrays(arrays){var ret=[];var positions=[];var notDuplicates={};for(var x=0;xpositions[x]&&arrays[x][positions[x]].lev===smallest&&!notDuplicates[arrays[x][positions[x]].fullPath]){ret.push(arrays[x][positions[x]]);notDuplicates[arrays[x][positions[x]].fullPath]=true;positions[x]+=1;}}}return ret;}var queries=query.raw.split(",");var results={"in_args":[],"returned":[],"others":[],};for(var i=0;i1){return{"in_args":mergeArrays(results.in_args),"returned":mergeArrays(results.returned),"others":mergeArrays(results.others),};}else{return{"in_args":results.in_args[0],"returned":results.returned[0],"others":results.others[0],};}}function getFilterCrates(){var elem=document.getElementById("crate-search");if(elem&&elem.value!=="All crates"&&rawSearchIndex.hasOwnProperty(elem.value)){return elem.value;}return undefined;}function search(e,forced){var params=getQueryStringParams();var query=getQuery(search_input.value.trim());if(e){e.preventDefault();}if(query.query.length===0){return;}if(forced!==true&&query.id===currentResults){if(query.query.length>0){putBackSearch(search_input);}return;}document.title="Results for "+query.query+" - Rust";if(browserSupportsHistoryApi()){if(!history.state&&!params.search){history.pushState(query,"","?search="+encodeURIComponent(query.raw));}else{history.replaceState(query,"","?search="+encodeURIComponent(query.raw));}}var filterCrates=getFilterCrates();showResults(execSearch(query,index,filterCrates),filterCrates);}function buildIndex(rawSearchIndex){searchIndex=[];var searchWords=[];var i;for(var crate in rawSearchIndex){if(!rawSearchIndex.hasOwnProperty(crate)){continue;}searchWords.push(crate);searchIndex.push({crate:crate,ty:1,name:crate,path:"",desc:rawSearchIndex[crate].doc,type:null,});var items=rawSearchIndex[crate].i;var paths=rawSearchIndex[crate].p;var len=paths.length;for(i=0;i"+""+"
"+code.outerHTML+"
";list.appendChild(display);}}};if(window.pending_implementors){window.register_implementors(window.pending_implementors);}function labelForToggleButton(sectionIsCollapsed){if(sectionIsCollapsed){return"+";}return"\u2212";}function onEveryMatchingChild(elem,className,func){if(elem&&className&&func){var length=elem.childNodes.length;var nodes=elem.childNodes;for(var i=0;i"+labelForToggleButton(sectionIsCollapsed)+"
]";return toggle;}var toggle=createSimpleToggle(false);var hideMethodDocs=getCurrentValue("rustdoc-method-docs")==="true";var pageId=getPageId();var func=function(e){var next=e.nextElementSibling;if(!next){return;}if(hasClass(next,"docblock")===true||(hasClass(next,"stability")===true&&hasClass(next.nextElementSibling,"docblock")===true)){var newToggle=toggle.cloneNode(true);insertAfter(newToggle,e.childNodes[e.childNodes.length-1]);if(hideMethodDocs===true&&hasClass(e,"method")===true){collapseDocs(newToggle,"hide",pageId);}}};var funcImpl=function(e){var next=e.nextElementSibling;if(next&&hasClass(next,"docblock")){next=next.nextElementSibling;}if(!next){return;}if(next.getElementsByClassName("method").length>0&&hasClass(e,"impl")){insertAfter(toggle.cloneNode(true),e.childNodes[e.childNodes.length-1]);}};onEachLazy(document.getElementsByClassName("method"),func);onEachLazy(document.getElementsByClassName("associatedconstant"),func);onEachLazy(document.getElementsByClassName("impl"),funcImpl);var impl_call=function(){};if(hideMethodDocs===true){impl_call=function(e,newToggle,pageId){if(e.id.match(/^impl(?:-\d+)?$/)===null){if(hasClass(e,"impl")===true){collapseDocs(newToggle,"hide",pageId);}}};}var newToggle=document.createElement("a");newToggle.href="javascript:void(0)";newToggle.className="collapse-toggle hidden-default collapsed";newToggle.innerHTML="["+labelForToggleButton(true)+"] Show hidden undocumented items";function toggleClicked(){if(hasClass(this,"collapsed")){removeClass(this,"collapsed");onEachLazy(this.parentNode.getElementsByClassName("hidden"),function(x){if(hasClass(x,"content")===false){removeClass(x,"hidden");addClass(x,"x");}},true);this.innerHTML="["+labelForToggleButton(false)+"] Hide undocumented items";}else{addClass(this,"collapsed");onEachLazy(this.parentNode.getElementsByClassName("x"),function(x){if(hasClass(x,"content")===false){addClass(x,"hidden");removeClass(x,"x");}},true);this.innerHTML="["+labelForToggleButton(true)+"] Show hidden undocumented items";}}onEachLazy(document.getElementsByClassName("impl-items"),function(e){onEachLazy(e.getElementsByClassName("associatedconstant"),func);var hiddenElems=e.getElementsByClassName("hidden");var needToggle=false;var hlength=hiddenElems.length;for(var i=0;i0){inner[0].innerHTML="+";}}if(extraClass){addClass(wrapper,extraClass);}wrapper.appendChild(mainToggle);return wrapper;}var showItemDeclarations=getCurrentValue("rustdoc-item-declarations")==="false";function buildToggleWrapper(e){if(hasClass(e,"autohide")){var wrap=e.previousElementSibling;if(wrap&&hasClass(wrap,"toggle-wrapper")){var inner_toggle=wrap.childNodes[0];var extra=e.childNodes[0].tagName==="H3";e.style.display="none";addClass(wrap,"collapsed");onEachLazy(inner_toggle.getElementsByClassName("inner"),function(e){e.innerHTML=labelForToggleButton(true);});onEachLazy(inner_toggle.getElementsByClassName("toggle-label"),function(e){e.style.display="inline-block";if(extra===true){i_e.innerHTML=" Show "+e.childNodes[0].innerHTML;}});}}if(e.parentNode.id==="main"){var otherMessage="";var fontSize;var extraClass;if(hasClass(e,"type-decl")){fontSize="20px";otherMessage=" Show declaration";if(showItemDeclarations===false){extraClass="collapsed";}}else if(hasClass(e,"sub-variant")){otherMessage=" Show fields";}else if(hasClass(e,"non-exhaustive")){otherMessage=" This ";if(hasClass(e,"non-exhaustive-struct")){otherMessage+="struct";}else if(hasClass(e,"non-exhaustive-enum")){otherMessage+="enum";}else if(hasClass(e,"non-exhaustive-variant")){otherMessage+="enum variant";}else if(hasClass(e,"non-exhaustive-type")){otherMessage+="type";}otherMessage+=" is marked as non-exhaustive";}else if(hasClass(e.childNodes[0],"impl-items")){extraClass="marg-left";}e.parentNode.insertBefore(createToggle(otherMessage,fontSize,extraClass,hasClass(e,"type-decl")===false||showItemDeclarations===true),e);if(hasClass(e,"type-decl")===true&&showItemDeclarations===true){collapseDocs(e.previousSibling.childNodes[0],"toggle");}if(hasClass(e,"non-exhaustive")===true){collapseDocs(e.previousSibling.childNodes[0],"toggle");}}}onEachLazy(document.getElementsByClassName("docblock"),buildToggleWrapper);onEachLazy(document.getElementsByClassName("sub-variant"),buildToggleWrapper);function createToggleWrapper(tog){var span=document.createElement("span");span.className="toggle-label";span.style.display="none";span.innerHTML=" Expand attributes";tog.appendChild(span);var wrapper=document.createElement("div");wrapper.className="toggle-wrapper toggle-attributes";wrapper.appendChild(tog);return wrapper;}var itemAttributesFunc=function(){};if(getCurrentValue("rustdoc-item-attributes")!=="false"){itemAttributesFunc=function(x){collapseDocs(x.previousSibling.childNodes[0],"toggle");};}var attributesToggle=createToggleWrapper(createSimpleToggle(false));onEachLazy(main.getElementsByClassName("attributes"),function(i_e){var attr_tog=attributesToggle.cloneNode(true);if(hasClass(i_e,"top-attr")===true){addClass(attr_tog,"top-attr");}i_e.parentNode.insertBefore(attr_tog,i_e);itemAttributesFunc(i_e);});var lineNumbersFunc=function(){};if(getCurrentValue("rustdoc-line-numbers")==="true"){lineNumbersFunc=function(x){var count=x.textContent.split("\n").length;var elems=[];for(var i=0;i
✕"+"
"+content+"";document.getElementsByTagName("body")[0].appendChild(modal);document.getElementById("modal-close").onclick=hideModal;modal.onclick=hideModal;}function hideModal(){var modal=document.getElementById("important");if(modal){modal.parentNode.removeChild(modal);}}onEachLazy(document.getElementsByClassName("important-traits"),function(e){e.onclick=function(){showModal(e.lastElementChild.innerHTML);};});function printTab(nb){if(nb===0||nb===1||nb===2){currentTab=nb;}var nb_copy=nb;onEachLazy(document.getElementById("titles").childNodes,function(elem){if(nb_copy===0){addClass(elem,"selected");}else{removeClass(elem,"selected");}nb_copy-=1;});onEachLazy(document.getElementById("results").childNodes,function(elem){if(nb===0){elem.style.display="";}else{elem.style.display="none";}nb-=1;});}function putBackSearch(search_input){if(search_input.value!==""){addClass(main,"hidden");removeClass(document.getElementById("search"),"hidden");if(browserSupportsHistoryApi()){history.replaceState(search_input.value,"","?search="+encodeURIComponent(search_input.value));}}}if(search_input){search_input.onfocus=function(){putBackSearch(this);};}var params=getQueryStringParams();if(params&¶ms.search){addClass(main,"hidden");var search=document.getElementById("search");removeClass(search,"hidden");search.innerHTML="

Loading search results...

";}var sidebar_menu=document.getElementsByClassName("sidebar-menu")[0];if(sidebar_menu){sidebar_menu.onclick=function(){var sidebar=document.getElementsByClassName("sidebar")[0];if(hasClass(sidebar,"mobile")===true){hideSidebar();}else{showSidebar();}};}window.onresize=function(){hideSidebar();};autoCollapse(getPageId(),getCurrentValue("rustdoc-collapse")==="true");if(window.location.hash&&window.location.hash.length>0){expandSection(window.location.hash.replace(/^#/,""));}if(main){onEachLazy(main.getElementsByClassName("loading-content"),function(e){e.remove();});onEachLazy(main.childNodes,function(e){if(e.tagName==="H2"||e.tagName==="H3"){var nextTagName=e.nextElementSibling.tagName;if(nextTagName=="H2"||nextTagName=="H3"){e.nextElementSibling.style.display="flex";}else{e.nextElementSibling.style.display="block";}}});}function addSearchOptions(crates){var elem=document.getElementById('crate-search');if(!elem){return;}var crates_text=[];if(Object.keys(crates).length>1){for(var crate in crates){if(crates.hasOwnProperty(crate)){crates_text.push(crate);}}}crates_text.sort(function(a,b){var lower_a=a.toLowerCase();var lower_b=b.toLowerCase();if(lower_alower_b){return 1;}return 0;});for(var i=0;iList of all items in this crate

[] + + List of all items

Structs

Functions

\ No newline at end of file diff --git a/target/doc/memchr/fn.memchr.html b/target/doc/memchr/fn.memchr.html new file mode 100644 index 0000000..9d68170 --- /dev/null +++ b/target/doc/memchr/fn.memchr.html @@ -0,0 +1,16 @@ +memchr::memchr - Rust

[][src]Function memchr::memchr

pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize>

Search for the first occurrence of a byte in a slice.

+

This returns the index corresponding to the first occurrence of needle in +haystack, or None if one is not found.

+

While this is operationally the same as something like +haystack.iter().position(|&b| b == needle), memchr will use a highly +optimized routine that can be up to an order of magnitude faster in some +cases.

+

Example

+

This shows how to find the first position of a byte in a byte string.

+ +
+use memchr::memchr;
+
+let haystack = b"the quick brown fox";
+assert_eq!(memchr(b'k', haystack), Some(8));
+
\ No newline at end of file diff --git a/target/doc/memchr/fn.memchr2.html b/target/doc/memchr/fn.memchr2.html new file mode 100644 index 0000000..0c045f2 --- /dev/null +++ b/target/doc/memchr/fn.memchr2.html @@ -0,0 +1,2 @@ +memchr::memchr2 - Rust

[][src]Function memchr::memchr2

pub fn memchr2(needle1: u8, needle2: u8, haystack: &[u8]) -> Option<usize>

Like memchr, but searches for two bytes instead of one.

+
\ No newline at end of file diff --git a/target/doc/memchr/fn.memchr2_iter.html b/target/doc/memchr/fn.memchr2_iter.html new file mode 100644 index 0000000..6d21cf3 --- /dev/null +++ b/target/doc/memchr/fn.memchr2_iter.html @@ -0,0 +1,2 @@ +memchr::memchr2_iter - Rust

[][src]Function memchr::memchr2_iter

Important traits for Memchr2<'a>
pub fn memchr2_iter(needle1: u8, needle2: u8, haystack: &[u8]) -> Memchr2

An iterator over all occurrences of the needles in a haystack.

+
\ No newline at end of file diff --git a/target/doc/memchr/fn.memchr3.html b/target/doc/memchr/fn.memchr3.html new file mode 100644 index 0000000..98426ef --- /dev/null +++ b/target/doc/memchr/fn.memchr3.html @@ -0,0 +1,2 @@ +memchr::memchr3 - Rust

[][src]Function memchr::memchr3

pub fn memchr3(
    needle1: u8,
    needle2: u8,
    needle3: u8,
    haystack: &[u8]
) -> Option<usize>

Like memchr, but searches for three bytes instead of one.

+
\ No newline at end of file diff --git a/target/doc/memchr/fn.memchr3_iter.html b/target/doc/memchr/fn.memchr3_iter.html new file mode 100644 index 0000000..a0ebe8e --- /dev/null +++ b/target/doc/memchr/fn.memchr3_iter.html @@ -0,0 +1,2 @@ +memchr::memchr3_iter - Rust

[][src]Function memchr::memchr3_iter

Important traits for Memchr3<'a>
pub fn memchr3_iter(
    needle1: u8,
    needle2: u8,
    needle3: u8,
    haystack: &[u8]
) -> Memchr3

An iterator over all occurrences of the needles in a haystack.

+
\ No newline at end of file diff --git a/target/doc/memchr/fn.memchr_iter.html b/target/doc/memchr/fn.memchr_iter.html new file mode 100644 index 0000000..35294a8 --- /dev/null +++ b/target/doc/memchr/fn.memchr_iter.html @@ -0,0 +1,2 @@ +memchr::memchr_iter - Rust

[][src]Function memchr::memchr_iter

Important traits for Memchr<'a>
pub fn memchr_iter(needle: u8, haystack: &[u8]) -> Memchr

An iterator over all occurrences of the needle in a haystack.

+
\ No newline at end of file diff --git a/target/doc/memchr/fn.memrchr.html b/target/doc/memchr/fn.memrchr.html new file mode 100644 index 0000000..a1e2c1f --- /dev/null +++ b/target/doc/memchr/fn.memrchr.html @@ -0,0 +1,16 @@ +memchr::memrchr - Rust

[][src]Function memchr::memrchr

pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize>

Search for the last occurrence of a byte in a slice.

+

This returns the index corresponding to the last occurrence of needle in +haystack, or None if one is not found.

+

While this is operationally the same as something like +haystack.iter().rposition(|&b| b == needle), memrchr will use a highly +optimized routine that can be up to an order of magnitude faster in some +cases.

+

Example

+

This shows how to find the last position of a byte in a byte string.

+ +
+use memchr::memrchr;
+
+let haystack = b"the quick brown fox";
+assert_eq!(memrchr(b'o', haystack), Some(17));
+
\ No newline at end of file diff --git a/target/doc/memchr/fn.memrchr2.html b/target/doc/memchr/fn.memrchr2.html new file mode 100644 index 0000000..5705d07 --- /dev/null +++ b/target/doc/memchr/fn.memrchr2.html @@ -0,0 +1,2 @@ +memchr::memrchr2 - Rust

[][src]Function memchr::memrchr2

pub fn memrchr2(needle1: u8, needle2: u8, haystack: &[u8]) -> Option<usize>

Like memrchr, but searches for two bytes instead of one.

+
\ No newline at end of file diff --git a/target/doc/memchr/fn.memrchr2_iter.html b/target/doc/memchr/fn.memrchr2_iter.html new file mode 100644 index 0000000..e6dac1c --- /dev/null +++ b/target/doc/memchr/fn.memrchr2_iter.html @@ -0,0 +1,2 @@ +memchr::memrchr2_iter - Rust

[][src]Function memchr::memrchr2_iter

pub fn memrchr2_iter(needle1: u8, needle2: u8, haystack: &[u8]) -> Rev<Memchr2>

An iterator over all occurrences of the needles in a haystack, in reverse.

+
\ No newline at end of file diff --git a/target/doc/memchr/fn.memrchr3.html b/target/doc/memchr/fn.memrchr3.html new file mode 100644 index 0000000..ba82cd0 --- /dev/null +++ b/target/doc/memchr/fn.memrchr3.html @@ -0,0 +1,2 @@ +memchr::memrchr3 - Rust

[][src]Function memchr::memrchr3

pub fn memrchr3(
    needle1: u8,
    needle2: u8,
    needle3: u8,
    haystack: &[u8]
) -> Option<usize>

Like memrchr, but searches for three bytes instead of one.

+
\ No newline at end of file diff --git a/target/doc/memchr/fn.memrchr3_iter.html b/target/doc/memchr/fn.memrchr3_iter.html new file mode 100644 index 0000000..6f5a126 --- /dev/null +++ b/target/doc/memchr/fn.memrchr3_iter.html @@ -0,0 +1,2 @@ +memchr::memrchr3_iter - Rust

[][src]Function memchr::memrchr3_iter

pub fn memrchr3_iter(
    needle1: u8,
    needle2: u8,
    needle3: u8,
    haystack: &[u8]
) -> Rev<Memchr3>

An iterator over all occurrences of the needles in a haystack, in reverse.

+
\ No newline at end of file diff --git a/target/doc/memchr/fn.memrchr_iter.html b/target/doc/memchr/fn.memrchr_iter.html new file mode 100644 index 0000000..3b50183 --- /dev/null +++ b/target/doc/memchr/fn.memrchr_iter.html @@ -0,0 +1,2 @@ +memchr::memrchr_iter - Rust

[][src]Function memchr::memrchr_iter

pub fn memrchr_iter(needle: u8, haystack: &[u8]) -> Rev<Memchr>

An iterator over all occurrences of the needle in a haystack, in reverse.

+
\ No newline at end of file diff --git a/target/doc/memchr/index.html b/target/doc/memchr/index.html new file mode 100644 index 0000000..749d4b2 --- /dev/null +++ b/target/doc/memchr/index.html @@ -0,0 +1,34 @@ +memchr - Rust

[][src]Crate memchr

The memchr crate provides heavily optimized routines for searching bytes.

+

The memchr function is traditionally provided by libc, however, the +performance of memchr can vary significantly depending on the specific +implementation of libc that is used. They can range from manually tuned +Assembly implementations (like that found in GNU's libc) all the way to +non-vectorized C implementations (like that found in MUSL).

+

To smooth out the differences between implementations of libc, at least +on x86_64 for Rust 1.27+, this crate provides its own implementation of +memchr that should perform competitively with the one found in GNU's libc. +The implementation is in pure Rust and has no dependency on a C compiler or an +Assembler.

+

Additionally, GNU libc also provides an extension, memrchr. This crate +provides its own implementation of memrchr as well, on top of memchr2, +memchr3, memrchr2 and memrchr3. The difference between memchr and +memchr2 is that that memchr2 permits finding all occurrences of two bytes +instead of one. Similarly for memchr3.

+

Structs

+
Memchr

An iterator for memchr.

+
Memchr2

An iterator for memchr2.

+
Memchr3

An iterator for memchr3.

+

Functions

+
memchr

Search for the first occurrence of a byte in a slice.

+
memchr2_iter

An iterator over all occurrences of the needles in a haystack.

+
memchr2

Like memchr, but searches for two bytes instead of one.

+
memchr3_iter

An iterator over all occurrences of the needles in a haystack.

+
memchr3

Like memchr, but searches for three bytes instead of one.

+
memchr_iter

An iterator over all occurrences of the needle in a haystack.

+
memrchr

Search for the last occurrence of a byte in a slice.

+
memrchr2_iter

An iterator over all occurrences of the needles in a haystack, in reverse.

+
memrchr2

Like memrchr, but searches for two bytes instead of one.

+
memrchr3_iter

An iterator over all occurrences of the needles in a haystack, in reverse.

+
memrchr3

Like memrchr, but searches for three bytes instead of one.

+
memrchr_iter

An iterator over all occurrences of the needle in a haystack, in reverse.

+
\ No newline at end of file diff --git a/target/doc/memchr/iter/struct.Memchr.html b/target/doc/memchr/iter/struct.Memchr.html new file mode 100644 index 0000000..6b7dd8a --- /dev/null +++ b/target/doc/memchr/iter/struct.Memchr.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../memchr/struct.Memchr.html...

+ + + \ No newline at end of file diff --git a/target/doc/memchr/iter/struct.Memchr2.html b/target/doc/memchr/iter/struct.Memchr2.html new file mode 100644 index 0000000..ae44068 --- /dev/null +++ b/target/doc/memchr/iter/struct.Memchr2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../memchr/struct.Memchr2.html...

+ + + \ No newline at end of file diff --git a/target/doc/memchr/iter/struct.Memchr3.html b/target/doc/memchr/iter/struct.Memchr3.html new file mode 100644 index 0000000..576c4dc --- /dev/null +++ b/target/doc/memchr/iter/struct.Memchr3.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../memchr/struct.Memchr3.html...

+ + + \ No newline at end of file diff --git a/target/doc/memchr/sidebar-items.js b/target/doc/memchr/sidebar-items.js new file mode 100644 index 0000000..ff444e7 --- /dev/null +++ b/target/doc/memchr/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"fn":[["memchr","Search for the first occurrence of a byte in a slice."],["memchr2","Like `memchr`, but searches for two bytes instead of one."],["memchr2_iter","An iterator over all occurrences of the needles in a haystack."],["memchr3","Like `memchr`, but searches for three bytes instead of one."],["memchr3_iter","An iterator over all occurrences of the needles in a haystack."],["memchr_iter","An iterator over all occurrences of the needle in a haystack."],["memrchr","Search for the last occurrence of a byte in a slice."],["memrchr2","Like `memrchr`, but searches for two bytes instead of one."],["memrchr2_iter","An iterator over all occurrences of the needles in a haystack, in reverse."],["memrchr3","Like `memrchr`, but searches for three bytes instead of one."],["memrchr3_iter","An iterator over all occurrences of the needles in a haystack, in reverse."],["memrchr_iter","An iterator over all occurrences of the needle in a haystack, in reverse."]],"struct":[["Memchr","An iterator for `memchr`."],["Memchr2","An iterator for `memchr2`."],["Memchr3","An iterator for `memchr3`."]]}); \ No newline at end of file diff --git a/target/doc/memchr/struct.Memchr.html b/target/doc/memchr/struct.Memchr.html new file mode 100644 index 0000000..1d87519 --- /dev/null +++ b/target/doc/memchr/struct.Memchr.html @@ -0,0 +1,84 @@ +memchr::Memchr - Rust

[][src]Struct memchr::Memchr

pub struct Memchr<'a> { /* fields omitted */ }

An iterator for memchr.

+

Methods

impl<'a> Memchr<'a>[src]

Important traits for Memchr<'a>
pub fn new(needle: u8, haystack: &[u8]) -> Memchr[src]

Creates a new iterator that yields all positions of needle in haystack.

+

Trait Implementations

impl<'a> DoubleEndedIterator for Memchr<'a>[src]

fn nth_back(&mut self, n: usize) -> Option<Self::Item>[src]

🔬 This is a nightly-only experimental API. (iter_nth_back)

Returns the nth element from the end of the iterator. Read more

+

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

This is the reverse version of [try_fold()]: it takes elements starting from the back of the iterator. Read more

+

fn rfold<B, F>(self, accum: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.27.0[src]

An iterator method that reduces the iterator's elements to a single, final value, starting from the back. Read more

+

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.27.0[src]

Searches for an element of an iterator from the back that satisfies a predicate. Read more

+

impl<'a> Iterator for Memchr<'a>[src]

type Item = usize

The type of the elements being iterated over.

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

Auto Trait Implementations

impl<'a> Send for Memchr<'a>

impl<'a> Sync for Memchr<'a>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/memchr/struct.Memchr2.html b/target/doc/memchr/struct.Memchr2.html new file mode 100644 index 0000000..b3e5a80 --- /dev/null +++ b/target/doc/memchr/struct.Memchr2.html @@ -0,0 +1,84 @@ +memchr::Memchr2 - Rust

[][src]Struct memchr::Memchr2

pub struct Memchr2<'a> { /* fields omitted */ }

An iterator for memchr2.

+

Methods

impl<'a> Memchr2<'a>[src]

Important traits for Memchr2<'a>
pub fn new(needle1: u8, needle2: u8, haystack: &[u8]) -> Memchr2[src]

Creates a new iterator that yields all positions of needle in haystack.

+

Trait Implementations

impl<'a> DoubleEndedIterator for Memchr2<'a>[src]

fn nth_back(&mut self, n: usize) -> Option<Self::Item>[src]

🔬 This is a nightly-only experimental API. (iter_nth_back)

Returns the nth element from the end of the iterator. Read more

+

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

This is the reverse version of [try_fold()]: it takes elements starting from the back of the iterator. Read more

+

fn rfold<B, F>(self, accum: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.27.0[src]

An iterator method that reduces the iterator's elements to a single, final value, starting from the back. Read more

+

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.27.0[src]

Searches for an element of an iterator from the back that satisfies a predicate. Read more

+

impl<'a> Iterator for Memchr2<'a>[src]

type Item = usize

The type of the elements being iterated over.

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

Auto Trait Implementations

impl<'a> Send for Memchr2<'a>

impl<'a> Sync for Memchr2<'a>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/memchr/struct.Memchr3.html b/target/doc/memchr/struct.Memchr3.html new file mode 100644 index 0000000..a60132c --- /dev/null +++ b/target/doc/memchr/struct.Memchr3.html @@ -0,0 +1,84 @@ +memchr::Memchr3 - Rust

[][src]Struct memchr::Memchr3

pub struct Memchr3<'a> { /* fields omitted */ }

An iterator for memchr3.

+

Methods

impl<'a> Memchr3<'a>[src]

Important traits for Memchr3<'a>
pub fn new(needle1: u8, needle2: u8, needle3: u8, haystack: &[u8]) -> Memchr3[src]

Create a new Memchr3 that's initialized to zero with a haystack

+

Trait Implementations

impl<'a> DoubleEndedIterator for Memchr3<'a>[src]

fn nth_back(&mut self, n: usize) -> Option<Self::Item>[src]

🔬 This is a nightly-only experimental API. (iter_nth_back)

Returns the nth element from the end of the iterator. Read more

+

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

This is the reverse version of [try_fold()]: it takes elements starting from the back of the iterator. Read more

+

fn rfold<B, F>(self, accum: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.27.0[src]

An iterator method that reduces the iterator's elements to a single, final value, starting from the back. Read more

+

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.27.0[src]

Searches for an element of an iterator from the back that satisfies a predicate. Read more

+

impl<'a> Iterator for Memchr3<'a>[src]

type Item = usize

The type of the elements being iterated over.

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

Auto Trait Implementations

impl<'a> Send for Memchr3<'a>

impl<'a> Sync for Memchr3<'a>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/normalize.css b/target/doc/normalize.css new file mode 100644 index 0000000..45b6cb2 --- /dev/null +++ b/target/doc/normalize.css @@ -0,0 +1,2 @@ +/*! normalize.css v3.0.0 | MIT License | git.io/normalize */ +html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0} \ No newline at end of file diff --git a/target/doc/noscript.css b/target/doc/noscript.css new file mode 100644 index 0000000..fa0b2c4 --- /dev/null +++ b/target/doc/noscript.css @@ -0,0 +1 @@ +#main>h2+div,#main>h2+h3,#main>h3+div{display:block;}.loading-content{display:none;} \ No newline at end of file diff --git a/target/doc/owoify/all.html b/target/doc/owoify/all.html new file mode 100644 index 0000000..ab771f8 --- /dev/null +++ b/target/doc/owoify/all.html @@ -0,0 +1,3 @@ +List of all items in this crate

[] + + List of all items

Traits

\ No newline at end of file diff --git a/target/doc/owoify/index.html b/target/doc/owoify/index.html new file mode 100644 index 0000000..5f30bae --- /dev/null +++ b/target/doc/owoify/index.html @@ -0,0 +1,2 @@ +owoify - Rust

[][src]Crate owoify

Traits

+
OwOifiable
\ No newline at end of file diff --git a/target/doc/owoify/sidebar-items.js b/target/doc/owoify/sidebar-items.js new file mode 100644 index 0000000..51b045d --- /dev/null +++ b/target/doc/owoify/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"trait":[["OwOifiable",""]]}); \ No newline at end of file diff --git a/target/doc/owoify/trait.OwOifiable.html b/target/doc/owoify/trait.OwOifiable.html new file mode 100644 index 0000000..df3f444 --- /dev/null +++ b/target/doc/owoify/trait.OwOifiable.html @@ -0,0 +1,14 @@ +owoify::OwOifiable - Rust

[][src]Trait owoify::OwOifiable

pub trait OwOifiable {
+    fn owoify(&self) -> Self;
+}
+

Required methods

fn owoify(&self) -> Self

The owoification method

+
Loading content... +

Implementations on Foreign Types

impl OwOifiable for String[src]

fn owoify(&self) -> Self[src]

Owoifies a String

+

Examples

+
+use use owoify::OwOifiable;
+let owoified = String::from("Example text").owoify();
+
Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/all.html b/target/doc/ppv_lite86/all.html new file mode 100644 index 0000000..7e3116c --- /dev/null +++ b/target/doc/ppv_lite86/all.html @@ -0,0 +1,3 @@ +List of all items in this crate

[] + + List of all items

Structs

Unions

Traits

Macros

Typedefs

\ No newline at end of file diff --git a/target/doc/ppv_lite86/index.html b/target/doc/ppv_lite86/index.html new file mode 100644 index 0000000..9d1cdd1 --- /dev/null +++ b/target/doc/ppv_lite86/index.html @@ -0,0 +1,20 @@ +ppv_lite86 - Rust

[][src]Crate ppv_lite86

Re-exports

+
pub use self::arch::vec128_storage;
pub use self::arch::vec256_storage;
pub use self::arch::vec512_storage;

Modules

+
x86_64

Macros

+
dispatch

Generate the full set of optimized implementations to take advantage of the most important +hardware feature sets.

+
dispatch_light128

Generate only the basic implementations necessary to be able to operate efficiently on 128-bit +vectors on this platfrom. For x86-64, that would mean SSE2 and AVX.

+
dispatch_light256

Generate only the basic implementations necessary to be able to operate efficiently on 256-bit +vectors on this platfrom. For x86-64, that would mean SSE2, AVX, and AVX2.

+

Traits

+
AndNot
ArithOps

Ops that depend on word size

+
BSwap
BitOps0

Ops that are independent of word size and endian

+
BitOps32
BitOps64
BitOps128
LaneWords4

A vector composed one or more lanes each composed of four words.

+
Machine
MultiLane

A vector composed of multiple 128-bit lanes.

+
RotateEachWord32
RotateEachWord64
RotateEachWord128
Store
StoreBytes
Swap64

Exchange neigboring ranges of bits of the specified size

+
UnsafeFrom
VZip

Combine single vectors into a multi-lane vector.

+
Vec2

A vector composed of two elements, which may be words or themselves vectors.

+
Vec4

A vector composed of four elements, which may be words or themselves vectors.

+
Words4

A vector composed of four words; depending on their size, operations may cross lanes.

+
u128x1
u128x2
u128x4
u32x4
u32x4x2
u32x4x4
u64x2
u64x4
u64x2x2
u64x2x4
\ No newline at end of file diff --git a/target/doc/ppv_lite86/macro.dispatch!.html b/target/doc/ppv_lite86/macro.dispatch!.html new file mode 100644 index 0000000..0314e89 --- /dev/null +++ b/target/doc/ppv_lite86/macro.dispatch!.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to macro.dispatch.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/macro.dispatch.html b/target/doc/ppv_lite86/macro.dispatch.html new file mode 100644 index 0000000..0343415 --- /dev/null +++ b/target/doc/ppv_lite86/macro.dispatch.html @@ -0,0 +1,9 @@ +ppv_lite86::dispatch - Rust

[][src]Macro ppv_lite86::dispatch

+macro_rules! dispatch {
+    ($mach:ident, $MTy:ident, { $([$pub:tt$(($krate:tt))*])* fn $name:ident($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty $body:block }) => { ... };
+    ($mach:ident, $MTy:ident, { $([$pub:tt $(($krate:tt))*])* fn $name:ident($($arg:ident: $argty:ty),* $(,)*) $body:block }) => { ... };
+}
+

Generate the full set of optimized implementations to take advantage of the most important +hardware feature sets.

+

This dispatcher is suitable for maximizing throughput.

+
\ No newline at end of file diff --git a/target/doc/ppv_lite86/macro.dispatch_light128!.html b/target/doc/ppv_lite86/macro.dispatch_light128!.html new file mode 100644 index 0000000..a32f8a9 --- /dev/null +++ b/target/doc/ppv_lite86/macro.dispatch_light128!.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to macro.dispatch_light128.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/macro.dispatch_light128.html b/target/doc/ppv_lite86/macro.dispatch_light128.html new file mode 100644 index 0000000..3609680 --- /dev/null +++ b/target/doc/ppv_lite86/macro.dispatch_light128.html @@ -0,0 +1,11 @@ +ppv_lite86::dispatch_light128 - Rust

[][src]Macro ppv_lite86::dispatch_light128

+macro_rules! dispatch_light128 {
+    ($mach:ident, $MTy:ident, { $([$pub:tt$(($krate:tt))*])* fn $name:ident($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty $body:block }) => { ... };
+    ($mach:ident, $MTy:ident, { $([$pub:tt$(($krate:tt))*])* fn $name:ident($($arg:ident: $argty:ty),* $(,)*) $body:block }) => { ... };
+}
+

Generate only the basic implementations necessary to be able to operate efficiently on 128-bit +vectors on this platfrom. For x86-64, that would mean SSE2 and AVX.

+

This dispatcher is suitable for vector operations that do not benefit from advanced hardware +features (e.g. because they are done infrequently), so minimizing their contribution to code +size is more important.

+
\ No newline at end of file diff --git a/target/doc/ppv_lite86/macro.dispatch_light256!.html b/target/doc/ppv_lite86/macro.dispatch_light256!.html new file mode 100644 index 0000000..d578781 --- /dev/null +++ b/target/doc/ppv_lite86/macro.dispatch_light256!.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to macro.dispatch_light256.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/macro.dispatch_light256.html b/target/doc/ppv_lite86/macro.dispatch_light256.html new file mode 100644 index 0000000..74574c3 --- /dev/null +++ b/target/doc/ppv_lite86/macro.dispatch_light256.html @@ -0,0 +1,11 @@ +ppv_lite86::dispatch_light256 - Rust

[][src]Macro ppv_lite86::dispatch_light256

+macro_rules! dispatch_light256 {
+    ($mach:ident, $MTy:ident, { $([$pub:tt$(($krate:tt))*])* fn $name:ident($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty $body:block }) => { ... };
+    ($mach:ident, $MTy:ident, { $([$pub:tt$(($krate:tt))*])* fn $name:ident($($arg:ident: $argty:ty),* $(,)*) $body:block }) => { ... };
+}
+

Generate only the basic implementations necessary to be able to operate efficiently on 256-bit +vectors on this platfrom. For x86-64, that would mean SSE2, AVX, and AVX2.

+

This dispatcher is suitable for vector operations that do not benefit from advanced hardware +features (e.g. because they are done infrequently), so minimizing their contribution to code +size is more important.

+
\ No newline at end of file diff --git a/target/doc/ppv_lite86/sidebar-items.js b/target/doc/ppv_lite86/sidebar-items.js new file mode 100644 index 0000000..df22a65 --- /dev/null +++ b/target/doc/ppv_lite86/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"macro":[["dispatch","Generate the full set of optimized implementations to take advantage of the most important hardware feature sets."],["dispatch_light128","Generate only the basic implementations necessary to be able to operate efficiently on 128-bit vectors on this platfrom. For x86-64, that would mean SSE2 and AVX."],["dispatch_light256","Generate only the basic implementations necessary to be able to operate efficiently on 256-bit vectors on this platfrom. For x86-64, that would mean SSE2, AVX, and AVX2."]],"mod":[["x86_64",""]],"trait":[["AndNot",""],["ArithOps","Ops that depend on word size"],["BSwap",""],["BitOps0","Ops that are independent of word size and endian"],["BitOps128",""],["BitOps32",""],["BitOps64",""],["LaneWords4","A vector composed one or more lanes each composed of four words."],["Machine",""],["MultiLane","A vector composed of multiple 128-bit lanes."],["RotateEachWord128",""],["RotateEachWord32",""],["RotateEachWord64",""],["Store",""],["StoreBytes",""],["Swap64","Exchange neigboring ranges of bits of the specified size"],["UnsafeFrom",""],["VZip","Combine single vectors into a multi-lane vector."],["Vec2","A vector composed of two elements, which may be words or themselves vectors."],["Vec4","A vector composed of four elements, which may be words or themselves vectors."],["Words4","A vector composed of four words; depending on their size, operations may cross lanes."],["u128x1",""],["u128x2",""],["u128x4",""],["u32x4",""],["u32x4x2",""],["u32x4x4",""],["u64x2",""],["u64x2x2",""],["u64x2x4",""],["u64x4",""]]}); \ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.AndNot.html b/target/doc/ppv_lite86/trait.AndNot.html new file mode 100644 index 0000000..5a201b7 --- /dev/null +++ b/target/doc/ppv_lite86/trait.AndNot.html @@ -0,0 +1,9 @@ +ppv_lite86::AndNot - Rust

[][src]Trait ppv_lite86::AndNot

pub trait AndNot {
+    type Output;
+    fn andnot(self, rhs: Self) -> Self::Output;
+}
+

Associated Types

type Output

Loading content... +

Required methods

fn andnot(self, rhs: Self) -> Self::Output

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.ArithOps.html b/target/doc/ppv_lite86/trait.ArithOps.html new file mode 100644 index 0000000..aa280c1 --- /dev/null +++ b/target/doc/ppv_lite86/trait.ArithOps.html @@ -0,0 +1,5 @@ +ppv_lite86::ArithOps - Rust

[][src]Trait ppv_lite86::ArithOps

pub trait ArithOps: Add<Output = Self> + AddAssign + Sized + Copy + Clone + BSwap { }

Ops that depend on word size

+
+

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.BSwap.html b/target/doc/ppv_lite86/trait.BSwap.html new file mode 100644 index 0000000..d6873e8 --- /dev/null +++ b/target/doc/ppv_lite86/trait.BSwap.html @@ -0,0 +1,7 @@ +ppv_lite86::BSwap - Rust

[][src]Trait ppv_lite86::BSwap

pub trait BSwap {
+    fn bswap(self) -> Self;
+}
+

Required methods

fn bswap(self) -> Self

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.BitOps0.html b/target/doc/ppv_lite86/trait.BitOps0.html new file mode 100644 index 0000000..a863326 --- /dev/null +++ b/target/doc/ppv_lite86/trait.BitOps0.html @@ -0,0 +1,5 @@ +ppv_lite86::BitOps0 - Rust

[][src]Trait ppv_lite86::BitOps0

pub trait BitOps0: BitAnd<Output = Self> + BitOr<Output = Self> + BitXor<Output = Self> + BitXorAssign + Not<Output = Self> + AndNot<Output = Self> + Sized + Copy + Clone { }

Ops that are independent of word size and endian

+
+

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.BitOps128.html b/target/doc/ppv_lite86/trait.BitOps128.html new file mode 100644 index 0000000..eb66445 --- /dev/null +++ b/target/doc/ppv_lite86/trait.BitOps128.html @@ -0,0 +1,4 @@ +ppv_lite86::BitOps128 - Rust

[][src]Trait ppv_lite86::BitOps128

pub trait BitOps128: BitOps64 + RotateEachWord128 { }
+

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.BitOps32.html b/target/doc/ppv_lite86/trait.BitOps32.html new file mode 100644 index 0000000..88c0a2d --- /dev/null +++ b/target/doc/ppv_lite86/trait.BitOps32.html @@ -0,0 +1,4 @@ +ppv_lite86::BitOps32 - Rust

[][src]Trait ppv_lite86::BitOps32

pub trait BitOps32: BitOps0 + RotateEachWord32 { }
+

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.BitOps64.html b/target/doc/ppv_lite86/trait.BitOps64.html new file mode 100644 index 0000000..6eebd1e --- /dev/null +++ b/target/doc/ppv_lite86/trait.BitOps64.html @@ -0,0 +1,4 @@ +ppv_lite86::BitOps64 - Rust

[][src]Trait ppv_lite86::BitOps64

pub trait BitOps64: BitOps32 + RotateEachWord64 { }
+

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.LaneWords4.html b/target/doc/ppv_lite86/trait.LaneWords4.html new file mode 100644 index 0000000..7b24e5b --- /dev/null +++ b/target/doc/ppv_lite86/trait.LaneWords4.html @@ -0,0 +1,10 @@ +ppv_lite86::LaneWords4 - Rust

[][src]Trait ppv_lite86::LaneWords4

pub trait LaneWords4 {
+    fn shuffle_lane_words1230(self) -> Self;
+
fn shuffle_lane_words2301(self) -> Self; +
fn shuffle_lane_words3012(self) -> Self; +}

A vector composed one or more lanes each composed of four words.

+
+

Required methods

fn shuffle_lane_words1230(self) -> Self

fn shuffle_lane_words2301(self) -> Self

fn shuffle_lane_words3012(self) -> Self

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.Machine.html b/target/doc/ppv_lite86/trait.Machine.html new file mode 100644 index 0000000..3494b8c --- /dev/null +++ b/target/doc/ppv_lite86/trait.Machine.html @@ -0,0 +1,27 @@ +ppv_lite86::Machine - Rust

[][src]Trait ppv_lite86::Machine

pub trait Machine: Sized + Copy {
+    type u32x4: u32x4<Self>;
+    type u64x2: u64x2<Self>;
+    type u128x1: u128x1<Self>;
+    type u32x4x2: u32x4x2<Self>;
+    type u64x2x2: u64x2x2<Self>;
+    type u64x4: u64x4<Self>;
+    type u128x2: u128x2<Self>;
+    type u32x4x4: u32x4x4<Self>;
+    type u64x2x4: u64x2x4<Self>;
+    type u128x4: u128x4<Self>;
+    unsafe fn instance() -> Self;
+
+    fn unpack<S, V: Store<S>>(self, s: S) -> V { ... }
+
fn vec<V, A>(self, a: A) -> V
    where
        V: MultiLane<A>
, + { ... } +
fn read_le<V>(self, input: &[u8]) -> V
    where
        V: StoreBytes
, + { ... } +
fn read_be<V>(self, input: &[u8]) -> V
    where
        V: StoreBytes
, + { ... } +}
+

Associated Types

type u32x4: u32x4<Self>

type u64x2: u64x2<Self>

type u128x1: u128x1<Self>

type u32x4x2: u32x4x2<Self>

type u64x2x2: u64x2x2<Self>

type u64x4: u64x4<Self>

type u128x2: u128x2<Self>

type u32x4x4: u32x4x4<Self>

type u64x2x4: u64x2x4<Self>

type u128x4: u128x4<Self>

Loading content... +

Required methods

unsafe fn instance() -> Self

Loading content... +

Provided methods

fn unpack<S, V: Store<S>>(self, s: S) -> V

fn vec<V, A>(self, a: A) -> V where
    V: MultiLane<A>, 

fn read_le<V>(self, input: &[u8]) -> V where
    V: StoreBytes

fn read_be<V>(self, input: &[u8]) -> V where
    V: StoreBytes

Loading content... +

Implementors

impl<NI: Copy> Machine for Avx2Machine<NI> where
    u128x1_sse2<YesS3, YesS4, NI>: BSwap + Swap64,
    u64x2_sse2<YesS3, YesS4, NI>: BSwap + RotateEachWord32 + MultiLane<[u64; 2]> + Vec2<u64>,
    u32x4_sse2<YesS3, YesS4, NI>: BSwap + RotateEachWord32 + MultiLane<[u32; 4]> + Vec4<u32>,
    x2<u64x2_sse2<YesS3, YesS4, NI>, G1>: BSwap + Words4
[src]

type u32x4 = u32x4_sse2<YesS3, YesS4, NI>

type u64x2 = u64x2_sse2<YesS3, YesS4, NI>

type u128x1 = u128x1_sse2<YesS3, YesS4, NI>

type u32x4x2 = x2<u32x4_sse2<YesS3, YesS4, NI>, G0>

type u64x2x2 = x2<u64x2_sse2<YesS3, YesS4, NI>, G0>

type u64x4 = x2<u64x2_sse2<YesS3, YesS4, NI>, G1>

type u128x2 = x2<u128x1_sse2<YesS3, YesS4, NI>, G0>

type u32x4x4 = u32x4x4_avx2<NI>

type u64x2x4 = x4<u64x2_sse2<YesS3, YesS4, NI>>

type u128x4 = x4<u128x1_sse2<YesS3, YesS4, NI>>

fn unpack<S, V: Store<S>>(self, s: S) -> V[src]

fn vec<V, A>(self, a: A) -> V where
    V: MultiLane<A>, 
[src]

fn read_le<V>(self, input: &[u8]) -> V where
    V: StoreBytes
[src]

fn read_be<V>(self, input: &[u8]) -> V where
    V: StoreBytes
[src]

impl<S3: Copy, S4: Copy, NI: Copy> Machine for SseMachine<S3, S4, NI> where
    u128x1_sse2<S3, S4, NI>: Swap64,
    u64x2_sse2<S3, S4, NI>: BSwap + RotateEachWord32 + MultiLane<[u64; 2]> + Vec2<u64>,
    u32x4_sse2<S3, S4, NI>: BSwap + RotateEachWord32 + MultiLane<[u32; 4]> + Vec4<u32>,
    x2<u64x2_sse2<S3, S4, NI>, G1>: BSwap + Words4,
    u128x1_sse2<S3, S4, NI>: BSwap,
    x2<u128x1_sse2<S3, S4, NI>, G0>: Into<x2<u64x2_sse2<S3, S4, NI>, G0>>,
    x2<u128x1_sse2<S3, S4, NI>, G0>: Into<x2<u64x2_sse2<S3, S4, NI>, G1>>,
    x2<u128x1_sse2<S3, S4, NI>, G0>: Into<x2<u32x4_sse2<S3, S4, NI>, G0>>,
    x4<u128x1_sse2<S3, S4, NI>>: Into<x4<u64x2_sse2<S3, S4, NI>>>,
    x4<u128x1_sse2<S3, S4, NI>>: Into<x4<u32x4_sse2<S3, S4, NI>>>, 
[src]

type u32x4 = u32x4_sse2<S3, S4, NI>

type u64x2 = u64x2_sse2<S3, S4, NI>

type u128x1 = u128x1_sse2<S3, S4, NI>

type u32x4x2 = x2<u32x4_sse2<S3, S4, NI>, G0>

type u64x2x2 = x2<u64x2_sse2<S3, S4, NI>, G0>

type u64x4 = x2<u64x2_sse2<S3, S4, NI>, G1>

type u128x2 = x2<u128x1_sse2<S3, S4, NI>, G0>

type u32x4x4 = x4<u32x4_sse2<S3, S4, NI>>

type u64x2x4 = x4<u64x2_sse2<S3, S4, NI>>

type u128x4 = x4<u128x1_sse2<S3, S4, NI>>

fn unpack<S, V: Store<S>>(self, s: S) -> V[src]

fn vec<V, A>(self, a: A) -> V where
    V: MultiLane<A>, 
[src]

fn read_le<V>(self, input: &[u8]) -> V where
    V: StoreBytes
[src]

fn read_be<V>(self, input: &[u8]) -> V where
    V: StoreBytes
[src]

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.MultiLane.html b/target/doc/ppv_lite86/trait.MultiLane.html new file mode 100644 index 0000000..459c058 --- /dev/null +++ b/target/doc/ppv_lite86/trait.MultiLane.html @@ -0,0 +1,11 @@ +ppv_lite86::MultiLane - Rust

[][src]Trait ppv_lite86::MultiLane

pub trait MultiLane<Lanes> {
+    fn to_lanes(self) -> Lanes;
+
fn from_lanes(lanes: Lanes) -> Self; +}

A vector composed of multiple 128-bit lanes.

+
+

Required methods

fn to_lanes(self) -> Lanes

Split a multi-lane vector into single-lane vectors.

+

fn from_lanes(lanes: Lanes) -> Self

Build a multi-lane vector from individual lanes.

+
Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.RotateEachWord128.html b/target/doc/ppv_lite86/trait.RotateEachWord128.html new file mode 100644 index 0000000..074d967 --- /dev/null +++ b/target/doc/ppv_lite86/trait.RotateEachWord128.html @@ -0,0 +1,4 @@ +ppv_lite86::RotateEachWord128 - Rust

[][src]Trait ppv_lite86::RotateEachWord128

pub trait RotateEachWord128 { }
+

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.RotateEachWord32.html b/target/doc/ppv_lite86/trait.RotateEachWord32.html new file mode 100644 index 0000000..f92909b --- /dev/null +++ b/target/doc/ppv_lite86/trait.RotateEachWord32.html @@ -0,0 +1,14 @@ +ppv_lite86::RotateEachWord32 - Rust

[][src]Trait ppv_lite86::RotateEachWord32

pub trait RotateEachWord32 {
+    fn rotate_each_word_right7(self) -> Self;
+
fn rotate_each_word_right8(self) -> Self; +
fn rotate_each_word_right11(self) -> Self; +
fn rotate_each_word_right12(self) -> Self; +
fn rotate_each_word_right16(self) -> Self; +
fn rotate_each_word_right20(self) -> Self; +
fn rotate_each_word_right24(self) -> Self; +
fn rotate_each_word_right25(self) -> Self; +}
+

Required methods

fn rotate_each_word_right7(self) -> Self

fn rotate_each_word_right8(self) -> Self

fn rotate_each_word_right11(self) -> Self

fn rotate_each_word_right12(self) -> Self

fn rotate_each_word_right16(self) -> Self

fn rotate_each_word_right20(self) -> Self

fn rotate_each_word_right24(self) -> Self

fn rotate_each_word_right25(self) -> Self

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.RotateEachWord64.html b/target/doc/ppv_lite86/trait.RotateEachWord64.html new file mode 100644 index 0000000..3dd264a --- /dev/null +++ b/target/doc/ppv_lite86/trait.RotateEachWord64.html @@ -0,0 +1,7 @@ +ppv_lite86::RotateEachWord64 - Rust

[][src]Trait ppv_lite86::RotateEachWord64

pub trait RotateEachWord64 {
+    fn rotate_each_word_right32(self) -> Self;
+}
+

Required methods

fn rotate_each_word_right32(self) -> Self

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.Store.html b/target/doc/ppv_lite86/trait.Store.html new file mode 100644 index 0000000..2a45980 --- /dev/null +++ b/target/doc/ppv_lite86/trait.Store.html @@ -0,0 +1,7 @@ +ppv_lite86::Store - Rust

[][src]Trait ppv_lite86::Store

pub trait Store<S> {
+    unsafe fn unpack(p: S) -> Self;
+}
+

Required methods

unsafe fn unpack(p: S) -> Self

Loading content... +

Implementors

impl Store<vec128_storage> for vec128_storage[src]

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.StoreBytes.html b/target/doc/ppv_lite86/trait.StoreBytes.html new file mode 100644 index 0000000..665a46d --- /dev/null +++ b/target/doc/ppv_lite86/trait.StoreBytes.html @@ -0,0 +1,10 @@ +ppv_lite86::StoreBytes - Rust

[][src]Trait ppv_lite86::StoreBytes

pub trait StoreBytes {
+    unsafe fn unsafe_read_le(input: &[u8]) -> Self;
+
unsafe fn unsafe_read_be(input: &[u8]) -> Self; +
fn write_le(self, out: &mut [u8]); +
fn write_be(self, out: &mut [u8]); +}
+

Required methods

unsafe fn unsafe_read_le(input: &[u8]) -> Self

unsafe fn unsafe_read_be(input: &[u8]) -> Self

fn write_le(self, out: &mut [u8])

fn write_be(self, out: &mut [u8])

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.Swap64.html b/target/doc/ppv_lite86/trait.Swap64.html new file mode 100644 index 0000000..9a4cfcf --- /dev/null +++ b/target/doc/ppv_lite86/trait.Swap64.html @@ -0,0 +1,14 @@ +ppv_lite86::Swap64 - Rust

[][src]Trait ppv_lite86::Swap64

pub trait Swap64 {
+    fn swap1(self) -> Self;
+
fn swap2(self) -> Self; +
fn swap4(self) -> Self; +
fn swap8(self) -> Self; +
fn swap16(self) -> Self; +
fn swap32(self) -> Self; +
fn swap64(self) -> Self; +}

Exchange neigboring ranges of bits of the specified size

+
+

Required methods

fn swap1(self) -> Self

fn swap2(self) -> Self

fn swap4(self) -> Self

fn swap8(self) -> Self

fn swap16(self) -> Self

fn swap32(self) -> Self

fn swap64(self) -> Self

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.UnsafeFrom.html b/target/doc/ppv_lite86/trait.UnsafeFrom.html new file mode 100644 index 0000000..2171b54 --- /dev/null +++ b/target/doc/ppv_lite86/trait.UnsafeFrom.html @@ -0,0 +1,7 @@ +ppv_lite86::UnsafeFrom - Rust

[][src]Trait ppv_lite86::UnsafeFrom

pub trait UnsafeFrom<T> {
+    unsafe fn unsafe_from(t: T) -> Self;
+}
+

Required methods

unsafe fn unsafe_from(t: T) -> Self

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.VZip.html b/target/doc/ppv_lite86/trait.VZip.html new file mode 100644 index 0000000..9bf9d85 --- /dev/null +++ b/target/doc/ppv_lite86/trait.VZip.html @@ -0,0 +1,8 @@ +ppv_lite86::VZip - Rust

[][src]Trait ppv_lite86::VZip

pub trait VZip<V> {
+    fn vzip(self) -> V;
+}

Combine single vectors into a multi-lane vector.

+
+

Required methods

fn vzip(self) -> V

Loading content... +

Implementors

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.Vec2.html b/target/doc/ppv_lite86/trait.Vec2.html new file mode 100644 index 0000000..f8c242e --- /dev/null +++ b/target/doc/ppv_lite86/trait.Vec2.html @@ -0,0 +1,9 @@ +ppv_lite86::Vec2 - Rust

[][src]Trait ppv_lite86::Vec2

pub trait Vec2<W> {
+    fn extract(self, i: u32) -> W;
+
fn insert(self, w: W, i: u32) -> Self; +}

A vector composed of two elements, which may be words or themselves vectors.

+
+

Required methods

fn extract(self, i: u32) -> W

fn insert(self, w: W, i: u32) -> Self

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.Vec4.html b/target/doc/ppv_lite86/trait.Vec4.html new file mode 100644 index 0000000..06480fe --- /dev/null +++ b/target/doc/ppv_lite86/trait.Vec4.html @@ -0,0 +1,9 @@ +ppv_lite86::Vec4 - Rust

[][src]Trait ppv_lite86::Vec4

pub trait Vec4<W> {
+    fn extract(self, i: u32) -> W;
+
fn insert(self, w: W, i: u32) -> Self; +}

A vector composed of four elements, which may be words or themselves vectors.

+
+

Required methods

fn extract(self, i: u32) -> W

fn insert(self, w: W, i: u32) -> Self

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.Words4.html b/target/doc/ppv_lite86/trait.Words4.html new file mode 100644 index 0000000..20fe596 --- /dev/null +++ b/target/doc/ppv_lite86/trait.Words4.html @@ -0,0 +1,10 @@ +ppv_lite86::Words4 - Rust

[][src]Trait ppv_lite86::Words4

pub trait Words4 {
+    fn shuffle1230(self) -> Self;
+
fn shuffle2301(self) -> Self; +
fn shuffle3012(self) -> Self; +}

A vector composed of four words; depending on their size, operations may cross lanes.

+
+

Required methods

fn shuffle1230(self) -> Self

fn shuffle2301(self) -> Self

fn shuffle3012(self) -> Self

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.u128x1.html b/target/doc/ppv_lite86/trait.u128x1.html new file mode 100644 index 0000000..5ec8e86 --- /dev/null +++ b/target/doc/ppv_lite86/trait.u128x1.html @@ -0,0 +1,4 @@ +ppv_lite86::u128x1 - Rust

[][src]Trait ppv_lite86::u128x1

pub trait u128x1<M: Machine>: BitOps128 + Store<vec128_storage> + Swap64 + MultiLane<[u128; 1]> + Into<vec128_storage> { }
+

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.u128x2.html b/target/doc/ppv_lite86/trait.u128x2.html new file mode 100644 index 0000000..ede0e60 --- /dev/null +++ b/target/doc/ppv_lite86/trait.u128x2.html @@ -0,0 +1,4 @@ +ppv_lite86::u128x2 - Rust

[][src]Trait ppv_lite86::u128x2

pub trait u128x2<M: Machine>: BitOps128 + Store<vec256_storage> + Vec2<M::u128x1> + MultiLane<[M::u128x1; 2]> + Swap64 + Into<vec256_storage> { }
+

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.u128x4.html b/target/doc/ppv_lite86/trait.u128x4.html new file mode 100644 index 0000000..87fea11 --- /dev/null +++ b/target/doc/ppv_lite86/trait.u128x4.html @@ -0,0 +1,4 @@ +ppv_lite86::u128x4 - Rust

[][src]Trait ppv_lite86::u128x4

pub trait u128x4<M: Machine>: BitOps128 + Store<vec512_storage> + Vec4<M::u128x1> + MultiLane<[M::u128x1; 4]> + Swap64 + Into<vec512_storage> { }
+

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.u32x4.html b/target/doc/ppv_lite86/trait.u32x4.html new file mode 100644 index 0000000..48b12ed --- /dev/null +++ b/target/doc/ppv_lite86/trait.u32x4.html @@ -0,0 +1,4 @@ +ppv_lite86::u32x4 - Rust

[][src]Trait ppv_lite86::u32x4

pub trait u32x4<M: Machine>: BitOps32 + Store<vec128_storage> + ArithOps + Vec4<u32> + Words4 + LaneWords4 + StoreBytes + MultiLane<[u32; 4]> + Into<vec128_storage> { }
+

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.u32x4x2.html b/target/doc/ppv_lite86/trait.u32x4x2.html new file mode 100644 index 0000000..7473068 --- /dev/null +++ b/target/doc/ppv_lite86/trait.u32x4x2.html @@ -0,0 +1,4 @@ +ppv_lite86::u32x4x2 - Rust

[][src]Trait ppv_lite86::u32x4x2

pub trait u32x4x2<M: Machine>: BitOps32 + Store<vec256_storage> + Vec2<M::u32x4> + MultiLane<[M::u32x4; 2]> + ArithOps + Into<vec256_storage> { }
+

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.u32x4x4.html b/target/doc/ppv_lite86/trait.u32x4x4.html new file mode 100644 index 0000000..3b2d8aa --- /dev/null +++ b/target/doc/ppv_lite86/trait.u32x4x4.html @@ -0,0 +1,4 @@ +ppv_lite86::u32x4x4 - Rust

[][src]Trait ppv_lite86::u32x4x4

pub trait u32x4x4<M: Machine>: BitOps32 + Store<vec512_storage> + Vec4<M::u32x4> + MultiLane<[M::u32x4; 4]> + ArithOps + LaneWords4 + Into<vec512_storage> { }
+

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.u64x2.html b/target/doc/ppv_lite86/trait.u64x2.html new file mode 100644 index 0000000..eec2f0f --- /dev/null +++ b/target/doc/ppv_lite86/trait.u64x2.html @@ -0,0 +1,4 @@ +ppv_lite86::u64x2 - Rust

[][src]Trait ppv_lite86::u64x2

pub trait u64x2<M: Machine>: BitOps64 + Store<vec128_storage> + ArithOps + Vec2<u64> + MultiLane<[u64; 2]> + Into<vec128_storage> { }
+

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.u64x2x2.html b/target/doc/ppv_lite86/trait.u64x2x2.html new file mode 100644 index 0000000..2ccf74f --- /dev/null +++ b/target/doc/ppv_lite86/trait.u64x2x2.html @@ -0,0 +1,4 @@ +ppv_lite86::u64x2x2 - Rust

[][src]Trait ppv_lite86::u64x2x2

pub trait u64x2x2<M: Machine>: BitOps64 + Store<vec256_storage> + Vec2<M::u64x2> + MultiLane<[M::u64x2; 2]> + ArithOps + StoreBytes + Into<vec256_storage> { }
+

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.u64x2x4.html b/target/doc/ppv_lite86/trait.u64x2x4.html new file mode 100644 index 0000000..7f03a82 --- /dev/null +++ b/target/doc/ppv_lite86/trait.u64x2x4.html @@ -0,0 +1,4 @@ +ppv_lite86::u64x2x4 - Rust

[][src]Trait ppv_lite86::u64x2x4

pub trait u64x2x4<M: Machine>: BitOps64 + Store<vec512_storage> + Vec4<M::u64x2> + MultiLane<[M::u64x2; 4]> + ArithOps + Into<vec512_storage> { }
+

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/trait.u64x4.html b/target/doc/ppv_lite86/trait.u64x4.html new file mode 100644 index 0000000..3b8acd7 --- /dev/null +++ b/target/doc/ppv_lite86/trait.u64x4.html @@ -0,0 +1,4 @@ +ppv_lite86::u64x4 - Rust

[][src]Trait ppv_lite86::u64x4

pub trait u64x4<M: Machine>: BitOps64 + Store<vec256_storage> + Vec4<u64> + MultiLane<[u64; 4]> + ArithOps + Words4 + StoreBytes + Into<vec256_storage> { }
+

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/ppv_lite86/types/trait.AndNot.html b/target/doc/ppv_lite86/types/trait.AndNot.html new file mode 100644 index 0000000..7328e99 --- /dev/null +++ b/target/doc/ppv_lite86/types/trait.AndNot.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ppv_lite86/trait.AndNot.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/trait.ArithOps.html b/target/doc/ppv_lite86/types/trait.ArithOps.html new file mode 100644 index 0000000..b3ad4e9 --- /dev/null +++ b/target/doc/ppv_lite86/types/trait.ArithOps.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ppv_lite86/trait.ArithOps.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/trait.BSwap.html b/target/doc/ppv_lite86/types/trait.BSwap.html new file mode 100644 index 0000000..3292d5d --- /dev/null +++ b/target/doc/ppv_lite86/types/trait.BSwap.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ppv_lite86/trait.BSwap.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/trait.BitOps0.html b/target/doc/ppv_lite86/types/trait.BitOps0.html new file mode 100644 index 0000000..84e8bbd --- /dev/null +++ b/target/doc/ppv_lite86/types/trait.BitOps0.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ppv_lite86/trait.BitOps0.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/trait.BitOps128.html b/target/doc/ppv_lite86/types/trait.BitOps128.html new file mode 100644 index 0000000..6efef31 --- /dev/null +++ b/target/doc/ppv_lite86/types/trait.BitOps128.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ppv_lite86/trait.BitOps128.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/trait.BitOps32.html b/target/doc/ppv_lite86/types/trait.BitOps32.html new file mode 100644 index 0000000..760de68 --- /dev/null +++ b/target/doc/ppv_lite86/types/trait.BitOps32.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ppv_lite86/trait.BitOps32.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/trait.BitOps64.html b/target/doc/ppv_lite86/types/trait.BitOps64.html new file mode 100644 index 0000000..db252e0 --- /dev/null +++ b/target/doc/ppv_lite86/types/trait.BitOps64.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ppv_lite86/trait.BitOps64.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/trait.Machine.html b/target/doc/ppv_lite86/types/trait.Machine.html new file mode 100644 index 0000000..482f6ca --- /dev/null +++ b/target/doc/ppv_lite86/types/trait.Machine.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ppv_lite86/trait.Machine.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/trait.RotateEachWord128.html b/target/doc/ppv_lite86/types/trait.RotateEachWord128.html new file mode 100644 index 0000000..5b8e3fe --- /dev/null +++ b/target/doc/ppv_lite86/types/trait.RotateEachWord128.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ppv_lite86/trait.RotateEachWord128.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/trait.RotateEachWord32.html b/target/doc/ppv_lite86/types/trait.RotateEachWord32.html new file mode 100644 index 0000000..2735dc8 --- /dev/null +++ b/target/doc/ppv_lite86/types/trait.RotateEachWord32.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ppv_lite86/trait.RotateEachWord32.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/trait.RotateEachWord64.html b/target/doc/ppv_lite86/types/trait.RotateEachWord64.html new file mode 100644 index 0000000..12a99bd --- /dev/null +++ b/target/doc/ppv_lite86/types/trait.RotateEachWord64.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ppv_lite86/trait.RotateEachWord64.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/trait.Store.html b/target/doc/ppv_lite86/types/trait.Store.html new file mode 100644 index 0000000..1a7fb53 --- /dev/null +++ b/target/doc/ppv_lite86/types/trait.Store.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ppv_lite86/trait.Store.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/trait.StoreBytes.html b/target/doc/ppv_lite86/types/trait.StoreBytes.html new file mode 100644 index 0000000..ada0f31 --- /dev/null +++ b/target/doc/ppv_lite86/types/trait.StoreBytes.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ppv_lite86/trait.StoreBytes.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/types/trait.LaneWords4.html b/target/doc/ppv_lite86/types/types/trait.LaneWords4.html new file mode 100644 index 0000000..c36354f --- /dev/null +++ b/target/doc/ppv_lite86/types/types/trait.LaneWords4.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../ppv_lite86/trait.LaneWords4.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/types/trait.MultiLane.html b/target/doc/ppv_lite86/types/types/trait.MultiLane.html new file mode 100644 index 0000000..a75df3d --- /dev/null +++ b/target/doc/ppv_lite86/types/types/trait.MultiLane.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../ppv_lite86/trait.MultiLane.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/types/trait.Swap64.html b/target/doc/ppv_lite86/types/types/trait.Swap64.html new file mode 100644 index 0000000..8fba0e4 --- /dev/null +++ b/target/doc/ppv_lite86/types/types/trait.Swap64.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../ppv_lite86/trait.Swap64.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/types/trait.UnsafeFrom.html b/target/doc/ppv_lite86/types/types/trait.UnsafeFrom.html new file mode 100644 index 0000000..043851f --- /dev/null +++ b/target/doc/ppv_lite86/types/types/trait.UnsafeFrom.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../ppv_lite86/trait.UnsafeFrom.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/types/trait.VZip.html b/target/doc/ppv_lite86/types/types/trait.VZip.html new file mode 100644 index 0000000..8d84353 --- /dev/null +++ b/target/doc/ppv_lite86/types/types/trait.VZip.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../ppv_lite86/trait.VZip.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/types/trait.Vec2.html b/target/doc/ppv_lite86/types/types/trait.Vec2.html new file mode 100644 index 0000000..190d053 --- /dev/null +++ b/target/doc/ppv_lite86/types/types/trait.Vec2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../ppv_lite86/trait.Vec2.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/types/trait.Vec4.html b/target/doc/ppv_lite86/types/types/trait.Vec4.html new file mode 100644 index 0000000..ad29f65 --- /dev/null +++ b/target/doc/ppv_lite86/types/types/trait.Vec4.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../ppv_lite86/trait.Vec4.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/types/trait.Words4.html b/target/doc/ppv_lite86/types/types/trait.Words4.html new file mode 100644 index 0000000..d2a1f05 --- /dev/null +++ b/target/doc/ppv_lite86/types/types/trait.Words4.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../ppv_lite86/trait.Words4.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/types/trait.u128x1.html b/target/doc/ppv_lite86/types/types/trait.u128x1.html new file mode 100644 index 0000000..03cccc5 --- /dev/null +++ b/target/doc/ppv_lite86/types/types/trait.u128x1.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../ppv_lite86/trait.u128x1.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/types/trait.u128x2.html b/target/doc/ppv_lite86/types/types/trait.u128x2.html new file mode 100644 index 0000000..f642cbf --- /dev/null +++ b/target/doc/ppv_lite86/types/types/trait.u128x2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../ppv_lite86/trait.u128x2.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/types/trait.u128x4.html b/target/doc/ppv_lite86/types/types/trait.u128x4.html new file mode 100644 index 0000000..2ace43f --- /dev/null +++ b/target/doc/ppv_lite86/types/types/trait.u128x4.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../ppv_lite86/trait.u128x4.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/types/trait.u32x4.html b/target/doc/ppv_lite86/types/types/trait.u32x4.html new file mode 100644 index 0000000..37b6bab --- /dev/null +++ b/target/doc/ppv_lite86/types/types/trait.u32x4.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../ppv_lite86/trait.u32x4.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/types/trait.u32x4x2.html b/target/doc/ppv_lite86/types/types/trait.u32x4x2.html new file mode 100644 index 0000000..d1f6859 --- /dev/null +++ b/target/doc/ppv_lite86/types/types/trait.u32x4x2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../ppv_lite86/trait.u32x4x2.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/types/trait.u32x4x4.html b/target/doc/ppv_lite86/types/types/trait.u32x4x4.html new file mode 100644 index 0000000..f41a5e2 --- /dev/null +++ b/target/doc/ppv_lite86/types/types/trait.u32x4x4.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../ppv_lite86/trait.u32x4x4.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/types/trait.u64x2.html b/target/doc/ppv_lite86/types/types/trait.u64x2.html new file mode 100644 index 0000000..9fadd83 --- /dev/null +++ b/target/doc/ppv_lite86/types/types/trait.u64x2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../ppv_lite86/trait.u64x2.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/types/trait.u64x2x2.html b/target/doc/ppv_lite86/types/types/trait.u64x2x2.html new file mode 100644 index 0000000..1fa4920 --- /dev/null +++ b/target/doc/ppv_lite86/types/types/trait.u64x2x2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../ppv_lite86/trait.u64x2x2.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/types/trait.u64x2x4.html b/target/doc/ppv_lite86/types/types/trait.u64x2x4.html new file mode 100644 index 0000000..acc2277 --- /dev/null +++ b/target/doc/ppv_lite86/types/types/trait.u64x2x4.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../ppv_lite86/trait.u64x2x4.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/types/types/trait.u64x4.html b/target/doc/ppv_lite86/types/types/trait.u64x4.html new file mode 100644 index 0000000..833802d --- /dev/null +++ b/target/doc/ppv_lite86/types/types/trait.u64x4.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../ppv_lite86/trait.u64x4.html...

+ + + \ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/index.html b/target/doc/ppv_lite86/x86_64/index.html new file mode 100644 index 0000000..7109e69 --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/index.html @@ -0,0 +1,9 @@ +ppv_lite86::x86_64 - Rust

[][src]Module ppv_lite86::x86_64

Structs

+
Avx2Machine
NoA1
NoA2
NoNI
NoS3
NoS4
SseMachine
YesA1
YesA2
YesNI
YesS3
YesS4

Type Definitions

+
AVX

AVX but not AVX2: only 128-bit integer operations, but use VEX versions of everything +to avoid expensive SSE/VEX conflicts.

+
AVX2
SSE2
SSE41
SSSE3

Unions

+
vec128_storage

Generic wrapper for unparameterized storage of any of the possible impls. +Converting into and out of this type should be essentially free, although it may be more +aligned than a particular impl requires.

+
vec256_storage
vec512_storage
\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/sidebar-items.js b/target/doc/ppv_lite86/x86_64/sidebar-items.js new file mode 100644 index 0000000..c295d30 --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["Avx2Machine",""],["NoA1",""],["NoA2",""],["NoNI",""],["NoS3",""],["NoS4",""],["SseMachine",""],["YesA1",""],["YesA2",""],["YesNI",""],["YesS3",""],["YesS4",""]],"type":[["AVX","AVX but not AVX2: only 128-bit integer operations, but use VEX versions of everything to avoid expensive SSE/VEX conflicts."],["AVX2",""],["SSE2",""],["SSE41",""],["SSSE3",""]],"union":[["vec128_storage","Generic wrapper for unparameterized storage of any of the possible impls. Converting into and out of this type should be essentially free, although it may be more aligned than a particular impl requires."],["vec256_storage",""],["vec512_storage",""]]}); \ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/struct.Avx2Machine.html b/target/doc/ppv_lite86/x86_64/struct.Avx2Machine.html new file mode 100644 index 0000000..b14259e --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/struct.Avx2Machine.html @@ -0,0 +1,12 @@ +ppv_lite86::x86_64::Avx2Machine - Rust

[][src]Struct ppv_lite86::x86_64::Avx2Machine

pub struct Avx2Machine<NI>(_);

Trait Implementations

impl<NI: Copy> Machine for Avx2Machine<NI> where
    u128x1_sse2<YesS3, YesS4, NI>: BSwap + Swap64,
    u64x2_sse2<YesS3, YesS4, NI>: BSwap + RotateEachWord32 + MultiLane<[u64; 2]> + Vec2<u64>,
    u32x4_sse2<YesS3, YesS4, NI>: BSwap + RotateEachWord32 + MultiLane<[u32; 4]> + Vec4<u32>,
    x2<u64x2_sse2<YesS3, YesS4, NI>, G1>: BSwap + Words4
[src]

type u32x4 = u32x4_sse2<YesS3, YesS4, NI>

type u64x2 = u64x2_sse2<YesS3, YesS4, NI>

type u128x1 = u128x1_sse2<YesS3, YesS4, NI>

type u32x4x2 = x2<u32x4_sse2<YesS3, YesS4, NI>, G0>

type u64x2x2 = x2<u64x2_sse2<YesS3, YesS4, NI>, G0>

type u64x4 = x2<u64x2_sse2<YesS3, YesS4, NI>, G1>

type u128x2 = x2<u128x1_sse2<YesS3, YesS4, NI>, G0>

type u32x4x4 = u32x4x4_avx2<NI>

type u64x2x4 = x4<u64x2_sse2<YesS3, YesS4, NI>>

type u128x4 = x4<u128x1_sse2<YesS3, YesS4, NI>>

fn unpack<S, V: Store<S>>(self, s: S) -> V[src]

fn vec<V, A>(self, a: A) -> V where
    V: MultiLane<A>, 
[src]

fn read_le<V>(self, input: &[u8]) -> V where
    V: StoreBytes
[src]

fn read_be<V>(self, input: &[u8]) -> V where
    V: StoreBytes
[src]

impl<NI: Copy> Copy for Avx2Machine<NI>[src]

impl<NI: Clone> Clone for Avx2Machine<NI>[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

Auto Trait Implementations

impl<NI> Send for Avx2Machine<NI> where
    NI: Send

impl<NI> Sync for Avx2Machine<NI> where
    NI: Sync

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/struct.NoA1.html b/target/doc/ppv_lite86/x86_64/struct.NoA1.html new file mode 100644 index 0000000..d6079db --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/struct.NoA1.html @@ -0,0 +1,12 @@ +ppv_lite86::x86_64::NoA1 - Rust

[][src]Struct ppv_lite86::x86_64::NoA1

pub struct NoA1;

Trait Implementations

impl Copy for NoA1[src]

impl Clone for NoA1[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

Auto Trait Implementations

impl Send for NoA1

impl Sync for NoA1

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/struct.NoA2.html b/target/doc/ppv_lite86/x86_64/struct.NoA2.html new file mode 100644 index 0000000..f89865e --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/struct.NoA2.html @@ -0,0 +1,12 @@ +ppv_lite86::x86_64::NoA2 - Rust

[][src]Struct ppv_lite86::x86_64::NoA2

pub struct NoA2;

Trait Implementations

impl Copy for NoA2[src]

impl Clone for NoA2[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

Auto Trait Implementations

impl Send for NoA2

impl Sync for NoA2

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/struct.NoNI.html b/target/doc/ppv_lite86/x86_64/struct.NoNI.html new file mode 100644 index 0000000..b0ebea9 --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/struct.NoNI.html @@ -0,0 +1,12 @@ +ppv_lite86::x86_64::NoNI - Rust

[][src]Struct ppv_lite86::x86_64::NoNI

pub struct NoNI;

Trait Implementations

impl Copy for NoNI[src]

impl Clone for NoNI[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

Auto Trait Implementations

impl Send for NoNI

impl Sync for NoNI

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/struct.NoS3.html b/target/doc/ppv_lite86/x86_64/struct.NoS3.html new file mode 100644 index 0000000..e5bb2dc --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/struct.NoS3.html @@ -0,0 +1,12 @@ +ppv_lite86::x86_64::NoS3 - Rust

[][src]Struct ppv_lite86::x86_64::NoS3

pub struct NoS3;

Trait Implementations

impl Copy for NoS3[src]

impl Clone for NoS3[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

Auto Trait Implementations

impl Send for NoS3

impl Sync for NoS3

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/struct.NoS4.html b/target/doc/ppv_lite86/x86_64/struct.NoS4.html new file mode 100644 index 0000000..bbf1321 --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/struct.NoS4.html @@ -0,0 +1,12 @@ +ppv_lite86::x86_64::NoS4 - Rust

[][src]Struct ppv_lite86::x86_64::NoS4

pub struct NoS4;

Trait Implementations

impl Copy for NoS4[src]

impl Clone for NoS4[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

Auto Trait Implementations

impl Send for NoS4

impl Sync for NoS4

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/struct.SseMachine.html b/target/doc/ppv_lite86/x86_64/struct.SseMachine.html new file mode 100644 index 0000000..4aa6ad0 --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/struct.SseMachine.html @@ -0,0 +1,12 @@ +ppv_lite86::x86_64::SseMachine - Rust

[][src]Struct ppv_lite86::x86_64::SseMachine

pub struct SseMachine<S3, S4, NI>(_);

Trait Implementations

impl<S3: Copy, S4: Copy, NI: Copy> Machine for SseMachine<S3, S4, NI> where
    u128x1_sse2<S3, S4, NI>: Swap64,
    u64x2_sse2<S3, S4, NI>: BSwap + RotateEachWord32 + MultiLane<[u64; 2]> + Vec2<u64>,
    u32x4_sse2<S3, S4, NI>: BSwap + RotateEachWord32 + MultiLane<[u32; 4]> + Vec4<u32>,
    x2<u64x2_sse2<S3, S4, NI>, G1>: BSwap + Words4,
    u128x1_sse2<S3, S4, NI>: BSwap,
    x2<u128x1_sse2<S3, S4, NI>, G0>: Into<x2<u64x2_sse2<S3, S4, NI>, G0>>,
    x2<u128x1_sse2<S3, S4, NI>, G0>: Into<x2<u64x2_sse2<S3, S4, NI>, G1>>,
    x2<u128x1_sse2<S3, S4, NI>, G0>: Into<x2<u32x4_sse2<S3, S4, NI>, G0>>,
    x4<u128x1_sse2<S3, S4, NI>>: Into<x4<u64x2_sse2<S3, S4, NI>>>,
    x4<u128x1_sse2<S3, S4, NI>>: Into<x4<u32x4_sse2<S3, S4, NI>>>, 
[src]

type u32x4 = u32x4_sse2<S3, S4, NI>

type u64x2 = u64x2_sse2<S3, S4, NI>

type u128x1 = u128x1_sse2<S3, S4, NI>

type u32x4x2 = x2<u32x4_sse2<S3, S4, NI>, G0>

type u64x2x2 = x2<u64x2_sse2<S3, S4, NI>, G0>

type u64x4 = x2<u64x2_sse2<S3, S4, NI>, G1>

type u128x2 = x2<u128x1_sse2<S3, S4, NI>, G0>

type u32x4x4 = x4<u32x4_sse2<S3, S4, NI>>

type u64x2x4 = x4<u64x2_sse2<S3, S4, NI>>

type u128x4 = x4<u128x1_sse2<S3, S4, NI>>

fn unpack<S, V: Store<S>>(self, s: S) -> V[src]

fn vec<V, A>(self, a: A) -> V where
    V: MultiLane<A>, 
[src]

fn read_le<V>(self, input: &[u8]) -> V where
    V: StoreBytes
[src]

fn read_be<V>(self, input: &[u8]) -> V where
    V: StoreBytes
[src]

impl<S3: Copy, S4: Copy, NI: Copy> Copy for SseMachine<S3, S4, NI>[src]

impl<S3: Clone, S4: Clone, NI: Clone> Clone for SseMachine<S3, S4, NI>[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

Auto Trait Implementations

impl<S3, S4, NI> Send for SseMachine<S3, S4, NI> where
    NI: Send,
    S3: Send,
    S4: Send

impl<S3, S4, NI> Sync for SseMachine<S3, S4, NI> where
    NI: Sync,
    S3: Sync,
    S4: Sync

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/struct.YesA1.html b/target/doc/ppv_lite86/x86_64/struct.YesA1.html new file mode 100644 index 0000000..93d9b67 --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/struct.YesA1.html @@ -0,0 +1,12 @@ +ppv_lite86::x86_64::YesA1 - Rust

[][src]Struct ppv_lite86::x86_64::YesA1

pub struct YesA1;

Trait Implementations

impl Copy for YesA1[src]

impl Clone for YesA1[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

Auto Trait Implementations

impl Send for YesA1

impl Sync for YesA1

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/struct.YesA2.html b/target/doc/ppv_lite86/x86_64/struct.YesA2.html new file mode 100644 index 0000000..d883737 --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/struct.YesA2.html @@ -0,0 +1,12 @@ +ppv_lite86::x86_64::YesA2 - Rust

[][src]Struct ppv_lite86::x86_64::YesA2

pub struct YesA2;

Trait Implementations

impl Copy for YesA2[src]

impl Clone for YesA2[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

Auto Trait Implementations

impl Send for YesA2

impl Sync for YesA2

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/struct.YesNI.html b/target/doc/ppv_lite86/x86_64/struct.YesNI.html new file mode 100644 index 0000000..57474dd --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/struct.YesNI.html @@ -0,0 +1,12 @@ +ppv_lite86::x86_64::YesNI - Rust

[][src]Struct ppv_lite86::x86_64::YesNI

pub struct YesNI;

Trait Implementations

impl Copy for YesNI[src]

impl Clone for YesNI[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

Auto Trait Implementations

impl Send for YesNI

impl Sync for YesNI

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/struct.YesS3.html b/target/doc/ppv_lite86/x86_64/struct.YesS3.html new file mode 100644 index 0000000..858103f --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/struct.YesS3.html @@ -0,0 +1,12 @@ +ppv_lite86::x86_64::YesS3 - Rust

[][src]Struct ppv_lite86::x86_64::YesS3

pub struct YesS3;

Trait Implementations

impl Copy for YesS3[src]

impl Clone for YesS3[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

Auto Trait Implementations

impl Send for YesS3

impl Sync for YesS3

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/struct.YesS4.html b/target/doc/ppv_lite86/x86_64/struct.YesS4.html new file mode 100644 index 0000000..4fa9fec --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/struct.YesS4.html @@ -0,0 +1,12 @@ +ppv_lite86::x86_64::YesS4 - Rust

[][src]Struct ppv_lite86::x86_64::YesS4

pub struct YesS4;

Trait Implementations

impl Copy for YesS4[src]

impl Clone for YesS4[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

Auto Trait Implementations

impl Send for YesS4

impl Sync for YesS4

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/type.AVX.html b/target/doc/ppv_lite86/x86_64/type.AVX.html new file mode 100644 index 0000000..abf05f9 --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/type.AVX.html @@ -0,0 +1,3 @@ +ppv_lite86::x86_64::AVX - Rust

[][src]Type Definition ppv_lite86::x86_64::AVX

type AVX = SseMachine<YesS3, YesS4, NoNI>;

AVX but not AVX2: only 128-bit integer operations, but use VEX versions of everything +to avoid expensive SSE/VEX conflicts.

+
\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/type.AVX2.html b/target/doc/ppv_lite86/x86_64/type.AVX2.html new file mode 100644 index 0000000..58b4918 --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/type.AVX2.html @@ -0,0 +1 @@ +ppv_lite86::x86_64::AVX2 - Rust

[][src]Type Definition ppv_lite86::x86_64::AVX2

type AVX2 = Avx2Machine<NoNI>;
\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/type.SSE2.html b/target/doc/ppv_lite86/x86_64/type.SSE2.html new file mode 100644 index 0000000..cf87241 --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/type.SSE2.html @@ -0,0 +1 @@ +ppv_lite86::x86_64::SSE2 - Rust

[][src]Type Definition ppv_lite86::x86_64::SSE2

type SSE2 = SseMachine<NoS3, NoS4, NoNI>;
\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/type.SSE41.html b/target/doc/ppv_lite86/x86_64/type.SSE41.html new file mode 100644 index 0000000..af9d3bd --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/type.SSE41.html @@ -0,0 +1 @@ +ppv_lite86::x86_64::SSE41 - Rust

[][src]Type Definition ppv_lite86::x86_64::SSE41

type SSE41 = SseMachine<YesS3, YesS4, NoNI>;
\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/type.SSSE3.html b/target/doc/ppv_lite86/x86_64/type.SSSE3.html new file mode 100644 index 0000000..1040dcb --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/type.SSSE3.html @@ -0,0 +1 @@ +ppv_lite86::x86_64::SSSE3 - Rust

[][src]Type Definition ppv_lite86::x86_64::SSSE3

type SSSE3 = SseMachine<YesS3, NoS4, NoNI>;
\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/union.vec128_storage.html b/target/doc/ppv_lite86/x86_64/union.vec128_storage.html new file mode 100644 index 0000000..6d704d2 --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/union.vec128_storage.html @@ -0,0 +1,23 @@ +ppv_lite86::x86_64::vec128_storage - Rust

[][src]Union ppv_lite86::x86_64::vec128_storage

pub union vec128_storage {
+    // some fields omitted
+}

Generic wrapper for unparameterized storage of any of the possible impls. +Converting into and out of this type should be essentially free, although it may be more +aligned than a particular impl requires.

+

Trait Implementations

impl Store<vec128_storage> for vec128_storage[src]

impl Copy for vec128_storage[src]

impl<'a> Into<&'a [u32; 4]> for &'a vec128_storage[src]

impl Into<vec128_storage> for [u32; 4][src]

impl Into<[u32; 4]> for vec128_storage[src]

impl Into<[u64; 2]> for vec128_storage[src]

impl Into<[u128; 1]> for vec128_storage[src]

impl Clone for vec128_storage[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Default for vec128_storage[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/union.vec256_storage.html b/target/doc/ppv_lite86/x86_64/union.vec256_storage.html new file mode 100644 index 0000000..cda173e --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/union.vec256_storage.html @@ -0,0 +1,19 @@ +ppv_lite86::x86_64::vec256_storage - Rust

[][src]Union ppv_lite86::x86_64::vec256_storage

pub union vec256_storage {
+    // some fields omitted
+}

Methods

impl vec256_storage[src]

pub fn new128(xs: [vec128_storage; 2]) -> Self[src]

pub fn split128(self) -> [vec128_storage; 2][src]

Trait Implementations

impl Copy for vec256_storage[src]

impl Into<vec256_storage> for [u64; 4][src]

impl Into<[u32; 8]> for vec256_storage[src]

impl Into<[u64; 4]> for vec256_storage[src]

impl Into<[u128; 2]> for vec256_storage[src]

impl Clone for vec256_storage[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Default for vec256_storage[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/ppv_lite86/x86_64/union.vec512_storage.html b/target/doc/ppv_lite86/x86_64/union.vec512_storage.html new file mode 100644 index 0000000..7b0635e --- /dev/null +++ b/target/doc/ppv_lite86/x86_64/union.vec512_storage.html @@ -0,0 +1,18 @@ +ppv_lite86::x86_64::vec512_storage - Rust

[][src]Union ppv_lite86::x86_64::vec512_storage

pub union vec512_storage {
+    // some fields omitted
+}

Methods

impl vec512_storage[src]

pub fn new128(xs: [vec128_storage; 4]) -> Self[src]

pub fn split128(self) -> [vec128_storage; 4][src]

Trait Implementations

impl Copy for vec512_storage[src]

impl Into<[u32; 16]> for vec512_storage[src]

impl Into<[u64; 8]> for vec512_storage[src]

impl Into<[u128; 4]> for vec512_storage[src]

impl Clone for vec512_storage[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Default for vec512_storage[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/rand/all.html b/target/doc/rand/all.html new file mode 100644 index 0000000..2f3582f --- /dev/null +++ b/target/doc/rand/all.html @@ -0,0 +1,3 @@ +List of all items in this crate

[] + + List of all items

Structs

Enums

Traits

Functions

\ No newline at end of file diff --git a/target/doc/rand/distributions/bernoulli/enum.BernoulliError.html b/target/doc/rand/distributions/bernoulli/enum.BernoulliError.html new file mode 100644 index 0000000..81d8b1a --- /dev/null +++ b/target/doc/rand/distributions/bernoulli/enum.BernoulliError.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/enum.BernoulliError.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/bernoulli/struct.Bernoulli.html b/target/doc/rand/distributions/bernoulli/struct.Bernoulli.html new file mode 100644 index 0000000..353c860 --- /dev/null +++ b/target/doc/rand/distributions/bernoulli/struct.Bernoulli.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.Bernoulli.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/binomial/struct.Binomial.html b/target/doc/rand/distributions/binomial/struct.Binomial.html new file mode 100644 index 0000000..feaeb25 --- /dev/null +++ b/target/doc/rand/distributions/binomial/struct.Binomial.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.Binomial.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/cauchy/struct.Cauchy.html b/target/doc/rand/distributions/cauchy/struct.Cauchy.html new file mode 100644 index 0000000..3c53192 --- /dev/null +++ b/target/doc/rand/distributions/cauchy/struct.Cauchy.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.Cauchy.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/dirichlet/struct.Dirichlet.html b/target/doc/rand/distributions/dirichlet/struct.Dirichlet.html new file mode 100644 index 0000000..d7aec24 --- /dev/null +++ b/target/doc/rand/distributions/dirichlet/struct.Dirichlet.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.Dirichlet.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/enum.BernoulliError.html b/target/doc/rand/distributions/enum.BernoulliError.html new file mode 100644 index 0000000..c96af66 --- /dev/null +++ b/target/doc/rand/distributions/enum.BernoulliError.html @@ -0,0 +1,26 @@ +rand::distributions::BernoulliError - Rust

[][src]Enum rand::distributions::BernoulliError

pub enum BernoulliError {
+    InvalidProbability,
+}

Error type returned from Bernoulli::new.

+

+ Variants

+InvalidProbability

p < 0 or p > 1.

+

Trait Implementations

impl PartialEq<BernoulliError> for BernoulliError[src]

#[must_use] +
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests for !=.

+

impl Clone for BernoulliError[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for BernoulliError[src]

impl Copy for BernoulliError[src]

impl Debug for BernoulliError[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/exponential/struct.Exp.html b/target/doc/rand/distributions/exponential/struct.Exp.html new file mode 100644 index 0000000..ef7ec09 --- /dev/null +++ b/target/doc/rand/distributions/exponential/struct.Exp.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.Exp.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/exponential/struct.Exp1.html b/target/doc/rand/distributions/exponential/struct.Exp1.html new file mode 100644 index 0000000..4a37585 --- /dev/null +++ b/target/doc/rand/distributions/exponential/struct.Exp1.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.Exp1.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/float/struct.Open01.html b/target/doc/rand/distributions/float/struct.Open01.html new file mode 100644 index 0000000..0ae8fd8 --- /dev/null +++ b/target/doc/rand/distributions/float/struct.Open01.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.Open01.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/float/struct.OpenClosed01.html b/target/doc/rand/distributions/float/struct.OpenClosed01.html new file mode 100644 index 0000000..02c6d2e --- /dev/null +++ b/target/doc/rand/distributions/float/struct.OpenClosed01.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.OpenClosed01.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/gamma/struct.Beta.html b/target/doc/rand/distributions/gamma/struct.Beta.html new file mode 100644 index 0000000..9505d2a --- /dev/null +++ b/target/doc/rand/distributions/gamma/struct.Beta.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.Beta.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/gamma/struct.ChiSquared.html b/target/doc/rand/distributions/gamma/struct.ChiSquared.html new file mode 100644 index 0000000..511b55f --- /dev/null +++ b/target/doc/rand/distributions/gamma/struct.ChiSquared.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.ChiSquared.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/gamma/struct.FisherF.html b/target/doc/rand/distributions/gamma/struct.FisherF.html new file mode 100644 index 0000000..1df8e81 --- /dev/null +++ b/target/doc/rand/distributions/gamma/struct.FisherF.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.FisherF.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/gamma/struct.Gamma.html b/target/doc/rand/distributions/gamma/struct.Gamma.html new file mode 100644 index 0000000..7e2d784 --- /dev/null +++ b/target/doc/rand/distributions/gamma/struct.Gamma.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.Gamma.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/gamma/struct.StudentT.html b/target/doc/rand/distributions/gamma/struct.StudentT.html new file mode 100644 index 0000000..498dc52 --- /dev/null +++ b/target/doc/rand/distributions/gamma/struct.StudentT.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.StudentT.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/index.html b/target/doc/rand/distributions/index.html new file mode 100644 index 0000000..67584b7 --- /dev/null +++ b/target/doc/rand/distributions/index.html @@ -0,0 +1,103 @@ +rand::distributions - Rust

[][src]Module rand::distributions

Generating random samples from probability distributions

+

This module is the home of the [Distribution] trait and several of its +implementations. It is the workhorse behind some of the convenient +functionality of the [Rng] trait, e.g. [Rng::gen], [Rng::gen_range] and +of course [Rng::sample].

+

Abstractly, a probability distribution describes the probability of +occurance of each value in its sample space.

+

More concretely, an implementation of Distribution<T> for type X is an +algorithm for choosing values from the sample space (a subset of T) +according to the distribution X represents, using an external source of +randomness (an RNG supplied to the sample function).

+

A type X may implement Distribution<T> for multiple types T. +Any type implementing [Distribution] is stateless (i.e. immutable), +but it may have internal parameters set at construction time (for example, +Uniform allows specification of its sample space as a range within T).

+

The Standard distribution

+

The Standard distribution is important to mention. This is the +distribution used by [Rng::gen()] and represents the "default" way to +produce a random value for many different types, including most primitive +types, tuples, arrays, and a few derived types. See the documentation of +Standard for more details.

+

Implementing Distribution<T> for Standard for user types T makes it +possible to generate type T with [Rng::gen()], and by extension also +with the [random()] function.

+

Random characters

+

Alphanumeric is a simple distribution to sample random letters and +numbers of the char type; in contrast Standard may sample any valid +char.

+

Uniform numeric ranges

+

The Uniform distribution is more flexible than Standard, but also +more specialised: it supports fewer target types, but allows the sample +space to be specified as an arbitrary range within its target type T. +Both Standard and Uniform are in some sense uniform distributions.

+

Values may be sampled from this distribution using [Rng::gen_range] or +by creating a distribution object with Uniform::new, +Uniform::new_inclusive or From<Range>. When the range limits are not +known at compile time it is typically faster to reuse an existing +distribution object than to call [Rng::gen_range].

+

User types T may also implement Distribution<T> for Uniform, +although this is less straightforward than for Standard (see the +documentation in the uniform module. Doing so enables generation of +values of type T with [Rng::gen_range].

+

Open and half-open ranges

+

There are surprisingly many ways to uniformly generate random floats. A +range between 0 and 1 is standard, but the exact bounds (open vs closed) +and accuracy differ. In addition to the Standard distribution Rand offers +Open01 and OpenClosed01. See "Floating point implementation" section of +Standard documentation for more details.

+

Non-uniform sampling

+

Sampling a simple true/false outcome with a given probability has a name: +the Bernoulli distribution (this is used by [Rng::gen_bool]).

+

For weighted sampling from a sequence of discrete values, use the +weighted module.

+

This crate no longer includes other non-uniform distributions; instead +it is recommended that you use either rand_distr or statrs.

+

Re-exports

+
pub use self::weighted::WeightedIndex;
pub use self::weighted::WeightedError;

Modules

+
uniform

A distribution uniformly sampling numbers within a given range.

+
weighted

Weighted index sampling

+

Structs

+
Alphanumeric

Sample a char, uniformly distributed over ASCII letters and numbers: +a-z, A-Z and 0-9.

+
Bernoulli

The Bernoulli distribution.

+
BetaDeprecated

The Beta distribution with shape parameters alpha and beta.

+
BinomialDeprecated

The binomial distribution Binomial(n, p).

+
CauchyDeprecated

The Cauchy distribution Cauchy(median, scale).

+
ChiSquaredDeprecated

The chi-squared distribution χ²(k), where k is the degrees of +freedom.

+
DirichletDeprecated

The dirichelet distribution Dirichlet(alpha).

+
DistIter

An iterator that generates random values of T with distribution D, +using R as the source of randomness.

+
ExpDeprecated

The exponential distribution Exp(lambda).

+
Exp1Deprecated

Samples floating-point numbers according to the exponential distribution, +with rate parameter λ = 1. This is equivalent to Exp::new(1.0) or +sampling with -rng.gen::<f64>().ln(), but faster.

+
FisherFDeprecated

The Fisher F distribution F(m, n).

+
GammaDeprecated

The Gamma distribution Gamma(shape, scale) distribution.

+
LogNormalDeprecated

The log-normal distribution ln N(mean, std_dev**2).

+
NormalDeprecated

The normal distribution N(mean, std_dev**2).

+
Open01

A distribution to sample floating point numbers uniformly in the open +interval (0, 1), i.e. not including either endpoint.

+
OpenClosed01

A distribution to sample floating point numbers uniformly in the half-open +interval (0, 1], i.e. including 1 but not 0.

+
ParetoDeprecated

Samples floating-point numbers according to the Pareto distribution

+
PoissonDeprecated

The Poisson distribution Poisson(lambda).

+
Standard

A generic random value distribution, implemented for many primitive types. +Usually generates values with a numerically uniform distribution, and with a +range appropriate to the type.

+
StandardNormalDeprecated

Samples floating-point numbers according to the normal distribution +N(0, 1) (a.k.a. a standard normal, or Gaussian). This is equivalent to +Normal::new(0.0, 1.0) but faster.

+
StudentTDeprecated

The Student t distribution, t(nu), where nu is the degrees of +freedom.

+
TriangularDeprecated

The triangular distribution.

+
Uniform

Sample values uniformly between two bounds.

+
UnitCircleDeprecated

Samples uniformly from the edge of the unit circle in two dimensions.

+
UnitSphereSurfaceDeprecated

Samples uniformly from the surface of the unit sphere in three dimensions.

+
WeibullDeprecated

Samples floating-point numbers according to the Weibull distribution

+

Enums

+
BernoulliError

Error type returned from Bernoulli::new.

+

Traits

+
Distribution

Types (distributions) that can be used to create a random instance of T.

+
\ No newline at end of file diff --git a/target/doc/rand/distributions/normal/struct.LogNormal.html b/target/doc/rand/distributions/normal/struct.LogNormal.html new file mode 100644 index 0000000..54c86c7 --- /dev/null +++ b/target/doc/rand/distributions/normal/struct.LogNormal.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.LogNormal.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/normal/struct.Normal.html b/target/doc/rand/distributions/normal/struct.Normal.html new file mode 100644 index 0000000..e6db1ff --- /dev/null +++ b/target/doc/rand/distributions/normal/struct.Normal.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.Normal.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/normal/struct.StandardNormal.html b/target/doc/rand/distributions/normal/struct.StandardNormal.html new file mode 100644 index 0000000..2565372 --- /dev/null +++ b/target/doc/rand/distributions/normal/struct.StandardNormal.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.StandardNormal.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/other/struct.Alphanumeric.html b/target/doc/rand/distributions/other/struct.Alphanumeric.html new file mode 100644 index 0000000..f921312 --- /dev/null +++ b/target/doc/rand/distributions/other/struct.Alphanumeric.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.Alphanumeric.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/pareto/struct.Pareto.html b/target/doc/rand/distributions/pareto/struct.Pareto.html new file mode 100644 index 0000000..8276bae --- /dev/null +++ b/target/doc/rand/distributions/pareto/struct.Pareto.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.Pareto.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/poisson/struct.Poisson.html b/target/doc/rand/distributions/poisson/struct.Poisson.html new file mode 100644 index 0000000..79d474b --- /dev/null +++ b/target/doc/rand/distributions/poisson/struct.Poisson.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.Poisson.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/sidebar-items.js b/target/doc/rand/distributions/sidebar-items.js new file mode 100644 index 0000000..ce19081 --- /dev/null +++ b/target/doc/rand/distributions/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"enum":[["BernoulliError","Error type returned from `Bernoulli::new`."]],"mod":[["uniform","A distribution uniformly sampling numbers within a given range."],["weighted","Weighted index sampling"]],"struct":[["Alphanumeric","Sample a `char`, uniformly distributed over ASCII letters and numbers: a-z, A-Z and 0-9."],["Bernoulli","The Bernoulli distribution."],["Beta","The Beta distribution with shape parameters `alpha` and `beta`."],["Binomial","The binomial distribution `Binomial(n, p)`."],["Cauchy","The Cauchy distribution `Cauchy(median, scale)`."],["ChiSquared","The chi-squared distribution `χ²(k)`, where `k` is the degrees of freedom."],["Dirichlet","The dirichelet distribution `Dirichlet(alpha)`."],["DistIter","An iterator that generates random values of `T` with distribution `D`, using `R` as the source of randomness."],["Exp","The exponential distribution `Exp(lambda)`."],["Exp1","Samples floating-point numbers according to the exponential distribution, with rate parameter `λ = 1`. This is equivalent to `Exp::new(1.0)` or sampling with `-rng.gen::().ln()`, but faster."],["FisherF","The Fisher F distribution `F(m, n)`."],["Gamma","The Gamma distribution `Gamma(shape, scale)` distribution."],["LogNormal","The log-normal distribution `ln N(mean, std_dev**2)`."],["Normal","The normal distribution `N(mean, std_dev**2)`."],["Open01","A distribution to sample floating point numbers uniformly in the open interval `(0, 1)`, i.e. not including either endpoint."],["OpenClosed01","A distribution to sample floating point numbers uniformly in the half-open interval `(0, 1]`, i.e. including 1 but not 0."],["Pareto","Samples floating-point numbers according to the Pareto distribution"],["Poisson","The Poisson distribution `Poisson(lambda)`."],["Standard","A generic random value distribution, implemented for many primitive types. Usually generates values with a numerically uniform distribution, and with a range appropriate to the type."],["StandardNormal","Samples floating-point numbers according to the normal distribution `N(0, 1)` (a.k.a. a standard normal, or Gaussian). This is equivalent to `Normal::new(0.0, 1.0)` but faster."],["StudentT","The Student t distribution, `t(nu)`, where `nu` is the degrees of freedom."],["Triangular","The triangular distribution."],["Uniform","Sample values uniformly between two bounds."],["UnitCircle","Samples uniformly from the edge of the unit circle in two dimensions."],["UnitSphereSurface","Samples uniformly from the surface of the unit sphere in three dimensions."],["Weibull","Samples floating-point numbers according to the Weibull distribution"]],"trait":[["Distribution","Types (distributions) that can be used to create a random instance of `T`."]]}); \ No newline at end of file diff --git a/target/doc/rand/distributions/struct.Alphanumeric.html b/target/doc/rand/distributions/struct.Alphanumeric.html new file mode 100644 index 0000000..a264bdc --- /dev/null +++ b/target/doc/rand/distributions/struct.Alphanumeric.html @@ -0,0 +1,27 @@ +rand::distributions::Alphanumeric - Rust

[][src]Struct rand::distributions::Alphanumeric

pub struct Alphanumeric;

Sample a char, uniformly distributed over ASCII letters and numbers: +a-z, A-Z and 0-9.

+

Example

+
+use std::iter;
+use rand::{Rng, thread_rng};
+use rand::distributions::Alphanumeric;
+ 
+let mut rng = thread_rng();
+let chars: String = iter::repeat(())
+        .map(|()| rng.sample(Alphanumeric))
+        .take(7)
+        .collect();
+println!("Random chars: {}", chars);
+

Trait Implementations

impl Distribution<char> for Alphanumeric[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Debug for Alphanumeric[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.Bernoulli.html b/target/doc/rand/distributions/struct.Bernoulli.html new file mode 100644 index 0000000..e4754ff --- /dev/null +++ b/target/doc/rand/distributions/struct.Bernoulli.html @@ -0,0 +1,44 @@ +rand::distributions::Bernoulli - Rust

[][src]Struct rand::distributions::Bernoulli

pub struct Bernoulli { /* fields omitted */ }

The Bernoulli distribution.

+

This is a special case of the Binomial distribution where n = 1.

+

Example

+
+use rand::distributions::{Bernoulli, Distribution};
+
+let d = Bernoulli::new(0.3).unwrap();
+let v = d.sample(&mut rand::thread_rng());
+println!("{} is from a Bernoulli distribution", v);
+

Precision

+

This Bernoulli distribution uses 64 bits from the RNG (a u64), +so only probabilities that are multiples of 2-64 can be +represented.

+

Methods

impl Bernoulli[src]

pub fn new(p: f64) -> Result<Bernoulli, BernoulliError>[src]

Construct a new Bernoulli with the given probability of success p.

+

Precision

+

For p = 1.0, the resulting distribution will always generate true. +For p = 0.0, the resulting distribution will always generate false.

+

This method is accurate for any input p in the range [0, 1] which is +a multiple of 2-64. (Note that not all multiples of +2-64 in [0, 1] can be represented as a f64.)

+

pub fn from_ratio(
    numerator: u32,
    denominator: u32
) -> Result<Bernoulli, BernoulliError>
[src]

Construct a new Bernoulli with the probability of success of +numerator-in-denominator. I.e. new_ratio(2, 3) will return +a Bernoulli with a 2-in-3 chance, or about 67%, of returning true.

+

If numerator == denominator then the returned Bernoulli will always +return true. If numerator == 0 it will always return false.

+

Trait Implementations

impl Distribution<bool> for Bernoulli[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for Bernoulli[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for Bernoulli[src]

impl Debug for Bernoulli[src]

Auto Trait Implementations

impl Send for Bernoulli

impl Sync for Bernoulli

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.Beta.html b/target/doc/rand/distributions/struct.Beta.html new file mode 100644 index 0000000..977a267 --- /dev/null +++ b/target/doc/rand/distributions/struct.Beta.html @@ -0,0 +1,24 @@ +rand::distributions::Beta - Rust

[][src]Struct rand::distributions::Beta

pub struct Beta { /* fields omitted */ }
Deprecated since 0.7.0:

moved to rand_distr crate

+

The Beta distribution with shape parameters alpha and beta.

+

Methods

impl Beta[src]

pub fn new(alpha: f64, beta: f64) -> Beta[src]

Construct an object representing the Beta(alpha, beta) +distribution.

+

Panics if shape <= 0 or scale <= 0.

+

Trait Implementations

impl Distribution<f64> for Beta[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for Beta[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for Beta[src]

impl Debug for Beta[src]

Auto Trait Implementations

impl Send for Beta

impl Sync for Beta

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.Binomial.html b/target/doc/rand/distributions/struct.Binomial.html new file mode 100644 index 0000000..da7b11b --- /dev/null +++ b/target/doc/rand/distributions/struct.Binomial.html @@ -0,0 +1,26 @@ +rand::distributions::Binomial - Rust

[][src]Struct rand::distributions::Binomial

pub struct Binomial { /* fields omitted */ }
Deprecated since 0.7.0:

moved to rand_distr crate

+

The binomial distribution Binomial(n, p).

+

This distribution has density function: +f(k) = n!/(k! (n-k)!) p^k (1-p)^(n-k) for k >= 0.

+

Methods

impl Binomial[src]

pub fn new(n: u64, p: f64) -> Binomial[src]

Construct a new Binomial with the given shape parameters n (number +of trials) and p (probability of success).

+

Panics if p < 0 or p > 1.

+

Trait Implementations

impl Distribution<u64> for Binomial[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for Binomial[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for Binomial[src]

impl Debug for Binomial[src]

Auto Trait Implementations

impl Send for Binomial

impl Sync for Binomial

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.Cauchy.html b/target/doc/rand/distributions/struct.Cauchy.html new file mode 100644 index 0000000..b94dfbc --- /dev/null +++ b/target/doc/rand/distributions/struct.Cauchy.html @@ -0,0 +1,26 @@ +rand::distributions::Cauchy - Rust

[][src]Struct rand::distributions::Cauchy

pub struct Cauchy { /* fields omitted */ }
Deprecated since 0.7.0:

moved to rand_distr crate

+

The Cauchy distribution Cauchy(median, scale).

+

This distribution has a density function: +f(x) = 1 / (pi * scale * (1 + ((x - median) / scale)^2))

+

Methods

impl Cauchy[src]

pub fn new(median: f64, scale: f64) -> Cauchy[src]

Construct a new Cauchy with the given shape parameters +median the peak location and scale the scale factor. +Panics if scale <= 0.

+

Trait Implementations

impl Distribution<f64> for Cauchy[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for Cauchy[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for Cauchy[src]

impl Debug for Cauchy[src]

Auto Trait Implementations

impl Send for Cauchy

impl Sync for Cauchy

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.ChiSquared.html b/target/doc/rand/distributions/struct.ChiSquared.html new file mode 100644 index 0000000..d75a7e8 --- /dev/null +++ b/target/doc/rand/distributions/struct.ChiSquared.html @@ -0,0 +1,28 @@ +rand::distributions::ChiSquared - Rust

[][src]Struct rand::distributions::ChiSquared

pub struct ChiSquared { /* fields omitted */ }
Deprecated since 0.7.0:

moved to rand_distr crate

+

The chi-squared distribution χ²(k), where k is the degrees of +freedom.

+

For k > 0 integral, this distribution is the sum of the squares +of k independent standard normal random variables. For other +k, this uses the equivalent characterisation +χ²(k) = Gamma(k/2, 2).

+

Methods

impl ChiSquared[src]

pub fn new(k: f64) -> ChiSquared[src]

Create a new chi-squared distribution with degrees-of-freedom +k. Panics if k < 0.

+

Trait Implementations

impl Distribution<f64> for ChiSquared[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for ChiSquared[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for ChiSquared[src]

impl Debug for ChiSquared[src]

Auto Trait Implementations

impl Send for ChiSquared

impl Sync for ChiSquared

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.Dirichlet.html b/target/doc/rand/distributions/struct.Dirichlet.html new file mode 100644 index 0000000..0a7a182 --- /dev/null +++ b/target/doc/rand/distributions/struct.Dirichlet.html @@ -0,0 +1,35 @@ +rand::distributions::Dirichlet - Rust

[][src]Struct rand::distributions::Dirichlet

pub struct Dirichlet { /* fields omitted */ }
Deprecated since 0.7.0:

moved to rand_distr crate

+

The dirichelet distribution Dirichlet(alpha).

+

The Dirichlet distribution is a family of continuous multivariate +probability distributions parameterized by a vector alpha of positive reals. +It is a multivariate generalization of the beta distribution.

+

Methods

impl Dirichlet[src]

pub fn new<V: Into<Vec<f64>>>(alpha: V) -> Dirichlet[src]

Construct a new Dirichlet with the given alpha parameter alpha.

+

Panics

+
    +
  • if alpha.len() < 2
  • +
+

pub fn new_with_param(alpha: f64, size: usize) -> Dirichlet[src]

Construct a new Dirichlet with the given shape parameter alpha and size.

+

Panics

+
    +
  • if alpha <= 0.0
  • +
  • if size < 2
  • +
+

Trait Implementations

impl Distribution<Vec<f64>> for Dirichlet[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for Dirichlet[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Debug for Dirichlet[src]

Auto Trait Implementations

impl Send for Dirichlet

impl Sync for Dirichlet

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.DistIter.html b/target/doc/rand/distributions/struct.DistIter.html new file mode 100644 index 0000000..1a0bd9f --- /dev/null +++ b/target/doc/rand/distributions/struct.DistIter.html @@ -0,0 +1,85 @@ +rand::distributions::DistIter - Rust

[][src]Struct rand::distributions::DistIter

pub struct DistIter<D, R, T> { /* fields omitted */ }

An iterator that generates random values of T with distribution D, +using R as the source of randomness.

+

This struct is created by the sample_iter method on [Distribution]. +See its documentation for more.

+

Trait Implementations

impl<D, R, T> Iterator for DistIter<D, R, T> where
    D: Distribution<T>,
    R: Rng
[src]

type Item = T

The type of the elements being iterated over.

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

impl<D: Debug, R: Debug, T: Debug> Debug for DistIter<D, R, T>[src]

impl<D, R, T> FusedIterator for DistIter<D, R, T> where
    D: Distribution<T>,
    R: Rng
[src]

Auto Trait Implementations

impl<D, R, T> Send for DistIter<D, R, T> where
    D: Send,
    R: Send,
    T: Send

impl<D, R, T> Sync for DistIter<D, R, T> where
    D: Sync,
    R: Sync,
    T: Sync

Blanket Implementations

impl<I> IteratorRandom for I where
    I: Iterator
[src]

fn choose<R: ?Sized>(self, rng: &mut R) -> Option<Self::Item> where
    R: Rng
[src]

Choose one element at random from the iterator. Read more

+

fn choose_multiple_fill<R: ?Sized>(
    self,
    rng: &mut R,
    buf: &mut [Self::Item]
) -> usize where
    R: Rng
[src]

Collects values at random from the iterator into a supplied buffer until that buffer is filled. Read more

+

fn choose_multiple<R: ?Sized>(
    self,
    rng: &mut R,
    amount: usize
) -> Vec<Self::Item> where
    R: Rng
[src]

Collects amount values at random from the iterator into a vector. Read more

+

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.Exp.html b/target/doc/rand/distributions/struct.Exp.html new file mode 100644 index 0000000..5d740cd --- /dev/null +++ b/target/doc/rand/distributions/struct.Exp.html @@ -0,0 +1,26 @@ +rand::distributions::Exp - Rust

[][src]Struct rand::distributions::Exp

pub struct Exp { /* fields omitted */ }
Deprecated since 0.7.0:

moved to rand_distr crate

+

The exponential distribution Exp(lambda).

+

This distribution has density function: f(x) = lambda * exp(-lambda * x) +for x > 0.

+

Note that [Exp1][crate::distributions::Exp1] is an optimised implementation for lambda = 1.

+

Methods

impl Exp[src]

pub fn new(lambda: f64) -> Exp[src]

Construct a new Exp with the given shape parameter +lambda. Panics if lambda <= 0.

+

Trait Implementations

impl Distribution<f64> for Exp[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for Exp[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for Exp[src]

impl Debug for Exp[src]

Auto Trait Implementations

impl Send for Exp

impl Sync for Exp

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.Exp1.html b/target/doc/rand/distributions/struct.Exp1.html new file mode 100644 index 0000000..125d607 --- /dev/null +++ b/target/doc/rand/distributions/struct.Exp1.html @@ -0,0 +1,29 @@ +rand::distributions::Exp1 - Rust

[][src]Struct rand::distributions::Exp1

pub struct Exp1;
Deprecated since 0.7.0:

moved to rand_distr crate

+

Samples floating-point numbers according to the exponential distribution, +with rate parameter λ = 1. This is equivalent to Exp::new(1.0) or +sampling with -rng.gen::<f64>().ln(), but faster.

+

See Exp for the general exponential distribution.

+

Implemented via the ZIGNOR variant1 of the Ziggurat method. The exact +description in the paper was adjusted to use tables for the exponential +distribution rather than normal.

+

  1. Jurgen A. Doornik (2005). An Improved Ziggurat Method to +Generate Normal Random Samples. +Nuffield College, Oxford 

Trait Implementations

impl Distribution<f64> for Exp1[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for Exp1[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for Exp1[src]

impl Debug for Exp1[src]

Auto Trait Implementations

impl Send for Exp1

impl Sync for Exp1

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.FisherF.html b/target/doc/rand/distributions/struct.FisherF.html new file mode 100644 index 0000000..1446cd6 --- /dev/null +++ b/target/doc/rand/distributions/struct.FisherF.html @@ -0,0 +1,25 @@ +rand::distributions::FisherF - Rust

[][src]Struct rand::distributions::FisherF

pub struct FisherF { /* fields omitted */ }
Deprecated since 0.7.0:

moved to rand_distr crate

+

The Fisher F distribution F(m, n).

+

This distribution is equivalent to the ratio of two normalised +chi-squared distributions, that is, F(m,n) = (χ²(m)/m) / (χ²(n)/n).

+

Methods

impl FisherF[src]

pub fn new(m: f64, n: f64) -> FisherF[src]

Create a new FisherF distribution, with the given +parameter. Panics if either m or n are not positive.

+

Trait Implementations

impl Distribution<f64> for FisherF[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for FisherF[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for FisherF[src]

impl Debug for FisherF[src]

Auto Trait Implementations

impl Send for FisherF

impl Sync for FisherF

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.Gamma.html b/target/doc/rand/distributions/struct.Gamma.html new file mode 100644 index 0000000..b0ca6ad --- /dev/null +++ b/target/doc/rand/distributions/struct.Gamma.html @@ -0,0 +1,35 @@ +rand::distributions::Gamma - Rust

[][src]Struct rand::distributions::Gamma

pub struct Gamma { /* fields omitted */ }
Deprecated since 0.7.0:

moved to rand_distr crate

+

The Gamma distribution Gamma(shape, scale) distribution.

+

The density function of this distribution is

+
f(x) =  x^(k - 1) * exp(-x / θ) / (Γ(k) * θ^k)
+
+

where Γ is the Gamma function, k is the shape and θ is the +scale and both k and θ are strictly positive.

+

The algorithm used is that described by Marsaglia & Tsang 20001, +falling back to directly sampling from an Exponential for shape == 1, and using the boosting technique described in that paper for +shape < 1.

+

  1. George Marsaglia and Wai Wan Tsang. 2000. "A Simple Method for +Generating Gamma Variables" ACM Trans. Math. Softw. 26, 3 +(September 2000), 363-372. +DOI:10.1145/358407.358414 

Methods

impl Gamma[src]

pub fn new(shape: f64, scale: f64) -> Gamma[src]

Construct an object representing the Gamma(shape, scale) +distribution.

+

Panics if shape <= 0 or scale <= 0.

+

Trait Implementations

impl Distribution<f64> for Gamma[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for Gamma[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for Gamma[src]

impl Debug for Gamma[src]

Auto Trait Implementations

impl Send for Gamma

impl Sync for Gamma

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.LogNormal.html b/target/doc/rand/distributions/struct.LogNormal.html new file mode 100644 index 0000000..d620fe5 --- /dev/null +++ b/target/doc/rand/distributions/struct.LogNormal.html @@ -0,0 +1,27 @@ +rand::distributions::LogNormal - Rust

[][src]Struct rand::distributions::LogNormal

pub struct LogNormal { /* fields omitted */ }
Deprecated since 0.7.0:

moved to rand_distr crate

+

The log-normal distribution ln N(mean, std_dev**2).

+

If X is log-normal distributed, then ln(X) is N(mean, std_dev**2) +distributed.

+

Methods

impl LogNormal[src]

pub fn new(mean: f64, std_dev: f64) -> LogNormal[src]

Construct a new LogNormal distribution with the given mean +and standard deviation.

+

Panics

+

Panics if std_dev < 0.

+

Trait Implementations

impl Distribution<f64> for LogNormal[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for LogNormal[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for LogNormal[src]

impl Debug for LogNormal[src]

Auto Trait Implementations

impl Send for LogNormal

impl Sync for LogNormal

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.Normal.html b/target/doc/rand/distributions/struct.Normal.html new file mode 100644 index 0000000..0f33552 --- /dev/null +++ b/target/doc/rand/distributions/struct.Normal.html @@ -0,0 +1,29 @@ +rand::distributions::Normal - Rust

[][src]Struct rand::distributions::Normal

pub struct Normal { /* fields omitted */ }
Deprecated since 0.7.0:

moved to rand_distr crate

+

The normal distribution N(mean, std_dev**2).

+

This uses the ZIGNOR variant of the Ziggurat method, see StandardNormal +for more details.

+

Note that StandardNormal is an optimised implementation for mean 0, and +standard deviation 1.

+

Methods

impl Normal[src]

pub fn new(mean: f64, std_dev: f64) -> Normal[src]

Construct a new Normal distribution with the given mean and +standard deviation.

+

Panics

+

Panics if std_dev < 0.

+

Trait Implementations

impl Distribution<f64> for Normal[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for Normal[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for Normal[src]

impl Debug for Normal[src]

Auto Trait Implementations

impl Send for Normal

impl Sync for Normal

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.Open01.html b/target/doc/rand/distributions/struct.Open01.html new file mode 100644 index 0000000..48c95ed --- /dev/null +++ b/target/doc/rand/distributions/struct.Open01.html @@ -0,0 +1,36 @@ +rand::distributions::Open01 - Rust

[][src]Struct rand::distributions::Open01

pub struct Open01;

A distribution to sample floating point numbers uniformly in the open +interval (0, 1), i.e. not including either endpoint.

+

All values that can be generated are of the form n * ε + ε/2. For f32 +the 22 most significant random bits of an u32 are used, for f64 52 from +an u64. The conversion uses a transmute-based method.

+

See also: Standard which samples from [0, 1), OpenClosed01 +which samples from (0, 1] and Uniform which samples from arbitrary +ranges.

+

Example

+
+use rand::{thread_rng, Rng};
+use rand::distributions::Open01;
+
+let val: f32 = thread_rng().sample(Open01);
+println!("f32 from (0, 1): {}", val);
+

Trait Implementations

impl Distribution<f32> for Open01[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<f64> for Open01[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for Open01[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for Open01[src]

impl Debug for Open01[src]

Auto Trait Implementations

impl Send for Open01

impl Sync for Open01

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.OpenClosed01.html b/target/doc/rand/distributions/struct.OpenClosed01.html new file mode 100644 index 0000000..7f6af10 --- /dev/null +++ b/target/doc/rand/distributions/struct.OpenClosed01.html @@ -0,0 +1,37 @@ +rand::distributions::OpenClosed01 - Rust

[][src]Struct rand::distributions::OpenClosed01

pub struct OpenClosed01;

A distribution to sample floating point numbers uniformly in the half-open +interval (0, 1], i.e. including 1 but not 0.

+

All values that can be generated are of the form n * ε/2. For f32 +the 23 most significant random bits of a u32 are used and for f64 the +53 most significant bits of a u64 are used. The conversion uses the +multiplicative method.

+

See also: Standard which samples from [0, 1), Open01 +which samples from (0, 1) and Uniform which samples from arbitrary +ranges.

+

Example

+
+use rand::{thread_rng, Rng};
+use rand::distributions::OpenClosed01;
+
+let val: f32 = thread_rng().sample(OpenClosed01);
+println!("f32 from (0, 1): {}", val);
+

Trait Implementations

impl Distribution<f32> for OpenClosed01[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<f64> for OpenClosed01[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for OpenClosed01[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for OpenClosed01[src]

impl Debug for OpenClosed01[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.Pareto.html b/target/doc/rand/distributions/struct.Pareto.html new file mode 100644 index 0000000..0dd92d1 --- /dev/null +++ b/target/doc/rand/distributions/struct.Pareto.html @@ -0,0 +1,26 @@ +rand::distributions::Pareto - Rust

[][src]Struct rand::distributions::Pareto

pub struct Pareto { /* fields omitted */ }
Deprecated since 0.7.0:

moved to rand_distr crate

+

Samples floating-point numbers according to the Pareto distribution

+

Methods

impl Pareto[src]

pub fn new(scale: f64, shape: f64) -> Pareto[src]

Construct a new Pareto distribution with given scale and shape.

+

In the literature, scale is commonly written as xm or k and +shape is often written as α.

+

Panics

+

scale and shape have to be non-zero and positive.

+

Trait Implementations

impl Distribution<f64> for Pareto[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for Pareto[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for Pareto[src]

impl Debug for Pareto[src]

Auto Trait Implementations

impl Send for Pareto

impl Sync for Pareto

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.Poisson.html b/target/doc/rand/distributions/struct.Poisson.html new file mode 100644 index 0000000..dcf10cb --- /dev/null +++ b/target/doc/rand/distributions/struct.Poisson.html @@ -0,0 +1,25 @@ +rand::distributions::Poisson - Rust

[][src]Struct rand::distributions::Poisson

pub struct Poisson { /* fields omitted */ }
Deprecated since 0.7.0:

moved to rand_distr crate

+

The Poisson distribution Poisson(lambda).

+

This distribution has a density function: +f(k) = lambda^k * exp(-lambda) / k! for k >= 0.

+

Methods

impl Poisson[src]

pub fn new(lambda: f64) -> Poisson[src]

Construct a new Poisson with the given shape parameter +lambda. Panics if lambda <= 0.

+

Trait Implementations

impl Distribution<u64> for Poisson[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for Poisson[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for Poisson[src]

impl Debug for Poisson[src]

Auto Trait Implementations

impl Send for Poisson

impl Sync for Poisson

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.Standard.html b/target/doc/rand/distributions/struct.Standard.html new file mode 100644 index 0000000..9fe9a39 --- /dev/null +++ b/target/doc/rand/distributions/struct.Standard.html @@ -0,0 +1,222 @@ +rand::distributions::Standard - Rust

[][src]Struct rand::distributions::Standard

pub struct Standard;

A generic random value distribution, implemented for many primitive types. +Usually generates values with a numerically uniform distribution, and with a +range appropriate to the type.

+

Provided implementations

+

Assuming the provided Rng is well-behaved, these implementations +generate values with the following ranges and distributions:

+
    +
  • Integers (i32, u32, isize, usize, etc.): Uniformly distributed +over all values of the type.
  • +
  • char: Uniformly distributed over all Unicode scalar values, i.e. all +code points in the range 0...0x10_FFFF, except for the range +0xD800...0xDFFF (the surrogate code points). This includes +unassigned/reserved code points.
  • +
  • bool: Generates false or true, each with probability 0.5.
  • +
  • Floating point types (f32 and f64): Uniformly distributed in the +half-open range [0, 1). See notes below.
  • +
  • Wrapping integers (Wrapping<T>), besides the type identical to their +normal integer variants.
  • +
+

The Standard distribution also supports generation of the following +compound types where all component types are supported:

+
    +
  • Tuples (up to 12 elements): each element is generated sequentially.
  • +
  • Arrays (up to 32 elements): each element is generated sequentially; +see also [Rng::fill] which supports arbitrary array length for integer +types and tends to be faster for u32 and smaller types.
  • +
  • Option<T> first generates a bool, and if true generates and returns +Some(value) where value: T, otherwise returning None.
  • +
+

Custom implementations

+

The [Standard] distribution may be implemented for user types as follows:

+ +
+use rand::Rng;
+use rand::distributions::{Distribution, Standard};
+
+struct MyF32 {
+    x: f32,
+}
+
+impl Distribution<MyF32> for Standard {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> MyF32 {
+        MyF32 { x: rng.gen() }
+    }
+}
+

Example usage

+
+use rand::prelude::*;
+use rand::distributions::Standard;
+
+let val: f32 = StdRng::from_entropy().sample(Standard);
+println!("f32 from [0, 1): {}", val);
+

Floating point implementation

+

The floating point implementations for Standard generate a random value in +the half-open interval [0, 1), i.e. including 0 but not 1.

+

All values that can be generated are of the form n * ε/2. For f32 +the 23 most significant random bits of a u32 are used and for f64 the +53 most significant bits of a u64 are used. The conversion uses the +multiplicative method: (rng.gen::<$uty>() >> N) as $ty * (ε/2).

+

See also: [Open01] which samples from (0, 1), [OpenClosed01] which +samples from (0, 1] and Rng::gen_range(0, 1) which also samples from +[0, 1). Note that Open01 and gen_range (which uses Uniform) use +transmute-based methods which yield 1 bit less precision but may perform +faster on some architectures (on modern Intel CPUs all methods have +approximately equal performance).

+

Trait Implementations

impl Distribution<f32> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<f64> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<u8> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<u16> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<u32> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<u64> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<u128> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<usize> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<i8> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<i16> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<i32> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<i64> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<i128> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<isize> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<NonZeroU8> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<NonZeroU16> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<NonZeroU32> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<NonZeroU64> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<NonZeroU128> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<NonZeroUsize> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<char> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<bool> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Distribution<()> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<A> Distribution<(A,)> for Standard where
    Standard: Distribution<A>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<A, B> Distribution<(A, B)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<A, B, C> Distribution<(A, B, C)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<A, B, C, D> Distribution<(A, B, C, D)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>,
    Standard: Distribution<D>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<A, B, C, D, E> Distribution<(A, B, C, D, E)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>,
    Standard: Distribution<D>,
    Standard: Distribution<E>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<A, B, C, D, E, F> Distribution<(A, B, C, D, E, F)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>,
    Standard: Distribution<D>,
    Standard: Distribution<E>,
    Standard: Distribution<F>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<A, B, C, D, E, F, G> Distribution<(A, B, C, D, E, F, G)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>,
    Standard: Distribution<D>,
    Standard: Distribution<E>,
    Standard: Distribution<F>,
    Standard: Distribution<G>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<A, B, C, D, E, F, G, H> Distribution<(A, B, C, D, E, F, G, H)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>,
    Standard: Distribution<D>,
    Standard: Distribution<E>,
    Standard: Distribution<F>,
    Standard: Distribution<G>,
    Standard: Distribution<H>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<A, B, C, D, E, F, G, H, I> Distribution<(A, B, C, D, E, F, G, H, I)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>,
    Standard: Distribution<D>,
    Standard: Distribution<E>,
    Standard: Distribution<F>,
    Standard: Distribution<G>,
    Standard: Distribution<H>,
    Standard: Distribution<I>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<A, B, C, D, E, F, G, H, I, J> Distribution<(A, B, C, D, E, F, G, H, I, J)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>,
    Standard: Distribution<D>,
    Standard: Distribution<E>,
    Standard: Distribution<F>,
    Standard: Distribution<G>,
    Standard: Distribution<H>,
    Standard: Distribution<I>,
    Standard: Distribution<J>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<A, B, C, D, E, F, G, H, I, J, K> Distribution<(A, B, C, D, E, F, G, H, I, J, K)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>,
    Standard: Distribution<D>,
    Standard: Distribution<E>,
    Standard: Distribution<F>,
    Standard: Distribution<G>,
    Standard: Distribution<H>,
    Standard: Distribution<I>,
    Standard: Distribution<J>,
    Standard: Distribution<K>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<A, B, C, D, E, F, G, H, I, J, K, L> Distribution<(A, B, C, D, E, F, G, H, I, J, K, L)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>,
    Standard: Distribution<D>,
    Standard: Distribution<E>,
    Standard: Distribution<F>,
    Standard: Distribution<G>,
    Standard: Distribution<H>,
    Standard: Distribution<I>,
    Standard: Distribution<J>,
    Standard: Distribution<K>,
    Standard: Distribution<L>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 0]> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 1]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 2]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 3]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 4]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 5]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 6]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 7]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 8]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 9]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 10]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 11]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 12]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 13]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 14]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 15]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 16]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 17]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 18]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 19]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 20]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 21]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 22]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 23]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 24]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 25]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 26]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 27]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 28]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 29]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 30]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 31]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<[T; 32]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<Option<T>> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<T> Distribution<Wrapping<T>> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for Standard[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for Standard[src]

impl Debug for Standard[src]

Auto Trait Implementations

impl Send for Standard

impl Sync for Standard

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.StandardNormal.html b/target/doc/rand/distributions/struct.StandardNormal.html new file mode 100644 index 0000000..84a626f --- /dev/null +++ b/target/doc/rand/distributions/struct.StandardNormal.html @@ -0,0 +1,27 @@ +rand::distributions::StandardNormal - Rust

[][src]Struct rand::distributions::StandardNormal

pub struct StandardNormal;
Deprecated since 0.7.0:

moved to rand_distr crate

+

Samples floating-point numbers according to the normal distribution +N(0, 1) (a.k.a. a standard normal, or Gaussian). This is equivalent to +Normal::new(0.0, 1.0) but faster.

+

See Normal for the general normal distribution.

+

Implemented via the ZIGNOR variant1 of the Ziggurat method.

+

  1. Jurgen A. Doornik (2005). An Improved Ziggurat Method to +Generate Normal Random Samples. +Nuffield College, Oxford 

Trait Implementations

impl Distribution<f64> for StandardNormal[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for StandardNormal[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for StandardNormal[src]

impl Debug for StandardNormal[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.StudentT.html b/target/doc/rand/distributions/struct.StudentT.html new file mode 100644 index 0000000..1259ea9 --- /dev/null +++ b/target/doc/rand/distributions/struct.StudentT.html @@ -0,0 +1,24 @@ +rand::distributions::StudentT - Rust

[][src]Struct rand::distributions::StudentT

pub struct StudentT { /* fields omitted */ }
Deprecated since 0.7.0:

moved to rand_distr crate

+

The Student t distribution, t(nu), where nu is the degrees of +freedom.

+

Methods

impl StudentT[src]

pub fn new(n: f64) -> StudentT[src]

Create a new Student t distribution with n degrees of +freedom. Panics if n <= 0.

+

Trait Implementations

impl Distribution<f64> for StudentT[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for StudentT[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for StudentT[src]

impl Debug for StudentT[src]

Auto Trait Implementations

impl Send for StudentT

impl Sync for StudentT

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.Triangular.html b/target/doc/rand/distributions/struct.Triangular.html new file mode 100644 index 0000000..08ba34e --- /dev/null +++ b/target/doc/rand/distributions/struct.Triangular.html @@ -0,0 +1,25 @@ +rand::distributions::Triangular - Rust

[][src]Struct rand::distributions::Triangular

pub struct Triangular { /* fields omitted */ }
Deprecated since 0.7.0:

moved to rand_distr crate

+

The triangular distribution.

+

Methods

impl Triangular[src]

pub fn new(min: f64, max: f64, mode: f64) -> Triangular[src]

Construct a new Triangular with minimum min, maximum max and mode +mode.

+

Panics

+

If max < mode, mode < max or max == min.

+

Trait Implementations

impl Distribution<f64> for Triangular[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for Triangular[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for Triangular[src]

impl Debug for Triangular[src]

Auto Trait Implementations

impl Send for Triangular

impl Sync for Triangular

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.Uniform.html b/target/doc/rand/distributions/struct.Uniform.html new file mode 100644 index 0000000..9094774 --- /dev/null +++ b/target/doc/rand/distributions/struct.Uniform.html @@ -0,0 +1,55 @@ +rand::distributions::Uniform - Rust

[][src]Struct rand::distributions::Uniform

pub struct Uniform<X: SampleUniform> { /* fields omitted */ }

Sample values uniformly between two bounds.

+

[Uniform::new] and [Uniform::new_inclusive] construct a uniform +distribution sampling from the given range; these functions may do extra +work up front to make sampling of multiple values faster.

+

When sampling from a constant range, many calculations can happen at +compile-time and all methods should be fast; for floating-point ranges and +the full range of integer types this should have comparable performance to +the Standard distribution.

+

Steps are taken to avoid bias which might be present in naive +implementations; for example rng.gen::<u8>() % 170 samples from the range +[0, 169] but is twice as likely to select numbers less than 85 than other +values. Further, the implementations here give more weight to the high-bits +generated by the RNG than the low bits, since with some RNGs the low-bits +are of lower quality than the high bits.

+

Implementations must sample in [low, high) range for +Uniform::new(low, high), i.e., excluding high. In particular care must +be taken to ensure that rounding never results values < low or >= high.

+

Example

+
+use rand::distributions::{Distribution, Uniform};
+
+fn main() {
+    let between = Uniform::from(10..10000);
+    let mut rng = rand::thread_rng();
+    let mut sum = 0;
+    for _ in 0..1000 {
+        sum += between.sample(&mut rng);
+    }
+    println!("{}", sum);
+}
+

Methods

impl<X: SampleUniform> Uniform<X>[src]

pub fn new<B1, B2>(low: B1, high: B2) -> Uniform<X> where
    B1: SampleBorrow<X> + Sized,
    B2: SampleBorrow<X> + Sized
[src]

Create a new Uniform instance which samples uniformly from the half +open range [low, high) (excluding high). Panics if low >= high.

+

pub fn new_inclusive<B1, B2>(low: B1, high: B2) -> Uniform<X> where
    B1: SampleBorrow<X> + Sized,
    B2: SampleBorrow<X> + Sized
[src]

Create a new Uniform instance which samples uniformly from the closed +range [low, high] (inclusive). Panics if low > high.

+

Trait Implementations

impl<X: SampleUniform> Distribution<X> for Uniform<X>[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<X: SampleUniform> From<Range<X>> for Uniform<X>[src]

impl<X: SampleUniform> From<RangeInclusive<X>> for Uniform<X>[src]

impl<X: Clone + SampleUniform> Clone for Uniform<X> where
    X::Sampler: Clone
[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl<X: Copy + SampleUniform> Copy for Uniform<X> where
    X::Sampler: Copy
[src]

impl<X: Debug + SampleUniform> Debug for Uniform<X> where
    X::Sampler: Debug
[src]

Auto Trait Implementations

impl<X> Send for Uniform<X> where
    <X as SampleUniform>::Sampler: Send

impl<X> Sync for Uniform<X> where
    <X as SampleUniform>::Sampler: Sync

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.UnitCircle.html b/target/doc/rand/distributions/struct.UnitCircle.html new file mode 100644 index 0000000..502a4cd --- /dev/null +++ b/target/doc/rand/distributions/struct.UnitCircle.html @@ -0,0 +1,26 @@ +rand::distributions::UnitCircle - Rust

[][src]Struct rand::distributions::UnitCircle

pub struct UnitCircle;
Deprecated since 0.7.0:

moved to rand_distr crate

+

Samples uniformly from the edge of the unit circle in two dimensions.

+

Implemented via a method by von Neumann1.

+

  1. von Neumann, J. (1951) Various Techniques Used in Connection with +Random Digits. +NBS Appl. Math. Ser., No. 12. Washington, DC: U.S. Government Printing +Office, pp. 36-38. 

Methods

impl UnitCircle[src]

pub fn new() -> UnitCircle[src]

Construct a new UnitCircle distribution.

+

Trait Implementations

impl Distribution<[f64; 2]> for UnitCircle[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for UnitCircle[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for UnitCircle[src]

impl Debug for UnitCircle[src]

Auto Trait Implementations

impl Send for UnitCircle

impl Sync for UnitCircle

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.UnitSphereSurface.html b/target/doc/rand/distributions/struct.UnitSphereSurface.html new file mode 100644 index 0000000..2dc703b --- /dev/null +++ b/target/doc/rand/distributions/struct.UnitSphereSurface.html @@ -0,0 +1,25 @@ +rand::distributions::UnitSphereSurface - Rust

[][src]Struct rand::distributions::UnitSphereSurface

pub struct UnitSphereSurface;
Deprecated since 0.7.0:

moved to rand_distr crate

+

Samples uniformly from the surface of the unit sphere in three dimensions.

+

Implemented via a method by Marsaglia1.

+

  1. Marsaglia, George (1972). Choosing a Point from the Surface of a +Sphere. +Ann. Math. Statist. 43, no. 2, 645--646. 

Methods

impl UnitSphereSurface[src]

pub fn new() -> UnitSphereSurface[src]

Construct a new UnitSphereSurface distribution.

+

Trait Implementations

impl Distribution<[f64; 3]> for UnitSphereSurface[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for UnitSphereSurface[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for UnitSphereSurface[src]

impl Debug for UnitSphereSurface[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/struct.Weibull.html b/target/doc/rand/distributions/struct.Weibull.html new file mode 100644 index 0000000..427db16 --- /dev/null +++ b/target/doc/rand/distributions/struct.Weibull.html @@ -0,0 +1,24 @@ +rand::distributions::Weibull - Rust

[][src]Struct rand::distributions::Weibull

pub struct Weibull { /* fields omitted */ }
Deprecated since 0.7.0:

moved to rand_distr crate

+

Samples floating-point numbers according to the Weibull distribution

+

Methods

impl Weibull[src]

pub fn new(scale: f64, shape: f64) -> Weibull[src]

Construct a new Weibull distribution with given scale and shape.

+

Panics

+

scale and shape have to be non-zero and positive.

+

Trait Implementations

impl Distribution<f64> for Weibull[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl Clone for Weibull[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for Weibull[src]

impl Debug for Weibull[src]

Auto Trait Implementations

impl Send for Weibull

impl Sync for Weibull

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/trait.Distribution.html b/target/doc/rand/distributions/trait.Distribution.html new file mode 100644 index 0000000..ff4e1e9 --- /dev/null +++ b/target/doc/rand/distributions/trait.Distribution.html @@ -0,0 +1,47 @@ +rand::distributions::Distribution - Rust

[][src]Trait rand::distributions::Distribution

pub trait Distribution<T> {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> T;
+
+    fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T>
    where
        R: Rng,
        Self: Sized
, + { ... } +}

Types (distributions) that can be used to create a random instance of T.

+

It is possible to sample from a distribution through both the +Distribution and [Rng] traits, via distr.sample(&mut rng) and +rng.sample(distr). They also both offer the sample_iter method, which +produces an iterator that samples from the distribution.

+

All implementations are expected to be immutable; this has the significant +advantage of not needing to consider thread safety, and for most +distributions efficient state-less sampling algorithms are available.

+
+

Required methods

fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> T

Generate a random value of T, using rng as the source of randomness.

+
Loading content... +

Provided methods

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized

Create an iterator that generates random values of T, using rng as +the source of randomness.

+

Note that this function takes self by value. This works since +Distribution<T> is impl'd for &D where D: Distribution<T>, +however borrowing is not automatic hence distr.sample_iter(...) may +need to be replaced with (&distr).sample_iter(...) to borrow or +(&*distr).sample_iter(...) to reborrow an existing reference.

+

Example

+
+use rand::thread_rng;
+use rand::distributions::{Distribution, Alphanumeric, Uniform, Standard};
+
+let rng = thread_rng();
+
+// Vec of 16 x f32:
+let v: Vec<f32> = Standard.sample_iter(rng).take(16).collect();
+
+// String:
+let s: String = Alphanumeric.sample_iter(rng).take(7).collect();
+
+// Dice-rolling:
+let die_range = Uniform::new_inclusive(1, 6);
+let mut roll_die = die_range.sample_iter(rng);
+while roll_die.next().unwrap() != 6 {
+    println!("Not a 6; rolling again!");
+}
+
Loading content... +

Implementations on Foreign Types

impl<'a, T, D: Distribution<T>> Distribution<T> for &'a D[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Loading content... +

Implementors

impl Distribution<[f64; 2]> for UnitCircle[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<[f64; 3]> for UnitSphereSurface[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<bool> for Bernoulli[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<bool> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<char> for Alphanumeric[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<char> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f32> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f32> for Open01[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f32> for OpenClosed01[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f64> for Gamma[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f64> for ChiSquared[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f64> for FisherF[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f64> for StudentT[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f64> for Beta[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f64> for StandardNormal[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f64> for Normal[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f64> for LogNormal[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f64> for Exp[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f64> for Pareto[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f64> for Cauchy[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f64> for Triangular[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f64> for Weibull[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f64> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f64> for Exp1[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f64> for Open01[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<f64> for OpenClosed01[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<i128> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<i16> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<i32> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<i64> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<i8> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<isize> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<u128> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<u16> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<u32> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<u64> for Poisson[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<u64> for Binomial[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<u64> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<u8> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<()> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<usize> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<Vec<f64>> for Dirichlet[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<NonZeroU128> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<NonZeroU16> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<NonZeroU32> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<NonZeroU64> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<NonZeroU8> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl Distribution<NonZeroUsize> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<A> Distribution<(A,)> for Standard where
    Standard: Distribution<A>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<A, B> Distribution<(A, B)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<A, B, C> Distribution<(A, B, C)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<A, B, C, D> Distribution<(A, B, C, D)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>,
    Standard: Distribution<D>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<A, B, C, D, E> Distribution<(A, B, C, D, E)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>,
    Standard: Distribution<D>,
    Standard: Distribution<E>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<A, B, C, D, E, F> Distribution<(A, B, C, D, E, F)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>,
    Standard: Distribution<D>,
    Standard: Distribution<E>,
    Standard: Distribution<F>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<A, B, C, D, E, F, G> Distribution<(A, B, C, D, E, F, G)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>,
    Standard: Distribution<D>,
    Standard: Distribution<E>,
    Standard: Distribution<F>,
    Standard: Distribution<G>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<A, B, C, D, E, F, G, H> Distribution<(A, B, C, D, E, F, G, H)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>,
    Standard: Distribution<D>,
    Standard: Distribution<E>,
    Standard: Distribution<F>,
    Standard: Distribution<G>,
    Standard: Distribution<H>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<A, B, C, D, E, F, G, H, I> Distribution<(A, B, C, D, E, F, G, H, I)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>,
    Standard: Distribution<D>,
    Standard: Distribution<E>,
    Standard: Distribution<F>,
    Standard: Distribution<G>,
    Standard: Distribution<H>,
    Standard: Distribution<I>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<A, B, C, D, E, F, G, H, I, J> Distribution<(A, B, C, D, E, F, G, H, I, J)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>,
    Standard: Distribution<D>,
    Standard: Distribution<E>,
    Standard: Distribution<F>,
    Standard: Distribution<G>,
    Standard: Distribution<H>,
    Standard: Distribution<I>,
    Standard: Distribution<J>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<A, B, C, D, E, F, G, H, I, J, K> Distribution<(A, B, C, D, E, F, G, H, I, J, K)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>,
    Standard: Distribution<D>,
    Standard: Distribution<E>,
    Standard: Distribution<F>,
    Standard: Distribution<G>,
    Standard: Distribution<H>,
    Standard: Distribution<I>,
    Standard: Distribution<J>,
    Standard: Distribution<K>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<A, B, C, D, E, F, G, H, I, J, K, L> Distribution<(A, B, C, D, E, F, G, H, I, J, K, L)> for Standard where
    Standard: Distribution<A>,
    Standard: Distribution<B>,
    Standard: Distribution<C>,
    Standard: Distribution<D>,
    Standard: Distribution<E>,
    Standard: Distribution<F>,
    Standard: Distribution<G>,
    Standard: Distribution<H>,
    Standard: Distribution<I>,
    Standard: Distribution<J>,
    Standard: Distribution<K>,
    Standard: Distribution<L>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<Option<T>> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 0]> for Standard[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 1]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 2]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 3]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 4]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 5]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 6]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 7]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 8]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 9]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 10]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 11]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 12]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 13]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 14]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 15]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 16]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 17]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 18]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 19]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 20]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 21]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 22]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 23]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 24]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 25]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 26]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 27]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 28]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 29]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 30]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 31]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<[T; 32]> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<T> Distribution<Wrapping<T>> for Standard where
    Standard: Distribution<T>, 
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<W: Weight> Distribution<usize> for rand::distributions::weighted::alias_method::WeightedIndex<W>[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<X> Distribution<usize> for rand::distributions::weighted::WeightedIndex<X> where
    X: SampleUniform + PartialOrd
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

impl<X: SampleUniform> Distribution<X> for Uniform<X>[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Loading content...
\ No newline at end of file diff --git a/target/doc/rand/distributions/triangular/struct.Triangular.html b/target/doc/rand/distributions/triangular/struct.Triangular.html new file mode 100644 index 0000000..c03a4e5 --- /dev/null +++ b/target/doc/rand/distributions/triangular/struct.Triangular.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.Triangular.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/uniform/index.html b/target/doc/rand/distributions/uniform/index.html new file mode 100644 index 0000000..ea56420 --- /dev/null +++ b/target/doc/rand/distributions/uniform/index.html @@ -0,0 +1,94 @@ +rand::distributions::uniform - Rust

[][src]Module rand::distributions::uniform

A distribution uniformly sampling numbers within a given range.

+

[Uniform] is the standard distribution to sample uniformly from a range; +e.g. Uniform::new_inclusive(1, 6) can sample integers from 1 to 6, like a +standard die. [Rng::gen_range] supports any type supported by +[Uniform].

+

This distribution is provided with support for several primitive types +(all integer and floating-point types) as well as [std::time::Duration], +and supports extension to user-defined types via a type-specific back-end +implementation.

+

The types UniformInt, UniformFloat and UniformDuration are the +back-ends supporting sampling from primitive integer and floating-point +ranges as well as from [std::time::Duration]; these types do not normally +need to be used directly (unless implementing a derived back-end).

+

Example usage

+
+use rand::{Rng, thread_rng};
+use rand::distributions::Uniform;
+
+let mut rng = thread_rng();
+let side = Uniform::new(-10.0, 10.0);
+
+// sample between 1 and 10 points
+for _ in 0..rng.gen_range(1, 11) {
+    // sample a point from the square with sides -10 - 10 in two dimensions
+    let (x, y) = (rng.sample(side), rng.sample(side));
+    println!("Point: {}, {}", x, y);
+}
+

Extending Uniform to support a custom type

+

To extend [Uniform] to support your own types, write a back-end which +implements the UniformSampler trait, then implement the SampleUniform +helper trait to "register" your back-end. See the MyF32 example below.

+

At a minimum, the back-end needs to store any parameters needed for sampling +(e.g. the target range) and implement new, new_inclusive and sample. +Those methods should include an assert to check the range is valid (i.e. +low < high). The example below merely wraps another back-end.

+

The new, new_inclusive and sample_single functions use arguments of +type SampleBorrow in order to support passing in values by reference or +by value. In the implementation of these functions, you can choose to +simply use the reference returned by SampleBorrow::borrow, or you can choose +to copy or clone the value, whatever is appropriate for your type.

+ +
+use rand::prelude::*;
+use rand::distributions::uniform::{Uniform, SampleUniform,
+        UniformSampler, UniformFloat, SampleBorrow};
+
+struct MyF32(f32);
+
+#[derive(Clone, Copy, Debug)]
+struct UniformMyF32 {
+    inner: UniformFloat<f32>,
+}
+
+impl UniformSampler for UniformMyF32 {
+    type X = MyF32;
+    fn new<B1, B2>(low: B1, high: B2) -> Self
+        where B1: SampleBorrow<Self::X> + Sized,
+              B2: SampleBorrow<Self::X> + Sized
+    {
+        UniformMyF32 {
+            inner: UniformFloat::<f32>::new(low.borrow().0, high.borrow().0),
+        }
+    }
+    fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self
+        where B1: SampleBorrow<Self::X> + Sized,
+              B2: SampleBorrow<Self::X> + Sized
+    {
+        UniformSampler::new(low, high)
+    }
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
+        MyF32(self.inner.sample(rng))
+    }
+}
+
+impl SampleUniform for MyF32 {
+    type Sampler = UniformMyF32;
+}
+
+let (low, high) = (MyF32(17.0f32), MyF32(22.0f32));
+let uniform = Uniform::new(low, high);
+let x = uniform.sample(&mut thread_rng());
+

Structs

+
Uniform

Sample values uniformly between two bounds.

+
UniformDuration

The back-end implementing [UniformSampler] for Duration.

+
UniformFloat

The back-end implementing [UniformSampler] for floating-point types.

+
UniformInt

The back-end implementing [UniformSampler] for integer types.

+

Traits

+
SampleBorrow

Helper trait similar to Borrow but implemented +only for SampleUniform and references to SampleUniform in +order to resolve ambiguity issues.

+
SampleUniform

Helper trait for creating objects using the correct implementation of +[UniformSampler] for the sampling type.

+
UniformSampler

Helper trait handling actual uniform sampling.

+
\ No newline at end of file diff --git a/target/doc/rand/distributions/uniform/sidebar-items.js b/target/doc/rand/distributions/uniform/sidebar-items.js new file mode 100644 index 0000000..d1dbb52 --- /dev/null +++ b/target/doc/rand/distributions/uniform/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["Uniform","Sample values uniformly between two bounds."],["UniformDuration","The back-end implementing [`UniformSampler`] for `Duration`."],["UniformFloat","The back-end implementing [`UniformSampler`] for floating-point types."],["UniformInt","The back-end implementing [`UniformSampler`] for integer types."]],"trait":[["SampleBorrow","Helper trait similar to [`Borrow`] but implemented only for SampleUniform and references to SampleUniform in order to resolve ambiguity issues."],["SampleUniform","Helper trait for creating objects using the correct implementation of [`UniformSampler`] for the sampling type."],["UniformSampler","Helper trait handling actual uniform sampling."]]}); \ No newline at end of file diff --git a/target/doc/rand/distributions/uniform/struct.Uniform.html b/target/doc/rand/distributions/uniform/struct.Uniform.html new file mode 100644 index 0000000..2d9bab3 --- /dev/null +++ b/target/doc/rand/distributions/uniform/struct.Uniform.html @@ -0,0 +1,55 @@ +rand::distributions::uniform::Uniform - Rust

[][src]Struct rand::distributions::uniform::Uniform

pub struct Uniform<X: SampleUniform> { /* fields omitted */ }

Sample values uniformly between two bounds.

+

[Uniform::new] and [Uniform::new_inclusive] construct a uniform +distribution sampling from the given range; these functions may do extra +work up front to make sampling of multiple values faster.

+

When sampling from a constant range, many calculations can happen at +compile-time and all methods should be fast; for floating-point ranges and +the full range of integer types this should have comparable performance to +the Standard distribution.

+

Steps are taken to avoid bias which might be present in naive +implementations; for example rng.gen::<u8>() % 170 samples from the range +[0, 169] but is twice as likely to select numbers less than 85 than other +values. Further, the implementations here give more weight to the high-bits +generated by the RNG than the low bits, since with some RNGs the low-bits +are of lower quality than the high bits.

+

Implementations must sample in [low, high) range for +Uniform::new(low, high), i.e., excluding high. In particular care must +be taken to ensure that rounding never results values < low or >= high.

+

Example

+
+use rand::distributions::{Distribution, Uniform};
+
+fn main() {
+    let between = Uniform::from(10..10000);
+    let mut rng = rand::thread_rng();
+    let mut sum = 0;
+    for _ in 0..1000 {
+        sum += between.sample(&mut rng);
+    }
+    println!("{}", sum);
+}
+

Methods

impl<X: SampleUniform> Uniform<X>[src]

pub fn new<B1, B2>(low: B1, high: B2) -> Uniform<X> where
    B1: SampleBorrow<X> + Sized,
    B2: SampleBorrow<X> + Sized
[src]

Create a new Uniform instance which samples uniformly from the half +open range [low, high) (excluding high). Panics if low >= high.

+

pub fn new_inclusive<B1, B2>(low: B1, high: B2) -> Uniform<X> where
    B1: SampleBorrow<X> + Sized,
    B2: SampleBorrow<X> + Sized
[src]

Create a new Uniform instance which samples uniformly from the closed +range [low, high] (inclusive). Panics if low > high.

+

Trait Implementations

impl<X: SampleUniform> Distribution<X> for Uniform<X>[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<X: SampleUniform> From<Range<X>> for Uniform<X>[src]

impl<X: SampleUniform> From<RangeInclusive<X>> for Uniform<X>[src]

impl<X: Clone + SampleUniform> Clone for Uniform<X> where
    X::Sampler: Clone
[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl<X: Copy + SampleUniform> Copy for Uniform<X> where
    X::Sampler: Copy
[src]

impl<X: Debug + SampleUniform> Debug for Uniform<X> where
    X::Sampler: Debug
[src]

Auto Trait Implementations

impl<X> Send for Uniform<X> where
    <X as SampleUniform>::Sampler: Send

impl<X> Sync for Uniform<X> where
    <X as SampleUniform>::Sampler: Sync

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/uniform/struct.UniformDuration.html b/target/doc/rand/distributions/uniform/struct.UniformDuration.html new file mode 100644 index 0000000..37ab81b --- /dev/null +++ b/target/doc/rand/distributions/uniform/struct.UniformDuration.html @@ -0,0 +1,25 @@ +rand::distributions::uniform::UniformDuration - Rust

[][src]Struct rand::distributions::uniform::UniformDuration

pub struct UniformDuration { /* fields omitted */ }

The back-end implementing [UniformSampler] for Duration.

+

Unless you are implementing [UniformSampler] for your own types, this type +should not be used directly, use [Uniform] instead.

+

Trait Implementations

impl UniformSampler for UniformDuration[src]

type X = Duration

The type sampled by this implementation.

+

fn sample_single<R: Rng + ?Sized, B1, B2>(
    low: B1,
    high: B2,
    rng: &mut R
) -> Self::X where
    B1: SampleBorrow<Self::X> + Sized,
    B2: SampleBorrow<Self::X> + Sized
[src]

Sample a single value uniformly from a range with inclusive lower bound and exclusive upper bound [low, high). Read more

+

impl Clone for UniformDuration[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Copy for UniformDuration[src]

impl Debug for UniformDuration[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/uniform/struct.UniformFloat.html b/target/doc/rand/distributions/uniform/struct.UniformFloat.html new file mode 100644 index 0000000..2f8d726 --- /dev/null +++ b/target/doc/rand/distributions/uniform/struct.UniformFloat.html @@ -0,0 +1,38 @@ +rand::distributions::uniform::UniformFloat - Rust

[][src]Struct rand::distributions::uniform::UniformFloat

pub struct UniformFloat<X> { /* fields omitted */ }

The back-end implementing [UniformSampler] for floating-point types.

+

Unless you are implementing [UniformSampler] for your own type, this type +should not be used directly, use [Uniform] instead.

+

Implementation notes

+

Instead of generating a float in the [0, 1) range using Standard, the +UniformFloat implementation converts the output of an PRNG itself. This +way one or two steps can be optimized out.

+

The floats are first converted to a value in the [1, 2) interval using a +transmute-based method, and then mapped to the expected range with a +multiply and addition. Values produced this way have what equals 22 bits of +random digits for an f32, and 52 for an f64.

+

Trait Implementations

impl UniformSampler for UniformFloat<f32>[src]

type X = f32

The type sampled by this implementation.

+

impl UniformSampler for UniformFloat<f64>[src]

type X = f64

The type sampled by this implementation.

+

impl<X: Clone> Clone for UniformFloat<X>[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl<X: Copy> Copy for UniformFloat<X>[src]

impl<X: Debug> Debug for UniformFloat<X>[src]

Auto Trait Implementations

impl<X> Send for UniformFloat<X> where
    X: Send

impl<X> Sync for UniformFloat<X> where
    X: Sync

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/uniform/struct.UniformInt.html b/target/doc/rand/distributions/uniform/struct.UniformInt.html new file mode 100644 index 0000000..3b07a43 --- /dev/null +++ b/target/doc/rand/distributions/uniform/struct.UniformInt.html @@ -0,0 +1,103 @@ +rand::distributions::uniform::UniformInt - Rust

[][src]Struct rand::distributions::uniform::UniformInt

pub struct UniformInt<X> { /* fields omitted */ }

The back-end implementing [UniformSampler] for integer types.

+

Unless you are implementing [UniformSampler] for your own type, this type +should not be used directly, use [Uniform] instead.

+

Implementation notes

+

For simplicity, we use the same generic struct UniformInt<X> for all +integer types X. This gives us only one field type, X; to store unsigned +values of this size, we take use the fact that these conversions are no-ops.

+

For a closed range, the number of possible numbers we should generate is +range = (high - low + 1). To avoid bias, we must ensure that the size of +our sample space, zone, is a multiple of range; other values must be +rejected (by replacing with a new random sample).

+

As a special case, we use range = 0 to represent the full range of the +result type (i.e. for new_inclusive($ty::MIN, $ty::MAX)).

+

The optimum zone is the largest product of range which fits in our +(unsigned) target type. We calculate this by calculating how many numbers we +must reject: reject = (MAX + 1) % range = (MAX - range + 1) % range. Any (large) +product of range will suffice, thus in sample_single we multiply by a +power of 2 via bit-shifting (faster but may cause more rejections).

+

The smallest integer PRNGs generate is u32. For 8- and 16-bit outputs we +use u32 for our zone and samples (because it's not slower and because +it reduces the chance of having to reject a sample). In this case we cannot +store zone in the target type since it is too large, however we know +ints_to_reject < range <= $unsigned::MAX.

+

An alternative to using a modulus is widening multiply: After a widening +multiply by range, the result is in the high word. Then comparing the low +word against zone makes sure our distribution is uniform.

+

Trait Implementations

impl UniformSampler for UniformInt<i8>[src]

type X = i8

The type sampled by this implementation.

+

impl UniformSampler for UniformInt<i16>[src]

type X = i16

The type sampled by this implementation.

+

impl UniformSampler for UniformInt<i32>[src]

type X = i32

The type sampled by this implementation.

+

impl UniformSampler for UniformInt<i64>[src]

type X = i64

The type sampled by this implementation.

+

impl UniformSampler for UniformInt<i128>[src]

type X = i128

The type sampled by this implementation.

+

impl UniformSampler for UniformInt<isize>[src]

type X = isize

The type sampled by this implementation.

+

impl UniformSampler for UniformInt<u8>[src]

type X = u8

The type sampled by this implementation.

+

impl UniformSampler for UniformInt<u16>[src]

type X = u16

The type sampled by this implementation.

+

impl UniformSampler for UniformInt<u32>[src]

type X = u32

The type sampled by this implementation.

+

impl UniformSampler for UniformInt<u64>[src]

type X = u64

The type sampled by this implementation.

+

impl UniformSampler for UniformInt<usize>[src]

type X = usize

The type sampled by this implementation.

+

impl UniformSampler for UniformInt<u128>[src]

type X = u128

The type sampled by this implementation.

+

impl<X: Clone> Clone for UniformInt<X>[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl<X: Copy> Copy for UniformInt<X>[src]

impl<X: Debug> Debug for UniformInt<X>[src]

Auto Trait Implementations

impl<X> Send for UniformInt<X> where
    X: Send

impl<X> Sync for UniformInt<X> where
    X: Sync

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/uniform/trait.SampleBorrow.html b/target/doc/rand/distributions/uniform/trait.SampleBorrow.html new file mode 100644 index 0000000..c6d96d7 --- /dev/null +++ b/target/doc/rand/distributions/uniform/trait.SampleBorrow.html @@ -0,0 +1,12 @@ +rand::distributions::uniform::SampleBorrow - Rust

[][src]Trait rand::distributions::uniform::SampleBorrow

pub trait SampleBorrow<Borrowed> {
+    fn borrow(&self) -> &Borrowed;
+}

Helper trait similar to Borrow but implemented +only for SampleUniform and references to SampleUniform in +order to resolve ambiguity issues.

+
+

Required methods

fn borrow(&self) -> &Borrowed

Immutably borrows from an owned value. See Borrow::borrow

+
Loading content... +

Implementations on Foreign Types

impl<'a, Borrowed> SampleBorrow<Borrowed> for &'a Borrowed where
    Borrowed: SampleUniform
[src]

Loading content... +

Implementors

impl<Borrowed> SampleBorrow<Borrowed> for Borrowed where
    Borrowed: SampleUniform
[src]

Loading content...
\ No newline at end of file diff --git a/target/doc/rand/distributions/uniform/trait.SampleUniform.html b/target/doc/rand/distributions/uniform/trait.SampleUniform.html new file mode 100644 index 0000000..40f1e08 --- /dev/null +++ b/target/doc/rand/distributions/uniform/trait.SampleUniform.html @@ -0,0 +1,13 @@ +rand::distributions::uniform::SampleUniform - Rust

[][src]Trait rand::distributions::uniform::SampleUniform

pub trait SampleUniform: Sized {
+    type Sampler: UniformSampler<X = Self>;
+}

Helper trait for creating objects using the correct implementation of +[UniformSampler] for the sampling type.

+

See the module documentation on how to implement [Uniform] range +sampling for a custom type.

+
+

Associated Types

type Sampler: UniformSampler<X = Self>

The UniformSampler implementation supporting type X.

+
Loading content... +

Implementations on Foreign Types

impl SampleUniform for i8[src]

impl SampleUniform for i16[src]

impl SampleUniform for i32[src]

impl SampleUniform for i64[src]

impl SampleUniform for i128[src]

impl SampleUniform for isize[src]

impl SampleUniform for u8[src]

impl SampleUniform for u16[src]

impl SampleUniform for u32[src]

impl SampleUniform for u64[src]

impl SampleUniform for usize[src]

impl SampleUniform for u128[src]

impl SampleUniform for f32[src]

impl SampleUniform for f64[src]

impl SampleUniform for Duration[src]

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/rand/distributions/uniform/trait.UniformSampler.html b/target/doc/rand/distributions/uniform/trait.UniformSampler.html new file mode 100644 index 0000000..7479b55 --- /dev/null +++ b/target/doc/rand/distributions/uniform/trait.UniformSampler.html @@ -0,0 +1,37 @@ +rand::distributions::uniform::UniformSampler - Rust

[][src]Trait rand::distributions::uniform::UniformSampler

pub trait UniformSampler: Sized {
+    type X;
+    fn new<B1, B2>(low: B1, high: B2) -> Self
    where
        B1: SampleBorrow<Self::X> + Sized,
        B2: SampleBorrow<Self::X> + Sized
; +
fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self
    where
        B1: SampleBorrow<Self::X> + Sized,
        B2: SampleBorrow<Self::X> + Sized
; +
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X; + + fn sample_single<R: Rng + ?Sized, B1, B2>(
        low: B1,
        high: B2,
        rng: &mut R
    ) -> Self::X
    where
        B1: SampleBorrow<Self::X> + Sized,
        B2: SampleBorrow<Self::X> + Sized
, + { ... } +}

Helper trait handling actual uniform sampling.

+

See the module documentation on how to implement [Uniform] range +sampling for a custom type.

+

Implementation of sample_single is optional, and is only useful when +the implementation can be faster than Self::new(low, high).sample(rng).

+
+

Associated Types

type X

The type sampled by this implementation.

+
Loading content... +

Required methods

fn new<B1, B2>(low: B1, high: B2) -> Self where
    B1: SampleBorrow<Self::X> + Sized,
    B2: SampleBorrow<Self::X> + Sized

Construct self, with inclusive lower bound and exclusive upper bound +[low, high).

+

Usually users should not call this directly but instead use +Uniform::new, which asserts that low < high before calling this.

+

fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self where
    B1: SampleBorrow<Self::X> + Sized,
    B2: SampleBorrow<Self::X> + Sized

Construct self, with inclusive bounds [low, high].

+

Usually users should not call this directly but instead use +Uniform::new_inclusive, which asserts that low <= high before +calling this.

+

fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X

Sample a value.

+
Loading content... +

Provided methods

fn sample_single<R: Rng + ?Sized, B1, B2>(
    low: B1,
    high: B2,
    rng: &mut R
) -> Self::X where
    B1: SampleBorrow<Self::X> + Sized,
    B2: SampleBorrow<Self::X> + Sized

Sample a single value uniformly from a range with inclusive lower bound +and exclusive upper bound [low, high).

+

By default this is implemented using +UniformSampler::new(low, high).sample(rng). However, for some types +more optimal implementations for single usage may be provided via this +method (which is the case for integers and floats). +Results may not be identical.

+
Loading content... +

Implementors

impl UniformSampler for UniformDuration[src]

type X = Duration

fn sample_single<R: Rng + ?Sized, B1, B2>(
    low: B1,
    high: B2,
    rng: &mut R
) -> Self::X where
    B1: SampleBorrow<Self::X> + Sized,
    B2: SampleBorrow<Self::X> + Sized
[src]

impl UniformSampler for UniformFloat<f32>[src]

type X = f32

impl UniformSampler for UniformFloat<f64>[src]

type X = f64

impl UniformSampler for UniformInt<i128>[src]

type X = i128

impl UniformSampler for UniformInt<i16>[src]

type X = i16

impl UniformSampler for UniformInt<i32>[src]

type X = i32

impl UniformSampler for UniformInt<i64>[src]

type X = i64

impl UniformSampler for UniformInt<i8>[src]

type X = i8

impl UniformSampler for UniformInt<isize>[src]

type X = isize

impl UniformSampler for UniformInt<u128>[src]

type X = u128

impl UniformSampler for UniformInt<u16>[src]

type X = u16

impl UniformSampler for UniformInt<u32>[src]

type X = u32

impl UniformSampler for UniformInt<u64>[src]

type X = u64

impl UniformSampler for UniformInt<u8>[src]

type X = u8

impl UniformSampler for UniformInt<usize>[src]

type X = usize

Loading content...
\ No newline at end of file diff --git a/target/doc/rand/distributions/unit_circle/struct.UnitCircle.html b/target/doc/rand/distributions/unit_circle/struct.UnitCircle.html new file mode 100644 index 0000000..fd7be41 --- /dev/null +++ b/target/doc/rand/distributions/unit_circle/struct.UnitCircle.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.UnitCircle.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/unit_sphere/struct.UnitSphereSurface.html b/target/doc/rand/distributions/unit_sphere/struct.UnitSphereSurface.html new file mode 100644 index 0000000..64c37e8 --- /dev/null +++ b/target/doc/rand/distributions/unit_sphere/struct.UnitSphereSurface.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.UnitSphereSurface.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/weibull/struct.Weibull.html b/target/doc/rand/distributions/weibull/struct.Weibull.html new file mode 100644 index 0000000..a89ee24 --- /dev/null +++ b/target/doc/rand/distributions/weibull/struct.Weibull.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/distributions/struct.Weibull.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/distributions/weighted/alias_method/index.html b/target/doc/rand/distributions/weighted/alias_method/index.html new file mode 100644 index 0000000..79a31b1 --- /dev/null +++ b/target/doc/rand/distributions/weighted/alias_method/index.html @@ -0,0 +1,9 @@ +rand::distributions::weighted::alias_method - Rust

[][src]Module rand::distributions::weighted::alias_method

This module contains an implementation of alias method for sampling random +indices with probabilities proportional to a collection of weights.

+

Structs

+
WeightedIndex

A distribution using weighted sampling to pick a discretely selected item.

+

Traits

+
Weight

Trait that must be implemented for weights, that are used with +[WeightedIndex]. Currently no guarantees on the correctness of +[WeightedIndex] are given for custom implementations of this trait.

+
\ No newline at end of file diff --git a/target/doc/rand/distributions/weighted/alias_method/sidebar-items.js b/target/doc/rand/distributions/weighted/alias_method/sidebar-items.js new file mode 100644 index 0000000..f94db45 --- /dev/null +++ b/target/doc/rand/distributions/weighted/alias_method/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["WeightedIndex","A distribution using weighted sampling to pick a discretely selected item."]],"trait":[["Weight","Trait that must be implemented for weights, that are used with [`WeightedIndex`]. Currently no guarantees on the correctness of [`WeightedIndex`] are given for custom implementations of this trait."]]}); \ No newline at end of file diff --git a/target/doc/rand/distributions/weighted/alias_method/struct.WeightedIndex.html b/target/doc/rand/distributions/weighted/alias_method/struct.WeightedIndex.html new file mode 100644 index 0000000..283be50 --- /dev/null +++ b/target/doc/rand/distributions/weighted/alias_method/struct.WeightedIndex.html @@ -0,0 +1,61 @@ +rand::distributions::weighted::alias_method::WeightedIndex - Rust

[][src]Struct rand::distributions::weighted::alias_method::WeightedIndex

pub struct WeightedIndex<W: Weight> { /* fields omitted */ }

A distribution using weighted sampling to pick a discretely selected item.

+

Sampling a WeightedIndex<W> distribution returns the index of a randomly +selected element from the vector used to create the WeightedIndex<W>. +The chance of a given element being picked is proportional to the value of +the element. The weights can have any type W for which a implementation of +Weight exists.

+

Performance

+

Given that n is the number of items in the vector used to create an +WeightedIndex<W>, WeightedIndex<W> will require O(n) amount of +memory. More specifically it takes up some constant amount of memory plus +the vector used to create it and a Vec<u32> with capacity n.

+

Time complexity for the creation of a WeightedIndex<W> is O(n). +Sampling is O(1), it makes a call to Uniform<u32>::sample and a call +to Uniform<W>::sample.

+

Example

+
+use rand::distributions::weighted::alias_method::WeightedIndex;
+use rand::prelude::*;
+
+let choices = vec!['a', 'b', 'c'];
+let weights = vec![2, 1, 1];
+let dist = WeightedIndex::new(weights).unwrap();
+let mut rng = thread_rng();
+for _ in 0..100 {
+    // 50% chance to print 'a', 25% chance to print 'b', 25% chance to print 'c'
+    println!("{}", choices[dist.sample(&mut rng)]);
+}
+
+let items = [('a', 0), ('b', 3), ('c', 7)];
+let dist2 = WeightedIndex::new(items.iter().map(|item| item.1).collect()).unwrap();
+for _ in 0..100 {
+    // 0% chance to print 'a', 30% chance to print 'b', 70% chance to print 'c'
+    println!("{}", items[dist2.sample(&mut rng)].0);
+}
+

Methods

impl<W: Weight> WeightedIndex<W>[src]

pub fn new(weights: Vec<W>) -> Result<Self, WeightedError>[src]

Creates a new [WeightedIndex].

+

Returns an error if:

+
    +
  • The vector is empty.
  • +
  • The vector is longer than u32::MAX.
  • +
  • For any weight w: w < 0 or w > max where max = W::MAX / weights.len().
  • +
  • The sum of weights is zero.
  • +
+

Trait Implementations

impl<W: Weight> Distribution<usize> for WeightedIndex<W>[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<W: Weight> Clone for WeightedIndex<W> where
    Uniform<W>: Clone
[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl<W: Weight> Debug for WeightedIndex<W> where
    W: Debug,
    Uniform<W>: Debug
[src]

Auto Trait Implementations

impl<W> Send for WeightedIndex<W> where
    W: Send,
    <W as SampleUniform>::Sampler: Send

impl<W> Sync for WeightedIndex<W> where
    W: Sync,
    <W as SampleUniform>::Sampler: Sync

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/weighted/alias_method/trait.Weight.html b/target/doc/rand/distributions/weighted/alias_method/trait.Weight.html new file mode 100644 index 0000000..1619d3a --- /dev/null +++ b/target/doc/rand/distributions/weighted/alias_method/trait.Weight.html @@ -0,0 +1,24 @@ +rand::distributions::weighted::alias_method::Weight - Rust

[][src]Trait rand::distributions::weighted::alias_method::Weight

pub trait Weight: Sized + Copy + SampleUniform + PartialOrd + Add<Output = Self> + AddAssign + Sub<Output = Self> + SubAssign + Mul<Output = Self> + MulAssign + Div<Output = Self> + DivAssign + Sum {
+    const MAX: Self;
+    const ZERO: Self;
+
+    fn try_from_u32_lossy(n: u32) -> Option<Self>;
+
+    fn sum(values: &[Self]) -> Self { ... }
+}

Trait that must be implemented for weights, that are used with +[WeightedIndex]. Currently no guarantees on the correctness of +[WeightedIndex] are given for custom implementations of this trait.

+
+

Associated Constants

const MAX: Self

Maximum number representable by Self.

+

const ZERO: Self

Element of Self equivalent to 0.

+
Loading content... +

Required methods

fn try_from_u32_lossy(n: u32) -> Option<Self>

Produce an instance of Self from a u32 value, or return None if +out of range. Loss of precision (where Self is a floating point type) +is acceptable.

+
Loading content... +

Provided methods

fn sum(values: &[Self]) -> Self

Sums all values in slice values.

+
Loading content... +

Implementations on Foreign Types

impl Weight for f64[src]

impl Weight for f32[src]

impl Weight for usize[src]

fn sum(values: &[Self]) -> Self[src]

impl Weight for u128[src]

fn sum(values: &[Self]) -> Self[src]

impl Weight for u64[src]

fn sum(values: &[Self]) -> Self[src]

impl Weight for u32[src]

fn sum(values: &[Self]) -> Self[src]

impl Weight for u16[src]

fn sum(values: &[Self]) -> Self[src]

impl Weight for u8[src]

fn sum(values: &[Self]) -> Self[src]

impl Weight for isize[src]

fn sum(values: &[Self]) -> Self[src]

impl Weight for i128[src]

fn sum(values: &[Self]) -> Self[src]

impl Weight for i64[src]

fn sum(values: &[Self]) -> Self[src]

impl Weight for i32[src]

fn sum(values: &[Self]) -> Self[src]

impl Weight for i16[src]

fn sum(values: &[Self]) -> Self[src]

impl Weight for i8[src]

fn sum(values: &[Self]) -> Self[src]

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/rand/distributions/weighted/enum.WeightedError.html b/target/doc/rand/distributions/weighted/enum.WeightedError.html new file mode 100644 index 0000000..e86de0d --- /dev/null +++ b/target/doc/rand/distributions/weighted/enum.WeightedError.html @@ -0,0 +1,39 @@ +rand::distributions::weighted::WeightedError - Rust

[][src]Enum rand::distributions::weighted::WeightedError

pub enum WeightedError {
+    NoItem,
+    InvalidWeight,
+    AllWeightsZero,
+    TooMany,
+}

Error type returned from WeightedIndex::new.

+

+ Variants

+NoItem

The provided weight collection contains no items.

+
InvalidWeight

A weight is either less than zero, greater than the supported maximum or +otherwise invalid.

+
AllWeightsZero

All items in the provided weight collection are zero.

+
TooMany

Too many weights are provided (length greater than u32::MAX)

+

Trait Implementations

impl PartialEq<WeightedError> for WeightedError[src]

#[must_use] +
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests for !=.

+

impl Clone for WeightedError[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for WeightedError[src]

impl Copy for WeightedError[src]

impl Display for WeightedError[src]

impl Debug for WeightedError[src]

impl Error for WeightedError[src]

fn source(&self) -> Option<&(dyn Error + 'static)>1.30.0[src]

The lower-level source of this error, if any. Read more

+

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/distributions/weighted/index.html b/target/doc/rand/distributions/weighted/index.html new file mode 100644 index 0000000..525421d --- /dev/null +++ b/target/doc/rand/distributions/weighted/index.html @@ -0,0 +1,16 @@ +rand::distributions::weighted - Rust

[][src]Module rand::distributions::weighted

Weighted index sampling

+

This module provides two implementations for sampling indices:

+ +

Modules

+
alias_method

This module contains an implementation of alias method for sampling random +indices with probabilities proportional to a collection of weights.

+

Structs

+
WeightedIndex

A distribution using weighted sampling to pick a discretely selected +item.

+

Enums

+
WeightedError

Error type returned from WeightedIndex::new.

+
\ No newline at end of file diff --git a/target/doc/rand/distributions/weighted/sidebar-items.js b/target/doc/rand/distributions/weighted/sidebar-items.js new file mode 100644 index 0000000..874c352 --- /dev/null +++ b/target/doc/rand/distributions/weighted/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"enum":[["WeightedError","Error type returned from `WeightedIndex::new`."]],"mod":[["alias_method","This module contains an implementation of alias method for sampling random indices with probabilities proportional to a collection of weights."]],"struct":[["WeightedIndex","A distribution using weighted sampling to pick a discretely selected item."]]}); \ No newline at end of file diff --git a/target/doc/rand/distributions/weighted/struct.WeightedIndex.html b/target/doc/rand/distributions/weighted/struct.WeightedIndex.html new file mode 100644 index 0000000..f80607a --- /dev/null +++ b/target/doc/rand/distributions/weighted/struct.WeightedIndex.html @@ -0,0 +1,66 @@ +rand::distributions::weighted::WeightedIndex - Rust

[][src]Struct rand::distributions::weighted::WeightedIndex

pub struct WeightedIndex<X: SampleUniform + PartialOrd> { /* fields omitted */ }

A distribution using weighted sampling to pick a discretely selected +item.

+

Sampling a WeightedIndex distribution returns the index of a randomly +selected element from the iterator used when the WeightedIndex was +created. The chance of a given element being picked is proportional to the +value of the element. The weights can use any type X for which an +implementation of Uniform<X> exists.

+

Performance

+

A WeightedIndex<X> contains a Vec<X> and a Uniform<X> and so its +size is the sum of the size of those objects, possibly plus some alignment.

+

Creating a WeightedIndex<X> will allocate enough space to hold N - 1 +weights of type X, where N is the number of weights. However, since +Vec doesn't guarantee a particular growth strategy, additional memory +might be allocated but not used. Since the WeightedIndex object also +contains, this might cause additional allocations, though for primitive +types, ['Uniform`] doesn't allocate any memory.

+

Time complexity of sampling from WeightedIndex is O(log N) where +N is the number of weights.

+

Sampling from WeightedIndex will result in a single call to +Uniform<X>::sample (method of the [Distribution] trait), which typically +will request a single value from the underlying RngCore, though the +exact number depends on the implementaiton of Uniform<X>::sample.

+

Example

+
+use rand::prelude::*;
+use rand::distributions::WeightedIndex;
+
+let choices = ['a', 'b', 'c'];
+let weights = [2,   1,   1];
+let dist = WeightedIndex::new(&weights).unwrap();
+let mut rng = thread_rng();
+for _ in 0..100 {
+    // 50% chance to print 'a', 25% chance to print 'b', 25% chance to print 'c'
+    println!("{}", choices[dist.sample(&mut rng)]);
+}
+
+let items = [('a', 0), ('b', 3), ('c', 7)];
+let dist2 = WeightedIndex::new(items.iter().map(|item| item.1)).unwrap();
+for _ in 0..100 {
+    // 0% chance to print 'a', 30% chance to print 'b', 70% chance to print 'c'
+    println!("{}", items[dist2.sample(&mut rng)].0);
+}
+

Methods

impl<X: SampleUniform + PartialOrd> WeightedIndex<X>[src]

pub fn new<I>(weights: I) -> Result<WeightedIndex<X>, WeightedError> where
    I: IntoIterator,
    I::Item: SampleBorrow<X>,
    X: for<'a> AddAssign<&'a X> + Clone + Default
[src]

Creates a new a WeightedIndex [Distribution] using the values +in weights. The weights can use any type X for which an +implementation of Uniform<X> exists.

+

Returns an error if the iterator is empty, if any weight is < 0, or +if its total value is 0.

+

Trait Implementations

impl<X> Distribution<usize> for WeightedIndex<X> where
    X: SampleUniform + PartialOrd
[src]

Important traits for DistIter<D, R, T>
fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where
    R: Rng,
    Self: Sized
[src]

Create an iterator that generates random values of T, using rng as the source of randomness. Read more

+

impl<X: Clone + SampleUniform + PartialOrd> Clone for WeightedIndex<X> where
    X::Sampler: Clone
[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl<X: Debug + SampleUniform + PartialOrd> Debug for WeightedIndex<X> where
    X::Sampler: Debug
[src]

Auto Trait Implementations

impl<X> Send for WeightedIndex<X> where
    X: Send,
    <X as SampleUniform>::Sampler: Send

impl<X> Sync for WeightedIndex<X> where
    X: Sync,
    <X as SampleUniform>::Sampler: Sync

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/fn.random.html b/target/doc/rand/fn.random.html new file mode 100644 index 0000000..128249e --- /dev/null +++ b/target/doc/rand/fn.random.html @@ -0,0 +1,35 @@ +rand::random - Rust

[][src]Function rand::random

pub fn random<T>() -> T where
    Standard: Distribution<T>, 

Generates a random value using the thread-local random number generator.

+

This is simply a shortcut for thread_rng().gen(). See [thread_rng] for +documentation of the entropy source and Standard for documentation of +distributions and type-specific generation.

+

Examples

+
+let x = rand::random::<u8>();
+println!("{}", x);
+
+let y = rand::random::<f64>();
+println!("{}", y);
+
+if rand::random() { // generates a boolean
+    println!("Better lucky than good!");
+}
+

If you're calling random() in a loop, caching the generator as in the +following example can increase performance.

+ +
+use rand::Rng;
+
+let mut v = vec![1, 2, 3];
+
+for x in v.iter_mut() {
+    *x = rand::random()
+}
+
+// can be made faster by caching thread_rng
+
+let mut rng = rand::thread_rng();
+
+for x in v.iter_mut() {
+    *x = rng.gen();
+}
+
\ No newline at end of file diff --git a/target/doc/rand/fn.thread_rng.html b/target/doc/rand/fn.thread_rng.html new file mode 100644 index 0000000..862bc51 --- /dev/null +++ b/target/doc/rand/fn.thread_rng.html @@ -0,0 +1,7 @@ +rand::thread_rng - Rust

[][src]Function rand::thread_rng

pub fn thread_rng() -> ThreadRng

Retrieve the lazily-initialized thread-local random number generator, +seeded by the system. Intended to be used in method chaining style, +e.g. thread_rng().gen::<i32>(), or cached locally, e.g. +let mut rng = thread_rng();. Invoked by the Default trait, making +ThreadRng::default() equivalent.

+

For more information see [ThreadRng].

+
\ No newline at end of file diff --git a/target/doc/rand/index.html b/target/doc/rand/index.html new file mode 100644 index 0000000..07640e8 --- /dev/null +++ b/target/doc/rand/index.html @@ -0,0 +1,49 @@ +rand - Rust

[][src]Crate rand

Utilities for random number generation

+

Rand provides utilities to generate random numbers, to convert them to +useful types and distributions, and some randomness-related algorithms.

+

Quick Start

+

To get you started quickly, the easiest and highest-level way to get +a random value is to use [random()]; alternatively you can use +[thread_rng()]. The [Rng] trait provides a useful API on all RNGs, while +the [distributions] and [seq] modules provide further +functionality on top of RNGs.

+ +
+use rand::prelude::*;
+
+if rand::random() { // generates a boolean
+    // Try printing a random unicode code point (probably a bad idea)!
+    println!("char: {}", rand::random::<char>());
+}
+
+let mut rng = rand::thread_rng();
+let y: f64 = rng.gen(); // generates a float between 0 and 1
+
+let mut nums: Vec<i32> = (1..100).collect();
+nums.shuffle(&mut rng);
+

The Book

+

For the user guide and futher documentation, please read +The Rust Rand Book.

+

Modules

+
distributions

Generating random samples from probability distributions

+
prelude

Convenience re-export of common members

+
rngs

Random number generators and adapters

+
seq

Sequence-related functionality

+

Structs

+
Error

Error type of random number generators

+

Traits

+
AsByteSliceMut

Trait for casting types to byte slices

+
CryptoRng

A marker trait used to indicate that an [RngCore] or BlockRngCore +implementation is supposed to be cryptographically secure.

+
Rng

An automatically-implemented extension trait on [RngCore] providing high-level +generic methods for sampling values and other convenience methods.

+
RngCore

The core of a random number generator.

+
SeedableRng

A random number generator that can be explicitly seeded.

+

Functions

+
random

Generates a random value using the thread-local random number generator.

+
thread_rng

Retrieve the lazily-initialized thread-local random number generator, +seeded by the system. Intended to be used in method chaining style, +e.g. thread_rng().gen::<i32>(), or cached locally, e.g. +let mut rng = thread_rng();. Invoked by the Default trait, making +ThreadRng::default() equivalent.

+
\ No newline at end of file diff --git a/target/doc/rand/prelude/index.html b/target/doc/rand/prelude/index.html new file mode 100644 index 0000000..ed94af5 --- /dev/null +++ b/target/doc/rand/prelude/index.html @@ -0,0 +1,9 @@ +rand::prelude - Rust

[][src]Module rand::prelude

Convenience re-export of common members

+

Like the standard library's prelude, this module simplifies importing of +common items. Unlike the standard prelude, the contents of this module must +be imported manually:

+ +
+use rand::prelude::*;
+

Re-exports

+
pub use crate::distributions::Distribution;
pub use crate::rngs::StdRng;
pub use crate::rngs::ThreadRng;
pub use crate::Rng;
pub use crate::RngCore;
pub use crate::CryptoRng;
pub use crate::SeedableRng;
pub use crate::random;
pub use crate::thread_rng;
pub use crate::seq::SliceRandom;
pub use crate::seq::IteratorRandom;
\ No newline at end of file diff --git a/target/doc/rand/prelude/sidebar-items.js b/target/doc/rand/prelude/sidebar-items.js new file mode 100644 index 0000000..48333d3 --- /dev/null +++ b/target/doc/rand/prelude/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({}); \ No newline at end of file diff --git a/target/doc/rand/rngs/adapter/index.html b/target/doc/rand/rngs/adapter/index.html new file mode 100644 index 0000000..f8d7cc2 --- /dev/null +++ b/target/doc/rand/rngs/adapter/index.html @@ -0,0 +1,8 @@ +rand::rngs::adapter - Rust

[][src]Module rand::rngs::adapter

Wrappers / adapters forming RNGs

+

Structs

+
ReadError

ReadRng error type

+
ReadRng

An RNG that reads random bytes straight from any type supporting +[std::io::Read], for example files.

+
ReseedingRng

A wrapper around any PRNG that implements BlockRngCore, that adds the +ability to reseed it.

+
\ No newline at end of file diff --git a/target/doc/rand/rngs/adapter/read/struct.ReadError.html b/target/doc/rand/rngs/adapter/read/struct.ReadError.html new file mode 100644 index 0000000..a924427 --- /dev/null +++ b/target/doc/rand/rngs/adapter/read/struct.ReadError.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../../rand/rngs/adapter/struct.ReadError.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/rngs/adapter/read/struct.ReadRng.html b/target/doc/rand/rngs/adapter/read/struct.ReadRng.html new file mode 100644 index 0000000..47beefd --- /dev/null +++ b/target/doc/rand/rngs/adapter/read/struct.ReadRng.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../../rand/rngs/adapter/struct.ReadRng.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/rngs/adapter/reseeding/struct.ReseedingRng.html b/target/doc/rand/rngs/adapter/reseeding/struct.ReseedingRng.html new file mode 100644 index 0000000..ab23f15 --- /dev/null +++ b/target/doc/rand/rngs/adapter/reseeding/struct.ReseedingRng.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../../rand/rngs/adapter/struct.ReseedingRng.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/rngs/adapter/sidebar-items.js b/target/doc/rand/rngs/adapter/sidebar-items.js new file mode 100644 index 0000000..9158072 --- /dev/null +++ b/target/doc/rand/rngs/adapter/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["ReadError","`ReadRng` error type"],["ReadRng","An RNG that reads random bytes straight from any type supporting [`std::io::Read`], for example files."],["ReseedingRng","A wrapper around any PRNG that implements [`BlockRngCore`], that adds the ability to reseed it."]]}); \ No newline at end of file diff --git a/target/doc/rand/rngs/adapter/struct.ReadError.html b/target/doc/rand/rngs/adapter/struct.ReadError.html new file mode 100644 index 0000000..0853c86 --- /dev/null +++ b/target/doc/rand/rngs/adapter/struct.ReadError.html @@ -0,0 +1,18 @@ +rand::rngs::adapter::ReadError - Rust

[][src]Struct rand::rngs::adapter::ReadError

pub struct ReadError(_);

ReadRng error type

+

Trait Implementations

impl Display for ReadError[src]

impl Debug for ReadError[src]

impl Error for ReadError[src]

fn description(&self) -> &str1.0.0[src]

This method is soft-deprecated. Read more

+

fn cause(&self) -> Option<&dyn Error>1.0.0[src]

Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

+

The lower-level cause of this error, if any. Read more

+

Auto Trait Implementations

impl Send for ReadError

impl Sync for ReadError

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/rngs/adapter/struct.ReadRng.html b/target/doc/rand/rngs/adapter/struct.ReadRng.html new file mode 100644 index 0000000..de9669c --- /dev/null +++ b/target/doc/rand/rngs/adapter/struct.ReadRng.html @@ -0,0 +1,42 @@ +rand::rngs::adapter::ReadRng - Rust

[][src]Struct rand::rngs::adapter::ReadRng

pub struct ReadRng<R> { /* fields omitted */ }

An RNG that reads random bytes straight from any type supporting +[std::io::Read], for example files.

+

This will work best with an infinite reader, but that is not required.

+

This can be used with /dev/urandom on Unix but it is recommended to use +OsRng instead.

+

Panics

+

ReadRng uses [std::io::Read::read_exact], which retries on interrupts. +All other errors from the underlying reader, including when it does not +have enough data, will only be reported through try_fill_bytes. +The other [RngCore] methods will panic in case of an error.

+

Example

+
+use rand::Rng;
+use rand::rngs::adapter::ReadRng;
+
+let data = vec![1, 2, 3, 4, 5, 6, 7, 8];
+let mut rng = ReadRng::new(&data[..]);
+println!("{:x}", rng.gen::<u32>());
+

Methods

impl<R: Read> ReadRng<R>[src]

pub fn new(r: R) -> ReadRng<R>[src]

Create a new ReadRng from a Read.

+

Trait Implementations

impl<R: Debug> Debug for ReadRng<R>[src]

impl<R: Read> RngCore for ReadRng<R>[src]

Auto Trait Implementations

impl<R> Send for ReadRng<R> where
    R: Send

impl<R> Sync for ReadRng<R> where
    R: Sync

Blanket Implementations

impl<R> Rng for R where
    R: RngCore + ?Sized
[src]

fn gen<T>(&mut self) -> T where
    Standard: Distribution<T>, 
[src]

Return a random value supporting the [Standard] distribution. Read more

+

fn gen_range<T: SampleUniform, B1, B2>(&mut self, low: B1, high: B2) -> T where
    B1: SampleBorrow<T> + Sized,
    B2: SampleBorrow<T> + Sized
[src]

Generate a random value in the range [low, high), i.e. inclusive of low and exclusive of high. Read more

+

fn sample<T, D: Distribution<T>>(&mut self, distr: D) -> T[src]

Sample a new value, using the given distribution. Read more

+

Important traits for DistIter<D, R, T>
fn sample_iter<T, D>(self, distr: D) -> DistIter<D, Self, T> where
    D: Distribution<T>,
    Self: Sized
[src]

Create an iterator that generates values using the given distribution. Read more

+

fn fill<T: AsByteSliceMut + ?Sized>(&mut self, dest: &mut T)[src]

Fill dest entirely with random bytes (uniform value distribution), where dest is any type supporting [AsByteSliceMut], namely slices and arrays over primitive integer types (i8, i16, u32, etc.). Read more

+

fn try_fill<T: AsByteSliceMut + ?Sized>(
    &mut self,
    dest: &mut T
) -> Result<(), Error>
[src]

Fill dest entirely with random bytes (uniform value distribution), where dest is any type supporting [AsByteSliceMut], namely slices and arrays over primitive integer types (i8, i16, u32, etc.). Read more

+

fn gen_bool(&mut self, p: f64) -> bool[src]

Return a bool with a probability p of being true. Read more

+

fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool[src]

Return a bool with a probability of numerator/denominator of being true. I.e. gen_ratio(2, 3) has chance of 2 in 3, or about 67%, of returning true. If numerator == denominator, then the returned value is guaranteed to be true. If numerator == 0, then the returned value is guaranteed to be false. Read more

+

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/rngs/adapter/struct.ReseedingRng.html b/target/doc/rand/rngs/adapter/struct.ReseedingRng.html new file mode 100644 index 0000000..5ba0eca --- /dev/null +++ b/target/doc/rand/rngs/adapter/struct.ReseedingRng.html @@ -0,0 +1,81 @@ +rand::rngs::adapter::ReseedingRng - Rust

[][src]Struct rand::rngs::adapter::ReseedingRng

pub struct ReseedingRng<R, Rsdr>(_)
where
    R: BlockRngCore + SeedableRng,
    Rsdr: RngCore
;

A wrapper around any PRNG that implements BlockRngCore, that adds the +ability to reseed it.

+

ReseedingRng reseeds the underlying PRNG in the following cases:

+
    +
  • On a manual call to reseed().
  • +
  • After clone(), the clone will be reseeded on first use.
  • +
  • After a process is forked, the RNG in the child process is reseeded within +the next few generated values, depending on the block size of the +underlying PRNG. For ChaCha and Hc128 this is a maximum of +15 u32 values before reseeding.
  • +
  • After the PRNG has generated a configurable number of random bytes.
  • +
+

When should reseeding after a fixed number of generated bytes be used?

+

Reseeding after a fixed number of generated bytes is never strictly +necessary. Cryptographic PRNGs don't have a limited number of bytes they +can output, or at least not a limit reachable in any practical way. There is +no such thing as 'running out of entropy'.

+

Occasionally reseeding can be seen as some form of 'security in depth'. Even +if in the future a cryptographic weakness is found in the CSPRNG being used, +or a flaw in the implementation, occasionally reseeding should make +exploiting it much more difficult or even impossible.

+

Use ReseedingRng::new with a threshold of 0 to disable reseeding +after a fixed number of generated bytes.

+

Error handling

+

Although unlikely, reseeding the wrapped PRNG can fail. ReseedingRng will +never panic but try to handle the error intelligently through some +combination of retrying and delaying reseeding until later. +If handling the source error fails ReseedingRng will continue generating +data from the wrapped PRNG without reseeding.

+

Manually calling reseed() will not have this retry or delay logic, but +reports the error.

+

Example

+
+use rand::prelude::*;
+use rand_chacha::ChaCha20Core; // Internal part of ChaChaRng that
+                             // implements BlockRngCore
+use rand::rngs::OsRng;
+use rand::rngs::adapter::ReseedingRng;
+
+let prng = ChaCha20Core::from_entropy();
+let mut reseeding_rng = ReseedingRng::new(prng, 0, OsRng);
+
+println!("{}", reseeding_rng.gen::<u64>());
+
+let mut cloned_rng = reseeding_rng.clone();
+assert!(reseeding_rng.gen::<u64>() != cloned_rng.gen::<u64>());
+

Methods

impl<R, Rsdr> ReseedingRng<R, Rsdr> where
    R: BlockRngCore + SeedableRng,
    Rsdr: RngCore
[src]

pub fn new(rng: R, threshold: u64, reseeder: Rsdr) -> Self[src]

Create a new ReseedingRng from an existing PRNG, combined with a RNG +to use as reseeder.

+

threshold sets the number of generated bytes after which to reseed the +PRNG. Set it to zero to never reseed based on the number of generated +values.

+

pub fn reseed(&mut self) -> Result<(), Error>[src]

Reseed the internal PRNG.

+

Trait Implementations

impl<R, Rsdr> Clone for ReseedingRng<R, Rsdr> where
    R: BlockRngCore + SeedableRng + Clone,
    Rsdr: RngCore + Clone
[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl<R: Debug, Rsdr: Debug> Debug for ReseedingRng<R, Rsdr> where
    R: BlockRngCore + SeedableRng,
    Rsdr: RngCore
[src]

impl<R, Rsdr: RngCore> RngCore for ReseedingRng<R, Rsdr> where
    R: BlockRngCore<Item = u32> + SeedableRng,
    <R as BlockRngCore>::Results: AsRef<[u32]> + AsMut<[u32]>, 
[src]

impl<R, Rsdr> CryptoRng for ReseedingRng<R, Rsdr> where
    R: BlockRngCore + SeedableRng + CryptoRng,
    Rsdr: RngCore + CryptoRng
[src]

Auto Trait Implementations

impl<R, Rsdr> Send for ReseedingRng<R, Rsdr> where
    R: Send,
    Rsdr: Send,
    <R as BlockRngCore>::Results: Send

impl<R, Rsdr> Sync for ReseedingRng<R, Rsdr> where
    R: Sync,
    Rsdr: Sync,
    <R as BlockRngCore>::Results: Sync

Blanket Implementations

impl<R> Rng for R where
    R: RngCore + ?Sized
[src]

fn gen<T>(&mut self) -> T where
    Standard: Distribution<T>, 
[src]

Return a random value supporting the [Standard] distribution. Read more

+

fn gen_range<T: SampleUniform, B1, B2>(&mut self, low: B1, high: B2) -> T where
    B1: SampleBorrow<T> + Sized,
    B2: SampleBorrow<T> + Sized
[src]

Generate a random value in the range [low, high), i.e. inclusive of low and exclusive of high. Read more

+

fn sample<T, D: Distribution<T>>(&mut self, distr: D) -> T[src]

Sample a new value, using the given distribution. Read more

+

Important traits for DistIter<D, R, T>
fn sample_iter<T, D>(self, distr: D) -> DistIter<D, Self, T> where
    D: Distribution<T>,
    Self: Sized
[src]

Create an iterator that generates values using the given distribution. Read more

+

fn fill<T: AsByteSliceMut + ?Sized>(&mut self, dest: &mut T)[src]

Fill dest entirely with random bytes (uniform value distribution), where dest is any type supporting [AsByteSliceMut], namely slices and arrays over primitive integer types (i8, i16, u32, etc.). Read more

+

fn try_fill<T: AsByteSliceMut + ?Sized>(
    &mut self,
    dest: &mut T
) -> Result<(), Error>
[src]

Fill dest entirely with random bytes (uniform value distribution), where dest is any type supporting [AsByteSliceMut], namely slices and arrays over primitive integer types (i8, i16, u32, etc.). Read more

+

fn gen_bool(&mut self, p: f64) -> bool[src]

Return a bool with a probability p of being true. Read more

+

fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool[src]

Return a bool with a probability of numerator/denominator of being true. I.e. gen_ratio(2, 3) has chance of 2 in 3, or about 67%, of returning true. If numerator == denominator, then the returned value is guaranteed to be true. If numerator == 0, then the returned value is guaranteed to be false. Read more

+

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/rngs/entropy/struct.EntropyRng.html b/target/doc/rand/rngs/entropy/struct.EntropyRng.html new file mode 100644 index 0000000..62bf6c7 --- /dev/null +++ b/target/doc/rand/rngs/entropy/struct.EntropyRng.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/rngs/struct.EntropyRng.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/rngs/index.html b/target/doc/rand/rngs/index.html new file mode 100644 index 0000000..cb32293 --- /dev/null +++ b/target/doc/rand/rngs/index.html @@ -0,0 +1,82 @@ +rand::rngs - Rust

[][src]Module rand::rngs

Random number generators and adapters

+

Background: Random number generators (RNGs)

+

Computers cannot produce random numbers from nowhere. We classify +random number generators as follows:

+
    +
  • "True" random number generators (TRNGs) use hard-to-predict data sources +(e.g. the high-resolution parts of event timings and sensor jitter) to +harvest random bit-sequences, apply algorithms to remove bias and +estimate available entropy, then combine these bits into a byte-sequence +or an entropy pool. This job is usually done by the operating system or +a hardware generator (HRNG).
  • +
  • "Pseudo"-random number generators (PRNGs) use algorithms to transform a +seed into a sequence of pseudo-random numbers. These generators can be +fast and produce well-distributed unpredictable random numbers (or not). +They are usually deterministic: given algorithm and seed, the output +sequence can be reproduced. They have finite period and eventually loop; +with many algorithms this period is fixed and can be proven sufficiently +long, while others are chaotic and the period depends on the seed.
  • +
  • "Cryptographically secure" pseudo-random number generators (CSPRNGs) +are the sub-set of PRNGs which are secure. Security of the generator +relies both on hiding the internal state and using a strong algorithm.
  • +
+

Traits and functionality

+

All RNGs implement the [RngCore] trait, as a consequence of which the +[Rng] extension trait is automatically implemented. Secure RNGs may +additionally implement the [CryptoRng] trait.

+

All PRNGs require a seed to produce their random number sequence. The +[SeedableRng] trait provides three ways of constructing PRNGs:

+
    +
  • from_seed accepts a type specific to the PRNG
  • +
  • from_rng allows a PRNG to be seeded from any other RNG
  • +
  • seed_from_u64 allows any PRNG to be seeded from a u64 insecurely
  • +
  • from_entropy securely seeds a PRNG from fresh entropy
  • +
+

Use the [rand_core] crate when implementing your own RNGs.

+

Our generators

+

This crate provides several random number generators:

+
    +
  • OsRng is an interface to the operating system's random number +source. Typically the operating system uses a CSPRNG with entropy +provided by a TRNG and some type of on-going re-seeding.
  • +
  • ThreadRng, provided by the [thread_rng] function, is a handle to a +thread-local CSPRNG with periodic seeding from OsRng. Because this +is local, it is typically much faster than OsRng. It should be +secure, though the paranoid may prefer OsRng.
  • +
  • StdRng is a CSPRNG chosen for good performance and trust of security +(based on reviews, maturity and usage). The current algorithm is ChaCha20, +which is well established and rigorously analysed. +StdRng provides the algorithm used by ThreadRng but without +periodic reseeding.
  • +
  • SmallRng is an insecure PRNG designed to be fast, simple, require +little memory, and have good output quality.
  • +
+

The algorithms selected for StdRng and SmallRng may change in any +release and may be platform-dependent, therefore they should be considered +not reproducible.

+

Additional generators

+

TRNGs: The rdrand crate provides an interface to the RDRAND and +RDSEED instructions available in modern Intel and AMD CPUs. +The rand_jitter crate provides a user-space implementation of +entropy harvesting from CPU timer jitter, but is very slow and has +security issues.

+

PRNGs: Several companion crates are available, providing individual or +families of PRNG algorithms. These provide the implementations behind +StdRng and SmallRng but can also be used directly, indeed should +be used directly when reproducibility matters. +Some suggestions are: rand_chacha, rand_pcg, rand_xoshiro. +A full list can be found by searching for crates with the rng tag.

+

Modules

+
adapter

Wrappers / adapters forming RNGs

+
mock

Mock random number generator

+

Structs

+
EntropyRngDeprecated

An interface returning random data from external source(s), provided +specifically for securely seeding algorithmic generators (PRNGs).

+
OsRng

A random number generator that retrieves randomness from from the +operating system.

+
StdRng

The standard RNG. The PRNG algorithm in StdRng is chosen to be efficient +on the current platform, to be statistically strong and unpredictable +(meaning a cryptographically secure PRNG).

+
ThreadRng

The type returned by [thread_rng], essentially just a reference to the +PRNG in thread-local memory.

+
\ No newline at end of file diff --git a/target/doc/rand/rngs/mock/index.html b/target/doc/rand/rngs/mock/index.html new file mode 100644 index 0000000..75b9096 --- /dev/null +++ b/target/doc/rand/rngs/mock/index.html @@ -0,0 +1,4 @@ +rand::rngs::mock - Rust

[][src]Module rand::rngs::mock

Mock random number generator

+

Structs

+
StepRng

A simple implementation of RngCore for testing purposes.

+
\ No newline at end of file diff --git a/target/doc/rand/rngs/mock/sidebar-items.js b/target/doc/rand/rngs/mock/sidebar-items.js new file mode 100644 index 0000000..aca61f8 --- /dev/null +++ b/target/doc/rand/rngs/mock/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["StepRng","A simple implementation of `RngCore` for testing purposes."]]}); \ No newline at end of file diff --git a/target/doc/rand/rngs/mock/struct.StepRng.html b/target/doc/rand/rngs/mock/struct.StepRng.html new file mode 100644 index 0000000..6af4448 --- /dev/null +++ b/target/doc/rand/rngs/mock/struct.StepRng.html @@ -0,0 +1,43 @@ +rand::rngs::mock::StepRng - Rust

[][src]Struct rand::rngs::mock::StepRng

pub struct StepRng { /* fields omitted */ }

A simple implementation of RngCore for testing purposes.

+

This generates an arithmetic sequence (i.e. adds a constant each step) +over a u64 number, using wrapping arithmetic. If the increment is 0 +the generator yields a constant.

+ +
+use rand::Rng;
+use rand::rngs::mock::StepRng;
+ 
+let mut my_rng = StepRng::new(2, 1);
+let sample: [u64; 3] = my_rng.gen();
+assert_eq!(sample, [2, 3, 4]);
+

Methods

impl StepRng[src]

pub fn new(initial: u64, increment: u64) -> Self[src]

Create a StepRng, yielding an arithmetic sequence starting with +initial and incremented by increment each time.

+

Trait Implementations

impl Clone for StepRng[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Debug for StepRng[src]

impl RngCore for StepRng[src]

Auto Trait Implementations

impl Send for StepRng

impl Sync for StepRng

Blanket Implementations

impl<R> Rng for R where
    R: RngCore + ?Sized
[src]

fn gen<T>(&mut self) -> T where
    Standard: Distribution<T>, 
[src]

Return a random value supporting the [Standard] distribution. Read more

+

fn gen_range<T: SampleUniform, B1, B2>(&mut self, low: B1, high: B2) -> T where
    B1: SampleBorrow<T> + Sized,
    B2: SampleBorrow<T> + Sized
[src]

Generate a random value in the range [low, high), i.e. inclusive of low and exclusive of high. Read more

+

fn sample<T, D: Distribution<T>>(&mut self, distr: D) -> T[src]

Sample a new value, using the given distribution. Read more

+

Important traits for DistIter<D, R, T>
fn sample_iter<T, D>(self, distr: D) -> DistIter<D, Self, T> where
    D: Distribution<T>,
    Self: Sized
[src]

Create an iterator that generates values using the given distribution. Read more

+

fn fill<T: AsByteSliceMut + ?Sized>(&mut self, dest: &mut T)[src]

Fill dest entirely with random bytes (uniform value distribution), where dest is any type supporting [AsByteSliceMut], namely slices and arrays over primitive integer types (i8, i16, u32, etc.). Read more

+

fn try_fill<T: AsByteSliceMut + ?Sized>(
    &mut self,
    dest: &mut T
) -> Result<(), Error>
[src]

Fill dest entirely with random bytes (uniform value distribution), where dest is any type supporting [AsByteSliceMut], namely slices and arrays over primitive integer types (i8, i16, u32, etc.). Read more

+

fn gen_bool(&mut self, p: f64) -> bool[src]

Return a bool with a probability p of being true. Read more

+

fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool[src]

Return a bool with a probability of numerator/denominator of being true. I.e. gen_ratio(2, 3) has chance of 2 in 3, or about 67%, of returning true. If numerator == denominator, then the returned value is guaranteed to be true. If numerator == 0, then the returned value is guaranteed to be false. Read more

+

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/rngs/os/struct.OsRng.html b/target/doc/rand/rngs/os/struct.OsRng.html new file mode 100644 index 0000000..52105c6 --- /dev/null +++ b/target/doc/rand/rngs/os/struct.OsRng.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/rngs/struct.OsRng.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/rngs/sidebar-items.js b/target/doc/rand/rngs/sidebar-items.js new file mode 100644 index 0000000..59219a0 --- /dev/null +++ b/target/doc/rand/rngs/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"mod":[["adapter","Wrappers / adapters forming RNGs"],["mock","Mock random number generator"]],"struct":[["EntropyRng","An interface returning random data from external source(s), provided specifically for securely seeding algorithmic generators (PRNGs)."],["OsRng","A random number generator that retrieves randomness from from the operating system."],["StdRng","The standard RNG. The PRNG algorithm in `StdRng` is chosen to be efficient on the current platform, to be statistically strong and unpredictable (meaning a cryptographically secure PRNG)."],["ThreadRng","The type returned by [`thread_rng`], essentially just a reference to the PRNG in thread-local memory."]]}); \ No newline at end of file diff --git a/target/doc/rand/rngs/std/struct.StdRng.html b/target/doc/rand/rngs/std/struct.StdRng.html new file mode 100644 index 0000000..563af84 --- /dev/null +++ b/target/doc/rand/rngs/std/struct.StdRng.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/rngs/struct.StdRng.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/rngs/struct.EntropyRng.html b/target/doc/rand/rngs/struct.EntropyRng.html new file mode 100644 index 0000000..7418278 --- /dev/null +++ b/target/doc/rand/rngs/struct.EntropyRng.html @@ -0,0 +1,32 @@ +rand::rngs::EntropyRng - Rust

[][src]Struct rand::rngs::EntropyRng

pub struct EntropyRng { /* fields omitted */ }
Deprecated since 0.7.0:

use rngs::OsRng instead

+

An interface returning random data from external source(s), provided +specifically for securely seeding algorithmic generators (PRNGs).

+

This is deprecated. It is suggested you use rngs::OsRng instead.

+

Methods

impl EntropyRng[src]

pub fn new() -> Self[src]

Create a new EntropyRng.

+

This method will do no system calls or other initialization routines, +those are done on first use. This is done to make new infallible, +and try_fill_bytes the only place to report errors.

+

Trait Implementations

impl Default for EntropyRng[src]

impl Debug for EntropyRng[src]

impl RngCore for EntropyRng[src]

impl CryptoRng for EntropyRng[src]

Auto Trait Implementations

impl Send for EntropyRng

impl Sync for EntropyRng

Blanket Implementations

impl<R> Rng for R where
    R: RngCore + ?Sized
[src]

fn gen<T>(&mut self) -> T where
    Standard: Distribution<T>, 
[src]

Return a random value supporting the [Standard] distribution. Read more

+

fn gen_range<T: SampleUniform, B1, B2>(&mut self, low: B1, high: B2) -> T where
    B1: SampleBorrow<T> + Sized,
    B2: SampleBorrow<T> + Sized
[src]

Generate a random value in the range [low, high), i.e. inclusive of low and exclusive of high. Read more

+

fn sample<T, D: Distribution<T>>(&mut self, distr: D) -> T[src]

Sample a new value, using the given distribution. Read more

+

Important traits for DistIter<D, R, T>
fn sample_iter<T, D>(self, distr: D) -> DistIter<D, Self, T> where
    D: Distribution<T>,
    Self: Sized
[src]

Create an iterator that generates values using the given distribution. Read more

+

fn fill<T: AsByteSliceMut + ?Sized>(&mut self, dest: &mut T)[src]

Fill dest entirely with random bytes (uniform value distribution), where dest is any type supporting [AsByteSliceMut], namely slices and arrays over primitive integer types (i8, i16, u32, etc.). Read more

+

fn try_fill<T: AsByteSliceMut + ?Sized>(
    &mut self,
    dest: &mut T
) -> Result<(), Error>
[src]

Fill dest entirely with random bytes (uniform value distribution), where dest is any type supporting [AsByteSliceMut], namely slices and arrays over primitive integer types (i8, i16, u32, etc.). Read more

+

fn gen_bool(&mut self, p: f64) -> bool[src]

Return a bool with a probability p of being true. Read more

+

fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool[src]

Return a bool with a probability of numerator/denominator of being true. I.e. gen_ratio(2, 3) has chance of 2 in 3, or about 67%, of returning true. If numerator == denominator, then the returned value is guaranteed to be true. If numerator == 0, then the returned value is guaranteed to be false. Read more

+

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/rngs/struct.OsRng.html b/target/doc/rand/rngs/struct.OsRng.html new file mode 100644 index 0000000..35916ce --- /dev/null +++ b/target/doc/rand/rngs/struct.OsRng.html @@ -0,0 +1,57 @@ +rand::rngs::OsRng - Rust

[][src]Struct rand::rngs::OsRng

pub struct OsRng;

A random number generator that retrieves randomness from from the +operating system.

+

This is a zero-sized struct. It can be freely constructed with OsRng.

+

The implementation is provided by the getrandom crate. Refer to +getrandom documentation for details.

+

Blocking and error handling

+

It is possible that when used during early boot the first call to OsRng +will block until the system's RNG is initialised. It is also possible +(though highly unlikely) for OsRng to fail on some platforms, most +likely due to system mis-configuration.

+

After the first successful call, it is highly unlikely that failures or +significant delays will occur (although performance should be expected to +be much slower than a user-space PRNG).

+

Usage example

+
+use rand::rngs::{StdRng, OsRng};
+use rand::{RngCore, SeedableRng};
+
+let mut key = [0u8; 16];
+OsRng.fill_bytes(&mut key);
+let random_u64 = OsRng.next_u64();
+ 
+// OsRng is especially useful for seeding other RNGs (see also from_entropy)
+let mut rng = StdRng::from_rng(OsRng).unwrap();
+let _ = rng.next_u32();
+

Methods

impl OsRng[src]

pub fn new() -> Result<OsRng, Error>[src]

Deprecated since 0.7.0:

replace OsRng::new().unwrap() with just OsRng

+

Create a new OsRng.

+

Trait Implementations

impl Clone for OsRng[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Default for OsRng[src]

impl Copy for OsRng[src]

impl Debug for OsRng[src]

impl RngCore for OsRng[src]

impl CryptoRng for OsRng[src]

Auto Trait Implementations

impl Send for OsRng

impl Sync for OsRng

Blanket Implementations

impl<R> Rng for R where
    R: RngCore + ?Sized
[src]

fn gen<T>(&mut self) -> T where
    Standard: Distribution<T>, 
[src]

Return a random value supporting the [Standard] distribution. Read more

+

fn gen_range<T: SampleUniform, B1, B2>(&mut self, low: B1, high: B2) -> T where
    B1: SampleBorrow<T> + Sized,
    B2: SampleBorrow<T> + Sized
[src]

Generate a random value in the range [low, high), i.e. inclusive of low and exclusive of high. Read more

+

fn sample<T, D: Distribution<T>>(&mut self, distr: D) -> T[src]

Sample a new value, using the given distribution. Read more

+

Important traits for DistIter<D, R, T>
fn sample_iter<T, D>(self, distr: D) -> DistIter<D, Self, T> where
    D: Distribution<T>,
    Self: Sized
[src]

Create an iterator that generates values using the given distribution. Read more

+

fn fill<T: AsByteSliceMut + ?Sized>(&mut self, dest: &mut T)[src]

Fill dest entirely with random bytes (uniform value distribution), where dest is any type supporting [AsByteSliceMut], namely slices and arrays over primitive integer types (i8, i16, u32, etc.). Read more

+

fn try_fill<T: AsByteSliceMut + ?Sized>(
    &mut self,
    dest: &mut T
) -> Result<(), Error>
[src]

Fill dest entirely with random bytes (uniform value distribution), where dest is any type supporting [AsByteSliceMut], namely slices and arrays over primitive integer types (i8, i16, u32, etc.). Read more

+

fn gen_bool(&mut self, p: f64) -> bool[src]

Return a bool with a probability p of being true. Read more

+

fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool[src]

Return a bool with a probability of numerator/denominator of being true. I.e. gen_ratio(2, 3) has chance of 2 in 3, or about 67%, of returning true. If numerator == denominator, then the returned value is guaranteed to be true. If numerator == 0, then the returned value is guaranteed to be false. Read more

+

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/rngs/struct.StdRng.html b/target/doc/rand/rngs/struct.StdRng.html new file mode 100644 index 0000000..273e09b --- /dev/null +++ b/target/doc/rand/rngs/struct.StdRng.html @@ -0,0 +1,45 @@ +rand::rngs::StdRng - Rust

[][src]Struct rand::rngs::StdRng

pub struct StdRng(_);

The standard RNG. The PRNG algorithm in StdRng is chosen to be efficient +on the current platform, to be statistically strong and unpredictable +(meaning a cryptographically secure PRNG).

+

The current algorithm used is the ChaCha block cipher with either 20 or 12 +rounds (see the stdrng_* feature flags, documented in the README). +This may change as new evidence of cipher security and performance +becomes available.

+

The algorithm is deterministic but should not be considered reproducible +due to dependence on configuration and possible replacement in future +library versions. For a secure reproducible generator, we recommend use of +the rand_chacha crate directly.

+

Trait Implementations

impl Clone for StdRng[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Debug for StdRng[src]

impl RngCore for StdRng[src]

impl CryptoRng for StdRng[src]

impl SeedableRng for StdRng[src]

type Seed = <Rng as SeedableRng>::Seed

Seed type, which is restricted to types mutably-dereferencable as u8 arrays (we recommend [u8; N] for some N). Read more

+

fn seed_from_u64(state: u64) -> Self[src]

Create a new PRNG using a u64 seed. Read more

+

fn from_entropy() -> Self[src]

Creates a new instance of the RNG seeded via [getrandom]. Read more

+

Auto Trait Implementations

impl Send for StdRng

impl Sync for StdRng

Blanket Implementations

impl<R> Rng for R where
    R: RngCore + ?Sized
[src]

fn gen<T>(&mut self) -> T where
    Standard: Distribution<T>, 
[src]

Return a random value supporting the [Standard] distribution. Read more

+

fn gen_range<T: SampleUniform, B1, B2>(&mut self, low: B1, high: B2) -> T where
    B1: SampleBorrow<T> + Sized,
    B2: SampleBorrow<T> + Sized
[src]

Generate a random value in the range [low, high), i.e. inclusive of low and exclusive of high. Read more

+

fn sample<T, D: Distribution<T>>(&mut self, distr: D) -> T[src]

Sample a new value, using the given distribution. Read more

+

Important traits for DistIter<D, R, T>
fn sample_iter<T, D>(self, distr: D) -> DistIter<D, Self, T> where
    D: Distribution<T>,
    Self: Sized
[src]

Create an iterator that generates values using the given distribution. Read more

+

fn fill<T: AsByteSliceMut + ?Sized>(&mut self, dest: &mut T)[src]

Fill dest entirely with random bytes (uniform value distribution), where dest is any type supporting [AsByteSliceMut], namely slices and arrays over primitive integer types (i8, i16, u32, etc.). Read more

+

fn try_fill<T: AsByteSliceMut + ?Sized>(
    &mut self,
    dest: &mut T
) -> Result<(), Error>
[src]

Fill dest entirely with random bytes (uniform value distribution), where dest is any type supporting [AsByteSliceMut], namely slices and arrays over primitive integer types (i8, i16, u32, etc.). Read more

+

fn gen_bool(&mut self, p: f64) -> bool[src]

Return a bool with a probability p of being true. Read more

+

fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool[src]

Return a bool with a probability of numerator/denominator of being true. I.e. gen_ratio(2, 3) has chance of 2 in 3, or about 67%, of returning true. If numerator == denominator, then the returned value is guaranteed to be true. If numerator == 0, then the returned value is guaranteed to be false. Read more

+

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/rngs/struct.ThreadRng.html b/target/doc/rand/rngs/struct.ThreadRng.html new file mode 100644 index 0000000..cbc483b --- /dev/null +++ b/target/doc/rand/rngs/struct.ThreadRng.html @@ -0,0 +1,41 @@ +rand::rngs::ThreadRng - Rust

[][src]Struct rand::rngs::ThreadRng

pub struct ThreadRng { /* fields omitted */ }

The type returned by [thread_rng], essentially just a reference to the +PRNG in thread-local memory.

+

ThreadRng uses the same PRNG as StdRng for security and performance. +As hinted by the name, the generator is thread-local. ThreadRng is a +handle to this generator and thus supports Copy, but not Send or Sync.

+

Unlike StdRng, ThreadRng uses the ReseedingRng wrapper to reseed +the PRNG from fresh entropy every 64 kiB of random data. +[OsRng] is used to provide seed data.

+

Note that the reseeding is done as an extra precaution against side-channel +attacks and mis-use (e.g. if somehow weak entropy were supplied initially). +The PRNG algorithms used are assumed to be secure.

+

Trait Implementations

impl Clone for ThreadRng[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Default for ThreadRng[src]

impl Copy for ThreadRng[src]

impl Debug for ThreadRng[src]

impl RngCore for ThreadRng[src]

impl CryptoRng for ThreadRng[src]

Auto Trait Implementations

impl !Send for ThreadRng

impl !Sync for ThreadRng

Blanket Implementations

impl<R> Rng for R where
    R: RngCore + ?Sized
[src]

fn gen<T>(&mut self) -> T where
    Standard: Distribution<T>, 
[src]

Return a random value supporting the [Standard] distribution. Read more

+

fn gen_range<T: SampleUniform, B1, B2>(&mut self, low: B1, high: B2) -> T where
    B1: SampleBorrow<T> + Sized,
    B2: SampleBorrow<T> + Sized
[src]

Generate a random value in the range [low, high), i.e. inclusive of low and exclusive of high. Read more

+

fn sample<T, D: Distribution<T>>(&mut self, distr: D) -> T[src]

Sample a new value, using the given distribution. Read more

+

Important traits for DistIter<D, R, T>
fn sample_iter<T, D>(self, distr: D) -> DistIter<D, Self, T> where
    D: Distribution<T>,
    Self: Sized
[src]

Create an iterator that generates values using the given distribution. Read more

+

fn fill<T: AsByteSliceMut + ?Sized>(&mut self, dest: &mut T)[src]

Fill dest entirely with random bytes (uniform value distribution), where dest is any type supporting [AsByteSliceMut], namely slices and arrays over primitive integer types (i8, i16, u32, etc.). Read more

+

fn try_fill<T: AsByteSliceMut + ?Sized>(
    &mut self,
    dest: &mut T
) -> Result<(), Error>
[src]

Fill dest entirely with random bytes (uniform value distribution), where dest is any type supporting [AsByteSliceMut], namely slices and arrays over primitive integer types (i8, i16, u32, etc.). Read more

+

fn gen_bool(&mut self, p: f64) -> bool[src]

Return a bool with a probability p of being true. Read more

+

fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool[src]

Return a bool with a probability of numerator/denominator of being true. I.e. gen_ratio(2, 3) has chance of 2 in 3, or about 67%, of returning true. If numerator == denominator, then the returned value is guaranteed to be true. If numerator == 0, then the returned value is guaranteed to be false. Read more

+

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/rngs/thread/fn.thread_rng.html b/target/doc/rand/rngs/thread/fn.thread_rng.html new file mode 100644 index 0000000..06602fd --- /dev/null +++ b/target/doc/rand/rngs/thread/fn.thread_rng.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/fn.thread_rng.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/rngs/thread/struct.ThreadRng.html b/target/doc/rand/rngs/thread/struct.ThreadRng.html new file mode 100644 index 0000000..11702f7 --- /dev/null +++ b/target/doc/rand/rngs/thread/struct.ThreadRng.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../rand/rngs/struct.ThreadRng.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand/seq/index.html b/target/doc/rand/seq/index.html new file mode 100644 index 0000000..7942b77 --- /dev/null +++ b/target/doc/rand/seq/index.html @@ -0,0 +1,24 @@ +rand::seq - Rust

[][src]Module rand::seq

Sequence-related functionality

+

This module provides:

+
    +
  • [seq::SliceRandom] slice sampling and mutation
  • +
  • [seq::IteratorRandom] iterator sampling
  • +
  • [seq::index::sample] low-level API to choose multiple indices from +0..length
  • +
+

Also see:

+
    +
  • [distributions::weighted] module which provides implementations of +weighted index sampling.
  • +
+

In order to make results reproducible across 32-64 bit architectures, all +usize indices are sampled as a u32 where possible (also providing a +small performance boost in some cases).

+

Modules

+
index

Low-level API for sampling indices

+

Structs

+
SliceChooseIter

An iterator over multiple slice elements.

+

Traits

+
IteratorRandom

Extension trait on iterators, providing random sampling methods.

+
SliceRandom

Extension trait on slices, providing random mutation and sampling methods.

+
\ No newline at end of file diff --git a/target/doc/rand/seq/index/enum.IndexVec.html b/target/doc/rand/seq/index/enum.IndexVec.html new file mode 100644 index 0000000..c2fa427 --- /dev/null +++ b/target/doc/rand/seq/index/enum.IndexVec.html @@ -0,0 +1,33 @@ +rand::seq::index::IndexVec - Rust

[][src]Enum rand::seq::index::IndexVec

pub enum IndexVec {
+    // some variants omitted
+}

A vector of indices.

+

Multiple internal representations are possible.

+

Methods

impl IndexVec[src]

pub fn len(&self) -> usize[src]

Returns the number of indices

+

pub fn index(&self, index: usize) -> usize[src]

Return the value at the given index.

+

(Note: we cannot implement [std::ops::Index] because of lifetime +restrictions.)

+

pub fn into_vec(self) -> Vec<usize>[src]

Return result as a Vec<usize>. Conversion may or may not be trivial.

+

Important traits for IndexVecIter<'a>
pub fn iter<'a>(&'a self) -> IndexVecIter<'a>[src]

Iterate over the indices as a sequence of usize values

+

Important traits for IndexVecIntoIter
pub fn into_iter(self) -> IndexVecIntoIter[src]

Convert into an iterator over the indices as a sequence of usize values

+

Trait Implementations

impl PartialEq<IndexVec> for IndexVec[src]

#[must_use] +
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests for !=.

+

impl From<Vec<u32>> for IndexVec[src]

impl From<Vec<usize>> for IndexVec[src]

impl Clone for IndexVec[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Debug for IndexVec[src]

Auto Trait Implementations

impl Send for IndexVec

impl Sync for IndexVec

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/seq/index/enum.IndexVecIntoIter.html b/target/doc/rand/seq/index/enum.IndexVecIntoIter.html new file mode 100644 index 0000000..9f7c345 --- /dev/null +++ b/target/doc/rand/seq/index/enum.IndexVecIntoIter.html @@ -0,0 +1,92 @@ +rand::seq::index::IndexVecIntoIter - Rust

[][src]Enum rand::seq::index::IndexVecIntoIter

pub enum IndexVecIntoIter {
+    // some variants omitted
+}

Return type of IndexVec::into_iter.

+

Trait Implementations

impl Iterator for IndexVecIntoIter[src]

type Item = usize

The type of the elements being iterated over.

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

impl Clone for IndexVecIntoIter[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl ExactSizeIterator for IndexVecIntoIter[src]

fn len(&self) -> usize1.0.0[src]

Returns the exact number of times the iterator will iterate. Read more

+

fn is_empty(&self) -> bool[src]

🔬 This is a nightly-only experimental API. (exact_size_is_empty)

Returns true if the iterator is empty. Read more

+

impl Debug for IndexVecIntoIter[src]

Auto Trait Implementations

Blanket Implementations

impl<I> IteratorRandom for I where
    I: Iterator
[src]

fn choose<R: ?Sized>(self, rng: &mut R) -> Option<Self::Item> where
    R: Rng
[src]

Choose one element at random from the iterator. Read more

+

fn choose_multiple_fill<R: ?Sized>(
    self,
    rng: &mut R,
    buf: &mut [Self::Item]
) -> usize where
    R: Rng
[src]

Collects values at random from the iterator into a supplied buffer until that buffer is filled. Read more

+

fn choose_multiple<R: ?Sized>(
    self,
    rng: &mut R,
    amount: usize
) -> Vec<Self::Item> where
    R: Rng
[src]

Collects amount values at random from the iterator into a vector. Read more

+

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/seq/index/enum.IndexVecIter.html b/target/doc/rand/seq/index/enum.IndexVecIter.html new file mode 100644 index 0000000..0384de9 --- /dev/null +++ b/target/doc/rand/seq/index/enum.IndexVecIter.html @@ -0,0 +1,86 @@ +rand::seq::index::IndexVecIter - Rust

[][src]Enum rand::seq::index::IndexVecIter

pub enum IndexVecIter<'a> {
+    // some variants omitted
+}

Return type of IndexVec::iter.

+

Trait Implementations

impl<'a> Iterator for IndexVecIter<'a>[src]

type Item = usize

The type of the elements being iterated over.

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

impl<'a> ExactSizeIterator for IndexVecIter<'a>[src]

fn len(&self) -> usize1.0.0[src]

Returns the exact number of times the iterator will iterate. Read more

+

fn is_empty(&self) -> bool[src]

🔬 This is a nightly-only experimental API. (exact_size_is_empty)

Returns true if the iterator is empty. Read more

+

impl<'a> Debug for IndexVecIter<'a>[src]

Auto Trait Implementations

impl<'a> Send for IndexVecIter<'a>

impl<'a> Sync for IndexVecIter<'a>

Blanket Implementations

impl<I> IteratorRandom for I where
    I: Iterator
[src]

fn choose<R: ?Sized>(self, rng: &mut R) -> Option<Self::Item> where
    R: Rng
[src]

Choose one element at random from the iterator. Read more

+

fn choose_multiple_fill<R: ?Sized>(
    self,
    rng: &mut R,
    buf: &mut [Self::Item]
) -> usize where
    R: Rng
[src]

Collects values at random from the iterator into a supplied buffer until that buffer is filled. Read more

+

fn choose_multiple<R: ?Sized>(
    self,
    rng: &mut R,
    amount: usize
) -> Vec<Self::Item> where
    R: Rng
[src]

Collects amount values at random from the iterator into a vector. Read more

+

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/seq/index/fn.sample.html b/target/doc/rand/seq/index/fn.sample.html new file mode 100644 index 0000000..7d2aae5 --- /dev/null +++ b/target/doc/rand/seq/index/fn.sample.html @@ -0,0 +1,18 @@ +rand::seq::index::sample - Rust

[][src]Function rand::seq::index::sample

pub fn sample<R: ?Sized>(rng: &mut R, length: usize, amount: usize) -> IndexVec where
    R: Rng

Randomly sample exactly amount distinct indices from 0..length, and +return them in random order (fully shuffled).

+

This method is used internally by the slice sampling methods, but it can +sometimes be useful to have the indices themselves so this is provided as +an alternative.

+

The implementation used is not specified; we automatically select the +fastest available algorithm for the length and amount parameters +(based on detailed profiling on an Intel Haswell CPU). Roughly speaking, +complexity is O(amount), except that when amount is small, performance +is closer to O(amount^2), and when length is close to amount then +O(length).

+

Note that performance is significantly better over u32 indices than over +u64 indices. Because of this we hide the underlying type behind an +abstraction, IndexVec.

+

If an allocation-free no_std function is required, it is suggested +to adapt the internal sample_floyd implementation.

+

Panics if amount > length.

+
\ No newline at end of file diff --git a/target/doc/rand/seq/index/index.html b/target/doc/rand/seq/index/index.html new file mode 100644 index 0000000..f5085f2 --- /dev/null +++ b/target/doc/rand/seq/index/index.html @@ -0,0 +1,9 @@ +rand::seq::index - Rust

[][src]Module rand::seq::index

Low-level API for sampling indices

+

Enums

+
IndexVec

A vector of indices.

+
IndexVecIntoIter

Return type of IndexVec::into_iter.

+
IndexVecIter

Return type of IndexVec::iter.

+

Functions

+
sample

Randomly sample exactly amount distinct indices from 0..length, and +return them in random order (fully shuffled).

+
\ No newline at end of file diff --git a/target/doc/rand/seq/index/sidebar-items.js b/target/doc/rand/seq/index/sidebar-items.js new file mode 100644 index 0000000..7df2fd8 --- /dev/null +++ b/target/doc/rand/seq/index/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"enum":[["IndexVec","A vector of indices."],["IndexVecIntoIter","Return type of `IndexVec::into_iter`."],["IndexVecIter","Return type of `IndexVec::iter`."]],"fn":[["sample","Randomly sample exactly `amount` distinct indices from `0..length`, and return them in random order (fully shuffled)."]]}); \ No newline at end of file diff --git a/target/doc/rand/seq/sidebar-items.js b/target/doc/rand/seq/sidebar-items.js new file mode 100644 index 0000000..7cccd4d --- /dev/null +++ b/target/doc/rand/seq/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"mod":[["index","Low-level API for sampling indices"]],"struct":[["SliceChooseIter","An iterator over multiple slice elements."]],"trait":[["IteratorRandom","Extension trait on iterators, providing random sampling methods."],["SliceRandom","Extension trait on slices, providing random mutation and sampling methods."]]}); \ No newline at end of file diff --git a/target/doc/rand/seq/struct.SliceChooseIter.html b/target/doc/rand/seq/struct.SliceChooseIter.html new file mode 100644 index 0000000..255fa0a --- /dev/null +++ b/target/doc/rand/seq/struct.SliceChooseIter.html @@ -0,0 +1,86 @@ +rand::seq::SliceChooseIter - Rust

[][src]Struct rand::seq::SliceChooseIter

pub struct SliceChooseIter<'a, S: ?Sized + 'a, T: 'a> { /* fields omitted */ }

An iterator over multiple slice elements.

+

This struct is created by +SliceRandom::choose_multiple.

+

Trait Implementations

impl<'a, S: Index<usize, Output = T> + ?Sized + 'a, T: 'a> Iterator for SliceChooseIter<'a, S, T>[src]

type Item = &'a T

The type of the elements being iterated over.

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

impl<'a, S: Index<usize, Output = T> + ?Sized + 'a, T: 'a> ExactSizeIterator for SliceChooseIter<'a, S, T>[src]

fn is_empty(&self) -> bool[src]

🔬 This is a nightly-only experimental API. (exact_size_is_empty)

Returns true if the iterator is empty. Read more

+

impl<'a, S: Debug + ?Sized + 'a, T: Debug + 'a> Debug for SliceChooseIter<'a, S, T>[src]

Auto Trait Implementations

impl<'a, S: ?Sized, T> Send for SliceChooseIter<'a, S, T> where
    S: Sync,
    T: Send

impl<'a, S: ?Sized, T> Sync for SliceChooseIter<'a, S, T> where
    S: Sync,
    T: Sync

Blanket Implementations

impl<I> IteratorRandom for I where
    I: Iterator
[src]

fn choose<R: ?Sized>(self, rng: &mut R) -> Option<Self::Item> where
    R: Rng
[src]

Choose one element at random from the iterator. Read more

+

fn choose_multiple_fill<R: ?Sized>(
    self,
    rng: &mut R,
    buf: &mut [Self::Item]
) -> usize where
    R: Rng
[src]

Collects values at random from the iterator into a supplied buffer until that buffer is filled. Read more

+

fn choose_multiple<R: ?Sized>(
    self,
    rng: &mut R,
    amount: usize
) -> Vec<Self::Item> where
    R: Rng
[src]

Collects amount values at random from the iterator into a vector. Read more

+

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/seq/trait.IteratorRandom.html b/target/doc/rand/seq/trait.IteratorRandom.html new file mode 100644 index 0000000..9007228 --- /dev/null +++ b/target/doc/rand/seq/trait.IteratorRandom.html @@ -0,0 +1,57 @@ +rand::seq::IteratorRandom - Rust

[][src]Trait rand::seq::IteratorRandom

pub trait IteratorRandom: Iterator + Sized {
+    fn choose<R: ?Sized>(self, rng: &mut R) -> Option<Self::Item>
    where
        R: Rng
, + { ... } +
fn choose_multiple_fill<R: ?Sized>(
        self,
        rng: &mut R,
        buf: &mut [Self::Item]
    ) -> usize
    where
        R: Rng
, + { ... } +
fn choose_multiple<R: ?Sized>(
        self,
        rng: &mut R,
        amount: usize
    ) -> Vec<Self::Item>
    where
        R: Rng
, + { ... } +}

Extension trait on iterators, providing random sampling methods.

+

This trait is implemented on all sized iterators, providing methods for +choosing one or more elements. You must use this trait:

+ +
+use rand::seq::IteratorRandom;
+ 
+fn main() {
+    let mut rng = rand::thread_rng();
+     
+    let faces = "😀😎😐😕😠😢";
+    println!("I am {}!", faces.chars().choose(&mut rng).unwrap());
+}
+

Example output (non-deterministic):

+
I am 😀!
+
+
+

Provided methods

fn choose<R: ?Sized>(self, rng: &mut R) -> Option<Self::Item> where
    R: Rng

Choose one element at random from the iterator.

+

Returns None if and only if the iterator is empty.

+

This method uses [Iterator::size_hint] for optimisation. With an +accurate hint and where [Iterator::nth] is a constant-time operation +this method can offer O(1) performance. Where no size hint is +available, complexity is O(n) where n is the iterator length. +Partial hints (where lower > 0) also improve performance.

+

For slices, prefer [SliceRandom::choose] which guarantees O(1) +performance.

+

fn choose_multiple_fill<R: ?Sized>(
    self,
    rng: &mut R,
    buf: &mut [Self::Item]
) -> usize where
    R: Rng

Collects values at random from the iterator into a supplied buffer +until that buffer is filled.

+

Although the elements are selected randomly, the order of elements in +the buffer is neither stable nor fully random. If random ordering is +desired, shuffle the result.

+

Returns the number of elements added to the buffer. This equals the length +of the buffer unless the iterator contains insufficient elements, in which +case this equals the number of elements available.

+

Complexity is O(n) where n is the length of the iterator. +For slices, prefer [SliceRandom::choose_multiple].

+

fn choose_multiple<R: ?Sized>(
    self,
    rng: &mut R,
    amount: usize
) -> Vec<Self::Item> where
    R: Rng

Collects amount values at random from the iterator into a vector.

+

This is equivalent to choose_multiple_fill except for the result type.

+

Although the elements are selected randomly, the order of elements in +the buffer is neither stable nor fully random. If random ordering is +desired, shuffle the result.

+

The length of the returned vector equals amount unless the iterator +contains insufficient elements, in which case it equals the number of +elements available.

+

Complexity is O(n) where n is the length of the iterator. +For slices, prefer [SliceRandom::choose_multiple].

+
Loading content... +

Implementors

impl<I> IteratorRandom for I where
    I: Iterator + Sized
[src]

fn choose<R: ?Sized>(self, rng: &mut R) -> Option<Self::Item> where
    R: Rng
[src]

fn choose_multiple_fill<R: ?Sized>(
    self,
    rng: &mut R,
    buf: &mut [Self::Item]
) -> usize where
    R: Rng
[src]

fn choose_multiple<R: ?Sized>(
    self,
    rng: &mut R,
    amount: usize
) -> Vec<Self::Item> where
    R: Rng
[src]

Loading content...
\ No newline at end of file diff --git a/target/doc/rand/seq/trait.SliceRandom.html b/target/doc/rand/seq/trait.SliceRandom.html new file mode 100644 index 0000000..c5c8365 --- /dev/null +++ b/target/doc/rand/seq/trait.SliceRandom.html @@ -0,0 +1,115 @@ +rand::seq::SliceRandom - Rust

[][src]Trait rand::seq::SliceRandom

pub trait SliceRandom {
+    type Item;
+    fn choose<R: ?Sized>(&self, rng: &mut R) -> Option<&Self::Item>
    where
        R: Rng
; +
fn choose_mut<R: ?Sized>(&mut self, rng: &mut R) -> Option<&mut Self::Item>
    where
        R: Rng
; +
fn choose_multiple<R: ?Sized>(
        &self,
        rng: &mut R,
        amount: usize
    ) -> SliceChooseIter<Self, Self::Item>
    where
        R: Rng
; +
fn choose_weighted<R: ?Sized, F, B, X>(
        &self,
        rng: &mut R,
        weight: F
    ) -> Result<&Self::Item, WeightedError>
    where
        R: Rng,
        F: Fn(&Self::Item) -> B,
        B: SampleBorrow<X>,
        X: SampleUniform + for<'a> AddAssign<&'a X> + PartialOrd<X> + Clone + Default
; +
fn choose_weighted_mut<R: ?Sized, F, B, X>(
        &mut self,
        rng: &mut R,
        weight: F
    ) -> Result<&mut Self::Item, WeightedError>
    where
        R: Rng,
        F: Fn(&Self::Item) -> B,
        B: SampleBorrow<X>,
        X: SampleUniform + for<'a> AddAssign<&'a X> + PartialOrd<X> + Clone + Default
; +
fn shuffle<R: ?Sized>(&mut self, rng: &mut R)
    where
        R: Rng
; +
fn partial_shuffle<R: ?Sized>(
        &mut self,
        rng: &mut R,
        amount: usize
    ) -> (&mut [Self::Item], &mut [Self::Item])
    where
        R: Rng
; +}

Extension trait on slices, providing random mutation and sampling methods.

+

This trait is implemented on all [T] slice types, providing several +methods for choosing and shuffling elements. You must use this trait:

+ +
+use rand::seq::SliceRandom;
+ 
+fn main() {
+    let mut rng = rand::thread_rng();
+    let mut bytes = "Hello, random!".to_string().into_bytes();
+    bytes.shuffle(&mut rng);
+    let str = String::from_utf8(bytes).unwrap();
+    println!("{}", str);
+}
+

Example output (non-deterministic):

+
l,nmroHado !le
+
+
+

Associated Types

type Item

The element type.

+
Loading content... +

Required methods

fn choose<R: ?Sized>(&self, rng: &mut R) -> Option<&Self::Item> where
    R: Rng

Returns a reference to one random element of the slice, or None if the +slice is empty.

+

For slices, complexity is O(1).

+

Example

+
+use rand::thread_rng;
+use rand::seq::SliceRandom;
+
+let choices = [1, 2, 4, 8, 16, 32];
+let mut rng = thread_rng();
+println!("{:?}", choices.choose(&mut rng));
+assert_eq!(choices[..0].choose(&mut rng), None);
+

fn choose_mut<R: ?Sized>(&mut self, rng: &mut R) -> Option<&mut Self::Item> where
    R: Rng

Returns a mutable reference to one random element of the slice, or +None if the slice is empty.

+

For slices, complexity is O(1).

+

Important traits for SliceChooseIter<'a, S, T>
fn choose_multiple<R: ?Sized>(
    &self,
    rng: &mut R,
    amount: usize
) -> SliceChooseIter<Self, Self::Item> where
    R: Rng

Chooses amount elements from the slice at random, without repetition, +and in random order. The returned iterator is appropriate both for +collection into a Vec and filling an existing buffer (see example).

+

In case this API is not sufficiently flexible, use [index::sample].

+

For slices, complexity is the same as [index::sample].

+

Example

+
+use rand::seq::SliceRandom;
+
+let mut rng = &mut rand::thread_rng();
+let sample = "Hello, audience!".as_bytes();
+
+// collect the results into a vector:
+let v: Vec<u8> = sample.choose_multiple(&mut rng, 3).cloned().collect();
+
+// store in a buffer:
+let mut buf = [0u8; 5];
+for (b, slot) in sample.choose_multiple(&mut rng, buf.len()).zip(buf.iter_mut()) {
+    *slot = *b;
+}
+

fn choose_weighted<R: ?Sized, F, B, X>(
    &self,
    rng: &mut R,
    weight: F
) -> Result<&Self::Item, WeightedError> where
    R: Rng,
    F: Fn(&Self::Item) -> B,
    B: SampleBorrow<X>,
    X: SampleUniform + for<'a> AddAssign<&'a X> + PartialOrd<X> + Clone + Default

Similar to choose, but where the likelihood of each outcome may be +specified.

+

The specified function weight maps each item x to a relative +likelihood weight(x). The probability of each item being selected is +therefore weight(x) / s, where s is the sum of all weight(x).

+

For slices of length n, complexity is O(n). +See also choose_weighted_mut, distributions::weighted.

+

Example

+
+use rand::prelude::*;
+
+let choices = [('a', 2), ('b', 1), ('c', 1)];
+let mut rng = thread_rng();
+// 50% chance to print 'a', 25% chance to print 'b', 25% chance to print 'c'
+println!("{:?}", choices.choose_weighted(&mut rng, |item| item.1).unwrap().0);
+

fn choose_weighted_mut<R: ?Sized, F, B, X>(
    &mut self,
    rng: &mut R,
    weight: F
) -> Result<&mut Self::Item, WeightedError> where
    R: Rng,
    F: Fn(&Self::Item) -> B,
    B: SampleBorrow<X>,
    X: SampleUniform + for<'a> AddAssign<&'a X> + PartialOrd<X> + Clone + Default

Similar to choose_mut, but where the likelihood of each outcome may +be specified.

+

The specified function weight maps each item x to a relative +likelihood weight(x). The probability of each item being selected is +therefore weight(x) / s, where s is the sum of all weight(x).

+

For slices of length n, complexity is O(n). +See also choose_weighted, distributions::weighted.

+

fn shuffle<R: ?Sized>(&mut self, rng: &mut R) where
    R: Rng

Shuffle a mutable slice in place.

+

For slices of length n, complexity is O(n).

+

Example

+
+use rand::seq::SliceRandom;
+use rand::thread_rng;
+
+let mut rng = thread_rng();
+let mut y = [1, 2, 3, 4, 5];
+println!("Unshuffled: {:?}", y);
+y.shuffle(&mut rng);
+println!("Shuffled:   {:?}", y);
+

fn partial_shuffle<R: ?Sized>(
    &mut self,
    rng: &mut R,
    amount: usize
) -> (&mut [Self::Item], &mut [Self::Item]) where
    R: Rng

Shuffle a slice in place, but exit early.

+

Returns two mutable slices from the source slice. The first contains +amount elements randomly permuted. The second has the remaining +elements that are not fully shuffled.

+

This is an efficient method to select amount elements at random from +the slice, provided the slice may be mutated.

+

If you only need to choose elements randomly and amount > self.len()/2 +then you may improve performance by taking +amount = values.len() - amount and using only the second slice.

+

If amount is greater than the number of elements in the slice, this +will perform a full shuffle.

+

For slices, complexity is O(m) where m = amount.

+
Loading content... +

Implementations on Foreign Types

impl<T> SliceRandom for [T][src]

type Item = T

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/rand/sidebar-items.js b/target/doc/rand/sidebar-items.js new file mode 100644 index 0000000..e3933f0 --- /dev/null +++ b/target/doc/rand/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"fn":[["random","Generates a random value using the thread-local random number generator."],["thread_rng","Retrieve the lazily-initialized thread-local random number generator, seeded by the system. Intended to be used in method chaining style, e.g. `thread_rng().gen::()`, or cached locally, e.g. `let mut rng = thread_rng();`. Invoked by the `Default` trait, making `ThreadRng::default()` equivalent."]],"mod":[["distributions","Generating random samples from probability distributions"],["prelude","Convenience re-export of common members"],["rngs","Random number generators and adapters"],["seq","Sequence-related functionality"]],"struct":[["Error","Error type of random number generators"]],"trait":[["AsByteSliceMut","Trait for casting types to byte slices"],["CryptoRng","A marker trait used to indicate that an [`RngCore`] or [`BlockRngCore`] implementation is supposed to be cryptographically secure."],["Rng","An automatically-implemented extension trait on [`RngCore`] providing high-level generic methods for sampling values and other convenience methods."],["RngCore","The core of a random number generator."],["SeedableRng","A random number generator that can be explicitly seeded."]]}); \ No newline at end of file diff --git a/target/doc/rand/struct.Error.html b/target/doc/rand/struct.Error.html new file mode 100644 index 0000000..9a874e6 --- /dev/null +++ b/target/doc/rand/struct.Error.html @@ -0,0 +1,36 @@ +rand::Error - Rust

[][src]Struct rand::Error

pub struct Error { /* fields omitted */ }

Error type of random number generators

+

In order to be compatible with std and no_std, this type has two +possible implementations: with std a boxed Error trait object is stored, +while with no_std we merely store an error code.

+

Methods

impl Error[src]

pub fn new<E>(err: E) -> Error where
    E: Into<Box<dyn Error + 'static + Sync + Send>>, 
[src]

Construct from any type supporting std::error::Error

+

Available only when configured with std.

+

See also From<NonZeroU32>, which is available with and without std.

+

pub fn inner(&self) -> &(dyn Error + 'static + Sync + Send)[src]

Reference the inner error (std only)

+

When configured with std, this is a trivial operation and never +panics. Without std, this method is simply unavailable.

+

pub fn take_inner(self) -> Box<dyn Error + 'static + Sync + Send>[src]

Unwrap the inner error (std only)

+

When configured with std, this is a trivial operation and never +panics. Without std, this method is simply unavailable.

+

pub fn code(&self) -> Option<NonZeroU32>[src]

Retrieve the error code, if any.

+

If this Error was constructed via From<NonZeroU32>, then this method +will return this NonZeroU32 code (for no_std this is always the +case). Otherwise, this method will return None.

+

Trait Implementations

impl Debug for Error[src]

impl Display for Error[src]

impl From<NonZeroU32> for Error[src]

impl From<Error> for Error[src]

impl Error for Error[src]

fn description(&self) -> &str1.0.0[src]

This method is soft-deprecated. Read more

+

fn cause(&self) -> Option<&dyn Error>1.0.0[src]

Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

+

The lower-level cause of this error, if any. Read more

+

Auto Trait Implementations

impl Send for Error

impl Sync for Error

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand/trait.AsByteSliceMut.html b/target/doc/rand/trait.AsByteSliceMut.html new file mode 100644 index 0000000..cf35451 --- /dev/null +++ b/target/doc/rand/trait.AsByteSliceMut.html @@ -0,0 +1,13 @@ +rand::AsByteSliceMut - Rust

[][src]Trait rand::AsByteSliceMut

pub trait AsByteSliceMut {
+    fn as_byte_slice_mut(&mut self) -> &mut [u8];
+
fn to_le(&mut self); +}

Trait for casting types to byte slices

+

This is used by the [Rng::fill] and [Rng::try_fill] methods.

+
+

Required methods

fn as_byte_slice_mut(&mut self) -> &mut [u8]

Return a mutable reference to self as a byte slice

+

fn to_le(&mut self)

Call to_le on each element (i.e. byte-swap on Big Endian platforms).

+
Loading content... +

Implementations on Foreign Types

impl AsByteSliceMut for [u8][src]

impl AsByteSliceMut for [u16][src]

impl AsByteSliceMut for [Wrapping<u16>][src]

impl AsByteSliceMut for [u32][src]

impl AsByteSliceMut for [Wrapping<u32>][src]

impl AsByteSliceMut for [u64][src]

impl AsByteSliceMut for [Wrapping<u64>][src]

impl AsByteSliceMut for [usize][src]

impl AsByteSliceMut for [Wrapping<usize>][src]

impl AsByteSliceMut for [u128][src]

impl AsByteSliceMut for [Wrapping<u128>][src]

impl AsByteSliceMut for [i8][src]

impl AsByteSliceMut for [Wrapping<i8>][src]

impl AsByteSliceMut for [i16][src]

impl AsByteSliceMut for [Wrapping<i16>][src]

impl AsByteSliceMut for [i32][src]

impl AsByteSliceMut for [Wrapping<i32>][src]

impl AsByteSliceMut for [i64][src]

impl AsByteSliceMut for [Wrapping<i64>][src]

impl AsByteSliceMut for [isize][src]

impl AsByteSliceMut for [Wrapping<isize>][src]

impl AsByteSliceMut for [i128][src]

impl AsByteSliceMut for [Wrapping<i128>][src]

impl<T> AsByteSliceMut for [T; 32] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 31] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 30] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 29] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 28] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 27] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 26] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 25] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 24] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 23] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 22] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 21] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 20] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 19] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 18] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 17] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 16] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 15] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 14] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 13] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 12] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 11] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 10] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 9] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 8] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 7] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 6] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 5] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 4] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 3] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 2] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 1] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 0] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 4096] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 2048] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 1024] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 512] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 256] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 128] where
    [T]: AsByteSliceMut
[src]

impl<T> AsByteSliceMut for [T; 64] where
    [T]: AsByteSliceMut
[src]

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/rand/trait.CryptoRng.html b/target/doc/rand/trait.CryptoRng.html new file mode 100644 index 0000000..3759fb2 --- /dev/null +++ b/target/doc/rand/trait.CryptoRng.html @@ -0,0 +1,21 @@ +rand::CryptoRng - Rust

[][src]Trait rand::CryptoRng

pub trait CryptoRng { }

A marker trait used to indicate that an [RngCore] or BlockRngCore +implementation is supposed to be cryptographically secure.

+

Cryptographically secure generators, also known as CSPRNGs, should +satisfy an additional properties over other generators: given the first +k bits of an algorithm's output +sequence, it should not be possible using polynomial-time algorithms to +predict the next bit with probability significantly greater than 50%.

+

Some generators may satisfy an additional property, however this is not +required by this trait: if the CSPRNG's state is revealed, it should not be +computationally-feasible to reconstruct output prior to this. Some other +generators allow backwards-computation and are consided reversible.

+

Note that this trait is provided for guidance only and cannot guarantee +suitability for cryptographic applications. In general it should only be +implemented for well-reviewed code implementing well-regarded algorithms.

+

Note also that use of a CryptoRng does not protect against other +weaknesses such as seeding from a weak entropy source or leaking state.

+
+

Implementations on Foreign Types

impl<'a, R> CryptoRng for &'a mut R where
    R: CryptoRng + ?Sized
[src]

impl<R> CryptoRng for BlockRng<R> where
    R: BlockRngCore + CryptoRng
[src]

impl<R> CryptoRng for Box<R> where
    R: CryptoRng + ?Sized
[src]

impl CryptoRng for ChaCha8Rng[src]

impl CryptoRng for ChaCha12Rng[src]

impl CryptoRng for ChaCha20Rng[src]

Loading content... +

Implementors

impl CryptoRng for EntropyRng[src]

impl CryptoRng for OsRng[src]

impl CryptoRng for StdRng[src]

impl CryptoRng for ThreadRng[src]

impl<R, Rsdr> CryptoRng for ReseedingRng<R, Rsdr> where
    R: BlockRngCore + SeedableRng + CryptoRng,
    Rsdr: RngCore + CryptoRng
[src]

Loading content...
\ No newline at end of file diff --git a/target/doc/rand/trait.Rng.html b/target/doc/rand/trait.Rng.html new file mode 100644 index 0000000..65be0bd --- /dev/null +++ b/target/doc/rand/trait.Rng.html @@ -0,0 +1,182 @@ +rand::Rng - Rust

[][src]Trait rand::Rng

pub trait Rng: RngCore {
+    fn gen<T>(&mut self) -> T
    where
        Standard: Distribution<T>
, + { ... } +
fn gen_range<T: SampleUniform, B1, B2>(&mut self, low: B1, high: B2) -> T
    where
        B1: SampleBorrow<T> + Sized,
        B2: SampleBorrow<T> + Sized
, + { ... } +
fn sample<T, D: Distribution<T>>(&mut self, distr: D) -> T { ... } +
fn sample_iter<T, D>(self, distr: D) -> DistIter<D, Self, T>
    where
        D: Distribution<T>,
        Self: Sized
, + { ... } +
fn fill<T: AsByteSliceMut + ?Sized>(&mut self, dest: &mut T) { ... } +
fn try_fill<T: AsByteSliceMut + ?Sized>(
        &mut self,
        dest: &mut T
    ) -> Result<(), Error> { ... } +
fn gen_bool(&mut self, p: f64) -> bool { ... } +
fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool { ... } +}

An automatically-implemented extension trait on [RngCore] providing high-level +generic methods for sampling values and other convenience methods.

+

This is the primary trait to use when generating random values.

+

Generic usage

+

The basic pattern is fn foo<R: Rng + ?Sized>(rng: &mut R). Some +things are worth noting here:

+
    +
  • Since Rng: RngCore and every RngCore implements Rng, it makes no +difference whether we use R: Rng or R: RngCore.
  • +
  • The + ?Sized un-bounding allows functions to be called directly on +type-erased references; i.e. foo(r) where r: &mut RngCore. Without +this it would be necessary to write foo(&mut r).
  • +
+

An alternative pattern is possible: fn foo<R: Rng>(rng: R). This has some +trade-offs. It allows the argument to be consumed directly without a &mut +(which is how from_rng(thread_rng()) works); also it still works directly +on references (including type-erased references). Unfortunately within the +function foo it is not known whether rng is a reference type or not, +hence many uses of rng require an extra reference, either explicitly +(distr.sample(&mut rng)) or implicitly (rng.gen()); one may hope the +optimiser can remove redundant references later.

+

Example:

+ +
+use rand::Rng;
+
+fn foo<R: Rng + ?Sized>(rng: &mut R) -> f32 {
+    rng.gen()
+}
+
+
+

Provided methods

fn gen<T>(&mut self) -> T where
    Standard: Distribution<T>, 

Return a random value supporting the Standard distribution.

+

Example

+
+use rand::{thread_rng, Rng};
+
+let mut rng = thread_rng();
+let x: u32 = rng.gen();
+println!("{}", x);
+println!("{:?}", rng.gen::<(f64, bool)>());
+

Arrays and tuples

+

The rng.gen() method is able to generate arrays (up to 32 elements) +and tuples (up to 12 elements), so long as all element types can be +generated.

+

For arrays of integers, especially for those with small element types +(< 64 bit), it will likely be faster to instead use [Rng::fill].

+ +
+use rand::{thread_rng, Rng};
+
+let mut rng = thread_rng();
+let tuple: (u8, i32, char) = rng.gen(); // arbitrary tuple support
+
+let arr1: [f32; 32] = rng.gen();        // array construction
+let mut arr2 = [0u8; 128];
+rng.fill(&mut arr2);                    // array fill
+

fn gen_range<T: SampleUniform, B1, B2>(&mut self, low: B1, high: B2) -> T where
    B1: SampleBorrow<T> + Sized,
    B2: SampleBorrow<T> + Sized

Generate a random value in the range [low, high), i.e. inclusive of +low and exclusive of high.

+

This function is optimised for the case that only a single sample is +made from the given range. See also the Uniform distribution +type which may be faster if sampling from the same range repeatedly.

+

Panics

+

Panics if low >= high.

+

Example

+
+use rand::{thread_rng, Rng};
+
+let mut rng = thread_rng();
+let n: u32 = rng.gen_range(0, 10);
+println!("{}", n);
+let m: f64 = rng.gen_range(-40.0f64, 1.3e5f64);
+println!("{}", m);
+

fn sample<T, D: Distribution<T>>(&mut self, distr: D) -> T

Sample a new value, using the given distribution.

+

Example

+
+use rand::{thread_rng, Rng};
+use rand::distributions::Uniform;
+
+let mut rng = thread_rng();
+let x = rng.sample(Uniform::new(10u32, 15));
+// Type annotation requires two types, the type and distribution; the
+// distribution can be inferred.
+let y = rng.sample::<u16, _>(Uniform::new(10, 15));
+

Important traits for DistIter<D, R, T>
fn sample_iter<T, D>(self, distr: D) -> DistIter<D, Self, T> where
    D: Distribution<T>,
    Self: Sized

Create an iterator that generates values using the given distribution.

+

Note that this function takes its arguments by value. This works since +(&mut R): Rng where R: Rng and +(&D): Distribution where D: Distribution, +however borrowing is not automatic hence rng.sample_iter(...) may +need to be replaced with (&mut rng).sample_iter(...).

+

Example

+
+use rand::{thread_rng, Rng};
+use rand::distributions::{Alphanumeric, Uniform, Standard};
+
+let rng = thread_rng();
+
+// Vec of 16 x f32:
+let v: Vec<f32> = rng.sample_iter(Standard).take(16).collect();
+
+// String:
+let s: String = rng.sample_iter(Alphanumeric).take(7).collect();
+
+// Combined values
+println!("{:?}", rng.sample_iter(Standard).take(5)
+                             .collect::<Vec<(f64, bool)>>());
+
+// Dice-rolling:
+let die_range = Uniform::new_inclusive(1, 6);
+let mut roll_die = rng.sample_iter(die_range);
+while roll_die.next().unwrap() != 6 {
+    println!("Not a 6; rolling again!");
+}
+

fn fill<T: AsByteSliceMut + ?Sized>(&mut self, dest: &mut T)

Fill dest entirely with random bytes (uniform value distribution), +where dest is any type supporting [AsByteSliceMut], namely slices +and arrays over primitive integer types (i8, i16, u32, etc.).

+

On big-endian platforms this performs byte-swapping to ensure +portability of results from reproducible generators.

+

This uses fill_bytes internally which may handle some RNG errors +implicitly (e.g. waiting if the OS generator is not ready), but panics +on other errors. See also try_fill which returns errors.

+

Example

+
+use rand::{thread_rng, Rng};
+
+let mut arr = [0i8; 20];
+thread_rng().fill(&mut arr[..]);
+

fn try_fill<T: AsByteSliceMut + ?Sized>(
    &mut self,
    dest: &mut T
) -> Result<(), Error>

Fill dest entirely with random bytes (uniform value distribution), +where dest is any type supporting [AsByteSliceMut], namely slices +and arrays over primitive integer types (i8, i16, u32, etc.).

+

On big-endian platforms this performs byte-swapping to ensure +portability of results from reproducible generators.

+

This is identical to fill except that it uses try_fill_bytes +internally and forwards RNG errors.

+

Example

+
+use rand::{thread_rng, Rng};
+
+let mut arr = [0u64; 4];
+thread_rng().try_fill(&mut arr[..])?;
+
+

fn gen_bool(&mut self, p: f64) -> bool

Return a bool with a probability p of being true.

+

See also the Bernoulli distribution, which may be faster if +sampling from the same probability repeatedly.

+

Example

+
+use rand::{thread_rng, Rng};
+
+let mut rng = thread_rng();
+println!("{}", rng.gen_bool(1.0 / 3.0));
+

Panics

+

If p < 0 or p > 1.

+

fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool

Return a bool with a probability of numerator/denominator of being +true. I.e. gen_ratio(2, 3) has chance of 2 in 3, or about 67%, of +returning true. If numerator == denominator, then the returned value +is guaranteed to be true. If numerator == 0, then the returned +value is guaranteed to be false.

+

See also the Bernoulli distribution, which may be faster if +sampling from the same numerator and denominator repeatedly.

+

Panics

+

If denominator == 0 or numerator > denominator.

+

Example

+
+use rand::{thread_rng, Rng};
+
+let mut rng = thread_rng();
+println!("{}", rng.gen_ratio(2, 3));
+
Loading content... +

Implementors

impl<R: RngCore + ?Sized> Rng for R[src]

fn gen<T>(&mut self) -> T where
    Standard: Distribution<T>, 
[src]

fn gen_range<T: SampleUniform, B1, B2>(&mut self, low: B1, high: B2) -> T where
    B1: SampleBorrow<T> + Sized,
    B2: SampleBorrow<T> + Sized
[src]

fn sample<T, D: Distribution<T>>(&mut self, distr: D) -> T[src]

Important traits for DistIter<D, R, T>
fn sample_iter<T, D>(self, distr: D) -> DistIter<D, Self, T> where
    D: Distribution<T>,
    Self: Sized
[src]

fn fill<T: AsByteSliceMut + ?Sized>(&mut self, dest: &mut T)[src]

fn try_fill<T: AsByteSliceMut + ?Sized>(
    &mut self,
    dest: &mut T
) -> Result<(), Error>
[src]

fn gen_bool(&mut self, p: f64) -> bool[src]

fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool[src]

Loading content...
\ No newline at end of file diff --git a/target/doc/rand/trait.RngCore.html b/target/doc/rand/trait.RngCore.html new file mode 100644 index 0000000..73b920e --- /dev/null +++ b/target/doc/rand/trait.RngCore.html @@ -0,0 +1,114 @@ +rand::RngCore - Rust

[][src]Trait rand::RngCore

pub trait RngCore {
+    fn next_u32(&mut self) -> u32;
+
fn next_u64(&mut self) -> u64; +
fn fill_bytes(&mut self, dest: &mut [u8]); +
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error>; +}

The core of a random number generator.

+

This trait encapsulates the low-level functionality common to all +generators, and is the "back end", to be implemented by generators. +End users should normally use the Rng trait from the rand crate, +which is automatically implemented for every type implementing RngCore.

+

Three different methods for generating random data are provided since the +optimal implementation of each is dependent on the type of generator. There +is no required relationship between the output of each; e.g. many +implementations of fill_bytes consume a whole number of u32 or u64 +values and drop any remaining unused bytes.

+

The try_fill_bytes method is a variant of fill_bytes allowing error +handling; it is not deemed sufficiently useful to add equivalents for +next_u32 or next_u64 since the latter methods are almost always used +with algorithmic generators (PRNGs), which are normally infallible.

+

Algorithmic generators implementing [SeedableRng] should normally have +portable, reproducible output, i.e. fix Endianness when converting values +to avoid platform differences, and avoid making any changes which affect +output (except by communicating that the release has breaking changes).

+

Typically implementators will implement only one of the methods available +in this trait directly, then use the helper functions from the +[impls] module to implement the other methods.

+

It is recommended that implementations also implement:

+
    +
  • Debug with a custom implementation which does not print any internal +state (at least, [CryptoRng]s should not risk leaking state through +Debug).
  • +
  • Serialize and Deserialize (from Serde), preferably making Serde +support optional at the crate level in PRNG libs.
  • +
  • Clone, if possible.
  • +
  • never implement Copy (accidental copies may cause repeated values).
  • +
  • do not implement Default for pseudorandom generators, but instead +implement [SeedableRng], to guide users towards proper seeding. +External / hardware RNGs can choose to implement Default.
  • +
  • Eq and PartialEq could be implemented, but are probably not useful.
  • +
+

Example

+

A simple example, obviously not generating very random output:

+ +
+#![allow(dead_code)]
+use rand_core::{RngCore, Error, impls};
+
+struct CountingRng(u64);
+
+impl RngCore for CountingRng {
+    fn next_u32(&mut self) -> u32 {
+        self.next_u64() as u32
+    }
+
+    fn next_u64(&mut self) -> u64 {
+        self.0 += 1;
+        self.0
+    }
+
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        impls::fill_bytes_via_next(self, dest)
+    }
+
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        Ok(self.fill_bytes(dest))
+    }
+}
+
+

Required methods

fn next_u32(&mut self) -> u32

Return the next random u32.

+

RNGs must implement at least one method from this trait directly. In +the case this method is not implemented directly, it can be implemented +using self.next_u64() as u32 or via +[fill_bytes][impls::next_u32_via_fill].

+

fn next_u64(&mut self) -> u64

Return the next random u64.

+

RNGs must implement at least one method from this trait directly. In +the case this method is not implemented directly, it can be implemented +via [next_u32][impls::next_u64_via_u32] or via +[fill_bytes][impls::next_u64_via_fill].

+

fn fill_bytes(&mut self, dest: &mut [u8])

Fill dest with random data.

+

RNGs must implement at least one method from this trait directly. In +the case this method is not implemented directly, it can be implemented +via [next_u*][impls::fill_bytes_via_next] or +via [try_fill_bytes][RngCore::try_fill_bytes]; if this generator can +fail the implementation must choose how best to handle errors here +(e.g. panic with a descriptive message or log a warning and retry a few +times).

+

This method should guarantee that dest is entirely filled +with new data, and may panic if this is impossible +(e.g. reading past the end of a file that is being used as the +source of randomness).

+

fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error>

Fill dest entirely with random data.

+

This is the only method which allows an RNG to report errors while +generating random data thus making this the primary method implemented +by external (true) RNGs (e.g. OsRng) which can fail. It may be used +directly to generate keys and to seed (infallible) PRNGs.

+

Other than error handling, this method is identical to fill_bytes; +thus this may be implemented using Ok(self.fill_bytes(dest)) or +fill_bytes may be implemented with +self.try_fill_bytes(dest).unwrap() or more specific error handling.

+
Loading content...

Trait Implementations

impl Read for dyn RngCore + 'static[src]

fn read_vectored(&mut self, bufs: &mut [IoSliceMut]) -> Result<usize, Error>1.36.0[src]

Like read, except that it reads into a slice of buffers. Read more

+

unsafe fn initializer(&self) -> Initializer[src]

🔬 This is a nightly-only experimental API. (read_initializer)

Determines if this Reader can work with buffers of uninitialized memory. Read more

+

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, Error>1.0.0[src]

Read all bytes until EOF in this source, placing them into buf. Read more

+

fn read_to_string(&mut self, buf: &mut String) -> Result<usize, Error>1.0.0[src]

Read all bytes until EOF in this source, appending them to buf. Read more

+

fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>1.6.0[src]

Read the exact number of bytes required to fill buf. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Creates a "by reference" adaptor for this instance of Read. Read more

+

fn bytes(self) -> Bytes<Self>1.0.0[src]

Transforms this Read instance to an [Iterator] over its bytes. Read more

+

fn chain<R>(self, next: R) -> Chain<Self, R> where
    R: Read
1.0.0[src]

Creates an adaptor which will chain this stream with another. Read more

+

fn take(self, limit: u64) -> Take<Self>1.0.0[src]

Creates an adaptor which will read at most limit bytes from it. Read more

+
+

Implementations on Foreign Types

impl<R> RngCore for BlockRng<R> where
    R: BlockRngCore<Item = u32>,
    <R as BlockRngCore>::Results: AsRef<[u32]>,
    <R as BlockRngCore>::Results: AsMut<[u32]>, 
[src]

impl<R> RngCore for Box<R> where
    R: RngCore + ?Sized
[src]

impl<R> RngCore for BlockRng64<R> where
    R: BlockRngCore<Item = u64>,
    <R as BlockRngCore>::Results: AsRef<[u64]>,
    <R as BlockRngCore>::Results: AsMut<[u64]>, 
[src]

impl<'a, R> RngCore for &'a mut R where
    R: RngCore + ?Sized
[src]

impl RngCore for ChaCha12Rng[src]

impl RngCore for ChaCha8Rng[src]

impl RngCore for ChaCha20Rng[src]

Loading content... +

Implementors

impl RngCore for StepRng[src]

impl RngCore for EntropyRng[src]

impl RngCore for OsRng[src]

impl RngCore for StdRng[src]

impl RngCore for ThreadRng[src]

impl<R, Rsdr: RngCore> RngCore for ReseedingRng<R, Rsdr> where
    R: BlockRngCore<Item = u32> + SeedableRng,
    <R as BlockRngCore>::Results: AsRef<[u32]> + AsMut<[u32]>, 
[src]

impl<R: Read> RngCore for ReadRng<R>[src]

Loading content...
\ No newline at end of file diff --git a/target/doc/rand/trait.SeedableRng.html b/target/doc/rand/trait.SeedableRng.html new file mode 100644 index 0000000..e4cb272 --- /dev/null +++ b/target/doc/rand/trait.SeedableRng.html @@ -0,0 +1,116 @@ +rand::SeedableRng - Rust

[][src]Trait rand::SeedableRng

pub trait SeedableRng {
+    type Seed: Sized + Default + AsMut<[u8]>;
+    fn from_seed(seed: Self::Seed) -> Self;
+
+    fn seed_from_u64(state: u64) -> Self { ... }
+
fn from_rng<R>(rng: R) -> Result<Self, Error>
    where
        R: RngCore
, + { ... } +
fn from_entropy() -> Self { ... } +}

A random number generator that can be explicitly seeded.

+

This trait encapsulates the low-level functionality common to all +pseudo-random number generators (PRNGs, or algorithmic generators).

+
+

Associated Types

type Seed: Sized + Default + AsMut<[u8]>

Seed type, which is restricted to types mutably-dereferencable as u8 +arrays (we recommend [u8; N] for some N).

+

It is recommended to seed PRNGs with a seed of at least circa 100 bits, +which means an array of [u8; 12] or greater to avoid picking RNGs with +partially overlapping periods.

+

For cryptographic RNG's a seed of 256 bits is recommended, [u8; 32].

+

Implementing SeedableRng for RNGs with large seeds

+

Note that the required traits core::default::Default and +core::convert::AsMut<u8> are not implemented for large arrays +[u8; N] with N > 32. To be able to implement the traits required by +SeedableRng for RNGs with such large seeds, the newtype pattern can be +used:

+ +
+use rand_core::SeedableRng;
+
+const N: usize = 64;
+pub struct MyRngSeed(pub [u8; N]);
+pub struct MyRng(MyRngSeed);
+
+impl Default for MyRngSeed {
+    fn default() -> MyRngSeed {
+        MyRngSeed([0; N])
+    }
+}
+
+impl AsMut<[u8]> for MyRngSeed {
+    fn as_mut(&mut self) -> &mut [u8] {
+        &mut self.0
+    }
+}
+
+impl SeedableRng for MyRng {
+    type Seed = MyRngSeed;
+
+    fn from_seed(seed: MyRngSeed) -> MyRng {
+        MyRng(seed)
+    }
+}
+
Loading content... +

Required methods

fn from_seed(seed: Self::Seed) -> Self

Create a new PRNG using the given seed.

+

PRNG implementations are allowed to assume that bits in the seed are +well distributed. That means usually that the number of one and zero +bits are roughly equal, and values like 0, 1 and (size - 1) are unlikely. +Note that many non-cryptographic PRNGs will show poor quality output +if this is not adhered to. If you wish to seed from simple numbers, use +seed_from_u64 instead.

+

All PRNG implementations should be reproducible unless otherwise noted: +given a fixed seed, the same sequence of output should be produced +on all runs, library versions and architectures (e.g. check endianness). +Any "value-breaking" changes to the generator should require bumping at +least the minor version and documentation of the change.

+

It is not required that this function yield the same state as a +reference implementation of the PRNG given equivalent seed; if necessary +another constructor replicating behaviour from a reference +implementation can be added.

+

PRNG implementations should make sure from_seed never panics. In the +case that some special values (like an all zero seed) are not viable +seeds it is preferable to map these to alternative constant value(s), +for example 0xBAD5EEDu32 or 0x0DDB1A5E5BAD5EEDu64 ("odd biases? bad +seed"). This is assuming only a small number of values must be rejected.

+
Loading content... +

Provided methods

fn seed_from_u64(state: u64) -> Self

Create a new PRNG using a u64 seed.

+

This is a convenience-wrapper around from_seed to allow construction +of any SeedableRng from a simple u64 value. It is designed such that +low Hamming Weight numbers like 0 and 1 can be used and should still +result in good, independent seeds to the PRNG which is returned.

+

This is not suitable for cryptography, as should be clear given that +the input size is only 64 bits.

+

Implementations for PRNGs may provide their own implementations of +this function, but the default implementation should be good enough for +all purposes. Changing the implementation of this function should be +considered a value-breaking change.

+

fn from_rng<R>(rng: R) -> Result<Self, Error> where
    R: RngCore

Create a new PRNG seeded from another Rng.

+

This may be useful when needing to rapidly seed many PRNGs from a master +PRNG, and to allow forking of PRNGs. It may be considered deterministic.

+

The master PRNG should be at least as high quality as the child PRNGs. +When seeding non-cryptographic child PRNGs, we recommend using a +different algorithm for the master PRNG (ideally a CSPRNG) to avoid +correlations between the child PRNGs. If this is not possible (e.g. +forking using small non-crypto PRNGs) ensure that your PRNG has a good +mixing function on the output or consider use of a hash function with +from_seed.

+

Note that seeding XorShiftRng from another XorShiftRng provides an +extreme example of what can go wrong: the new PRNG will be a clone +of the parent.

+

PRNG implementations are allowed to assume that a good RNG is provided +for seeding, and that it is cryptographically secure when appropriate. +As of rand 0.7 / rand_core 0.5, implementations overriding this +method should ensure the implementation satisfies reproducibility +(in prior versions this was not required).

+

fn from_entropy() -> Self

Creates a new instance of the RNG seeded via getrandom.

+

This method is the recommended way to construct non-deterministic PRNGs +since it is convenient and secure.

+

In case the overhead of using getrandom to seed many PRNGs is an +issue, one may prefer to seed from a local PRNG, e.g. +from_rng(thread_rng()).unwrap().

+

Panics

+

If getrandom is unable to provide secure entropy this method will panic.

+
Loading content... +

Implementations on Foreign Types

impl<R> SeedableRng for BlockRng<R> where
    R: BlockRngCore + SeedableRng
[src]

type Seed = <R as SeedableRng>::Seed

fn from_entropy() -> Self[src]

impl<R> SeedableRng for BlockRng64<R> where
    R: BlockRngCore + SeedableRng
[src]

type Seed = <R as SeedableRng>::Seed

fn from_entropy() -> Self[src]

impl SeedableRng for ChaCha12Core[src]

type Seed = [u8; 32]

fn seed_from_u64(state: u64) -> Self[src]

fn from_rng<R>(rng: R) -> Result<Self, Error> where
    R: RngCore
[src]

fn from_entropy() -> Self[src]

impl SeedableRng for ChaCha12Rng[src]

type Seed = [u8; 32]

fn seed_from_u64(state: u64) -> Self[src]

fn from_rng<R>(rng: R) -> Result<Self, Error> where
    R: RngCore
[src]

fn from_entropy() -> Self[src]

impl SeedableRng for ChaCha20Rng[src]

type Seed = [u8; 32]

fn seed_from_u64(state: u64) -> Self[src]

fn from_rng<R>(rng: R) -> Result<Self, Error> where
    R: RngCore
[src]

fn from_entropy() -> Self[src]

impl SeedableRng for ChaCha8Core[src]

type Seed = [u8; 32]

fn seed_from_u64(state: u64) -> Self[src]

fn from_rng<R>(rng: R) -> Result<Self, Error> where
    R: RngCore
[src]

fn from_entropy() -> Self[src]

impl SeedableRng for ChaCha8Rng[src]

type Seed = [u8; 32]

fn seed_from_u64(state: u64) -> Self[src]

fn from_rng<R>(rng: R) -> Result<Self, Error> where
    R: RngCore
[src]

fn from_entropy() -> Self[src]

impl SeedableRng for ChaCha20Core[src]

type Seed = [u8; 32]

fn seed_from_u64(state: u64) -> Self[src]

fn from_rng<R>(rng: R) -> Result<Self, Error> where
    R: RngCore
[src]

fn from_entropy() -> Self[src]

Loading content... +

Implementors

impl SeedableRng for StdRng[src]

type Seed = <Rng as SeedableRng>::Seed

fn seed_from_u64(state: u64) -> Self[src]

fn from_entropy() -> Self[src]

Loading content...
\ No newline at end of file diff --git a/target/doc/rand_chacha/all.html b/target/doc/rand_chacha/all.html new file mode 100644 index 0000000..809d4c7 --- /dev/null +++ b/target/doc/rand_chacha/all.html @@ -0,0 +1,3 @@ +List of all items in this crate

[] + + List of all items

Structs

Typedefs

\ No newline at end of file diff --git a/target/doc/rand_chacha/chacha/struct.ChaCha12Core.html b/target/doc/rand_chacha/chacha/struct.ChaCha12Core.html new file mode 100644 index 0000000..705efaa --- /dev/null +++ b/target/doc/rand_chacha/chacha/struct.ChaCha12Core.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../rand_chacha/struct.ChaCha12Core.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand_chacha/chacha/struct.ChaCha12Rng.html b/target/doc/rand_chacha/chacha/struct.ChaCha12Rng.html new file mode 100644 index 0000000..bfcd29e --- /dev/null +++ b/target/doc/rand_chacha/chacha/struct.ChaCha12Rng.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../rand_chacha/struct.ChaCha12Rng.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand_chacha/chacha/struct.ChaCha20Core.html b/target/doc/rand_chacha/chacha/struct.ChaCha20Core.html new file mode 100644 index 0000000..a310d2e --- /dev/null +++ b/target/doc/rand_chacha/chacha/struct.ChaCha20Core.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../rand_chacha/struct.ChaCha20Core.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand_chacha/chacha/struct.ChaCha20Rng.html b/target/doc/rand_chacha/chacha/struct.ChaCha20Rng.html new file mode 100644 index 0000000..1bab540 --- /dev/null +++ b/target/doc/rand_chacha/chacha/struct.ChaCha20Rng.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../rand_chacha/struct.ChaCha20Rng.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand_chacha/chacha/struct.ChaCha8Core.html b/target/doc/rand_chacha/chacha/struct.ChaCha8Core.html new file mode 100644 index 0000000..98d6397 --- /dev/null +++ b/target/doc/rand_chacha/chacha/struct.ChaCha8Core.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../rand_chacha/struct.ChaCha8Core.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand_chacha/chacha/struct.ChaCha8Rng.html b/target/doc/rand_chacha/chacha/struct.ChaCha8Rng.html new file mode 100644 index 0000000..94c5515 --- /dev/null +++ b/target/doc/rand_chacha/chacha/struct.ChaCha8Rng.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../rand_chacha/struct.ChaCha8Rng.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand_chacha/index.html b/target/doc/rand_chacha/index.html new file mode 100644 index 0000000..4cd4d03 --- /dev/null +++ b/target/doc/rand_chacha/index.html @@ -0,0 +1,13 @@ +rand_chacha - Rust

[][src]Crate rand_chacha

The ChaCha random number generator.

+

Re-exports

+
pub use rand_core;

Structs

+
ChaCha8Core

ChaCha with 8 rounds

+
ChaCha8Rng

A cryptographically secure random number generator that uses the ChaCha algorithm.

+
ChaCha12Core

ChaCha with 12 rounds

+
ChaCha12Rng

A cryptographically secure random number generator that uses the ChaCha algorithm.

+
ChaCha20Core

ChaCha with 20 rounds

+
ChaCha20Rng

A cryptographically secure random number generator that uses the ChaCha algorithm.

+

Type Definitions

+
ChaChaCore

ChaCha with 20 rounds, low-level interface

+
ChaChaRng

ChaCha with 20 rounds

+
\ No newline at end of file diff --git a/target/doc/rand_chacha/sidebar-items.js b/target/doc/rand_chacha/sidebar-items.js new file mode 100644 index 0000000..00a0730 --- /dev/null +++ b/target/doc/rand_chacha/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["ChaCha12Core","ChaCha with 12 rounds"],["ChaCha12Rng","A cryptographically secure random number generator that uses the ChaCha algorithm."],["ChaCha20Core","ChaCha with 20 rounds"],["ChaCha20Rng","A cryptographically secure random number generator that uses the ChaCha algorithm."],["ChaCha8Core","ChaCha with 8 rounds"],["ChaCha8Rng","A cryptographically secure random number generator that uses the ChaCha algorithm."]],"type":[["ChaChaCore","ChaCha with 20 rounds, low-level interface"],["ChaChaRng","ChaCha with 20 rounds"]]}); \ No newline at end of file diff --git a/target/doc/rand_chacha/struct.ChaCha12Core.html b/target/doc/rand_chacha/struct.ChaCha12Core.html new file mode 100644 index 0000000..90cdfd0 --- /dev/null +++ b/target/doc/rand_chacha/struct.ChaCha12Core.html @@ -0,0 +1,27 @@ +rand_chacha::ChaCha12Core - Rust

[][src]Struct rand_chacha::ChaCha12Core

pub struct ChaCha12Core { /* fields omitted */ }

ChaCha with 12 rounds

+

Trait Implementations

impl From<ChaCha12Core> for ChaCha12Rng[src]

impl Clone for ChaCha12Core[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Debug for ChaCha12Core[src]

impl BlockRngCore for ChaCha12Core[src]

type Item = u32

Results element type, e.g. u32.

+

type Results = Array64<u32>

Results type. This is the 'block' an RNG implementing BlockRngCore generates, which will usually be an array like [u32; 16]. Read more

+

impl SeedableRng for ChaCha12Core[src]

type Seed = [u8; 32]

Seed type, which is restricted to types mutably-dereferencable as u8 arrays (we recommend [u8; N] for some N). Read more

+

fn seed_from_u64(state: u64) -> Self[src]

Create a new PRNG using a u64 seed. Read more

+

fn from_rng<R>(rng: R) -> Result<Self, Error> where
    R: RngCore
[src]

Create a new PRNG seeded from another Rng. Read more

+

fn from_entropy() -> Self[src]

Creates a new instance of the RNG seeded via [getrandom]. Read more

+

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand_chacha/struct.ChaCha12Rng.html b/target/doc/rand_chacha/struct.ChaCha12Rng.html new file mode 100644 index 0000000..ab5899e --- /dev/null +++ b/target/doc/rand_chacha/struct.ChaCha12Rng.html @@ -0,0 +1,69 @@ +rand_chacha::ChaCha12Rng - Rust

[][src]Struct rand_chacha::ChaCha12Rng

pub struct ChaCha12Rng { /* fields omitted */ }

A cryptographically secure random number generator that uses the ChaCha algorithm.

+

ChaCha is a stream cipher designed by Daniel J. Bernstein1, that we use as an RNG. It is +an improved variant of the Salsa20 cipher family, which was selected as one of the "stream +ciphers suitable for widespread adoption" by eSTREAM2.

+

ChaCha uses add-rotate-xor (ARX) operations as its basis. These are safe against timing +attacks, although that is mostly a concern for ciphers and not for RNGs. We provide a SIMD +implementation to support high throughput on a variety of common hardware platforms.

+

With the ChaCha algorithm it is possible to choose the number of rounds the core algorithm +should run. The number of rounds is a tradeoff between performance and security, where 8 +rounds is the minimum potentially secure configuration, and 20 rounds is widely used as a +conservative choice.

+

We use a 64-bit counter and 64-bit stream identifier as in Bernstein's implementation1 +except that we use a stream identifier in place of a nonce. A 64-bit counter over 64-byte +(16 word) blocks allows 1 ZiB of output before cycling, and the stream identifier allows +264 unique streams of output per seed. Both counter and stream are initialized +to zero but may be set via the set_word_pos and set_stream methods.

+

The word layout is:

+
constant  constant  constant  constant
+seed      seed      seed      seed
+seed      seed      seed      seed
+counter   counter   stream_id stream_id
+
+

This implementation uses an output buffer of sixteen u32 words, and uses +[BlockRng] to implement the [RngCore] methods.

+

Methods

impl ChaCha12Rng[src]

pub fn get_word_pos(&self) -> u128[src]

Get the offset from the start of the stream, in 32-bit words.

+

Since the generated blocks are 16 words (24) long and the +counter is 64-bits, the offset is a 68-bit number. Sub-word offsets are +not supported, hence the result can simply be multiplied by 4 to get a +byte-offset.

+

pub fn set_word_pos(&mut self, word_offset: u128)[src]

Set the offset from the start of the stream, in 32-bit words.

+

As with get_word_pos, we use a 68-bit number. Since the generator +simply cycles at the end of its period (1 ZiB), we ignore the upper +60 bits.

+

pub fn set_stream(&mut self, stream: u64)[src]

Set the stream number.

+

This is initialized to zero; 264 unique streams of output +are available per seed/key.

+

Note that in order to reproduce ChaCha output with a specific 64-bit +nonce, one can convert that nonce to a u64 in little-endian fashion +and pass to this function. In theory a 96-bit nonce can be used by +passing the last 64-bits to this function and using the first 32-bits as +the most significant half of the 64-bit counter (which may be set +indirectly via set_word_pos), but this is not directly supported.

+

Trait Implementations

impl From<ChaCha12Core> for ChaCha12Rng[src]

impl Clone for ChaCha12Rng[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Debug for ChaCha12Rng[src]

impl RngCore for ChaCha12Rng[src]

impl CryptoRng for ChaCha12Rng[src]

impl SeedableRng for ChaCha12Rng[src]

type Seed = [u8; 32]

Seed type, which is restricted to types mutably-dereferencable as u8 arrays (we recommend [u8; N] for some N). Read more

+

fn seed_from_u64(state: u64) -> Self[src]

Create a new PRNG using a u64 seed. Read more

+

fn from_rng<R>(rng: R) -> Result<Self, Error> where
    R: RngCore
[src]

Create a new PRNG seeded from another Rng. Read more

+

fn from_entropy() -> Self[src]

Creates a new instance of the RNG seeded via [getrandom]. Read more

+

Auto Trait Implementations

impl Send for ChaCha12Rng

impl Sync for ChaCha12Rng

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand_chacha/struct.ChaCha20Core.html b/target/doc/rand_chacha/struct.ChaCha20Core.html new file mode 100644 index 0000000..0c7f0a1 --- /dev/null +++ b/target/doc/rand_chacha/struct.ChaCha20Core.html @@ -0,0 +1,27 @@ +rand_chacha::ChaCha20Core - Rust

[][src]Struct rand_chacha::ChaCha20Core

pub struct ChaCha20Core { /* fields omitted */ }

ChaCha with 20 rounds

+

Trait Implementations

impl From<ChaCha20Core> for ChaCha20Rng[src]

impl Clone for ChaCha20Core[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Debug for ChaCha20Core[src]

impl BlockRngCore for ChaCha20Core[src]

type Item = u32

Results element type, e.g. u32.

+

type Results = Array64<u32>

Results type. This is the 'block' an RNG implementing BlockRngCore generates, which will usually be an array like [u32; 16]. Read more

+

impl SeedableRng for ChaCha20Core[src]

type Seed = [u8; 32]

Seed type, which is restricted to types mutably-dereferencable as u8 arrays (we recommend [u8; N] for some N). Read more

+

fn seed_from_u64(state: u64) -> Self[src]

Create a new PRNG using a u64 seed. Read more

+

fn from_rng<R>(rng: R) -> Result<Self, Error> where
    R: RngCore
[src]

Create a new PRNG seeded from another Rng. Read more

+

fn from_entropy() -> Self[src]

Creates a new instance of the RNG seeded via [getrandom]. Read more

+

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand_chacha/struct.ChaCha20Rng.html b/target/doc/rand_chacha/struct.ChaCha20Rng.html new file mode 100644 index 0000000..67627e7 --- /dev/null +++ b/target/doc/rand_chacha/struct.ChaCha20Rng.html @@ -0,0 +1,69 @@ +rand_chacha::ChaCha20Rng - Rust

[][src]Struct rand_chacha::ChaCha20Rng

pub struct ChaCha20Rng { /* fields omitted */ }

A cryptographically secure random number generator that uses the ChaCha algorithm.

+

ChaCha is a stream cipher designed by Daniel J. Bernstein1, that we use as an RNG. It is +an improved variant of the Salsa20 cipher family, which was selected as one of the "stream +ciphers suitable for widespread adoption" by eSTREAM2.

+

ChaCha uses add-rotate-xor (ARX) operations as its basis. These are safe against timing +attacks, although that is mostly a concern for ciphers and not for RNGs. We provide a SIMD +implementation to support high throughput on a variety of common hardware platforms.

+

With the ChaCha algorithm it is possible to choose the number of rounds the core algorithm +should run. The number of rounds is a tradeoff between performance and security, where 8 +rounds is the minimum potentially secure configuration, and 20 rounds is widely used as a +conservative choice.

+

We use a 64-bit counter and 64-bit stream identifier as in Bernstein's implementation1 +except that we use a stream identifier in place of a nonce. A 64-bit counter over 64-byte +(16 word) blocks allows 1 ZiB of output before cycling, and the stream identifier allows +264 unique streams of output per seed. Both counter and stream are initialized +to zero but may be set via the set_word_pos and set_stream methods.

+

The word layout is:

+
constant  constant  constant  constant
+seed      seed      seed      seed
+seed      seed      seed      seed
+counter   counter   stream_id stream_id
+
+

This implementation uses an output buffer of sixteen u32 words, and uses +[BlockRng] to implement the [RngCore] methods.

+

Methods

impl ChaCha20Rng[src]

pub fn get_word_pos(&self) -> u128[src]

Get the offset from the start of the stream, in 32-bit words.

+

Since the generated blocks are 16 words (24) long and the +counter is 64-bits, the offset is a 68-bit number. Sub-word offsets are +not supported, hence the result can simply be multiplied by 4 to get a +byte-offset.

+

pub fn set_word_pos(&mut self, word_offset: u128)[src]

Set the offset from the start of the stream, in 32-bit words.

+

As with get_word_pos, we use a 68-bit number. Since the generator +simply cycles at the end of its period (1 ZiB), we ignore the upper +60 bits.

+

pub fn set_stream(&mut self, stream: u64)[src]

Set the stream number.

+

This is initialized to zero; 264 unique streams of output +are available per seed/key.

+

Note that in order to reproduce ChaCha output with a specific 64-bit +nonce, one can convert that nonce to a u64 in little-endian fashion +and pass to this function. In theory a 96-bit nonce can be used by +passing the last 64-bits to this function and using the first 32-bits as +the most significant half of the 64-bit counter (which may be set +indirectly via set_word_pos), but this is not directly supported.

+

Trait Implementations

impl From<ChaCha20Core> for ChaCha20Rng[src]

impl Clone for ChaCha20Rng[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Debug for ChaCha20Rng[src]

impl RngCore for ChaCha20Rng[src]

impl CryptoRng for ChaCha20Rng[src]

impl SeedableRng for ChaCha20Rng[src]

type Seed = [u8; 32]

Seed type, which is restricted to types mutably-dereferencable as u8 arrays (we recommend [u8; N] for some N). Read more

+

fn seed_from_u64(state: u64) -> Self[src]

Create a new PRNG using a u64 seed. Read more

+

fn from_rng<R>(rng: R) -> Result<Self, Error> where
    R: RngCore
[src]

Create a new PRNG seeded from another Rng. Read more

+

fn from_entropy() -> Self[src]

Creates a new instance of the RNG seeded via [getrandom]. Read more

+

Auto Trait Implementations

impl Send for ChaCha20Rng

impl Sync for ChaCha20Rng

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand_chacha/struct.ChaCha8Core.html b/target/doc/rand_chacha/struct.ChaCha8Core.html new file mode 100644 index 0000000..3495614 --- /dev/null +++ b/target/doc/rand_chacha/struct.ChaCha8Core.html @@ -0,0 +1,27 @@ +rand_chacha::ChaCha8Core - Rust

[][src]Struct rand_chacha::ChaCha8Core

pub struct ChaCha8Core { /* fields omitted */ }

ChaCha with 8 rounds

+

Trait Implementations

impl From<ChaCha8Core> for ChaCha8Rng[src]

impl Clone for ChaCha8Core[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Debug for ChaCha8Core[src]

impl BlockRngCore for ChaCha8Core[src]

type Item = u32

Results element type, e.g. u32.

+

type Results = Array64<u32>

Results type. This is the 'block' an RNG implementing BlockRngCore generates, which will usually be an array like [u32; 16]. Read more

+

impl SeedableRng for ChaCha8Core[src]

type Seed = [u8; 32]

Seed type, which is restricted to types mutably-dereferencable as u8 arrays (we recommend [u8; N] for some N). Read more

+

fn seed_from_u64(state: u64) -> Self[src]

Create a new PRNG using a u64 seed. Read more

+

fn from_rng<R>(rng: R) -> Result<Self, Error> where
    R: RngCore
[src]

Create a new PRNG seeded from another Rng. Read more

+

fn from_entropy() -> Self[src]

Creates a new instance of the RNG seeded via [getrandom]. Read more

+

Auto Trait Implementations

impl Send for ChaCha8Core

impl Sync for ChaCha8Core

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand_chacha/struct.ChaCha8Rng.html b/target/doc/rand_chacha/struct.ChaCha8Rng.html new file mode 100644 index 0000000..3cfd012 --- /dev/null +++ b/target/doc/rand_chacha/struct.ChaCha8Rng.html @@ -0,0 +1,69 @@ +rand_chacha::ChaCha8Rng - Rust

[][src]Struct rand_chacha::ChaCha8Rng

pub struct ChaCha8Rng { /* fields omitted */ }

A cryptographically secure random number generator that uses the ChaCha algorithm.

+

ChaCha is a stream cipher designed by Daniel J. Bernstein1, that we use as an RNG. It is +an improved variant of the Salsa20 cipher family, which was selected as one of the "stream +ciphers suitable for widespread adoption" by eSTREAM2.

+

ChaCha uses add-rotate-xor (ARX) operations as its basis. These are safe against timing +attacks, although that is mostly a concern for ciphers and not for RNGs. We provide a SIMD +implementation to support high throughput on a variety of common hardware platforms.

+

With the ChaCha algorithm it is possible to choose the number of rounds the core algorithm +should run. The number of rounds is a tradeoff between performance and security, where 8 +rounds is the minimum potentially secure configuration, and 20 rounds is widely used as a +conservative choice.

+

We use a 64-bit counter and 64-bit stream identifier as in Bernstein's implementation1 +except that we use a stream identifier in place of a nonce. A 64-bit counter over 64-byte +(16 word) blocks allows 1 ZiB of output before cycling, and the stream identifier allows +264 unique streams of output per seed. Both counter and stream are initialized +to zero but may be set via the set_word_pos and set_stream methods.

+

The word layout is:

+
constant  constant  constant  constant
+seed      seed      seed      seed
+seed      seed      seed      seed
+counter   counter   stream_id stream_id
+
+

This implementation uses an output buffer of sixteen u32 words, and uses +[BlockRng] to implement the [RngCore] methods.

+

Methods

impl ChaCha8Rng[src]

pub fn get_word_pos(&self) -> u128[src]

Get the offset from the start of the stream, in 32-bit words.

+

Since the generated blocks are 16 words (24) long and the +counter is 64-bits, the offset is a 68-bit number. Sub-word offsets are +not supported, hence the result can simply be multiplied by 4 to get a +byte-offset.

+

pub fn set_word_pos(&mut self, word_offset: u128)[src]

Set the offset from the start of the stream, in 32-bit words.

+

As with get_word_pos, we use a 68-bit number. Since the generator +simply cycles at the end of its period (1 ZiB), we ignore the upper +60 bits.

+

pub fn set_stream(&mut self, stream: u64)[src]

Set the stream number.

+

This is initialized to zero; 264 unique streams of output +are available per seed/key.

+

Note that in order to reproduce ChaCha output with a specific 64-bit +nonce, one can convert that nonce to a u64 in little-endian fashion +and pass to this function. In theory a 96-bit nonce can be used by +passing the last 64-bits to this function and using the first 32-bits as +the most significant half of the 64-bit counter (which may be set +indirectly via set_word_pos), but this is not directly supported.

+

Trait Implementations

impl From<ChaCha8Core> for ChaCha8Rng[src]

impl Clone for ChaCha8Rng[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Debug for ChaCha8Rng[src]

impl RngCore for ChaCha8Rng[src]

impl CryptoRng for ChaCha8Rng[src]

impl SeedableRng for ChaCha8Rng[src]

type Seed = [u8; 32]

Seed type, which is restricted to types mutably-dereferencable as u8 arrays (we recommend [u8; N] for some N). Read more

+

fn seed_from_u64(state: u64) -> Self[src]

Create a new PRNG using a u64 seed. Read more

+

fn from_rng<R>(rng: R) -> Result<Self, Error> where
    R: RngCore
[src]

Create a new PRNG seeded from another Rng. Read more

+

fn from_entropy() -> Self[src]

Creates a new instance of the RNG seeded via [getrandom]. Read more

+

Auto Trait Implementations

impl Send for ChaCha8Rng

impl Sync for ChaCha8Rng

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 
[src]

\ No newline at end of file diff --git a/target/doc/rand_chacha/type.ChaChaCore.html b/target/doc/rand_chacha/type.ChaChaCore.html new file mode 100644 index 0000000..c234abd --- /dev/null +++ b/target/doc/rand_chacha/type.ChaChaCore.html @@ -0,0 +1,2 @@ +rand_chacha::ChaChaCore - Rust

[][src]Type Definition rand_chacha::ChaChaCore

type ChaChaCore = ChaCha20Core;

ChaCha with 20 rounds, low-level interface

+
\ No newline at end of file diff --git a/target/doc/rand_chacha/type.ChaChaRng.html b/target/doc/rand_chacha/type.ChaChaRng.html new file mode 100644 index 0000000..2ec0db1 --- /dev/null +++ b/target/doc/rand_chacha/type.ChaChaRng.html @@ -0,0 +1,2 @@ +rand_chacha::ChaChaRng - Rust

[][src]Type Definition rand_chacha::ChaChaRng

type ChaChaRng = ChaCha20Rng;

ChaCha with 20 rounds

+
\ No newline at end of file diff --git a/target/doc/rand_core/all.html b/target/doc/rand_core/all.html new file mode 100644 index 0000000..7fa08b4 --- /dev/null +++ b/target/doc/rand_core/all.html @@ -0,0 +1,3 @@ +List of all items in this crate

[] + + List of all items

Structs

Traits

Functions

\ No newline at end of file diff --git a/target/doc/rand_core/block/index.html b/target/doc/rand_core/block/index.html new file mode 100644 index 0000000..0a86323 --- /dev/null +++ b/target/doc/rand_core/block/index.html @@ -0,0 +1,47 @@ +rand_core::block - Rust

[][src]Module rand_core::block

The BlockRngCore trait and implementation helpers

+

The BlockRngCore trait exists to assist in the implementation of RNGs +which generate a block of data in a cache instead of returning generated +values directly.

+

Usage of this trait is optional, but provides two advantages: +implementations only need to concern themselves with generation of the +block, not the various [RngCore] methods (especially fill_bytes, where +the optimal implementations are not trivial), and this allows +ReseedingRng (see rand crate) perform periodic +reseeding with very low overhead.

+

Example

+
use rand_core::block::{BlockRngCore, BlockRng};
+
+struct MyRngCore;
+
+impl BlockRngCore for MyRngCore {
+    type Results = [u32; 16];
+
+    fn generate(&mut self, results: &mut Self::Results) {
+        unimplemented!()
+    }
+}
+
+impl SeedableRng for MyRngCore {
+    type Seed = unimplemented!();
+    fn from_seed(seed: Self::Seed) -> Self {
+        unimplemented!()
+    }
+}
+
+// optionally, also implement CryptoRng for MyRngCore
+
+// Final RNG.
+type MyRng = BlockRng<u32, MyRngCore>;
+
+

Structs

+
BlockRng

A wrapper type implementing [RngCore] for some type implementing +[BlockRngCore] with u32 array buffer; i.e. this can be used to implement +a full RNG from just a generate function.

+
BlockRng64

A wrapper type implementing [RngCore] for some type implementing +[BlockRngCore] with u64 array buffer; i.e. this can be used to implement +a full RNG from just a generate function.

+

Traits

+
BlockRngCore

A trait for RNGs which do not generate random numbers individually, but in +blocks (typically [u32; N]). This technique is commonly used by +cryptographic RNGs to improve performance.

+
\ No newline at end of file diff --git a/target/doc/rand_core/block/sidebar-items.js b/target/doc/rand_core/block/sidebar-items.js new file mode 100644 index 0000000..1bc831f --- /dev/null +++ b/target/doc/rand_core/block/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["BlockRng","A wrapper type implementing [`RngCore`] for some type implementing [`BlockRngCore`] with `u32` array buffer; i.e. this can be used to implement a full RNG from just a `generate` function."],["BlockRng64","A wrapper type implementing [`RngCore`] for some type implementing [`BlockRngCore`] with `u64` array buffer; i.e. this can be used to implement a full RNG from just a `generate` function."]],"trait":[["BlockRngCore","A trait for RNGs which do not generate random numbers individually, but in blocks (typically `[u32; N]`). This technique is commonly used by cryptographic RNGs to improve performance."]]}); \ No newline at end of file diff --git a/target/doc/rand_core/block/struct.BlockRng.html b/target/doc/rand_core/block/struct.BlockRng.html new file mode 100644 index 0000000..6699302 --- /dev/null +++ b/target/doc/rand_core/block/struct.BlockRng.html @@ -0,0 +1,66 @@ +rand_core::block::BlockRng - Rust

[][src]Struct rand_core::block::BlockRng

pub struct BlockRng<R: BlockRngCore + ?Sized> {
+    pub core: R,
+    // some fields omitted
+}

A wrapper type implementing [RngCore] for some type implementing +[BlockRngCore] with u32 array buffer; i.e. this can be used to implement +a full RNG from just a generate function.

+

The core field may be accessed directly but the results buffer may not. +PRNG implementations can simply use a type alias +(pub type MyRng = BlockRng<MyRngCore>;) but might prefer to use a +wrapper type (pub struct MyRng(BlockRng<MyRngCore>);); the latter must +re-implement RngCore but hides the implementation details and allows +extra functionality to be defined on the RNG +(e.g. impl MyRng { fn set_stream(...){...} }).

+

BlockRng has heavily optimized implementations of the [RngCore] methods +reading values from the results buffer, as well as +calling [BlockRngCore::generate] directly on the output array when +fill_bytes / try_fill_bytes is called on a large array. These methods +also handle the bookkeeping of when to generate a new batch of values.

+

No whole generated u32 values are thown away and all values are consumed +in-order. next_u32 simply takes the next available u32 value. +next_u64 is implemented by combining two u32 values, least +significant first. fill_bytes and try_fill_bytes consume a whole +number of u32 values, converting each u32 to a byte slice in +little-endian order. If the requested byte length is not a multiple of 4, +some bytes will be discarded.

+

See also [BlockRng64] which uses u64 array buffers. Currently there is +no direct support for other buffer types.

+

For easy initialization BlockRng also implements [SeedableRng].

+

+ Fields

core: R

The core part of the RNG, implementing the generate function.

+

Methods

impl<R: BlockRngCore> BlockRng<R>[src]

pub fn new(core: R) -> BlockRng<R>[src]

Create a new BlockRng from an existing RNG implementing +BlockRngCore. Results will be generated on first use.

+

pub fn index(&self) -> usize[src]

Get the index into the result buffer.

+

If this is equal to or larger than the size of the result buffer then +the buffer is "empty" and generate() must be called to produce new +results.

+

pub fn reset(&mut self)[src]

Reset the number of available results. +This will force a new set of results to be generated on next use.

+

pub fn generate_and_set(&mut self, index: usize)[src]

Generate a new set of results immediately, setting the index to the +given value.

+

Trait Implementations

impl<R: BlockRngCore<Item = u32>> RngCore for BlockRng<R> where
    <R as BlockRngCore>::Results: AsRef<[u32]> + AsMut<[u32]>, 
[src]

impl<R: BlockRngCore + CryptoRng> CryptoRng for BlockRng<R>[src]

impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng<R>[src]

type Seed = R::Seed

Seed type, which is restricted to types mutably-dereferencable as u8 arrays (we recommend [u8; N] for some N). Read more

+

fn from_entropy() -> Self[src]

Creates a new instance of the RNG seeded via [getrandom]. Read more

+

impl<R: Clone + BlockRngCore + ?Sized> Clone for BlockRng<R> where
    R::Results: Clone
[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl<R: BlockRngCore + Debug> Debug for BlockRng<R>[src]

Auto Trait Implementations

impl<R: ?Sized> Send for BlockRng<R> where
    R: Send,
    <R as BlockRngCore>::Results: Send

impl<R: ?Sized> Sync for BlockRng<R> where
    R: Sync,
    <R as BlockRngCore>::Results: Sync

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/rand_core/block/struct.BlockRng64.html b/target/doc/rand_core/block/struct.BlockRng64.html new file mode 100644 index 0000000..ede9e25 --- /dev/null +++ b/target/doc/rand_core/block/struct.BlockRng64.html @@ -0,0 +1,55 @@ +rand_core::block::BlockRng64 - Rust

[][src]Struct rand_core::block::BlockRng64

pub struct BlockRng64<R: BlockRngCore + ?Sized> {
+    pub core: R,
+    // some fields omitted
+}

A wrapper type implementing [RngCore] for some type implementing +[BlockRngCore] with u64 array buffer; i.e. this can be used to implement +a full RNG from just a generate function.

+

This is similar to [BlockRng], but specialized for algorithms that operate +on u64 values.

+

No whole generated u64 values are thrown away and all values are consumed +in-order. next_u64 simply takes the next available u64 value. +next_u32 is however a bit special: half of a u64 is consumed, leaving +the other half in the buffer. If the next function called is next_u32 +then the other half is then consumed, however both next_u64 and +fill_bytes discard the rest of any half-consumed u64s when called.

+

fill_bytes and try_fill_bytes consume a whole number of u64 +values. If the requested length is not a multiple of 8, some bytes will be +discarded.

+

+ Fields

core: R

The core part of the RNG, implementing the generate function.

+

Methods

impl<R: BlockRngCore> BlockRng64<R>[src]

pub fn new(core: R) -> BlockRng64<R>[src]

Create a new BlockRng from an existing RNG implementing +BlockRngCore. Results will be generated on first use.

+

pub fn index(&self) -> usize[src]

Get the index into the result buffer.

+

If this is equal to or larger than the size of the result buffer then +the buffer is "empty" and generate() must be called to produce new +results.

+

pub fn reset(&mut self)[src]

Reset the number of available results. +This will force a new set of results to be generated on next use.

+

pub fn generate_and_set(&mut self, index: usize)[src]

Generate a new set of results immediately, setting the index to the +given value.

+

Trait Implementations

impl<R: BlockRngCore<Item = u64>> RngCore for BlockRng64<R> where
    <R as BlockRngCore>::Results: AsRef<[u64]> + AsMut<[u64]>, 
[src]

impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng64<R>[src]

type Seed = R::Seed

Seed type, which is restricted to types mutably-dereferencable as u8 arrays (we recommend [u8; N] for some N). Read more

+

fn from_entropy() -> Self[src]

Creates a new instance of the RNG seeded via [getrandom]. Read more

+

impl<R: Clone + BlockRngCore + ?Sized> Clone for BlockRng64<R> where
    R::Results: Clone
[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl<R: BlockRngCore + Debug> Debug for BlockRng64<R>[src]

Auto Trait Implementations

impl<R: ?Sized> Send for BlockRng64<R> where
    R: Send,
    <R as BlockRngCore>::Results: Send

impl<R: ?Sized> Sync for BlockRng64<R> where
    R: Sync,
    <R as BlockRngCore>::Results: Sync

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/rand_core/block/trait.BlockRngCore.html b/target/doc/rand_core/block/trait.BlockRngCore.html new file mode 100644 index 0000000..0b087e3 --- /dev/null +++ b/target/doc/rand_core/block/trait.BlockRngCore.html @@ -0,0 +1,18 @@ +rand_core::block::BlockRngCore - Rust

[][src]Trait rand_core::block::BlockRngCore

pub trait BlockRngCore {
+    type Item;
+    type Results: AsRef<[Self::Item]> + AsMut<[Self::Item]> + Default;
+    fn generate(&mut self, results: &mut Self::Results);
+}

A trait for RNGs which do not generate random numbers individually, but in +blocks (typically [u32; N]). This technique is commonly used by +cryptographic RNGs to improve performance.

+

See the [module][crate::block] documentation for details.

+
+

Associated Types

type Item

Results element type, e.g. u32.

+

type Results: AsRef<[Self::Item]> + AsMut<[Self::Item]> + Default

Results type. This is the 'block' an RNG implementing BlockRngCore +generates, which will usually be an array like [u32; 16].

+
Loading content... +

Required methods

fn generate(&mut self, results: &mut Self::Results)

Generate a new block of results.

+
Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/rand_core/error/struct.Error.html b/target/doc/rand_core/error/struct.Error.html new file mode 100644 index 0000000..3cf4623 --- /dev/null +++ b/target/doc/rand_core/error/struct.Error.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../rand_core/struct.Error.html...

+ + + \ No newline at end of file diff --git a/target/doc/rand_core/impls/fn.fill_bytes_via_next.html b/target/doc/rand_core/impls/fn.fill_bytes_via_next.html new file mode 100644 index 0000000..3bfcafc --- /dev/null +++ b/target/doc/rand_core/impls/fn.fill_bytes_via_next.html @@ -0,0 +1,6 @@ +rand_core::impls::fill_bytes_via_next - Rust

[][src]Function rand_core::impls::fill_bytes_via_next

pub fn fill_bytes_via_next<R: RngCore + ?Sized>(rng: &mut R, dest: &mut [u8])

Implement fill_bytes via next_u64 and next_u32, little-endian order.

+

The fastest way to fill a slice is usually to work as long as possible with +integers. That is why this method mostly uses next_u64, and only when +there are 4 or less bytes remaining at the end of the slice it uses +next_u32 once.

+
\ No newline at end of file diff --git a/target/doc/rand_core/impls/fn.fill_via_u32_chunks.html b/target/doc/rand_core/impls/fn.fill_via_u32_chunks.html new file mode 100644 index 0000000..1c07760 --- /dev/null +++ b/target/doc/rand_core/impls/fn.fill_via_u32_chunks.html @@ -0,0 +1,27 @@ +rand_core::impls::fill_via_u32_chunks - Rust

[][src]Function rand_core::impls::fill_via_u32_chunks

pub fn fill_via_u32_chunks(src: &[u32], dest: &mut [u8]) -> (usize, usize)

Implement fill_bytes by reading chunks from the output buffer of a block +based RNG.

+

The return values are (consumed_u32, filled_u8).

+

filled_u8 is the number of filled bytes in dest, which may be less than +the length of dest. +consumed_u32 is the number of words consumed from src, which is the same +as filled_u8 / 4 rounded up.

+

Example

+

(from IsaacRng)

+ +
This example is not tested
+fn fill_bytes(&mut self, dest: &mut [u8]) {
+    let mut read_len = 0;
+    while read_len < dest.len() {
+        if self.index >= self.rsl.len() {
+            self.isaac();
+        }
+
+        let (consumed_u32, filled_u8) =
+            impls::fill_via_u32_chunks(&mut self.rsl[self.index..],
+                                       &mut dest[read_len..]);
+
+        self.index += consumed_u32;
+        read_len += filled_u8;
+    }
+}
+
\ No newline at end of file diff --git a/target/doc/rand_core/impls/fn.fill_via_u64_chunks.html b/target/doc/rand_core/impls/fn.fill_via_u64_chunks.html new file mode 100644 index 0000000..00a57a5 --- /dev/null +++ b/target/doc/rand_core/impls/fn.fill_via_u64_chunks.html @@ -0,0 +1,9 @@ +rand_core::impls::fill_via_u64_chunks - Rust

[][src]Function rand_core::impls::fill_via_u64_chunks

pub fn fill_via_u64_chunks(src: &[u64], dest: &mut [u8]) -> (usize, usize)

Implement fill_bytes by reading chunks from the output buffer of a block +based RNG.

+

The return values are (consumed_u64, filled_u8). +filled_u8 is the number of filled bytes in dest, which may be less than +the length of dest. +consumed_u64 is the number of words consumed from src, which is the same +as filled_u8 / 8 rounded up.

+

See fill_via_u32_chunks for an example.

+
\ No newline at end of file diff --git a/target/doc/rand_core/impls/fn.next_u32_via_fill.html b/target/doc/rand_core/impls/fn.next_u32_via_fill.html new file mode 100644 index 0000000..aa90a21 --- /dev/null +++ b/target/doc/rand_core/impls/fn.next_u32_via_fill.html @@ -0,0 +1,2 @@ +rand_core::impls::next_u32_via_fill - Rust

[][src]Function rand_core::impls::next_u32_via_fill

pub fn next_u32_via_fill<R: RngCore + ?Sized>(rng: &mut R) -> u32

Implement next_u32 via fill_bytes, little-endian order.

+
\ No newline at end of file diff --git a/target/doc/rand_core/impls/fn.next_u64_via_fill.html b/target/doc/rand_core/impls/fn.next_u64_via_fill.html new file mode 100644 index 0000000..66d2871 --- /dev/null +++ b/target/doc/rand_core/impls/fn.next_u64_via_fill.html @@ -0,0 +1,2 @@ +rand_core::impls::next_u64_via_fill - Rust

[][src]Function rand_core::impls::next_u64_via_fill

pub fn next_u64_via_fill<R: RngCore + ?Sized>(rng: &mut R) -> u64

Implement next_u64 via fill_bytes, little-endian order.

+
\ No newline at end of file diff --git a/target/doc/rand_core/impls/fn.next_u64_via_u32.html b/target/doc/rand_core/impls/fn.next_u64_via_u32.html new file mode 100644 index 0000000..81cb5bd --- /dev/null +++ b/target/doc/rand_core/impls/fn.next_u64_via_u32.html @@ -0,0 +1,2 @@ +rand_core::impls::next_u64_via_u32 - Rust

[][src]Function rand_core::impls::next_u64_via_u32

pub fn next_u64_via_u32<R: RngCore + ?Sized>(rng: &mut R) -> u64

Implement next_u64 via next_u32, little-endian order.

+
\ No newline at end of file diff --git a/target/doc/rand_core/impls/index.html b/target/doc/rand_core/impls/index.html new file mode 100644 index 0000000..65ebc8b --- /dev/null +++ b/target/doc/rand_core/impls/index.html @@ -0,0 +1,18 @@ +rand_core::impls - Rust

[][src]Module rand_core::impls

Helper functions for implementing RngCore functions.

+

For cross-platform reproducibility, these functions all use Little Endian: +least-significant part first. For example, next_u64_via_u32 takes u32 +values x, y, then outputs (y << 32) | x. To implement next_u32 +from next_u64 in little-endian order, one should use next_u64() as u32.

+

Byte-swapping (like the std to_le functions) is only needed to convert +to/from byte sequences, and since its purpose is reproducibility, +non-reproducible sources (e.g. OsRng) need not bother with it.

+

Functions

+
fill_bytes_via_next

Implement fill_bytes via next_u64 and next_u32, little-endian order.

+
fill_via_u32_chunks

Implement fill_bytes by reading chunks from the output buffer of a block +based RNG.

+
fill_via_u64_chunks

Implement fill_bytes by reading chunks from the output buffer of a block +based RNG.

+
next_u32_via_fill

Implement next_u32 via fill_bytes, little-endian order.

+
next_u64_via_fill

Implement next_u64 via fill_bytes, little-endian order.

+
next_u64_via_u32

Implement next_u64 via next_u32, little-endian order.

+
\ No newline at end of file diff --git a/target/doc/rand_core/impls/sidebar-items.js b/target/doc/rand_core/impls/sidebar-items.js new file mode 100644 index 0000000..ac2123c --- /dev/null +++ b/target/doc/rand_core/impls/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"fn":[["fill_bytes_via_next","Implement `fill_bytes` via `next_u64` and `next_u32`, little-endian order."],["fill_via_u32_chunks","Implement `fill_bytes` by reading chunks from the output buffer of a block based RNG."],["fill_via_u64_chunks","Implement `fill_bytes` by reading chunks from the output buffer of a block based RNG."],["next_u32_via_fill","Implement `next_u32` via `fill_bytes`, little-endian order."],["next_u64_via_fill","Implement `next_u64` via `fill_bytes`, little-endian order."],["next_u64_via_u32","Implement `next_u64` via `next_u32`, little-endian order."]]}); \ No newline at end of file diff --git a/target/doc/rand_core/index.html b/target/doc/rand_core/index.html new file mode 100644 index 0000000..0d663bc --- /dev/null +++ b/target/doc/rand_core/index.html @@ -0,0 +1,24 @@ +rand_core - Rust

[][src]Crate rand_core

Random number generation traits

+

This crate is mainly of interest to crates publishing implementations of +[RngCore]. Other users are encouraged to use the rand crate instead +which re-exports the main traits and error types.

+

[RngCore] is the core trait implemented by algorithmic pseudo-random number +generators and external random-number sources.

+

[SeedableRng] is an extension trait for construction from fixed seeds and +other random number generators.

+

[Error] is provided for error-handling. It is safe to use in no_std +environments.

+

The [impls] and [le] sub-modules include a few small functions to assist +implementation of [RngCore].

+

Modules

+
block

The BlockRngCore trait and implementation helpers

+
impls

Helper functions for implementing RngCore functions.

+
le

Little-Endian utilities

+

Structs

+
Error

Error type of random number generators

+

Traits

+
CryptoRng

A marker trait used to indicate that an [RngCore] or BlockRngCore +implementation is supposed to be cryptographically secure.

+
RngCore

The core of a random number generator.

+
SeedableRng

A random number generator that can be explicitly seeded.

+
\ No newline at end of file diff --git a/target/doc/rand_core/le/fn.read_u32_into.html b/target/doc/rand_core/le/fn.read_u32_into.html new file mode 100644 index 0000000..03ea4bc --- /dev/null +++ b/target/doc/rand_core/le/fn.read_u32_into.html @@ -0,0 +1,3 @@ +rand_core::le::read_u32_into - Rust

[][src]Function rand_core::le::read_u32_into

pub fn read_u32_into(src: &[u8], dst: &mut [u32])

Reads unsigned 32 bit integers from src into dst. +Borrowed from the byteorder crate.

+
\ No newline at end of file diff --git a/target/doc/rand_core/le/fn.read_u64_into.html b/target/doc/rand_core/le/fn.read_u64_into.html new file mode 100644 index 0000000..ea2267f --- /dev/null +++ b/target/doc/rand_core/le/fn.read_u64_into.html @@ -0,0 +1,3 @@ +rand_core::le::read_u64_into - Rust

[][src]Function rand_core::le::read_u64_into

pub fn read_u64_into(src: &[u8], dst: &mut [u64])

Reads unsigned 64 bit integers from src into dst. +Borrowed from the byteorder crate.

+
\ No newline at end of file diff --git a/target/doc/rand_core/le/index.html b/target/doc/rand_core/le/index.html new file mode 100644 index 0000000..6457642 --- /dev/null +++ b/target/doc/rand_core/le/index.html @@ -0,0 +1,9 @@ +rand_core::le - Rust

[][src]Module rand_core::le

Little-Endian utilities

+

Little-Endian order has been chosen for internal usage; this makes some +useful functions available.

+

Functions

+
read_u32_into

Reads unsigned 32 bit integers from src into dst. +Borrowed from the byteorder crate.

+
read_u64_into

Reads unsigned 64 bit integers from src into dst. +Borrowed from the byteorder crate.

+
\ No newline at end of file diff --git a/target/doc/rand_core/le/sidebar-items.js b/target/doc/rand_core/le/sidebar-items.js new file mode 100644 index 0000000..a18f3ad --- /dev/null +++ b/target/doc/rand_core/le/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"fn":[["read_u32_into","Reads unsigned 32 bit integers from `src` into `dst`. Borrowed from the `byteorder` crate."],["read_u64_into","Reads unsigned 64 bit integers from `src` into `dst`. Borrowed from the `byteorder` crate."]]}); \ No newline at end of file diff --git a/target/doc/rand_core/sidebar-items.js b/target/doc/rand_core/sidebar-items.js new file mode 100644 index 0000000..a11b8df --- /dev/null +++ b/target/doc/rand_core/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"mod":[["block","The `BlockRngCore` trait and implementation helpers"],["impls","Helper functions for implementing `RngCore` functions."],["le","Little-Endian utilities"]],"struct":[["Error","Error type of random number generators"]],"trait":[["CryptoRng","A marker trait used to indicate that an [`RngCore`] or [`BlockRngCore`] implementation is supposed to be cryptographically secure."],["RngCore","The core of a random number generator."],["SeedableRng","A random number generator that can be explicitly seeded."]]}); \ No newline at end of file diff --git a/target/doc/rand_core/struct.Error.html b/target/doc/rand_core/struct.Error.html new file mode 100644 index 0000000..e5dc3a3 --- /dev/null +++ b/target/doc/rand_core/struct.Error.html @@ -0,0 +1,37 @@ +rand_core::Error - Rust

[][src]Struct rand_core::Error

pub struct Error { /* fields omitted */ }

Error type of random number generators

+

In order to be compatible with std and no_std, this type has two +possible implementations: with std a boxed Error trait object is stored, +while with no_std we merely store an error code.

+

Methods

impl Error[src]

pub fn new<E>(err: E) -> Self where
    E: Into<Box<dyn Error + Send + Sync + 'static>>, 
[src]

Construct from any type supporting std::error::Error

+

Available only when configured with std.

+

See also From<NonZeroU32>, which is available with and without std.

+

pub fn inner(&self) -> &(dyn Error + Send + Sync + 'static)[src]

Reference the inner error (std only)

+

When configured with std, this is a trivial operation and never +panics. Without std, this method is simply unavailable.

+

pub fn take_inner(self) -> Box<dyn Error + Send + Sync + 'static>[src]

Unwrap the inner error (std only)

+

When configured with std, this is a trivial operation and never +panics. Without std, this method is simply unavailable.

+

pub fn code(&self) -> Option<NonZeroU32>[src]

Retrieve the error code, if any.

+

If this Error was constructed via From<NonZeroU32>, then this method +will return this NonZeroU32 code (for no_std this is always the +case). Otherwise, this method will return None.

+

Trait Implementations

impl From<NonZeroU32> for Error[src]

impl From<Error> for Error[src]

impl From<Error> for Error[src]

impl Display for Error[src]

impl Debug for Error[src]

impl Error for Error[src]

fn description(&self) -> &str1.0.0[src]

This method is soft-deprecated. Read more

+

fn cause(&self) -> Option<&dyn Error>1.0.0[src]

Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

+

The lower-level cause of this error, if any. Read more

+

Auto Trait Implementations

impl Send for Error

impl Sync for Error

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/rand_core/trait.CryptoRng.html b/target/doc/rand_core/trait.CryptoRng.html new file mode 100644 index 0000000..7d3cfaf --- /dev/null +++ b/target/doc/rand_core/trait.CryptoRng.html @@ -0,0 +1,21 @@ +rand_core::CryptoRng - Rust

[][src]Trait rand_core::CryptoRng

pub trait CryptoRng { }

A marker trait used to indicate that an [RngCore] or BlockRngCore +implementation is supposed to be cryptographically secure.

+

Cryptographically secure generators, also known as CSPRNGs, should +satisfy an additional properties over other generators: given the first +k bits of an algorithm's output +sequence, it should not be possible using polynomial-time algorithms to +predict the next bit with probability significantly greater than 50%.

+

Some generators may satisfy an additional property, however this is not +required by this trait: if the CSPRNG's state is revealed, it should not be +computationally-feasible to reconstruct output prior to this. Some other +generators allow backwards-computation and are consided reversible.

+

Note that this trait is provided for guidance only and cannot guarantee +suitability for cryptographic applications. In general it should only be +implemented for well-reviewed code implementing well-regarded algorithms.

+

Note also that use of a CryptoRng does not protect against other +weaknesses such as seeding from a weak entropy source or leaking state.

+
+

Implementations on Foreign Types

impl<'a, R: CryptoRng + ?Sized> CryptoRng for &'a mut R[src]

impl<R: CryptoRng + ?Sized> CryptoRng for Box<R>[src]

Loading content... +

Implementors

impl<R: BlockRngCore + CryptoRng> CryptoRng for BlockRng<R>[src]

Loading content...
\ No newline at end of file diff --git a/target/doc/rand_core/trait.RngCore.html b/target/doc/rand_core/trait.RngCore.html new file mode 100644 index 0000000..3238d4d --- /dev/null +++ b/target/doc/rand_core/trait.RngCore.html @@ -0,0 +1,114 @@ +rand_core::RngCore - Rust

[][src]Trait rand_core::RngCore

pub trait RngCore {
+    fn next_u32(&mut self) -> u32;
+
fn next_u64(&mut self) -> u64; +
fn fill_bytes(&mut self, dest: &mut [u8]); +
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error>; +}

The core of a random number generator.

+

This trait encapsulates the low-level functionality common to all +generators, and is the "back end", to be implemented by generators. +End users should normally use the Rng trait from the rand crate, +which is automatically implemented for every type implementing RngCore.

+

Three different methods for generating random data are provided since the +optimal implementation of each is dependent on the type of generator. There +is no required relationship between the output of each; e.g. many +implementations of fill_bytes consume a whole number of u32 or u64 +values and drop any remaining unused bytes.

+

The try_fill_bytes method is a variant of fill_bytes allowing error +handling; it is not deemed sufficiently useful to add equivalents for +next_u32 or next_u64 since the latter methods are almost always used +with algorithmic generators (PRNGs), which are normally infallible.

+

Algorithmic generators implementing [SeedableRng] should normally have +portable, reproducible output, i.e. fix Endianness when converting values +to avoid platform differences, and avoid making any changes which affect +output (except by communicating that the release has breaking changes).

+

Typically implementators will implement only one of the methods available +in this trait directly, then use the helper functions from the +[impls] module to implement the other methods.

+

It is recommended that implementations also implement:

+
    +
  • Debug with a custom implementation which does not print any internal +state (at least, [CryptoRng]s should not risk leaking state through +Debug).
  • +
  • Serialize and Deserialize (from Serde), preferably making Serde +support optional at the crate level in PRNG libs.
  • +
  • Clone, if possible.
  • +
  • never implement Copy (accidental copies may cause repeated values).
  • +
  • do not implement Default for pseudorandom generators, but instead +implement [SeedableRng], to guide users towards proper seeding. +External / hardware RNGs can choose to implement Default.
  • +
  • Eq and PartialEq could be implemented, but are probably not useful.
  • +
+

Example

+

A simple example, obviously not generating very random output:

+ +
+#![allow(dead_code)]
+use rand_core::{RngCore, Error, impls};
+
+struct CountingRng(u64);
+
+impl RngCore for CountingRng {
+    fn next_u32(&mut self) -> u32 {
+        self.next_u64() as u32
+    }
+
+    fn next_u64(&mut self) -> u64 {
+        self.0 += 1;
+        self.0
+    }
+
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        impls::fill_bytes_via_next(self, dest)
+    }
+
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        Ok(self.fill_bytes(dest))
+    }
+}
+
+

Required methods

fn next_u32(&mut self) -> u32

Return the next random u32.

+

RNGs must implement at least one method from this trait directly. In +the case this method is not implemented directly, it can be implemented +using self.next_u64() as u32 or via +[fill_bytes][impls::next_u32_via_fill].

+

fn next_u64(&mut self) -> u64

Return the next random u64.

+

RNGs must implement at least one method from this trait directly. In +the case this method is not implemented directly, it can be implemented +via [next_u32][impls::next_u64_via_u32] or via +[fill_bytes][impls::next_u64_via_fill].

+

fn fill_bytes(&mut self, dest: &mut [u8])

Fill dest with random data.

+

RNGs must implement at least one method from this trait directly. In +the case this method is not implemented directly, it can be implemented +via [next_u*][impls::fill_bytes_via_next] or +via [try_fill_bytes][RngCore::try_fill_bytes]; if this generator can +fail the implementation must choose how best to handle errors here +(e.g. panic with a descriptive message or log a warning and retry a few +times).

+

This method should guarantee that dest is entirely filled +with new data, and may panic if this is impossible +(e.g. reading past the end of a file that is being used as the +source of randomness).

+

fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error>

Fill dest entirely with random data.

+

This is the only method which allows an RNG to report errors while +generating random data thus making this the primary method implemented +by external (true) RNGs (e.g. OsRng) which can fail. It may be used +directly to generate keys and to seed (infallible) PRNGs.

+

Other than error handling, this method is identical to fill_bytes; +thus this may be implemented using Ok(self.fill_bytes(dest)) or +fill_bytes may be implemented with +self.try_fill_bytes(dest).unwrap() or more specific error handling.

+
Loading content...

Trait Implementations

impl Read for dyn RngCore[src]

fn read_vectored(&mut self, bufs: &mut [IoSliceMut]) -> Result<usize, Error>1.36.0[src]

Like read, except that it reads into a slice of buffers. Read more

+

unsafe fn initializer(&self) -> Initializer[src]

🔬 This is a nightly-only experimental API. (read_initializer)

Determines if this Reader can work with buffers of uninitialized memory. Read more

+

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, Error>1.0.0[src]

Read all bytes until EOF in this source, placing them into buf. Read more

+

fn read_to_string(&mut self, buf: &mut String) -> Result<usize, Error>1.0.0[src]

Read all bytes until EOF in this source, appending them to buf. Read more

+

fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>1.6.0[src]

Read the exact number of bytes required to fill buf. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Creates a "by reference" adaptor for this instance of Read. Read more

+

fn bytes(self) -> Bytes<Self>1.0.0[src]

Transforms this Read instance to an [Iterator] over its bytes. Read more

+

fn chain<R>(self, next: R) -> Chain<Self, R> where
    R: Read
1.0.0[src]

Creates an adaptor which will chain this stream with another. Read more

+

fn take(self, limit: u64) -> Take<Self>1.0.0[src]

Creates an adaptor which will read at most limit bytes from it. Read more

+
+

Implementations on Foreign Types

impl<'a, R: RngCore + ?Sized> RngCore for &'a mut R[src]

impl<R: RngCore + ?Sized> RngCore for Box<R>[src]

Loading content... +

Implementors

impl<R: BlockRngCore<Item = u32>> RngCore for BlockRng<R> where
    <R as BlockRngCore>::Results: AsRef<[u32]> + AsMut<[u32]>, 
[src]

impl<R: BlockRngCore<Item = u64>> RngCore for BlockRng64<R> where
    <R as BlockRngCore>::Results: AsRef<[u64]> + AsMut<[u64]>, 
[src]

Loading content...
\ No newline at end of file diff --git a/target/doc/rand_core/trait.SeedableRng.html b/target/doc/rand_core/trait.SeedableRng.html new file mode 100644 index 0000000..159f876 --- /dev/null +++ b/target/doc/rand_core/trait.SeedableRng.html @@ -0,0 +1,114 @@ +rand_core::SeedableRng - Rust

[][src]Trait rand_core::SeedableRng

pub trait SeedableRng: Sized {
+    type Seed: Sized + Default + AsMut<[u8]>;
+    fn from_seed(seed: Self::Seed) -> Self;
+
+    fn seed_from_u64(state: u64) -> Self { ... }
+
fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error> { ... } +
fn from_entropy() -> Self { ... } +}

A random number generator that can be explicitly seeded.

+

This trait encapsulates the low-level functionality common to all +pseudo-random number generators (PRNGs, or algorithmic generators).

+
+

Associated Types

type Seed: Sized + Default + AsMut<[u8]>

Seed type, which is restricted to types mutably-dereferencable as u8 +arrays (we recommend [u8; N] for some N).

+

It is recommended to seed PRNGs with a seed of at least circa 100 bits, +which means an array of [u8; 12] or greater to avoid picking RNGs with +partially overlapping periods.

+

For cryptographic RNG's a seed of 256 bits is recommended, [u8; 32].

+

Implementing SeedableRng for RNGs with large seeds

+

Note that the required traits core::default::Default and +core::convert::AsMut<u8> are not implemented for large arrays +[u8; N] with N > 32. To be able to implement the traits required by +SeedableRng for RNGs with such large seeds, the newtype pattern can be +used:

+ +
+use rand_core::SeedableRng;
+
+const N: usize = 64;
+pub struct MyRngSeed(pub [u8; N]);
+pub struct MyRng(MyRngSeed);
+
+impl Default for MyRngSeed {
+    fn default() -> MyRngSeed {
+        MyRngSeed([0; N])
+    }
+}
+
+impl AsMut<[u8]> for MyRngSeed {
+    fn as_mut(&mut self) -> &mut [u8] {
+        &mut self.0
+    }
+}
+
+impl SeedableRng for MyRng {
+    type Seed = MyRngSeed;
+
+    fn from_seed(seed: MyRngSeed) -> MyRng {
+        MyRng(seed)
+    }
+}
+
Loading content... +

Required methods

fn from_seed(seed: Self::Seed) -> Self

Create a new PRNG using the given seed.

+

PRNG implementations are allowed to assume that bits in the seed are +well distributed. That means usually that the number of one and zero +bits are roughly equal, and values like 0, 1 and (size - 1) are unlikely. +Note that many non-cryptographic PRNGs will show poor quality output +if this is not adhered to. If you wish to seed from simple numbers, use +seed_from_u64 instead.

+

All PRNG implementations should be reproducible unless otherwise noted: +given a fixed seed, the same sequence of output should be produced +on all runs, library versions and architectures (e.g. check endianness). +Any "value-breaking" changes to the generator should require bumping at +least the minor version and documentation of the change.

+

It is not required that this function yield the same state as a +reference implementation of the PRNG given equivalent seed; if necessary +another constructor replicating behaviour from a reference +implementation can be added.

+

PRNG implementations should make sure from_seed never panics. In the +case that some special values (like an all zero seed) are not viable +seeds it is preferable to map these to alternative constant value(s), +for example 0xBAD5EEDu32 or 0x0DDB1A5E5BAD5EEDu64 ("odd biases? bad +seed"). This is assuming only a small number of values must be rejected.

+
Loading content... +

Provided methods

fn seed_from_u64(state: u64) -> Self

Create a new PRNG using a u64 seed.

+

This is a convenience-wrapper around from_seed to allow construction +of any SeedableRng from a simple u64 value. It is designed such that +low Hamming Weight numbers like 0 and 1 can be used and should still +result in good, independent seeds to the PRNG which is returned.

+

This is not suitable for cryptography, as should be clear given that +the input size is only 64 bits.

+

Implementations for PRNGs may provide their own implementations of +this function, but the default implementation should be good enough for +all purposes. Changing the implementation of this function should be +considered a value-breaking change.

+

fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error>

Create a new PRNG seeded from another Rng.

+

This may be useful when needing to rapidly seed many PRNGs from a master +PRNG, and to allow forking of PRNGs. It may be considered deterministic.

+

The master PRNG should be at least as high quality as the child PRNGs. +When seeding non-cryptographic child PRNGs, we recommend using a +different algorithm for the master PRNG (ideally a CSPRNG) to avoid +correlations between the child PRNGs. If this is not possible (e.g. +forking using small non-crypto PRNGs) ensure that your PRNG has a good +mixing function on the output or consider use of a hash function with +from_seed.

+

Note that seeding XorShiftRng from another XorShiftRng provides an +extreme example of what can go wrong: the new PRNG will be a clone +of the parent.

+

PRNG implementations are allowed to assume that a good RNG is provided +for seeding, and that it is cryptographically secure when appropriate. +As of rand 0.7 / rand_core 0.5, implementations overriding this +method should ensure the implementation satisfies reproducibility +(in prior versions this was not required).

+

fn from_entropy() -> Self

Creates a new instance of the RNG seeded via getrandom.

+

This method is the recommended way to construct non-deterministic PRNGs +since it is convenient and secure.

+

In case the overhead of using getrandom to seed many PRNGs is an +issue, one may prefer to seed from a local PRNG, e.g. +from_rng(thread_rng()).unwrap().

+

Panics

+

If getrandom is unable to provide secure entropy this method will panic.

+
Loading content... +

Implementors

impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng<R>[src]

type Seed = R::Seed

fn from_entropy() -> Self[src]

impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng64<R>[src]

type Seed = R::Seed

fn from_entropy() -> Self[src]

Loading content...
\ No newline at end of file diff --git a/target/doc/regex/all.html b/target/doc/regex/all.html new file mode 100644 index 0000000..56b3608 --- /dev/null +++ b/target/doc/regex/all.html @@ -0,0 +1,3 @@ +List of all items in this crate

[] + + List of all items

Structs

Enums

Traits

Functions

\ No newline at end of file diff --git a/target/doc/regex/bytes/index.html b/target/doc/regex/bytes/index.html new file mode 100644 index 0000000..b09b679 --- /dev/null +++ b/target/doc/regex/bytes/index.html @@ -0,0 +1,98 @@ +regex::bytes - Rust

[][src]Module regex::bytes

Match regular expressions on arbitrary bytes.

+

This module provides a nearly identical API to the one found in the +top-level of this crate. There are two important differences:

+
    +
  1. Matching is done on &[u8] instead of &str. Additionally, Vec<u8> +is used where String would have been used.
  2. +
  3. Unicode support can be disabled even when disabling it would result in +matching invalid UTF-8 bytes.
  4. +
+

Example: match null terminated string

+

This shows how to find all null-terminated strings in a slice of bytes:

+ +
+let re = Regex::new(r"(?-u)(?P<cstr>[^\x00]+)\x00").unwrap();
+let text = b"foo\x00bar\x00baz\x00";
+
+// Extract all of the strings without the null terminator from each match.
+// The unwrap is OK here since a match requires the `cstr` capture to match.
+let cstrs: Vec<&[u8]> =
+    re.captures_iter(text)
+      .map(|c| c.name("cstr").unwrap().as_bytes())
+      .collect();
+assert_eq!(vec![&b"foo"[..], &b"bar"[..], &b"baz"[..]], cstrs);
+

Example: selectively enable Unicode support

+

This shows how to match an arbitrary byte pattern followed by a UTF-8 encoded +string (e.g., to extract a title from a Matroska file):

+ +
+let re = Regex::new(
+    r"(?-u)\x7b\xa9(?:[\x80-\xfe]|[\x40-\xff].)(?u:(.*))"
+).unwrap();
+let text = b"\x12\xd0\x3b\x5f\x7b\xa9\x85\xe2\x98\x83\x80\x98\x54\x76\x68\x65";
+let caps = re.captures(text).unwrap();
+
+// Notice that despite the `.*` at the end, it will only match valid UTF-8
+// because Unicode mode was enabled with the `u` flag. Without the `u` flag,
+// the `.*` would match the rest of the bytes.
+let mat = caps.get(1).unwrap();
+assert_eq!((7, 10), (mat.start(), mat.end()));
+
+// If there was a match, Unicode mode guarantees that `title` is valid UTF-8.
+let title = str::from_utf8(&caps[1]).unwrap();
+assert_eq!("☃", title);
+

In general, if the Unicode flag is enabled in a capture group and that capture +is part of the overall match, then the capture is guaranteed to be valid +UTF-8.

+

Syntax

+

The supported syntax is pretty much the same as the syntax for Unicode +regular expressions with a few changes that make sense for matching arbitrary +bytes:

+
    +
  1. The u flag can be disabled even when disabling it might cause the regex to +match invalid UTF-8. When the u flag is disabled, the regex is said to be in +"ASCII compatible" mode.
  2. +
  3. In ASCII compatible mode, neither Unicode scalar values nor Unicode +character classes are allowed.
  4. +
  5. In ASCII compatible mode, Perl character classes (\w, \d and \s) +revert to their typical ASCII definition. \w maps to [[:word:]], \d maps +to [[:digit:]] and \s maps to [[:space:]].
  6. +
  7. In ASCII compatible mode, word boundaries use the ASCII compatible \w to +determine whether a byte is a word byte or not.
  8. +
  9. Hexadecimal notation can be used to specify arbitrary bytes instead of +Unicode codepoints. For example, in ASCII compatible mode, \xFF matches the +literal byte \xFF, while in Unicode mode, \xFF is a Unicode codepoint that +matches its UTF-8 encoding of \xC3\xBF. Similarly for octal notation when +enabled.
  10. +
  11. . matches any byte except for \n instead of any Unicode scalar value. +When the s flag is enabled, . matches any byte.
  12. +
+

Performance

+

In general, one should expect performance on &[u8] to be roughly similar to +performance on &str.

+

Structs

+
CaptureLocations

CaptureLocations is a low level representation of the raw offsets of each +submatch.

+
CaptureMatches

An iterator that yields all non-overlapping capture groups matching a +particular regular expression.

+
CaptureNames

An iterator over the names of all possible captures.

+
Captures

Captures represents a group of captured byte strings for a single match.

+
Match

Match represents a single match of a regex in a haystack.

+
Matches

An iterator over all non-overlapping matches for a particular string.

+
NoExpand

NoExpand indicates literal byte string replacement.

+
Regex

A compiled regular expression for matching arbitrary bytes.

+
RegexBuilder

A configurable builder for a regular expression.

+
RegexSet

Match multiple (possibly overlapping) regular expressions in a single scan.

+
RegexSetBuilder

A configurable builder for a set of regular expressions.

+
ReplacerRef

By-reference adaptor for a Replacer

+
SetMatches

A set of matches returned by a regex set.

+
SetMatchesIntoIter

An owned iterator over the set of matches from a regex set.

+
SetMatchesIter

A borrowed iterator over the set of matches from a regex set.

+
Split

Yields all substrings delimited by a regular expression match.

+
SplitN

Yields at most N substrings delimited by a regular expression match.

+
SubCaptureMatches

An iterator that yields all capturing matches in the order in which they +appear in the regex.

+

Traits

+
Replacer

Replacer describes types that can be used to replace matches in a byte +string.

+
\ No newline at end of file diff --git a/target/doc/regex/bytes/sidebar-items.js b/target/doc/regex/bytes/sidebar-items.js new file mode 100644 index 0000000..87294e5 --- /dev/null +++ b/target/doc/regex/bytes/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["CaptureLocations","CaptureLocations is a low level representation of the raw offsets of each submatch."],["CaptureMatches","An iterator that yields all non-overlapping capture groups matching a particular regular expression."],["CaptureNames","An iterator over the names of all possible captures."],["Captures","Captures represents a group of captured byte strings for a single match."],["Match","Match represents a single match of a regex in a haystack."],["Matches","An iterator over all non-overlapping matches for a particular string."],["NoExpand","`NoExpand` indicates literal byte string replacement."],["Regex","A compiled regular expression for matching arbitrary bytes."],["RegexBuilder","A configurable builder for a regular expression."],["RegexSet","Match multiple (possibly overlapping) regular expressions in a single scan."],["RegexSetBuilder","A configurable builder for a set of regular expressions."],["ReplacerRef","By-reference adaptor for a `Replacer`"],["SetMatches","A set of matches returned by a regex set."],["SetMatchesIntoIter","An owned iterator over the set of matches from a regex set."],["SetMatchesIter","A borrowed iterator over the set of matches from a regex set."],["Split","Yields all substrings delimited by a regular expression match."],["SplitN","Yields at most `N` substrings delimited by a regular expression match."],["SubCaptureMatches","An iterator that yields all capturing matches in the order in which they appear in the regex."]],"trait":[["Replacer","Replacer describes types that can be used to replace matches in a byte string."]]}); \ No newline at end of file diff --git a/target/doc/regex/bytes/struct.CaptureLocations.html b/target/doc/regex/bytes/struct.CaptureLocations.html new file mode 100644 index 0000000..81e3bd6 --- /dev/null +++ b/target/doc/regex/bytes/struct.CaptureLocations.html @@ -0,0 +1,36 @@ +regex::bytes::CaptureLocations - Rust

[][src]Struct regex::bytes::CaptureLocations

pub struct CaptureLocations(_);

CaptureLocations is a low level representation of the raw offsets of each +submatch.

+

You can think of this as a lower level +Captures, where this type does not support +named capturing groups directly and it does not borrow the text that these +offsets were matched on.

+

Primarily, this type is useful when using the lower level Regex APIs +such as read_captures, which permits amortizing the allocation in which +capture match locations are stored.

+

In order to build a value of this type, you'll need to call the +capture_locations method on the Regex being used to execute the search. +The value returned can then be reused in subsequent searches.

+

Methods

impl CaptureLocations[src]

pub fn get(&self, i: usize) -> Option<(usize, usize)>[src]

Returns the start and end positions of the Nth capture group. Returns +None if i is not a valid capture group or if the capture group did +not match anything. The positions returned are always byte indices +with respect to the original string matched.

+

pub fn len(&self) -> usize[src]

Returns the total number of capturing groups.

+

This is always at least 1 since every regex has at least 1 +capturing group that corresponds to the entire match.

+

Trait Implementations

impl Clone for CaptureLocations[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Debug for CaptureLocations[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/bytes/struct.CaptureMatches.html b/target/doc/regex/bytes/struct.CaptureMatches.html new file mode 100644 index 0000000..3274aaa --- /dev/null +++ b/target/doc/regex/bytes/struct.CaptureMatches.html @@ -0,0 +1,82 @@ +regex::bytes::CaptureMatches - Rust

[][src]Struct regex::bytes::CaptureMatches

pub struct CaptureMatches<'r, 't>(_);

An iterator that yields all non-overlapping capture groups matching a +particular regular expression.

+

The iterator stops when no more matches can be found.

+

'r is the lifetime of the compiled regular expression and 't is the +lifetime of the matched byte string.

+

Trait Implementations

impl<'r, 't> Iterator for CaptureMatches<'r, 't>[src]

type Item = Captures<'t>

The type of the elements being iterated over.

+

fn size_hint(&self) -> (usize, Option<usize>)1.0.0[src]

Returns the bounds on the remaining length of the iterator. Read more

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

Auto Trait Implementations

impl<'r, 't> !Send for CaptureMatches<'r, 't>

impl<'r, 't> !Sync for CaptureMatches<'r, 't>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/bytes/struct.CaptureNames.html b/target/doc/regex/bytes/struct.CaptureNames.html new file mode 100644 index 0000000..99c9933 --- /dev/null +++ b/target/doc/regex/bytes/struct.CaptureNames.html @@ -0,0 +1,81 @@ +regex::bytes::CaptureNames - Rust

[][src]Struct regex::bytes::CaptureNames

pub struct CaptureNames<'r>(_);

An iterator over the names of all possible captures.

+

None indicates an unnamed capture; the first element (capture 0, the +whole matched region) is always unnamed.

+

'r is the lifetime of the compiled regular expression.

+

Trait Implementations

impl<'r> Iterator for CaptureNames<'r>[src]

type Item = Option<&'r str>

The type of the elements being iterated over.

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

Auto Trait Implementations

impl<'r> Send for CaptureNames<'r>

impl<'r> Sync for CaptureNames<'r>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/bytes/struct.Captures.html b/target/doc/regex/bytes/struct.Captures.html new file mode 100644 index 0000000..26f5b1c --- /dev/null +++ b/target/doc/regex/bytes/struct.Captures.html @@ -0,0 +1,74 @@ +regex::bytes::Captures - Rust

[][src]Struct regex::bytes::Captures

pub struct Captures<'t> { /* fields omitted */ }

Captures represents a group of captured byte strings for a single match.

+

The 0th capture always corresponds to the entire match. Each subsequent +index corresponds to the next capture group in the regex. If a capture +group is named, then the matched byte string is also available via the +name method. (Note that the 0th capture is always unnamed and so must be +accessed with the get method.)

+

Positions returned from a capture group are always byte indices.

+

't is the lifetime of the matched text.

+

Methods

impl<'t> Captures<'t>[src]

pub fn get(&self, i: usize) -> Option<Match<'t>>[src]

Returns the match associated with the capture group at index i. If +i does not correspond to a capture group, or if the capture group +did not participate in the match, then None is returned.

+

Examples

+

Get the text of the match with a default of an empty string if this +group didn't participate in the match:

+ +
+let re = Regex::new(r"[a-z]+(?:([0-9]+)|([A-Z]+))").unwrap();
+let caps = re.captures(b"abc123").unwrap();
+
+let text1 = caps.get(1).map_or(&b""[..], |m| m.as_bytes());
+let text2 = caps.get(2).map_or(&b""[..], |m| m.as_bytes());
+assert_eq!(text1, &b"123"[..]);
+assert_eq!(text2, &b""[..]);
+

pub fn name(&self, name: &str) -> Option<Match<'t>>[src]

Returns the match for the capture group named name. If name isn't a +valid capture group or didn't match anything, then None is returned.

+

Important traits for SubCaptureMatches<'c, 't>
pub fn iter<'c>(&'c self) -> SubCaptureMatches<'c, 't>[src]

An iterator that yields all capturing matches in the order in which +they appear in the regex. If a particular capture group didn't +participate in the match, then None is yielded for that capture.

+

The first match always corresponds to the overall match of the regex.

+

pub fn expand(&self, replacement: &[u8], dst: &mut Vec<u8>)[src]

Expands all instances of $name in replacement to the corresponding +capture group name, and writes them to the dst buffer given.

+

name may be an integer corresponding to the index of the +capture group (counted by order of opening parenthesis where 0 is the +entire match) or it can be a name (consisting of letters, digits or +underscores) corresponding to a named capture group.

+

If name isn't a valid capture group (whether the name doesn't exist +or isn't a valid index), then it is replaced with the empty string.

+

The longest possible name is used. e.g., $1a looks up the capture +group named 1a and not the capture group at index 1. To exert more +precise control over the name, use braces, e.g., ${1}a.

+

To write a literal $ use $$.

+

pub fn len(&self) -> usize[src]

Returns the number of captured groups.

+

This is always at least 1, since every regex has at least one capture +group that corresponds to the full match.

+

Trait Implementations

impl<'t> Debug for Captures<'t>[src]

impl<'t> Index<usize> for Captures<'t>[src]

Get a group by index.

+

't is the lifetime of the matched text.

+

The text can't outlive the Captures object if this method is +used, because of how Index is defined (normally a[i] is part +of a and can't outlive it); to do that, use get() instead.

+

Panics

+

If there is no group at the given index.

+

type Output = [u8]

The returned type after indexing.

+

impl<'t, 'i> Index<&'i str> for Captures<'t>[src]

Get a group by name.

+

't is the lifetime of the matched text and 'i is the lifetime +of the group name (the index).

+

The text can't outlive the Captures object if this method is +used, because of how Index is defined (normally a[i] is part +of a and can't outlive it); to do that, use name instead.

+

Panics

+

If there is no group named by the given value.

+

type Output = [u8]

The returned type after indexing.

+

Auto Trait Implementations

impl<'t> Send for Captures<'t>

impl<'t> Sync for Captures<'t>

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/bytes/struct.Match.html b/target/doc/regex/bytes/struct.Match.html new file mode 100644 index 0000000..a6d1210 --- /dev/null +++ b/target/doc/regex/bytes/struct.Match.html @@ -0,0 +1,24 @@ +regex::bytes::Match - Rust

[][src]Struct regex::bytes::Match

pub struct Match<'t> { /* fields omitted */ }

Match represents a single match of a regex in a haystack.

+

The lifetime parameter 't refers to the lifetime of the matched text.

+

Methods

impl<'t> Match<'t>[src]

pub fn start(&self) -> usize[src]

Returns the starting byte offset of the match in the haystack.

+

pub fn end(&self) -> usize[src]

Returns the ending byte offset of the match in the haystack.

+

pub fn as_bytes(&self) -> &'t [u8][src]

Returns the matched text.

+

Trait Implementations

impl<'t> PartialEq<Match<'t>> for Match<'t>[src]

impl<'t> Clone for Match<'t>[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl<'t> Eq for Match<'t>[src]

impl<'t> Copy for Match<'t>[src]

impl<'t> Debug for Match<'t>[src]

Auto Trait Implementations

impl<'t> Send for Match<'t>

impl<'t> Sync for Match<'t>

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/bytes/struct.Matches.html b/target/doc/regex/bytes/struct.Matches.html new file mode 100644 index 0000000..b952e78 --- /dev/null +++ b/target/doc/regex/bytes/struct.Matches.html @@ -0,0 +1,83 @@ +regex::bytes::Matches - Rust

[][src]Struct regex::bytes::Matches

pub struct Matches<'r, 't>(_);

An iterator over all non-overlapping matches for a particular string.

+

The iterator yields a tuple of integers corresponding to the start and end +of the match. The indices are byte offsets. The iterator stops when no more +matches can be found.

+

'r is the lifetime of the compiled regular expression and 't is the +lifetime of the matched byte string.

+

Trait Implementations

impl<'r, 't> Iterator for Matches<'r, 't>[src]

type Item = Match<'t>

The type of the elements being iterated over.

+

fn size_hint(&self) -> (usize, Option<usize>)1.0.0[src]

Returns the bounds on the remaining length of the iterator. Read more

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

Auto Trait Implementations

impl<'r, 't> !Send for Matches<'r, 't>

impl<'r, 't> !Sync for Matches<'r, 't>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/bytes/struct.NoExpand.html b/target/doc/regex/bytes/struct.NoExpand.html new file mode 100644 index 0000000..05c019b --- /dev/null +++ b/target/doc/regex/bytes/struct.NoExpand.html @@ -0,0 +1,19 @@ +regex::bytes::NoExpand - Rust

[][src]Struct regex::bytes::NoExpand

pub struct NoExpand<'t>(pub &'t [u8]);

NoExpand indicates literal byte string replacement.

+

It can be used with replace and replace_all to do a literal byte string +replacement without expanding $name to their corresponding capture +groups. This can be both convenient (to avoid escaping $, for example) +and performant (since capture groups don't need to be found).

+

't is the lifetime of the literal text.

+

Trait Implementations

impl<'t> Replacer for NoExpand<'t>[src]

fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self>[src]

Return a Replacer that borrows and wraps this Replacer. Read more

+

Auto Trait Implementations

impl<'t> Send for NoExpand<'t>

impl<'t> Sync for NoExpand<'t>

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/bytes/struct.Regex.html b/target/doc/regex/bytes/struct.Regex.html new file mode 100644 index 0000000..6aa9160 --- /dev/null +++ b/target/doc/regex/bytes/struct.Regex.html @@ -0,0 +1,296 @@ +regex::bytes::Regex - Rust

[][src]Struct regex::bytes::Regex

pub struct Regex(_);

A compiled regular expression for matching arbitrary bytes.

+

It can be used to search, split or replace text. All searching is done with +an implicit .*? at the beginning and end of an expression. To force an +expression to match the whole string (or a prefix or a suffix), you must +use an anchor like ^ or $ (or \A and \z).

+

Like the Regex type in the parent module, matches with this regex return +byte offsets into the search text. Unlike the parent Regex type, +these byte offsets may not correspond to UTF-8 sequence boundaries since +the regexes in this module can match arbitrary bytes.

+

Methods

impl Regex[src]

Core regular expression methods.

+

pub fn new(re: &str) -> Result<Regex, Error>[src]

Compiles a regular expression. Once compiled, it can be used repeatedly +to search, split or replace text in a string.

+

If an invalid expression is given, then an error is returned.

+

pub fn is_match(&self, text: &[u8]) -> bool[src]

Returns true if and only if the regex matches the string given.

+

It is recommended to use this method if all you need to do is test +a match, since the underlying matching engine may be able to do less +work.

+

Example

+

Test if some text contains at least one word with exactly 13 ASCII word +bytes:

+ +
+let text = b"I categorically deny having triskaidekaphobia.";
+assert!(Regex::new(r"\b\w{13}\b").unwrap().is_match(text));
+

pub fn find<'t>(&self, text: &'t [u8]) -> Option<Match<'t>>[src]

Returns the start and end byte range of the leftmost-first match in +text. If no match exists, then None is returned.

+

Note that this should only be used if you want to discover the position +of the match. Testing the existence of a match is faster if you use +is_match.

+

Example

+

Find the start and end location of the first word with exactly 13 +ASCII word bytes:

+ +
+let text = b"I categorically deny having triskaidekaphobia.";
+let mat = Regex::new(r"\b\w{13}\b").unwrap().find(text).unwrap();
+assert_eq!((mat.start(), mat.end()), (2, 15));
+

Important traits for Matches<'r, 't>
pub fn find_iter<'r, 't>(&'r self, text: &'t [u8]) -> Matches<'r, 't>[src]

Returns an iterator for each successive non-overlapping match in +text, returning the start and end byte indices with respect to +text.

+

Example

+

Find the start and end location of every word with exactly 13 ASCII +word bytes:

+ +
+let text = b"Retroactively relinquishing remunerations is reprehensible.";
+for mat in Regex::new(r"\b\w{13}\b").unwrap().find_iter(text) {
+    println!("{:?}", mat);
+}
+

pub fn captures<'t>(&self, text: &'t [u8]) -> Option<Captures<'t>>[src]

Returns the capture groups corresponding to the leftmost-first +match in text. Capture group 0 always corresponds to the entire +match. If no match is found, then None is returned.

+

You should only use captures if you need access to the location of +capturing group matches. Otherwise, find is faster for discovering +the location of the overall match.

+

Examples

+

Say you have some text with movie names and their release years, +like "'Citizen Kane' (1941)". It'd be nice if we could search for text +looking like that, while also extracting the movie name and its release +year separately.

+ +
+let re = Regex::new(r"'([^']+)'\s+\((\d{4})\)").unwrap();
+let text = b"Not my favorite movie: 'Citizen Kane' (1941).";
+let caps = re.captures(text).unwrap();
+assert_eq!(caps.get(1).unwrap().as_bytes(), &b"Citizen Kane"[..]);
+assert_eq!(caps.get(2).unwrap().as_bytes(), &b"1941"[..]);
+assert_eq!(caps.get(0).unwrap().as_bytes(), &b"'Citizen Kane' (1941)"[..]);
+// You can also access the groups by index using the Index notation.
+// Note that this will panic on an invalid index.
+assert_eq!(&caps[1], b"Citizen Kane");
+assert_eq!(&caps[2], b"1941");
+assert_eq!(&caps[0], b"'Citizen Kane' (1941)");
+

Note that the full match is at capture group 0. Each subsequent +capture group is indexed by the order of its opening (.

+

We can make this example a bit clearer by using named capture groups:

+ +
+let re = Regex::new(r"'(?P<title>[^']+)'\s+\((?P<year>\d{4})\)")
+               .unwrap();
+let text = b"Not my favorite movie: 'Citizen Kane' (1941).";
+let caps = re.captures(text).unwrap();
+assert_eq!(caps.name("title").unwrap().as_bytes(), b"Citizen Kane");
+assert_eq!(caps.name("year").unwrap().as_bytes(), b"1941");
+assert_eq!(caps.get(0).unwrap().as_bytes(), &b"'Citizen Kane' (1941)"[..]);
+// You can also access the groups by name using the Index notation.
+// Note that this will panic on an invalid group name.
+assert_eq!(&caps["title"], b"Citizen Kane");
+assert_eq!(&caps["year"], b"1941");
+assert_eq!(&caps[0], b"'Citizen Kane' (1941)");
+
+

Here we name the capture groups, which we can access with the name +method or the Index notation with a &str. Note that the named +capture groups are still accessible with get or the Index notation +with a usize.

+

The 0th capture group is always unnamed, so it must always be +accessed with get(0) or [0].

+

Important traits for CaptureMatches<'r, 't>
pub fn captures_iter<'r, 't>(&'r self, text: &'t [u8]) -> CaptureMatches<'r, 't>[src]

Returns an iterator over all the non-overlapping capture groups matched +in text. This is operationally the same as find_iter, except it +yields information about capturing group matches.

+

Example

+

We can use this to find all movie titles and their release years in +some text, where the movie is formatted like "'Title' (xxxx)":

+ +
+let re = Regex::new(r"'(?P<title>[^']+)'\s+\((?P<year>\d{4})\)")
+               .unwrap();
+let text = b"'Citizen Kane' (1941), 'The Wizard of Oz' (1939), 'M' (1931).";
+for caps in re.captures_iter(text) {
+    let title = str::from_utf8(&caps["title"]).unwrap();
+    let year = str::from_utf8(&caps["year"]).unwrap();
+    println!("Movie: {:?}, Released: {:?}", title, year);
+}
+// Output:
+// Movie: Citizen Kane, Released: 1941
+// Movie: The Wizard of Oz, Released: 1939
+// Movie: M, Released: 1931
+

Important traits for Split<'r, 't>
pub fn split<'r, 't>(&'r self, text: &'t [u8]) -> Split<'r, 't>[src]

Returns an iterator of substrings of text delimited by a match of the +regular expression. Namely, each element of the iterator corresponds to +text that isn't matched by the regular expression.

+

This method will not copy the text given.

+

Example

+

To split a string delimited by arbitrary amounts of spaces or tabs:

+ +
+let re = Regex::new(r"[ \t]+").unwrap();
+let fields: Vec<&[u8]> = re.split(b"a b \t  c\td    e").collect();
+assert_eq!(fields, vec![
+    &b"a"[..], &b"b"[..], &b"c"[..], &b"d"[..], &b"e"[..],
+]);
+

Important traits for SplitN<'r, 't>
pub fn splitn<'r, 't>(&'r self, text: &'t [u8], limit: usize) -> SplitN<'r, 't>[src]

Returns an iterator of at most limit substrings of text delimited +by a match of the regular expression. (A limit of 0 will return no +substrings.) Namely, each element of the iterator corresponds to text +that isn't matched by the regular expression. The remainder of the +string that is not split will be the last element in the iterator.

+

This method will not copy the text given.

+

Example

+

Get the first two words in some text:

+ +
+let re = Regex::new(r"\W+").unwrap();
+let fields: Vec<&[u8]> = re.splitn(b"Hey! How are you?", 3).collect();
+assert_eq!(fields, vec![&b"Hey"[..], &b"How"[..], &b"are you?"[..]]);
+

pub fn replace<'t, R: Replacer>(&self, text: &'t [u8], rep: R) -> Cow<'t, [u8]>[src]

Replaces the leftmost-first match with the replacement provided. The +replacement can be a regular byte string (where $N and $name are +expanded to match capture groups) or a function that takes the matches' +Captures and returns the replaced byte string.

+

If no match is found, then a copy of the byte string is returned +unchanged.

+

Replacement string syntax

+

All instances of $name in the replacement text is replaced with the +corresponding capture group name.

+

name may be an integer corresponding to the index of the +capture group (counted by order of opening parenthesis where 0 is the +entire match) or it can be a name (consisting of letters, digits or +underscores) corresponding to a named capture group.

+

If name isn't a valid capture group (whether the name doesn't exist +or isn't a valid index), then it is replaced with the empty string.

+

The longest possible name is used. e.g., $1a looks up the capture +group named 1a and not the capture group at index 1. To exert more +precise control over the name, use braces, e.g., ${1}a.

+

To write a literal $ use $$.

+

Examples

+

Note that this function is polymorphic with respect to the replacement. +In typical usage, this can just be a normal byte string:

+ +
+let re = Regex::new("[^01]+").unwrap();
+assert_eq!(re.replace(b"1078910", &b""[..]), &b"1010"[..]);
+

But anything satisfying the Replacer trait will work. For example, a +closure of type |&Captures| -> Vec<u8> provides direct access to the +captures corresponding to a match. This allows one to access capturing +group matches easily:

+ +
+let re = Regex::new(r"([^,\s]+),\s+(\S+)").unwrap();
+let result = re.replace(b"Springsteen, Bruce", |caps: &Captures| {
+    let mut replacement = caps[2].to_owned();
+    replacement.push(b' ');
+    replacement.extend(&caps[1]);
+    replacement
+});
+assert_eq!(result, &b"Bruce Springsteen"[..]);
+

But this is a bit cumbersome to use all the time. Instead, a simple +syntax is supported that expands $name into the corresponding capture +group. Here's the last example, but using this expansion technique +with named capture groups:

+ +
+let re = Regex::new(r"(?P<last>[^,\s]+),\s+(?P<first>\S+)").unwrap();
+let result = re.replace(b"Springsteen, Bruce", &b"$first $last"[..]);
+assert_eq!(result, &b"Bruce Springsteen"[..]);
+

Note that using $2 instead of $first or $1 instead of $last +would produce the same result. To write a literal $ use $$.

+

Sometimes the replacement string requires use of curly braces to +delineate a capture group replacement and surrounding literal text. +For example, if we wanted to join two words together with an +underscore:

+ +
+let re = Regex::new(r"(?P<first>\w+)\s+(?P<second>\w+)").unwrap();
+let result = re.replace(b"deep fried", &b"${first}_$second"[..]);
+assert_eq!(result, &b"deep_fried"[..]);
+

Without the curly braces, the capture group name first_ would be +used, and since it doesn't exist, it would be replaced with the empty +string.

+

Finally, sometimes you just want to replace a literal string with no +regard for capturing group expansion. This can be done by wrapping a +byte string with NoExpand:

+ +
+use regex::bytes::NoExpand;
+
+let re = Regex::new(r"(?P<last>[^,\s]+),\s+(\S+)").unwrap();
+let result = re.replace(b"Springsteen, Bruce", NoExpand(b"$2 $last"));
+assert_eq!(result, &b"$2 $last"[..]);
+

pub fn replace_all<'t, R: Replacer>(
    &self,
    text: &'t [u8],
    rep: R
) -> Cow<'t, [u8]>
[src]

Replaces all non-overlapping matches in text with the replacement +provided. This is the same as calling replacen with limit set to +0.

+

See the documentation for replace for details on how to access +capturing group matches in the replacement text.

+

pub fn replacen<'t, R: Replacer>(
    &self,
    text: &'t [u8],
    limit: usize,
    rep: R
) -> Cow<'t, [u8]>
[src]

Replaces at most limit non-overlapping matches in text with the +replacement provided. If limit is 0, then all non-overlapping matches +are replaced.

+

See the documentation for replace for details on how to access +capturing group matches in the replacement text.

+

impl Regex[src]

Advanced or "lower level" search methods.

+

pub fn shortest_match(&self, text: &[u8]) -> Option<usize>[src]

Returns the end location of a match in the text given.

+

This method may have the same performance characteristics as +is_match, except it provides an end location for a match. In +particular, the location returned may be shorter than the proper end +of the leftmost-first match.

+

Example

+

Typically, a+ would match the entire first sequence of a in some +text, but shortest_match can give up as soon as it sees the first +a.

+ +
+let text = b"aaaaa";
+let pos = Regex::new(r"a+").unwrap().shortest_match(text);
+assert_eq!(pos, Some(1));
+

pub fn shortest_match_at(&self, text: &[u8], start: usize) -> Option<usize>[src]

Returns the same as shortest_match, but starts the search at the given +offset.

+

The significance of the starting point is that it takes the surrounding +context into consideration. For example, the \A anchor can only +match when start == 0.

+

pub fn is_match_at(&self, text: &[u8], start: usize) -> bool[src]

Returns the same as is_match, but starts the search at the given +offset.

+

The significance of the starting point is that it takes the surrounding +context into consideration. For example, the \A anchor can only +match when start == 0.

+

pub fn find_at<'t>(&self, text: &'t [u8], start: usize) -> Option<Match<'t>>[src]

Returns the same as find, but starts the search at the given +offset.

+

The significance of the starting point is that it takes the surrounding +context into consideration. For example, the \A anchor can only +match when start == 0.

+

pub fn captures_read<'t>(
    &self,
    locs: &mut CaptureLocations,
    text: &'t [u8]
) -> Option<Match<'t>>
[src]

This is like captures, but uses +CaptureLocations +instead of +Captures in order to amortize allocations.

+

To create a CaptureLocations value, use the +Regex::capture_locations method.

+

This returns the overall match if this was successful, which is always +equivalence to the 0th capture group.

+

pub fn captures_read_at<'t>(
    &self,
    locs: &mut CaptureLocations,
    text: &'t [u8],
    start: usize
) -> Option<Match<'t>>
[src]

Returns the same as captures_read, but starts the search at the given +offset and populates the capture locations given.

+

The significance of the starting point is that it takes the surrounding +context into consideration. For example, the \A anchor can only +match when start == 0.

+

impl Regex[src]

Auxiliary methods.

+

pub fn as_str(&self) -> &str[src]

Returns the original string of this regex.

+

Important traits for CaptureNames<'r>
pub fn capture_names(&self) -> CaptureNames[src]

Returns an iterator over the capture names.

+

pub fn captures_len(&self) -> usize[src]

Returns the number of captures.

+

pub fn capture_locations(&self) -> CaptureLocations[src]

Returns an empty set of capture locations that can be reused in +multiple calls to captures_read or captures_read_at.

+

Trait Implementations

impl Clone for Regex[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Display for Regex[src]

fn fmt(&self, f: &mut Formatter) -> Result[src]

Shows the original regular expression.

+

impl Debug for Regex[src]

fn fmt(&self, f: &mut Formatter) -> Result[src]

Shows the original regular expression.

+

impl FromStr for Regex[src]

type Err = Error

The associated error which can be returned from parsing.

+

fn from_str(s: &str) -> Result<Regex, Error>[src]

Attempts to parse a string into a regular expression

+

Auto Trait Implementations

impl Send for Regex

impl Sync for Regex

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/bytes/struct.RegexBuilder.html b/target/doc/regex/bytes/struct.RegexBuilder.html new file mode 100644 index 0000000..9c6861b --- /dev/null +++ b/target/doc/regex/bytes/struct.RegexBuilder.html @@ -0,0 +1,89 @@ +regex::bytes::RegexBuilder - Rust

[][src]Struct regex::bytes::RegexBuilder

pub struct RegexBuilder(_);

A configurable builder for a regular expression.

+

A builder can be used to configure how the regex is built, for example, by +setting the default flags (which can be overridden in the expression +itself) or setting various limits.

+

Methods

impl RegexBuilder[src]

pub fn new(pattern: &str) -> RegexBuilder[src]

Create a new regular expression builder with the given pattern.

+

If the pattern is invalid, then an error will be returned when +build is called.

+

pub fn build(&self) -> Result<Regex, Error>[src]

Consume the builder and compile the regular expression.

+

Note that calling as_str on the resulting Regex will produce the +pattern given to new verbatim. Notably, it will not incorporate any +of the flags set on this builder.

+

pub fn case_insensitive(&mut self, yes: bool) -> &mut RegexBuilder[src]

Set the value for the case insensitive (i) flag.

+

When enabled, letters in the pattern will match both upper case and +lower case variants.

+

pub fn multi_line(&mut self, yes: bool) -> &mut RegexBuilder[src]

Set the value for the multi-line matching (m) flag.

+

When enabled, ^ matches the beginning of lines and $ matches the +end of lines.

+

By default, they match beginning/end of the input.

+

pub fn dot_matches_new_line(&mut self, yes: bool) -> &mut RegexBuilder[src]

Set the value for the any character (s) flag, where in . matches +anything when s is set and matches anything except for new line when +it is not set (the default).

+

N.B. "matches anything" means "any byte" when Unicode is disabled and +means "any valid UTF-8 encoding of any Unicode scalar value" when +Unicode is enabled.

+

pub fn swap_greed(&mut self, yes: bool) -> &mut RegexBuilder[src]

Set the value for the greedy swap (U) flag.

+

When enabled, a pattern like a* is lazy (tries to find shortest +match) and a*? is greedy (tries to find longest match).

+

By default, a* is greedy and a*? is lazy.

+

pub fn ignore_whitespace(&mut self, yes: bool) -> &mut RegexBuilder[src]

Set the value for the ignore whitespace (x) flag.

+

When enabled, whitespace such as new lines and spaces will be ignored +between expressions of the pattern, and # can be used to start a +comment until the next new line.

+

pub fn unicode(&mut self, yes: bool) -> &mut RegexBuilder[src]

Set the value for the Unicode (u) flag.

+

Enabled by default. When disabled, character classes such as \w only +match ASCII word characters instead of all Unicode word characters.

+

pub fn octal(&mut self, yes: bool) -> &mut RegexBuilder[src]

Whether to support octal syntax or not.

+

Octal syntax is a little-known way of uttering Unicode codepoints in +a regular expression. For example, a, \x61, \u0061 and +\141 are all equivalent regular expressions, where the last example +shows octal syntax.

+

While supporting octal syntax isn't in and of itself a problem, it does +make good error messages harder. That is, in PCRE based regex engines, +syntax like \0 invokes a backreference, which is explicitly +unsupported in Rust's regex engine. However, many users expect it to +be supported. Therefore, when octal support is disabled, the error +message will explicitly mention that backreferences aren't supported.

+

Octal syntax is disabled by default.

+

pub fn size_limit(&mut self, limit: usize) -> &mut RegexBuilder[src]

Set the approximate size limit of the compiled regular expression.

+

This roughly corresponds to the number of bytes occupied by a single +compiled program. If the program exceeds this number, then a +compilation error is returned.

+

pub fn dfa_size_limit(&mut self, limit: usize) -> &mut RegexBuilder[src]

Set the approximate size of the cache used by the DFA.

+

This roughly corresponds to the number of bytes that the DFA will +use while searching.

+

Note that this is a per thread limit. There is no way to set a global +limit. In particular, if a regex is used from multiple threads +simultaneously, then each thread may use up to the number of bytes +specified here.

+

pub fn nest_limit(&mut self, limit: u32) -> &mut RegexBuilder[src]

Set the nesting limit for this parser.

+

The nesting limit controls how deep the abstract syntax tree is allowed +to be. If the AST exceeds the given limit (e.g., with too many nested +groups), then an error is returned by the parser.

+

The purpose of this limit is to act as a heuristic to prevent stack +overflow for consumers that do structural induction on an Ast using +explicit recursion. While this crate never does this (instead using +constant stack space and moving the call stack to the heap), other +crates may.

+

This limit is not checked until the entire Ast is parsed. Therefore, +if callers want to put a limit on the amount of heap space used, then +they should impose a limit on the length, in bytes, of the concrete +pattern string. In particular, this is viable since this parser +implementation will limit itself to heap space proportional to the +length of the pattern string.

+

Note that a nest limit of 0 will return a nest limit error for most +patterns but not all. For example, a nest limit of 0 permits a but +not ab, since ab requires a concatenation, which results in a nest +depth of 1. In general, a nest limit is not something that manifests +in an obvious way in the concrete syntax, therefore, it should not be +used in a granular way.

+

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/bytes/struct.RegexSet.html b/target/doc/regex/bytes/struct.RegexSet.html new file mode 100644 index 0000000..6edb419 --- /dev/null +++ b/target/doc/regex/bytes/struct.RegexSet.html @@ -0,0 +1,164 @@ +regex::bytes::RegexSet - Rust

[][src]Struct regex::bytes::RegexSet

pub struct RegexSet(_);

Match multiple (possibly overlapping) regular expressions in a single scan.

+

A regex set corresponds to the union of two or more regular expressions. +That is, a regex set will match text where at least one of its +constituent regular expressions matches. A regex set as its formulated here +provides a touch more power: it will also report which regular +expressions in the set match. Indeed, this is the key difference between +regex sets and a single Regex with many alternates, since only one +alternate can match at a time.

+

For example, consider regular expressions to match email addresses and +domains: [a-z]+@[a-z]+\.(com|org|net) and [a-z]+\.(com|org|net). If a +regex set is constructed from those regexes, then searching the text +foo@example.com will report both regexes as matching. Of course, one +could accomplish this by compiling each regex on its own and doing two +searches over the text. The key advantage of using a regex set is that it +will report the matching regexes using a single pass through the text. +If one has hundreds or thousands of regexes to match repeatedly (like a URL +router for a complex web application or a user agent matcher), then a regex +set can realize huge performance gains.

+

Example

+

This shows how the above two regexes (for matching email addresses and +domains) might work:

+ +
+let set = RegexSet::new(&[
+    r"[a-z]+@[a-z]+\.(com|org|net)",
+    r"[a-z]+\.(com|org|net)",
+]).unwrap();
+
+// Ask whether any regexes in the set match.
+assert!(set.is_match(b"foo@example.com"));
+
+// Identify which regexes in the set match.
+let matches: Vec<_> = set.matches(b"foo@example.com").into_iter().collect();
+assert_eq!(vec![0, 1], matches);
+
+// Try again, but with text that only matches one of the regexes.
+let matches: Vec<_> = set.matches(b"example.com").into_iter().collect();
+assert_eq!(vec![1], matches);
+
+// Try again, but with text that doesn't match any regex in the set.
+let matches: Vec<_> = set.matches(b"example").into_iter().collect();
+assert!(matches.is_empty());
+

Note that it would be possible to adapt the above example to using Regex +with an expression like:

+ +
This example is not tested
+(?P<email>[a-z]+@(?P<email_domain>[a-z]+[.](com|org|net)))|(?P<domain>[a-z]+[.](com|org|net))
+

After a match, one could then inspect the capture groups to figure out +which alternates matched. The problem is that it is hard to make this +approach scale when there are many regexes since the overlap between each +alternate isn't always obvious to reason about.

+

Limitations

+

Regex sets are limited to answering the following two questions:

+
    +
  1. Does any regex in the set match?
  2. +
  3. If so, which regexes in the set match?
  4. +
+

As with the main Regex type, it is cheaper to ask (1) instead of (2) +since the matching engines can stop after the first match is found.

+

Other features like finding the location of successive matches or their +sub-captures aren't supported. If you need this functionality, the +recommended approach is to compile each regex in the set independently and +selectively match them based on which regexes in the set matched.

+

Performance

+

A RegexSet has the same performance characteristics as Regex. Namely, +search takes O(mn) time, where m is proportional to the size of the +regex set and n is proportional to the length of the search text.

+

Methods

impl RegexSet[src]

pub fn new<I, S>(exprs: I) -> Result<RegexSet, Error> where
    S: AsRef<str>,
    I: IntoIterator<Item = S>, 
[src]

Create a new regex set with the given regular expressions.

+

This takes an iterator of S, where S is something that can produce +a &str. If any of the strings in the iterator are not valid regular +expressions, then an error is returned.

+

Example

+

Create a new regex set from an iterator of strings:

+ +
+let set = RegexSet::new(&[r"\w+", r"\d+"]).unwrap();
+assert!(set.is_match("foo"));
+

pub fn is_match(&self, text: &[u8]) -> bool[src]

Returns true if and only if one of the regexes in this set matches +the text given.

+

This method should be preferred if you only need to test whether any +of the regexes in the set should match, but don't care about which +regexes matched. This is because the underlying matching engine will +quit immediately after seeing the first match instead of continuing to +find all matches.

+

Note that as with searches using Regex, the expression is unanchored +by default. That is, if the regex does not start with ^ or \A, or +end with $ or \z, then it is permitted to match anywhere in the +text.

+

Example

+

Tests whether a set matches some text:

+ +
+let set = RegexSet::new(&[r"\w+", r"\d+"]).unwrap();
+assert!(set.is_match("foo"));
+assert!(!set.is_match("☃"));
+

pub fn matches(&self, text: &[u8]) -> SetMatches[src]

Returns the set of regular expressions that match in the given text.

+

The set returned contains the index of each regular expression that +matches in the given text. The index is in correspondence with the +order of regular expressions given to RegexSet's constructor.

+

The set can also be used to iterate over the matched indices.

+

Note that as with searches using Regex, the expression is unanchored +by default. That is, if the regex does not start with ^ or \A, or +end with $ or \z, then it is permitted to match anywhere in the +text.

+

Example

+

Tests which regular expressions match the given text:

+ +
+let set = RegexSet::new(&[
+    r"\w+",
+    r"\d+",
+    r"\pL+",
+    r"foo",
+    r"bar",
+    r"barfoo",
+    r"foobar",
+]).unwrap();
+let matches: Vec<_> = set.matches("foobar").into_iter().collect();
+assert_eq!(matches, vec![0, 2, 3, 4, 6]);
+
+// You can also test whether a particular regex matched:
+let matches = set.matches("foobar");
+assert!(!matches.matched(5));
+assert!(matches.matched(6));
+

pub fn len(&self) -> usize[src]

Returns the total number of regular expressions in this set.

+

pub fn patterns(&self) -> &[String][src]

Returns the patterns that this set will match on.

+

This function can be used to determine the pattern for a match. The +slice returned has exactly as many patterns givens to this regex set, +and the order of the slice is the same as the order of the patterns +provided to the set.

+

Example

+
+let set = RegexSet::new(&[
+    r"\w+",
+    r"\d+",
+    r"\pL+",
+    r"foo",
+    r"bar",
+    r"barfoo",
+    r"foobar",
+]).unwrap();
+let matches: Vec<_> = set
+    .matches("foobar")
+    .into_iter()
+    .map(|match_idx| &set.patterns()[match_idx])
+    .collect();
+assert_eq!(matches, vec![r"\w+", r"\pL+", r"foo", r"bar", r"foobar"]);
+

Trait Implementations

impl Clone for RegexSet[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Debug for RegexSet[src]

Auto Trait Implementations

impl Send for RegexSet

impl Sync for RegexSet

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/bytes/struct.RegexSetBuilder.html b/target/doc/regex/bytes/struct.RegexSetBuilder.html new file mode 100644 index 0000000..9d02f08 --- /dev/null +++ b/target/doc/regex/bytes/struct.RegexSetBuilder.html @@ -0,0 +1,73 @@ +regex::bytes::RegexSetBuilder - Rust

[][src]Struct regex::bytes::RegexSetBuilder

pub struct RegexSetBuilder(_);

A configurable builder for a set of regular expressions.

+

A builder can be used to configure how the regexes are built, for example, +by setting the default flags (which can be overridden in the expression +itself) or setting various limits.

+

Methods

impl RegexSetBuilder[src]

pub fn new<I, S>(patterns: I) -> RegexSetBuilder where
    S: AsRef<str>,
    I: IntoIterator<Item = S>, 
[src]

Create a new regular expression builder with the given pattern.

+

If the pattern is invalid, then an error will be returned when +build is called.

+

pub fn build(&self) -> Result<RegexSet, Error>[src]

Consume the builder and compile the regular expressions into a set.

+

pub fn case_insensitive(&mut self, yes: bool) -> &mut RegexSetBuilder[src]

Set the value for the case insensitive (i) flag.

+

pub fn multi_line(&mut self, yes: bool) -> &mut RegexSetBuilder[src]

Set the value for the multi-line matching (m) flag.

+

pub fn dot_matches_new_line(&mut self, yes: bool) -> &mut RegexSetBuilder[src]

Set the value for the any character (s) flag, where in . matches +anything when s is set and matches anything except for new line when +it is not set (the default).

+

N.B. "matches anything" means "any byte" for regex::bytes::RegexSet +expressions and means "any Unicode scalar value" for regex::RegexSet +expressions.

+

pub fn swap_greed(&mut self, yes: bool) -> &mut RegexSetBuilder[src]

Set the value for the greedy swap (U) flag.

+

pub fn ignore_whitespace(&mut self, yes: bool) -> &mut RegexSetBuilder[src]

Set the value for the ignore whitespace (x) flag.

+

pub fn unicode(&mut self, yes: bool) -> &mut RegexSetBuilder[src]

Set the value for the Unicode (u) flag.

+

pub fn octal(&mut self, yes: bool) -> &mut RegexSetBuilder[src]

Whether to support octal syntax or not.

+

Octal syntax is a little-known way of uttering Unicode codepoints in +a regular expression. For example, a, \x61, \u0061 and +\141 are all equivalent regular expressions, where the last example +shows octal syntax.

+

While supporting octal syntax isn't in and of itself a problem, it does +make good error messages harder. That is, in PCRE based regex engines, +syntax like \0 invokes a backreference, which is explicitly +unsupported in Rust's regex engine. However, many users expect it to +be supported. Therefore, when octal support is disabled, the error +message will explicitly mention that backreferences aren't supported.

+

Octal syntax is disabled by default.

+

pub fn size_limit(&mut self, limit: usize) -> &mut RegexSetBuilder[src]

Set the approximate size limit of the compiled regular expression.

+

This roughly corresponds to the number of bytes occupied by a single +compiled program. If the program exceeds this number, then a +compilation error is returned.

+

pub fn dfa_size_limit(&mut self, limit: usize) -> &mut RegexSetBuilder[src]

Set the approximate size of the cache used by the DFA.

+

This roughly corresponds to the number of bytes that the DFA will +use while searching.

+

Note that this is a per thread limit. There is no way to set a global +limit. In particular, if a regex is used from multiple threads +simultaneously, then each thread may use up to the number of bytes +specified here.

+

pub fn nest_limit(&mut self, limit: u32) -> &mut RegexSetBuilder[src]

Set the nesting limit for this parser.

+

The nesting limit controls how deep the abstract syntax tree is allowed +to be. If the AST exceeds the given limit (e.g., with too many nested +groups), then an error is returned by the parser.

+

The purpose of this limit is to act as a heuristic to prevent stack +overflow for consumers that do structural induction on an Ast using +explicit recursion. While this crate never does this (instead using +constant stack space and moving the call stack to the heap), other +crates may.

+

This limit is not checked until the entire Ast is parsed. Therefore, +if callers want to put a limit on the amount of heap space used, then +they should impose a limit on the length, in bytes, of the concrete +pattern string. In particular, this is viable since this parser +implementation will limit itself to heap space proportional to the +length of the pattern string.

+

Note that a nest limit of 0 will return a nest limit error for most +patterns but not all. For example, a nest limit of 0 permits a but +not ab, since ab requires a concatenation, which results in a nest +depth of 1. In general, a nest limit is not something that manifests +in an obvious way in the concrete syntax, therefore, it should not be +used in a granular way.

+

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/bytes/struct.ReplacerRef.html b/target/doc/regex/bytes/struct.ReplacerRef.html new file mode 100644 index 0000000..ce013a5 --- /dev/null +++ b/target/doc/regex/bytes/struct.ReplacerRef.html @@ -0,0 +1,16 @@ +regex::bytes::ReplacerRef - Rust

[][src]Struct regex::bytes::ReplacerRef

pub struct ReplacerRef<'a, R: ?Sized + 'a>(_);

By-reference adaptor for a Replacer

+

Returned by Replacer::by_ref.

+

Trait Implementations

impl<'a, R: Replacer + ?Sized + 'a> Replacer for ReplacerRef<'a, R>[src]

fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self>[src]

Return a Replacer that borrows and wraps this Replacer. Read more

+

impl<'a, R: Debug + ?Sized + 'a> Debug for ReplacerRef<'a, R>[src]

Auto Trait Implementations

impl<'a, R: ?Sized> Send for ReplacerRef<'a, R> where
    R: Send

impl<'a, R: ?Sized> Sync for ReplacerRef<'a, R> where
    R: Sync

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/bytes/struct.SetMatches.html b/target/doc/regex/bytes/struct.SetMatches.html new file mode 100644 index 0000000..3472cae --- /dev/null +++ b/target/doc/regex/bytes/struct.SetMatches.html @@ -0,0 +1,38 @@ +regex::bytes::SetMatches - Rust

[][src]Struct regex::bytes::SetMatches

pub struct SetMatches { /* fields omitted */ }

A set of matches returned by a regex set.

+

Methods

impl SetMatches[src]

pub fn matched_any(&self) -> bool[src]

Whether this set contains any matches.

+

pub fn matched(&self, regex_index: usize) -> bool[src]

Whether the regex at the given index matched.

+

The index for a regex is determined by its insertion order upon the +initial construction of a RegexSet, starting at 0.

+

Panics

+

If regex_index is greater than or equal to self.len().

+

pub fn len(&self) -> usize[src]

The total number of regexes in the set that created these matches.

+

Important traits for SetMatchesIter<'a>
pub fn iter(&self) -> SetMatchesIter[src]

Returns an iterator over indexes in the regex that matched.

+

This will always produces matches in ascending order of index, where +the index corresponds to the index of the regex that matched with +respect to its position when initially building the set.

+

Trait Implementations

impl Clone for SetMatches[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl IntoIterator for SetMatches[src]

type IntoIter = SetMatchesIntoIter

Which kind of iterator are we turning this into?

+

type Item = usize

The type of the elements being iterated over.

+

impl<'a> IntoIterator for &'a SetMatches[src]

type IntoIter = SetMatchesIter<'a>

Which kind of iterator are we turning this into?

+

type Item = usize

The type of the elements being iterated over.

+

impl Debug for SetMatches[src]

Auto Trait Implementations

impl Send for SetMatches

impl Sync for SetMatches

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/bytes/struct.SetMatchesIntoIter.html b/target/doc/regex/bytes/struct.SetMatchesIntoIter.html new file mode 100644 index 0000000..0b08c1e --- /dev/null +++ b/target/doc/regex/bytes/struct.SetMatchesIntoIter.html @@ -0,0 +1,86 @@ +regex::bytes::SetMatchesIntoIter - Rust

[][src]Struct regex::bytes::SetMatchesIntoIter

pub struct SetMatchesIntoIter(_);

An owned iterator over the set of matches from a regex set.

+

This will always produces matches in ascending order of index, where the +index corresponds to the index of the regex that matched with respect to +its position when initially building the set.

+

Trait Implementations

impl DoubleEndedIterator for SetMatchesIntoIter[src]

fn nth_back(&mut self, n: usize) -> Option<Self::Item>[src]

🔬 This is a nightly-only experimental API. (iter_nth_back)

Returns the nth element from the end of the iterator. Read more

+

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

This is the reverse version of [try_fold()]: it takes elements starting from the back of the iterator. Read more

+

fn rfold<B, F>(self, accum: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.27.0[src]

An iterator method that reduces the iterator's elements to a single, final value, starting from the back. Read more

+

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.27.0[src]

Searches for an element of an iterator from the back that satisfies a predicate. Read more

+

impl Iterator for SetMatchesIntoIter[src]

type Item = usize

The type of the elements being iterated over.

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/bytes/struct.SetMatchesIter.html b/target/doc/regex/bytes/struct.SetMatchesIter.html new file mode 100644 index 0000000..93186a5 --- /dev/null +++ b/target/doc/regex/bytes/struct.SetMatchesIter.html @@ -0,0 +1,93 @@ +regex::bytes::SetMatchesIter - Rust

[][src]Struct regex::bytes::SetMatchesIter

pub struct SetMatchesIter<'a>(_);

A borrowed iterator over the set of matches from a regex set.

+

The lifetime 'a refers to the lifetime of a SetMatches value.

+

This will always produces matches in ascending order of index, where the +index corresponds to the index of the regex that matched with respect to +its position when initially building the set.

+

Trait Implementations

impl<'a> DoubleEndedIterator for SetMatchesIter<'a>[src]

fn nth_back(&mut self, n: usize) -> Option<Self::Item>[src]

🔬 This is a nightly-only experimental API. (iter_nth_back)

Returns the nth element from the end of the iterator. Read more

+

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

This is the reverse version of [try_fold()]: it takes elements starting from the back of the iterator. Read more

+

fn rfold<B, F>(self, accum: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.27.0[src]

An iterator method that reduces the iterator's elements to a single, final value, starting from the back. Read more

+

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.27.0[src]

Searches for an element of an iterator from the back that satisfies a predicate. Read more

+

impl<'a> Iterator for SetMatchesIter<'a>[src]

type Item = usize

The type of the elements being iterated over.

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

impl<'a> Clone for SetMatchesIter<'a>[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

Auto Trait Implementations

impl<'a> Send for SetMatchesIter<'a>

impl<'a> Sync for SetMatchesIter<'a>

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/bytes/struct.Split.html b/target/doc/regex/bytes/struct.Split.html new file mode 100644 index 0000000..a837924 --- /dev/null +++ b/target/doc/regex/bytes/struct.Split.html @@ -0,0 +1,80 @@ +regex::bytes::Split - Rust

[][src]Struct regex::bytes::Split

pub struct Split<'r, 't> { /* fields omitted */ }

Yields all substrings delimited by a regular expression match.

+

'r is the lifetime of the compiled regular expression and 't is the +lifetime of the byte string being split.

+

Trait Implementations

impl<'r, 't> Iterator for Split<'r, 't>[src]

type Item = &'t [u8]

The type of the elements being iterated over.

+

fn size_hint(&self) -> (usize, Option<usize>)1.0.0[src]

Returns the bounds on the remaining length of the iterator. Read more

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

Auto Trait Implementations

impl<'r, 't> !Send for Split<'r, 't>

impl<'r, 't> !Sync for Split<'r, 't>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/bytes/struct.SplitN.html b/target/doc/regex/bytes/struct.SplitN.html new file mode 100644 index 0000000..ffcf141 --- /dev/null +++ b/target/doc/regex/bytes/struct.SplitN.html @@ -0,0 +1,81 @@ +regex::bytes::SplitN - Rust

[][src]Struct regex::bytes::SplitN

pub struct SplitN<'r, 't> { /* fields omitted */ }

Yields at most N substrings delimited by a regular expression match.

+

The last substring will be whatever remains after splitting.

+

'r is the lifetime of the compiled regular expression and 't is the +lifetime of the byte string being split.

+

Trait Implementations

impl<'r, 't> Iterator for SplitN<'r, 't>[src]

type Item = &'t [u8]

The type of the elements being iterated over.

+

fn size_hint(&self) -> (usize, Option<usize>)1.0.0[src]

Returns the bounds on the remaining length of the iterator. Read more

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

Auto Trait Implementations

impl<'r, 't> !Send for SplitN<'r, 't>

impl<'r, 't> !Sync for SplitN<'r, 't>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/bytes/struct.SubCaptureMatches.html b/target/doc/regex/bytes/struct.SubCaptureMatches.html new file mode 100644 index 0000000..f9192f5 --- /dev/null +++ b/target/doc/regex/bytes/struct.SubCaptureMatches.html @@ -0,0 +1,84 @@ +regex::bytes::SubCaptureMatches - Rust

[][src]Struct regex::bytes::SubCaptureMatches

pub struct SubCaptureMatches<'c, 't: 'c> { /* fields omitted */ }

An iterator that yields all capturing matches in the order in which they +appear in the regex.

+

If a particular capture group didn't participate in the match, then None +is yielded for that capture. The first match always corresponds to the +overall match of the regex.

+

The lifetime 'c corresponds to the lifetime of the Captures value, and +the lifetime 't corresponds to the originally matched text.

+

Trait Implementations

impl<'c, 't> Iterator for SubCaptureMatches<'c, 't>[src]

type Item = Option<Match<'t>>

The type of the elements being iterated over.

+

fn size_hint(&self) -> (usize, Option<usize>)1.0.0[src]

Returns the bounds on the remaining length of the iterator. Read more

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

Auto Trait Implementations

impl<'c, 't> Send for SubCaptureMatches<'c, 't>

impl<'c, 't> Sync for SubCaptureMatches<'c, 't>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/bytes/trait.Replacer.html b/target/doc/regex/bytes/trait.Replacer.html new file mode 100644 index 0000000..44a0ab6 --- /dev/null +++ b/target/doc/regex/bytes/trait.Replacer.html @@ -0,0 +1,45 @@ +regex::bytes::Replacer - Rust

[][src]Trait regex::bytes::Replacer

pub trait Replacer {
+    fn replace_append(&mut self, caps: &Captures, dst: &mut Vec<u8>);
+
+    fn no_expansion<'r>(&'r mut self) -> Option<Cow<'r, [u8]>> { ... }
+
fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self> { ... } +}

Replacer describes types that can be used to replace matches in a byte +string.

+

In general, users of this crate shouldn't need to implement this trait, +since implementations are already provided for &[u8] and +FnMut(&Captures) -> Vec<u8> (or any FnMut(&Captures) -> T +where T: AsRef<[u8]>), which covers most use cases.

+
+

Required methods

fn replace_append(&mut self, caps: &Captures, dst: &mut Vec<u8>)

Appends text to dst to replace the current match.

+

The current match is represented by caps, which is guaranteed to +have a match at capture group 0.

+

For example, a no-op replacement would be +dst.extend(&caps[0]).

+
Loading content... +

Provided methods

fn no_expansion<'r>(&'r mut self) -> Option<Cow<'r, [u8]>>

Return a fixed unchanging replacement byte string.

+

When doing replacements, if access to Captures is not needed (e.g., +the replacement byte string does not need $ expansion), then it can +be beneficial to avoid finding sub-captures.

+

In general, this is called once for every call to replacen.

+

fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self>

Return a Replacer that borrows and wraps this Replacer.

+

This is useful when you want to take a generic Replacer (which might +not be cloneable) and use it without consuming it, so it can be used +more than once.

+

Example

+
+use regex::bytes::{Regex, Replacer};
+
+fn replace_all_twice<R: Replacer>(
+    re: Regex,
+    src: &[u8],
+    mut rep: R,
+) -> Vec<u8> {
+    let dst = re.replace_all(src, rep.by_ref());
+    let dst = re.replace_all(&dst, rep.by_ref());
+    dst.into_owned()
+}
+
Loading content... +

Implementations on Foreign Types

impl<'a> Replacer for &'a [u8][src]

fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self>[src]

Loading content... +

Implementors

impl<'a, R: Replacer + ?Sized + 'a> Replacer for ReplacerRef<'a, R>[src]

fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self>[src]

impl<'t> Replacer for NoExpand<'t>[src]

fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self>[src]

impl<F, T> Replacer for F where
    F: FnMut(&Captures) -> T,
    T: AsRef<[u8]>, 
[src]

fn no_expansion<'r>(&'r mut self) -> Option<Cow<'r, [u8]>>[src]

fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self>[src]

Loading content...
\ No newline at end of file diff --git a/target/doc/regex/enum.Error.html b/target/doc/regex/enum.Error.html new file mode 100644 index 0000000..ee38590 --- /dev/null +++ b/target/doc/regex/enum.Error.html @@ -0,0 +1,35 @@ +regex::Error - Rust

[][src]Enum regex::Error

pub enum Error {
+    Syntax(String),
+    CompiledTooBig(usize),
+    // some variants omitted
+}

An error that occurred during parsing or compiling a regular expression.

+

+ Variants

+Syntax(String)

A syntax error.

+
CompiledTooBig(usize)

The compiled program exceeded the set size limit. +The argument is the size limit imposed.

+

Trait Implementations

impl PartialEq<Error> for Error[src]

impl Clone for Error[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Display for Error[src]

impl Debug for Error[src]

impl Error for Error[src]

fn cause(&self) -> Option<&dyn Error>1.0.0[src]

Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

+

The lower-level cause of this error, if any. Read more

+

fn source(&self) -> Option<&(dyn Error + 'static)>1.30.0[src]

The lower-level source of this error, if any. Read more

+

Auto Trait Implementations

impl Send for Error

impl Sync for Error

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/error/enum.Error.html b/target/doc/regex/error/enum.Error.html new file mode 100644 index 0000000..d5bba07 --- /dev/null +++ b/target/doc/regex/error/enum.Error.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/enum.Error.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/fn.escape.html b/target/doc/regex/fn.escape.html new file mode 100644 index 0000000..737f556 --- /dev/null +++ b/target/doc/regex/fn.escape.html @@ -0,0 +1,4 @@ +regex::escape - Rust

[][src]Function regex::escape

pub fn escape(text: &str) -> String

Escapes all regular expression meta characters in text.

+

The string returned may be safely used as a literal in a regular +expression.

+
\ No newline at end of file diff --git a/target/doc/regex/index.html b/target/doc/regex/index.html new file mode 100644 index 0000000..32610f9 --- /dev/null +++ b/target/doc/regex/index.html @@ -0,0 +1,418 @@ +regex - Rust

[][src]Crate regex

This crate provides a library for parsing, compiling, and executing regular +expressions. Its syntax is similar to Perl-style regular expressions, but lacks +a few features like look around and backreferences. In exchange, all searches +execute in linear time with respect to the size of the regular expression and +search text.

+

This crate's documentation provides some simple examples, describes +Unicode support and exhaustively lists the +supported syntax.

+

For more specific details on the API for regular expressions, please see the +documentation for the Regex type.

+

Usage

+

This crate is on crates.io and can be +used by adding regex to your dependencies in your project's Cargo.toml.

+
[dependencies]
+regex = "1"
+
+

and this to your crate root:

+ +
+extern crate regex;
+

Example: find a date

+

General use of regular expressions in this package involves compiling an +expression and then using it to search, split or replace text. For example, +to confirm that some text resembles a date:

+ +
+use regex::Regex;
+let re = Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();
+assert!(re.is_match("2014-01-01"));
+

Notice the use of the ^ and $ anchors. In this crate, every expression +is executed with an implicit .*? at the beginning and end, which allows +it to match anywhere in the text. Anchors can be used to ensure that the +full text matches an expression.

+

This example also demonstrates the utility of +raw strings +in Rust, which +are just like regular strings except they are prefixed with an r and do +not process any escape sequences. For example, "\\d" is the same +expression as r"\d".

+

Example: Avoid compiling the same regex in a loop

+

It is an anti-pattern to compile the same regular expression in a loop +since compilation is typically expensive. (It takes anywhere from a few +microseconds to a few milliseconds depending on the size of the +regex.) Not only is compilation itself expensive, but this also prevents +optimizations that reuse allocations internally to the matching engines.

+

In Rust, it can sometimes be a pain to pass regular expressions around if +they're used from inside a helper function. Instead, we recommend using the +lazy_static crate to ensure that +regular expressions are compiled exactly once.

+

For example:

+ +
+#[macro_use] extern crate lazy_static;
+extern crate regex;
+
+use regex::Regex;
+
+fn some_helper_function(text: &str) -> bool {
+    lazy_static! {
+        static ref RE: Regex = Regex::new("...").unwrap();
+    }
+    RE.is_match(text)
+}
+
+fn main() {}
+

Specifically, in this example, the regex will be compiled when it is used for +the first time. On subsequent uses, it will reuse the previous compilation.

+

Example: iterating over capture groups

+

This crate provides convenient iterators for matching an expression +repeatedly against a search string to find successive non-overlapping +matches. For example, to find all dates in a string and be able to access +them by their component pieces:

+ +
+let re = Regex::new(r"(\d{4})-(\d{2})-(\d{2})").unwrap();
+let text = "2012-03-14, 2013-01-01 and 2014-07-05";
+for cap in re.captures_iter(text) {
+    println!("Month: {} Day: {} Year: {}", &cap[2], &cap[3], &cap[1]);
+}
+// Output:
+// Month: 03 Day: 14 Year: 2012
+// Month: 01 Day: 01 Year: 2013
+// Month: 07 Day: 05 Year: 2014
+

Notice that the year is in the capture group indexed at 1. This is +because the entire match is stored in the capture group at index 0.

+

Example: replacement with named capture groups

+

Building on the previous example, perhaps we'd like to rearrange the date +formats. This can be done with text replacement. But to make the code +clearer, we can name our capture groups and use those names as variables +in our replacement text:

+ +
+let re = Regex::new(r"(?P<y>\d{4})-(?P<m>\d{2})-(?P<d>\d{2})").unwrap();
+let before = "2012-03-14, 2013-01-01 and 2014-07-05";
+let after = re.replace_all(before, "$m/$d/$y");
+assert_eq!(after, "03/14/2012, 01/01/2013 and 07/05/2014");
+

The replace methods are actually polymorphic in the replacement, which +provides more flexibility than is seen here. (See the documentation for +Regex::replace for more details.)

+

Note that if your regex gets complicated, you can use the x flag to +enable insignificant whitespace mode, which also lets you write comments:

+ +
+let re = Regex::new(r"(?x)
+  (?P<y>\d{4}) # the year
+  -
+  (?P<m>\d{2}) # the month
+  -
+  (?P<d>\d{2}) # the day
+").unwrap();
+let before = "2012-03-14, 2013-01-01 and 2014-07-05";
+let after = re.replace_all(before, "$m/$d/$y");
+assert_eq!(after, "03/14/2012, 01/01/2013 and 07/05/2014");
+

If you wish to match against whitespace in this mode, you can still use \s, +\n, \t, etc. For escaping a single space character, you can use its hex +character code \x20 or temporarily disable the x flag, e.g., (?-x: ).

+

Example: match multiple regular expressions simultaneously

+

This demonstrates how to use a RegexSet to match multiple (possibly +overlapping) regular expressions in a single scan of the search text:

+ +
+use regex::RegexSet;
+
+let set = RegexSet::new(&[
+    r"\w+",
+    r"\d+",
+    r"\pL+",
+    r"foo",
+    r"bar",
+    r"barfoo",
+    r"foobar",
+]).unwrap();
+
+// Iterate over and collect all of the matches.
+let matches: Vec<_> = set.matches("foobar").into_iter().collect();
+assert_eq!(matches, vec![0, 2, 3, 4, 6]);
+
+// You can also test whether a particular regex matched:
+let matches = set.matches("foobar");
+assert!(!matches.matched(5));
+assert!(matches.matched(6));
+

Pay for what you use

+

With respect to searching text with a regular expression, there are three +questions that can be asked:

+
    +
  1. Does the text match this expression?
  2. +
  3. If so, where does it match?
  4. +
  5. Where did the capturing groups match?
  6. +
+

Generally speaking, this crate could provide a function to answer only #3, +which would subsume #1 and #2 automatically. However, it can be significantly +more expensive to compute the location of capturing group matches, so it's best +not to do it if you don't need to.

+

Therefore, only use what you need. For example, don't use find if you +only need to test if an expression matches a string. (Use is_match +instead.)

+

Unicode

+

This implementation executes regular expressions only on valid UTF-8 +while exposing match locations as byte indices into the search string.

+

Only simple case folding is supported. Namely, when matching +case-insensitively, the characters are first mapped using the "simple" case +folding rules defined by Unicode.

+

Regular expressions themselves are only interpreted as a sequence of +Unicode scalar values. This means you can use Unicode characters directly +in your expression:

+ +
+let re = Regex::new(r"(?i)Δ+").unwrap();
+let mat = re.find("ΔδΔ").unwrap();
+assert_eq!((mat.start(), mat.end()), (0, 6));
+

Most features of the regular expressions in this crate are Unicode aware. Here +are some examples:

+
    +
  • . will match any valid UTF-8 encoded Unicode scalar value except for \n. +(To also match \n, enable the s flag, e.g., (?s:.).)
  • +
  • \w, \d and \s are Unicode aware. For example, \s will match all forms +of whitespace categorized by Unicode.
  • +
  • \b matches a Unicode word boundary.
  • +
  • Negated character classes like [^a] match all Unicode scalar values except +for a.
  • +
  • ^ and $ are not Unicode aware in multi-line mode. Namely, they only +recognize \n and not any of the other forms of line terminators defined +by Unicode.
  • +
+

Unicode general categories, scripts, script extensions, ages and a smattering +of boolean properties are available as character classes. For example, you can +match a sequence of numerals, Greek or Cherokee letters:

+ +
+let re = Regex::new(r"[\pN\p{Greek}\p{Cherokee}]+").unwrap();
+let mat = re.find("abcΔᎠβⅠᏴγδⅡxyz").unwrap();
+assert_eq!((mat.start(), mat.end()), (3, 23));
+

For a more detailed breakdown of Unicode support with respect to +UTS#18, +please see the +UNICODE +document in the root of the regex repository.

+

Opt out of Unicode support

+

The bytes sub-module provides a Regex type that can be used to match +on &[u8]. By default, text is interpreted as UTF-8 just like it is with +the main Regex type. However, this behavior can be disabled by turning +off the u flag, even if doing so could result in matching invalid UTF-8. +For example, when the u flag is disabled, . will match any byte instead +of any Unicode scalar value.

+

Disabling the u flag is also possible with the standard &str-based Regex +type, but it is only allowed where the UTF-8 invariant is maintained. For +example, (?-u:\w) is an ASCII-only \w character class and is legal in an +&str-based Regex, but (?-u:\xFF) will attempt to match the raw byte +\xFF, which is invalid UTF-8 and therefore is illegal in &str-based +regexes.

+

Syntax

+

The syntax supported in this crate is documented below.

+

Note that the regular expression parser and abstract syntax are exposed in +a separate crate, regex-syntax.

+

Matching one character

+.             any character except new line (includes new line with s flag)
+\d            digit (\p{Nd})
+\D            not digit
+\pN           One-letter name Unicode character class
+\p{Greek}     Unicode character class (general category or script)
+\PN           Negated one-letter name Unicode character class
+\P{Greek}     negated Unicode character class (general category or script)
+
+

Character classes

+[xyz]         A character class matching either x, y or z (union).
+[^xyz]        A character class matching any character except x, y and z.
+[a-z]         A character class matching any character in range a-z.
+[[:alpha:]]   ASCII character class ([A-Za-z])
+[[:^alpha:]]  Negated ASCII character class ([^A-Za-z])
+[x[^xyz]]     Nested/grouping character class (matching any character except y and z)
+[a-y&&xyz]    Intersection (matching x or y)
+[0-9&&[^4]]   Subtraction using intersection and negation (matching 0-9 except 4)
+[0-9--4]      Direct subtraction (matching 0-9 except 4)
+[a-g~~b-h]    Symmetric difference (matching `a` and `h` only)
+[\[\]]        Escaping in character classes (matching [ or ])
+
+

Any named character class may appear inside a bracketed [...] character +class. For example, [\p{Greek}[:digit:]] matches any Greek or ASCII +digit. [\p{Greek}&&\pL] matches Greek letters.

+

Precedence in character classes, from most binding to least:

+
    +
  1. Ranges: a-cd == [a-c]d
  2. +
  3. Union: ab&&bc == [ab]&&[bc]
  4. +
  5. Intersection: ^a-z&&b == ^[a-z&&b]
  6. +
  7. Negation
  8. +
+

Composites

+xy    concatenation (x followed by y)
+x|y   alternation (x or y, prefer x)
+
+

Repetitions

+x*        zero or more of x (greedy)
+x+        one or more of x (greedy)
+x?        zero or one of x (greedy)
+x*?       zero or more of x (ungreedy/lazy)
+x+?       one or more of x (ungreedy/lazy)
+x??       zero or one of x (ungreedy/lazy)
+x{n,m}    at least n x and at most m x (greedy)
+x{n,}     at least n x (greedy)
+x{n}      exactly n x
+x{n,m}?   at least n x and at most m x (ungreedy/lazy)
+x{n,}?    at least n x (ungreedy/lazy)
+x{n}?     exactly n x
+
+

Empty matches

+^     the beginning of text (or start-of-line with multi-line mode)
+$     the end of text (or end-of-line with multi-line mode)
+\A    only the beginning of text (even with multi-line mode enabled)
+\z    only the end of text (even with multi-line mode enabled)
+\b    a Unicode word boundary (\w on one side and \W, \A, or \z on other)
+\B    not a Unicode word boundary
+
+

Grouping and flags

+(exp)          numbered capture group (indexed by opening parenthesis)
+(?P<name>exp)  named (also numbered) capture group (allowed chars: [_0-9a-zA-Z])
+(?:exp)        non-capturing group
+(?flags)       set flags within current group
+(?flags:exp)   set flags for exp (non-capturing)
+
+

Flags are each a single character. For example, (?x) sets the flag x +and (?-x) clears the flag x. Multiple flags can be set or cleared at +the same time: (?xy) sets both the x and y flags and (?x-y) sets +the x flag and clears the y flag.

+

All flags are by default disabled unless stated otherwise. They are:

+
+i     case-insensitive: letters match both upper and lower case
+m     multi-line mode: ^ and $ match begin/end of line
+s     allow . to match \n
+U     swap the meaning of x* and x*?
+u     Unicode support (enabled by default)
+x     ignore whitespace and allow line comments (starting with `#`)
+
+

Flags can be toggled within a pattern. Here's an example that matches +case-insensitively for the first part but case-sensitively for the second part:

+ +
+let re = Regex::new(r"(?i)a+(?-i)b+").unwrap();
+let cap = re.captures("AaAaAbbBBBb").unwrap();
+assert_eq!(&cap[0], "AaAaAbb");
+

Notice that the a+ matches either a or A, but the b+ only matches +b.

+

Multi-line mode means ^ and $ no longer match just at the beginning/end of +the input, but at the beginning/end of lines:

+ +
+let re = Regex::new(r"(?m)^line \d+").unwrap();
+let m = re.find("line one\nline 2\n").unwrap();
+assert_eq!(m.as_str(), "line 2");
+

Note that ^ matches after new lines, even at the end of input:

+ +
+let re = Regex::new(r"(?m)^").unwrap();
+let m = re.find_iter("test\n").last().unwrap();
+assert_eq!((m.start(), m.end()), (5, 5));
+

Here is an example that uses an ASCII word boundary instead of a Unicode +word boundary:

+ +
+let re = Regex::new(r"(?-u:\b).+(?-u:\b)").unwrap();
+let cap = re.captures("$$abc$$").unwrap();
+assert_eq!(&cap[0], "abc");
+

Escape sequences

+\*          literal *, works for any punctuation character: \.+*?()|[]{}^$
+\a          bell (\x07)
+\f          form feed (\x0C)
+\t          horizontal tab
+\n          new line
+\r          carriage return
+\v          vertical tab (\x0B)
+\123        octal character code (up to three digits) (when enabled)
+\x7F        hex character code (exactly two digits)
+\x{10FFFF}  any hex character code corresponding to a Unicode code point
+\u007F      hex character code (exactly four digits)
+\u{7F}      any hex character code corresponding to a Unicode code point
+\U0000007F  hex character code (exactly eight digits)
+\U{7F}      any hex character code corresponding to a Unicode code point
+
+

Perl character classes (Unicode friendly)

+

These classes are based on the definitions provided in +UTS#18:

+
+\d     digit (\p{Nd})
+\D     not digit
+\s     whitespace (\p{White_Space})
+\S     not whitespace
+\w     word character (\p{Alphabetic} + \p{M} + \d + \p{Pc} + \p{Join_Control})
+\W     not word character
+
+

ASCII character classes

+[[:alnum:]]    alphanumeric ([0-9A-Za-z])
+[[:alpha:]]    alphabetic ([A-Za-z])
+[[:ascii:]]    ASCII ([\x00-\x7F])
+[[:blank:]]    blank ([\t ])
+[[:cntrl:]]    control ([\x00-\x1F\x7F])
+[[:digit:]]    digits ([0-9])
+[[:graph:]]    graphical ([!-~])
+[[:lower:]]    lower case ([a-z])
+[[:print:]]    printable ([ -~])
+[[:punct:]]    punctuation ([!-/:-@\[-`{-~])
+[[:space:]]    whitespace ([\t\n\v\f\r ])
+[[:upper:]]    upper case ([A-Z])
+[[:word:]]     word characters ([0-9A-Za-z_])
+[[:xdigit:]]   hex digit ([0-9A-Fa-f])
+
+

Untrusted input

+

This crate can handle both untrusted regular expressions and untrusted +search text.

+

Untrusted regular expressions are handled by capping the size of a compiled +regular expression. +(See RegexBuilder::size_limit.) +Without this, it would be trivial for an attacker to exhaust your system's +memory with expressions like a{100}{100}{100}.

+

Untrusted search text is allowed because the matching engine(s) in this +crate have time complexity O(mn) (with m ~ regex and n ~ search text), which means there's no way to cause exponential blow-up like with +some other regular expression engines. (We pay for this by disallowing +features like arbitrary look-ahead and backreferences.)

+

When a DFA is used, pathological cases with exponential state blow-up are +avoided by constructing the DFA lazily or in an "online" manner. Therefore, +at most one new state can be created for each byte of input. This satisfies +our time complexity guarantees, but can lead to memory growth +proportional to the size of the input. As a stopgap, the DFA is only +allowed to store a fixed number of states. When the limit is reached, its +states are wiped and continues on, possibly duplicating previous work. If +the limit is reached too frequently, it gives up and hands control off to +another matching engine with fixed memory requirements. +(The DFA size limit can also be tweaked. See +RegexBuilder::dfa_size_limit.)

+

Modules

+
bytes

Match regular expressions on arbitrary bytes.

+

Structs

+
CaptureLocations

CaptureLocations is a low level representation of the raw offsets of each +submatch.

+
CaptureMatches

An iterator that yields all non-overlapping capture groups matching a +particular regular expression.

+
CaptureNames

An iterator over the names of all possible captures.

+
Captures

Captures represents a group of captured strings for a single match.

+
Match

Match represents a single match of a regex in a haystack.

+
Matches

An iterator over all non-overlapping matches for a particular string.

+
NoExpand

NoExpand indicates literal string replacement.

+
Regex

A compiled regular expression for matching Unicode strings.

+
RegexBuilder

A configurable builder for a regular expression.

+
RegexSet

Match multiple (possibly overlapping) regular expressions in a single scan.

+
RegexSetBuilder

A configurable builder for a set of regular expressions.

+
ReplacerRef

By-reference adaptor for a Replacer

+
SetMatches

A set of matches returned by a regex set.

+
SetMatchesIntoIter

An owned iterator over the set of matches from a regex set.

+
SetMatchesIter

A borrowed iterator over the set of matches from a regex set.

+
Split

Yields all substrings delimited by a regular expression match.

+
SplitN

Yields at most N substrings delimited by a regular expression match.

+
SubCaptureMatches

An iterator that yields all capturing matches in the order in which they +appear in the regex.

+

Enums

+
Error

An error that occurred during parsing or compiling a regular expression.

+

Traits

+
Replacer

Replacer describes types that can be used to replace matches in a string.

+

Functions

+
escape

Escapes all regular expression meta characters in text.

+
\ No newline at end of file diff --git a/target/doc/regex/re_builder/bytes/struct.RegexBuilder.html b/target/doc/regex/re_builder/bytes/struct.RegexBuilder.html new file mode 100644 index 0000000..25b8b70 --- /dev/null +++ b/target/doc/regex/re_builder/bytes/struct.RegexBuilder.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../regex/bytes/struct.RegexBuilder.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_builder/set_bytes/struct.RegexSetBuilder.html b/target/doc/regex/re_builder/set_bytes/struct.RegexSetBuilder.html new file mode 100644 index 0000000..de62d2f --- /dev/null +++ b/target/doc/regex/re_builder/set_bytes/struct.RegexSetBuilder.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../regex/bytes/struct.RegexSetBuilder.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_builder/set_unicode/struct.RegexSetBuilder.html b/target/doc/regex/re_builder/set_unicode/struct.RegexSetBuilder.html new file mode 100644 index 0000000..d960845 --- /dev/null +++ b/target/doc/regex/re_builder/set_unicode/struct.RegexSetBuilder.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../regex/struct.RegexSetBuilder.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_builder/unicode/struct.RegexBuilder.html b/target/doc/regex/re_builder/unicode/struct.RegexBuilder.html new file mode 100644 index 0000000..e31d805 --- /dev/null +++ b/target/doc/regex/re_builder/unicode/struct.RegexBuilder.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../regex/struct.RegexBuilder.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_bytes/struct.CaptureLocations.html b/target/doc/regex/re_bytes/struct.CaptureLocations.html new file mode 100644 index 0000000..ee51ab3 --- /dev/null +++ b/target/doc/regex/re_bytes/struct.CaptureLocations.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/bytes/struct.CaptureLocations.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_bytes/struct.CaptureMatches.html b/target/doc/regex/re_bytes/struct.CaptureMatches.html new file mode 100644 index 0000000..80f3e55 --- /dev/null +++ b/target/doc/regex/re_bytes/struct.CaptureMatches.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/bytes/struct.CaptureMatches.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_bytes/struct.CaptureNames.html b/target/doc/regex/re_bytes/struct.CaptureNames.html new file mode 100644 index 0000000..419e2e8 --- /dev/null +++ b/target/doc/regex/re_bytes/struct.CaptureNames.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/bytes/struct.CaptureNames.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_bytes/struct.Captures.html b/target/doc/regex/re_bytes/struct.Captures.html new file mode 100644 index 0000000..de138c6 --- /dev/null +++ b/target/doc/regex/re_bytes/struct.Captures.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/bytes/struct.Captures.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_bytes/struct.Match.html b/target/doc/regex/re_bytes/struct.Match.html new file mode 100644 index 0000000..e92b560 --- /dev/null +++ b/target/doc/regex/re_bytes/struct.Match.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/bytes/struct.Match.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_bytes/struct.Matches.html b/target/doc/regex/re_bytes/struct.Matches.html new file mode 100644 index 0000000..e5826ef --- /dev/null +++ b/target/doc/regex/re_bytes/struct.Matches.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/bytes/struct.Matches.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_bytes/struct.NoExpand.html b/target/doc/regex/re_bytes/struct.NoExpand.html new file mode 100644 index 0000000..0e9aef8 --- /dev/null +++ b/target/doc/regex/re_bytes/struct.NoExpand.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/bytes/struct.NoExpand.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_bytes/struct.Regex.html b/target/doc/regex/re_bytes/struct.Regex.html new file mode 100644 index 0000000..d13d1f8 --- /dev/null +++ b/target/doc/regex/re_bytes/struct.Regex.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/bytes/struct.Regex.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_bytes/struct.ReplacerRef.html b/target/doc/regex/re_bytes/struct.ReplacerRef.html new file mode 100644 index 0000000..a4190f3 --- /dev/null +++ b/target/doc/regex/re_bytes/struct.ReplacerRef.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/bytes/struct.ReplacerRef.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_bytes/struct.Split.html b/target/doc/regex/re_bytes/struct.Split.html new file mode 100644 index 0000000..a5161e3 --- /dev/null +++ b/target/doc/regex/re_bytes/struct.Split.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/bytes/struct.Split.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_bytes/struct.SplitN.html b/target/doc/regex/re_bytes/struct.SplitN.html new file mode 100644 index 0000000..ea349bd --- /dev/null +++ b/target/doc/regex/re_bytes/struct.SplitN.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/bytes/struct.SplitN.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_bytes/struct.SubCaptureMatches.html b/target/doc/regex/re_bytes/struct.SubCaptureMatches.html new file mode 100644 index 0000000..25d680f --- /dev/null +++ b/target/doc/regex/re_bytes/struct.SubCaptureMatches.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/bytes/struct.SubCaptureMatches.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_bytes/trait.Replacer.html b/target/doc/regex/re_bytes/trait.Replacer.html new file mode 100644 index 0000000..001b626 --- /dev/null +++ b/target/doc/regex/re_bytes/trait.Replacer.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/bytes/trait.Replacer.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_set/bytes/struct.RegexSet.html b/target/doc/regex/re_set/bytes/struct.RegexSet.html new file mode 100644 index 0000000..8bb0a8c --- /dev/null +++ b/target/doc/regex/re_set/bytes/struct.RegexSet.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../regex/bytes/struct.RegexSet.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_set/bytes/struct.SetMatches.html b/target/doc/regex/re_set/bytes/struct.SetMatches.html new file mode 100644 index 0000000..ebe8039 --- /dev/null +++ b/target/doc/regex/re_set/bytes/struct.SetMatches.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../regex/bytes/struct.SetMatches.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_set/bytes/struct.SetMatchesIntoIter.html b/target/doc/regex/re_set/bytes/struct.SetMatchesIntoIter.html new file mode 100644 index 0000000..7409fdf --- /dev/null +++ b/target/doc/regex/re_set/bytes/struct.SetMatchesIntoIter.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../regex/bytes/struct.SetMatchesIntoIter.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_set/bytes/struct.SetMatchesIter.html b/target/doc/regex/re_set/bytes/struct.SetMatchesIter.html new file mode 100644 index 0000000..97d1d69 --- /dev/null +++ b/target/doc/regex/re_set/bytes/struct.SetMatchesIter.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../regex/bytes/struct.SetMatchesIter.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_set/unicode/struct.RegexSet.html b/target/doc/regex/re_set/unicode/struct.RegexSet.html new file mode 100644 index 0000000..88b72f8 --- /dev/null +++ b/target/doc/regex/re_set/unicode/struct.RegexSet.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../regex/struct.RegexSet.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_set/unicode/struct.SetMatches.html b/target/doc/regex/re_set/unicode/struct.SetMatches.html new file mode 100644 index 0000000..d6f0075 --- /dev/null +++ b/target/doc/regex/re_set/unicode/struct.SetMatches.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../regex/struct.SetMatches.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_set/unicode/struct.SetMatchesIntoIter.html b/target/doc/regex/re_set/unicode/struct.SetMatchesIntoIter.html new file mode 100644 index 0000000..1e8ebcb --- /dev/null +++ b/target/doc/regex/re_set/unicode/struct.SetMatchesIntoIter.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../regex/struct.SetMatchesIntoIter.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_set/unicode/struct.SetMatchesIter.html b/target/doc/regex/re_set/unicode/struct.SetMatchesIter.html new file mode 100644 index 0000000..34936ec --- /dev/null +++ b/target/doc/regex/re_set/unicode/struct.SetMatchesIter.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../regex/struct.SetMatchesIter.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_unicode/fn.escape.html b/target/doc/regex/re_unicode/fn.escape.html new file mode 100644 index 0000000..e1d0221 --- /dev/null +++ b/target/doc/regex/re_unicode/fn.escape.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/fn.escape.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_unicode/struct.CaptureLocations.html b/target/doc/regex/re_unicode/struct.CaptureLocations.html new file mode 100644 index 0000000..568d7e5 --- /dev/null +++ b/target/doc/regex/re_unicode/struct.CaptureLocations.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/struct.CaptureLocations.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_unicode/struct.CaptureMatches.html b/target/doc/regex/re_unicode/struct.CaptureMatches.html new file mode 100644 index 0000000..be43b3c --- /dev/null +++ b/target/doc/regex/re_unicode/struct.CaptureMatches.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/struct.CaptureMatches.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_unicode/struct.CaptureNames.html b/target/doc/regex/re_unicode/struct.CaptureNames.html new file mode 100644 index 0000000..6ef5891 --- /dev/null +++ b/target/doc/regex/re_unicode/struct.CaptureNames.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/struct.CaptureNames.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_unicode/struct.Captures.html b/target/doc/regex/re_unicode/struct.Captures.html new file mode 100644 index 0000000..9f065dc --- /dev/null +++ b/target/doc/regex/re_unicode/struct.Captures.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/struct.Captures.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_unicode/struct.Match.html b/target/doc/regex/re_unicode/struct.Match.html new file mode 100644 index 0000000..57b40af --- /dev/null +++ b/target/doc/regex/re_unicode/struct.Match.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/struct.Match.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_unicode/struct.Matches.html b/target/doc/regex/re_unicode/struct.Matches.html new file mode 100644 index 0000000..01b0655 --- /dev/null +++ b/target/doc/regex/re_unicode/struct.Matches.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/struct.Matches.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_unicode/struct.NoExpand.html b/target/doc/regex/re_unicode/struct.NoExpand.html new file mode 100644 index 0000000..d72348f --- /dev/null +++ b/target/doc/regex/re_unicode/struct.NoExpand.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/struct.NoExpand.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_unicode/struct.Regex.html b/target/doc/regex/re_unicode/struct.Regex.html new file mode 100644 index 0000000..d6d5a9b --- /dev/null +++ b/target/doc/regex/re_unicode/struct.Regex.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/struct.Regex.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_unicode/struct.ReplacerRef.html b/target/doc/regex/re_unicode/struct.ReplacerRef.html new file mode 100644 index 0000000..addd149 --- /dev/null +++ b/target/doc/regex/re_unicode/struct.ReplacerRef.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/struct.ReplacerRef.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_unicode/struct.Split.html b/target/doc/regex/re_unicode/struct.Split.html new file mode 100644 index 0000000..ed2945b --- /dev/null +++ b/target/doc/regex/re_unicode/struct.Split.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/struct.Split.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_unicode/struct.SplitN.html b/target/doc/regex/re_unicode/struct.SplitN.html new file mode 100644 index 0000000..ecf12e7 --- /dev/null +++ b/target/doc/regex/re_unicode/struct.SplitN.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/struct.SplitN.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_unicode/struct.SubCaptureMatches.html b/target/doc/regex/re_unicode/struct.SubCaptureMatches.html new file mode 100644 index 0000000..7eeede4 --- /dev/null +++ b/target/doc/regex/re_unicode/struct.SubCaptureMatches.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/struct.SubCaptureMatches.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/re_unicode/trait.Replacer.html b/target/doc/regex/re_unicode/trait.Replacer.html new file mode 100644 index 0000000..80e186a --- /dev/null +++ b/target/doc/regex/re_unicode/trait.Replacer.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex/trait.Replacer.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex/sidebar-items.js b/target/doc/regex/sidebar-items.js new file mode 100644 index 0000000..2319e7b --- /dev/null +++ b/target/doc/regex/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"enum":[["Error","An error that occurred during parsing or compiling a regular expression."]],"fn":[["escape","Escapes all regular expression meta characters in `text`."]],"mod":[["bytes","Match regular expressions on arbitrary bytes."]],"struct":[["CaptureLocations","CaptureLocations is a low level representation of the raw offsets of each submatch."],["CaptureMatches","An iterator that yields all non-overlapping capture groups matching a particular regular expression."],["CaptureNames","An iterator over the names of all possible captures."],["Captures","Captures represents a group of captured strings for a single match."],["Match","Match represents a single match of a regex in a haystack."],["Matches","An iterator over all non-overlapping matches for a particular string."],["NoExpand","`NoExpand` indicates literal string replacement."],["Regex","A compiled regular expression for matching Unicode strings."],["RegexBuilder","A configurable builder for a regular expression."],["RegexSet","Match multiple (possibly overlapping) regular expressions in a single scan."],["RegexSetBuilder","A configurable builder for a set of regular expressions."],["ReplacerRef","By-reference adaptor for a `Replacer`"],["SetMatches","A set of matches returned by a regex set."],["SetMatchesIntoIter","An owned iterator over the set of matches from a regex set."],["SetMatchesIter","A borrowed iterator over the set of matches from a regex set."],["Split","Yields all substrings delimited by a regular expression match."],["SplitN","Yields at most `N` substrings delimited by a regular expression match."],["SubCaptureMatches","An iterator that yields all capturing matches in the order in which they appear in the regex."]],"trait":[["Replacer","Replacer describes types that can be used to replace matches in a string."]]}); \ No newline at end of file diff --git a/target/doc/regex/struct.CaptureLocations.html b/target/doc/regex/struct.CaptureLocations.html new file mode 100644 index 0000000..c18442e --- /dev/null +++ b/target/doc/regex/struct.CaptureLocations.html @@ -0,0 +1,36 @@ +regex::CaptureLocations - Rust

[][src]Struct regex::CaptureLocations

pub struct CaptureLocations(_);

CaptureLocations is a low level representation of the raw offsets of each +submatch.

+

You can think of this as a lower level +Captures, where this type does not support +named capturing groups directly and it does not borrow the text that these +offsets were matched on.

+

Primarily, this type is useful when using the lower level Regex APIs +such as read_captures, which permits amortizing the allocation in which +capture match locations are stored.

+

In order to build a value of this type, you'll need to call the +capture_locations method on the Regex being used to execute the search. +The value returned can then be reused in subsequent searches.

+

Methods

impl CaptureLocations[src]

pub fn get(&self, i: usize) -> Option<(usize, usize)>[src]

Returns the start and end positions of the Nth capture group. Returns +None if i is not a valid capture group or if the capture group did +not match anything. The positions returned are always byte indices +with respect to the original string matched.

+

pub fn len(&self) -> usize[src]

Returns the total number of capturing groups.

+

This is always at least 1 since every regex has at least 1 +capturing group that corresponds to the entire match.

+

Trait Implementations

impl Clone for CaptureLocations[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Debug for CaptureLocations[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/struct.CaptureMatches.html b/target/doc/regex/struct.CaptureMatches.html new file mode 100644 index 0000000..3c982dc --- /dev/null +++ b/target/doc/regex/struct.CaptureMatches.html @@ -0,0 +1,82 @@ +regex::CaptureMatches - Rust

[][src]Struct regex::CaptureMatches

pub struct CaptureMatches<'r, 't>(_);

An iterator that yields all non-overlapping capture groups matching a +particular regular expression.

+

The iterator stops when no more matches can be found.

+

'r is the lifetime of the compiled regular expression and 't is the +lifetime of the matched string.

+

Trait Implementations

impl<'r, 't> Iterator for CaptureMatches<'r, 't>[src]

type Item = Captures<'t>

The type of the elements being iterated over.

+

fn size_hint(&self) -> (usize, Option<usize>)1.0.0[src]

Returns the bounds on the remaining length of the iterator. Read more

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

Auto Trait Implementations

impl<'r, 't> !Send for CaptureMatches<'r, 't>

impl<'r, 't> !Sync for CaptureMatches<'r, 't>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/struct.CaptureNames.html b/target/doc/regex/struct.CaptureNames.html new file mode 100644 index 0000000..050c584 --- /dev/null +++ b/target/doc/regex/struct.CaptureNames.html @@ -0,0 +1,81 @@ +regex::CaptureNames - Rust

[][src]Struct regex::CaptureNames

pub struct CaptureNames<'r>(_);

An iterator over the names of all possible captures.

+

None indicates an unnamed capture; the first element (capture 0, the +whole matched region) is always unnamed.

+

'r is the lifetime of the compiled regular expression.

+

Trait Implementations

impl<'r> Iterator for CaptureNames<'r>[src]

type Item = Option<&'r str>

The type of the elements being iterated over.

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

Auto Trait Implementations

impl<'r> Send for CaptureNames<'r>

impl<'r> Sync for CaptureNames<'r>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/struct.Captures.html b/target/doc/regex/struct.Captures.html new file mode 100644 index 0000000..472f549 --- /dev/null +++ b/target/doc/regex/struct.Captures.html @@ -0,0 +1,74 @@ +regex::Captures - Rust

[][src]Struct regex::Captures

pub struct Captures<'t> { /* fields omitted */ }

Captures represents a group of captured strings for a single match.

+

The 0th capture always corresponds to the entire match. Each subsequent +index corresponds to the next capture group in the regex. If a capture +group is named, then the matched string is also available via the name +method. (Note that the 0th capture is always unnamed and so must be +accessed with the get method.)

+

Positions returned from a capture group are always byte indices.

+

't is the lifetime of the matched text.

+

Methods

impl<'t> Captures<'t>[src]

pub fn get(&self, i: usize) -> Option<Match<'t>>[src]

Returns the match associated with the capture group at index i. If +i does not correspond to a capture group, or if the capture group +did not participate in the match, then None is returned.

+

Examples

+

Get the text of the match with a default of an empty string if this +group didn't participate in the match:

+ +
+let re = Regex::new(r"[a-z]+(?:([0-9]+)|([A-Z]+))").unwrap();
+let caps = re.captures("abc123").unwrap();
+
+let text1 = caps.get(1).map_or("", |m| m.as_str());
+let text2 = caps.get(2).map_or("", |m| m.as_str());
+assert_eq!(text1, "123");
+assert_eq!(text2, "");
+

pub fn name(&self, name: &str) -> Option<Match<'t>>[src]

Returns the match for the capture group named name. If name isn't a +valid capture group or didn't match anything, then None is returned.

+

Important traits for SubCaptureMatches<'c, 't>
pub fn iter<'c>(&'c self) -> SubCaptureMatches<'c, 't>[src]

An iterator that yields all capturing matches in the order in which +they appear in the regex. If a particular capture group didn't +participate in the match, then None is yielded for that capture.

+

The first match always corresponds to the overall match of the regex.

+

pub fn expand(&self, replacement: &str, dst: &mut String)[src]

Expands all instances of $name in replacement to the corresponding +capture group name, and writes them to the dst buffer given.

+

name may be an integer corresponding to the index of the +capture group (counted by order of opening parenthesis where 0 is the +entire match) or it can be a name (consisting of letters, digits or +underscores) corresponding to a named capture group.

+

If name isn't a valid capture group (whether the name doesn't exist +or isn't a valid index), then it is replaced with the empty string.

+

The longest possible name is used. e.g., $1a looks up the capture +group named 1a and not the capture group at index 1. To exert more +precise control over the name, use braces, e.g., ${1}a.

+

To write a literal $ use $$.

+

pub fn len(&self) -> usize[src]

Returns the number of captured groups.

+

This is always at least 1, since every regex has at least one capture +group that corresponds to the full match.

+

Trait Implementations

impl<'t> Debug for Captures<'t>[src]

impl<'t> Index<usize> for Captures<'t>[src]

Get a group by index.

+

't is the lifetime of the matched text.

+

The text can't outlive the Captures object if this method is +used, because of how Index is defined (normally a[i] is part +of a and can't outlive it); to do that, use get() instead.

+

Panics

+

If there is no group at the given index.

+

type Output = str

The returned type after indexing.

+

impl<'t, 'i> Index<&'i str> for Captures<'t>[src]

Get a group by name.

+

't is the lifetime of the matched text and 'i is the lifetime +of the group name (the index).

+

The text can't outlive the Captures object if this method is +used, because of how Index is defined (normally a[i] is part +of a and can't outlive it); to do that, use name instead.

+

Panics

+

If there is no group named by the given value.

+

type Output = str

The returned type after indexing.

+

Auto Trait Implementations

impl<'t> Send for Captures<'t>

impl<'t> Sync for Captures<'t>

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/struct.Match.html b/target/doc/regex/struct.Match.html new file mode 100644 index 0000000..f435231 --- /dev/null +++ b/target/doc/regex/struct.Match.html @@ -0,0 +1,25 @@ +regex::Match - Rust

[][src]Struct regex::Match

pub struct Match<'t> { /* fields omitted */ }

Match represents a single match of a regex in a haystack.

+

The lifetime parameter 't refers to the lifetime of the matched text.

+

Methods

impl<'t> Match<'t>[src]

pub fn start(&self) -> usize[src]

Returns the starting byte offset of the match in the haystack.

+

pub fn end(&self) -> usize[src]

Returns the ending byte offset of the match in the haystack.

+

pub fn as_str(&self) -> &'t str[src]

Returns the matched text.

+

Trait Implementations

impl<'t> PartialEq<Match<'t>> for Match<'t>[src]

impl<'t> From<Match<'t>> for &'t str[src]

impl<'t> Clone for Match<'t>[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl<'t> Eq for Match<'t>[src]

impl<'t> Copy for Match<'t>[src]

impl<'t> Debug for Match<'t>[src]

Auto Trait Implementations

impl<'t> Send for Match<'t>

impl<'t> Sync for Match<'t>

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/struct.Matches.html b/target/doc/regex/struct.Matches.html new file mode 100644 index 0000000..1cbd093 --- /dev/null +++ b/target/doc/regex/struct.Matches.html @@ -0,0 +1,82 @@ +regex::Matches - Rust

[][src]Struct regex::Matches

pub struct Matches<'r, 't>(_);

An iterator over all non-overlapping matches for a particular string.

+

The iterator yields a Match value. The iterator stops when no more +matches can be found.

+

'r is the lifetime of the compiled regular expression and 't is the +lifetime of the matched string.

+

Trait Implementations

impl<'r, 't> Iterator for Matches<'r, 't>[src]

type Item = Match<'t>

The type of the elements being iterated over.

+

fn size_hint(&self) -> (usize, Option<usize>)1.0.0[src]

Returns the bounds on the remaining length of the iterator. Read more

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

Auto Trait Implementations

impl<'r, 't> !Send for Matches<'r, 't>

impl<'r, 't> !Sync for Matches<'r, 't>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/struct.NoExpand.html b/target/doc/regex/struct.NoExpand.html new file mode 100644 index 0000000..4e38b43 --- /dev/null +++ b/target/doc/regex/struct.NoExpand.html @@ -0,0 +1,19 @@ +regex::NoExpand - Rust

[][src]Struct regex::NoExpand

pub struct NoExpand<'t>(pub &'t str);

NoExpand indicates literal string replacement.

+

It can be used with replace and replace_all to do a literal string +replacement without expanding $name to their corresponding capture +groups. This can be both convenient (to avoid escaping $, for example) +and performant (since capture groups don't need to be found).

+

't is the lifetime of the literal text.

+

Trait Implementations

impl<'t> Replacer for NoExpand<'t>[src]

fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self>[src]

Return a Replacer that borrows and wraps this Replacer. Read more

+

Auto Trait Implementations

impl<'t> Send for NoExpand<'t>

impl<'t> Sync for NoExpand<'t>

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/struct.Regex.html b/target/doc/regex/struct.Regex.html new file mode 100644 index 0000000..9764012 --- /dev/null +++ b/target/doc/regex/struct.Regex.html @@ -0,0 +1,324 @@ +regex::Regex - Rust

[][src]Struct regex::Regex

pub struct Regex(_);

A compiled regular expression for matching Unicode strings.

+

It is represented as either a sequence of bytecode instructions (dynamic) +or as a specialized Rust function (native). It can be used to search, split +or replace text. All searching is done with an implicit .*? at the +beginning and end of an expression. To force an expression to match the +whole string (or a prefix or a suffix), you must use an anchor like ^ or +$ (or \A and \z).

+

While this crate will handle Unicode strings (whether in the regular +expression or in the search text), all positions returned are byte +indices. Every byte index is guaranteed to be at a Unicode code point +boundary.

+

The lifetimes 'r and 't in this crate correspond to the lifetime of a +compiled regular expression and text to search, respectively.

+

The only methods that allocate new strings are the string replacement +methods. All other methods (searching and splitting) return borrowed +pointers into the string given.

+

Examples

+

Find the location of a US phone number:

+ +
+let re = Regex::new("[0-9]{3}-[0-9]{3}-[0-9]{4}").unwrap();
+let mat = re.find("phone: 111-222-3333").unwrap();
+assert_eq!((mat.start(), mat.end()), (7, 19));
+

Using the std::str::pattern methods with Regex

+
+

Note: This section requires that this crate is compiled with the +pattern Cargo feature enabled, which requires nightly Rust.

+
+

Since Regex implements Pattern, you can use regexes with methods +defined on &str. For example, is_match, find, find_iter +and split can be replaced with str::contains, str::find, +str::match_indices and str::split.

+

Here are some examples:

+ +
This example is not tested
+let re = Regex::new(r"\d+").unwrap();
+let haystack = "a111b222c";
+
+assert!(haystack.contains(&re));
+assert_eq!(haystack.find(&re), Some(1));
+assert_eq!(haystack.match_indices(&re).collect::<Vec<_>>(),
+           vec![(1, 4), (5, 8)]);
+assert_eq!(haystack.split(&re).collect::<Vec<_>>(), vec!["a", "b", "c"]);
+

Methods

impl Regex[src]

Core regular expression methods.

+

pub fn new(re: &str) -> Result<Regex, Error>[src]

Compiles a regular expression. Once compiled, it can be used repeatedly +to search, split or replace text in a string.

+

If an invalid expression is given, then an error is returned.

+

pub fn is_match(&self, text: &str) -> bool[src]

Returns true if and only if the regex matches the string given.

+

It is recommended to use this method if all you need to do is test +a match, since the underlying matching engine may be able to do less +work.

+

Example

+

Test if some text contains at least one word with exactly 13 +Unicode word characters:

+ +
+let text = "I categorically deny having triskaidekaphobia.";
+assert!(Regex::new(r"\b\w{13}\b").unwrap().is_match(text));
+

pub fn find<'t>(&self, text: &'t str) -> Option<Match<'t>>[src]

Returns the start and end byte range of the leftmost-first match in +text. If no match exists, then None is returned.

+

Note that this should only be used if you want to discover the position +of the match. Testing the existence of a match is faster if you use +is_match.

+

Example

+

Find the start and end location of the first word with exactly 13 +Unicode word characters:

+ +
+let text = "I categorically deny having triskaidekaphobia.";
+let mat = Regex::new(r"\b\w{13}\b").unwrap().find(text).unwrap();
+assert_eq!(mat.start(), 2);
+assert_eq!(mat.end(), 15);
+

Important traits for Matches<'r, 't>
pub fn find_iter<'r, 't>(&'r self, text: &'t str) -> Matches<'r, 't>[src]

Returns an iterator for each successive non-overlapping match in +text, returning the start and end byte indices with respect to +text.

+

Example

+

Find the start and end location of every word with exactly 13 Unicode +word characters:

+ +
+let text = "Retroactively relinquishing remunerations is reprehensible.";
+for mat in Regex::new(r"\b\w{13}\b").unwrap().find_iter(text) {
+    println!("{:?}", mat);
+}
+

pub fn captures<'t>(&self, text: &'t str) -> Option<Captures<'t>>[src]

Returns the capture groups corresponding to the leftmost-first +match in text. Capture group 0 always corresponds to the entire +match. If no match is found, then None is returned.

+

You should only use captures if you need access to the location of +capturing group matches. Otherwise, find is faster for discovering +the location of the overall match.

+

Examples

+

Say you have some text with movie names and their release years, +like "'Citizen Kane' (1941)". It'd be nice if we could search for text +looking like that, while also extracting the movie name and its release +year separately.

+ +
+let re = Regex::new(r"'([^']+)'\s+\((\d{4})\)").unwrap();
+let text = "Not my favorite movie: 'Citizen Kane' (1941).";
+let caps = re.captures(text).unwrap();
+assert_eq!(caps.get(1).unwrap().as_str(), "Citizen Kane");
+assert_eq!(caps.get(2).unwrap().as_str(), "1941");
+assert_eq!(caps.get(0).unwrap().as_str(), "'Citizen Kane' (1941)");
+// You can also access the groups by index using the Index notation.
+// Note that this will panic on an invalid index.
+assert_eq!(&caps[1], "Citizen Kane");
+assert_eq!(&caps[2], "1941");
+assert_eq!(&caps[0], "'Citizen Kane' (1941)");
+

Note that the full match is at capture group 0. Each subsequent +capture group is indexed by the order of its opening (.

+

We can make this example a bit clearer by using named capture groups:

+ +
+let re = Regex::new(r"'(?P<title>[^']+)'\s+\((?P<year>\d{4})\)")
+               .unwrap();
+let text = "Not my favorite movie: 'Citizen Kane' (1941).";
+let caps = re.captures(text).unwrap();
+assert_eq!(caps.name("title").unwrap().as_str(), "Citizen Kane");
+assert_eq!(caps.name("year").unwrap().as_str(), "1941");
+assert_eq!(caps.get(0).unwrap().as_str(), "'Citizen Kane' (1941)");
+// You can also access the groups by name using the Index notation.
+// Note that this will panic on an invalid group name.
+assert_eq!(&caps["title"], "Citizen Kane");
+assert_eq!(&caps["year"], "1941");
+assert_eq!(&caps[0], "'Citizen Kane' (1941)");
+
+

Here we name the capture groups, which we can access with the name +method or the Index notation with a &str. Note that the named +capture groups are still accessible with get or the Index notation +with a usize.

+

The 0th capture group is always unnamed, so it must always be +accessed with get(0) or [0].

+

Important traits for CaptureMatches<'r, 't>
pub fn captures_iter<'r, 't>(&'r self, text: &'t str) -> CaptureMatches<'r, 't>[src]

Returns an iterator over all the non-overlapping capture groups matched +in text. This is operationally the same as find_iter, except it +yields information about capturing group matches.

+

Example

+

We can use this to find all movie titles and their release years in +some text, where the movie is formatted like "'Title' (xxxx)":

+ +
+let re = Regex::new(r"'(?P<title>[^']+)'\s+\((?P<year>\d{4})\)")
+               .unwrap();
+let text = "'Citizen Kane' (1941), 'The Wizard of Oz' (1939), 'M' (1931).";
+for caps in re.captures_iter(text) {
+    println!("Movie: {:?}, Released: {:?}",
+             &caps["title"], &caps["year"]);
+}
+// Output:
+// Movie: Citizen Kane, Released: 1941
+// Movie: The Wizard of Oz, Released: 1939
+// Movie: M, Released: 1931
+

Important traits for Split<'r, 't>
pub fn split<'r, 't>(&'r self, text: &'t str) -> Split<'r, 't>[src]

Returns an iterator of substrings of text delimited by a match of the +regular expression. Namely, each element of the iterator corresponds to +text that isn't matched by the regular expression.

+

This method will not copy the text given.

+

Example

+

To split a string delimited by arbitrary amounts of spaces or tabs:

+ +
+let re = Regex::new(r"[ \t]+").unwrap();
+let fields: Vec<&str> = re.split("a b \t  c\td    e").collect();
+assert_eq!(fields, vec!["a", "b", "c", "d", "e"]);
+

Important traits for SplitN<'r, 't>
pub fn splitn<'r, 't>(&'r self, text: &'t str, limit: usize) -> SplitN<'r, 't>[src]

Returns an iterator of at most limit substrings of text delimited +by a match of the regular expression. (A limit of 0 will return no +substrings.) Namely, each element of the iterator corresponds to text +that isn't matched by the regular expression. The remainder of the +string that is not split will be the last element in the iterator.

+

This method will not copy the text given.

+

Example

+

Get the first two words in some text:

+ +
+let re = Regex::new(r"\W+").unwrap();
+let fields: Vec<&str> = re.splitn("Hey! How are you?", 3).collect();
+assert_eq!(fields, vec!("Hey", "How", "are you?"));
+

pub fn replace<'t, R: Replacer>(&self, text: &'t str, rep: R) -> Cow<'t, str>[src]

Replaces the leftmost-first match with the replacement provided. +The replacement can be a regular string (where $N and $name are +expanded to match capture groups) or a function that takes the matches' +Captures and returns the replaced string.

+

If no match is found, then a copy of the string is returned unchanged.

+

Replacement string syntax

+

All instances of $name in the replacement text is replaced with the +corresponding capture group name.

+

name may be an integer corresponding to the index of the +capture group (counted by order of opening parenthesis where 0 is the +entire match) or it can be a name (consisting of letters, digits or +underscores) corresponding to a named capture group.

+

If name isn't a valid capture group (whether the name doesn't exist +or isn't a valid index), then it is replaced with the empty string.

+

The longest possible name is used. e.g., $1a looks up the capture +group named 1a and not the capture group at index 1. To exert more +precise control over the name, use braces, e.g., ${1}a.

+

To write a literal $ use $$.

+

Examples

+

Note that this function is polymorphic with respect to the replacement. +In typical usage, this can just be a normal string:

+ +
+let re = Regex::new("[^01]+").unwrap();
+assert_eq!(re.replace("1078910", ""), "1010");
+

But anything satisfying the Replacer trait will work. For example, +a closure of type |&Captures| -> String provides direct access to the +captures corresponding to a match. This allows one to access +capturing group matches easily:

+ +
+let re = Regex::new(r"([^,\s]+),\s+(\S+)").unwrap();
+let result = re.replace("Springsteen, Bruce", |caps: &Captures| {
+    format!("{} {}", &caps[2], &caps[1])
+});
+assert_eq!(result, "Bruce Springsteen");
+

But this is a bit cumbersome to use all the time. Instead, a simple +syntax is supported that expands $name into the corresponding capture +group. Here's the last example, but using this expansion technique +with named capture groups:

+ +
+let re = Regex::new(r"(?P<last>[^,\s]+),\s+(?P<first>\S+)").unwrap();
+let result = re.replace("Springsteen, Bruce", "$first $last");
+assert_eq!(result, "Bruce Springsteen");
+

Note that using $2 instead of $first or $1 instead of $last +would produce the same result. To write a literal $ use $$.

+

Sometimes the replacement string requires use of curly braces to +delineate a capture group replacement and surrounding literal text. +For example, if we wanted to join two words together with an +underscore:

+ +
+let re = Regex::new(r"(?P<first>\w+)\s+(?P<second>\w+)").unwrap();
+let result = re.replace("deep fried", "${first}_$second");
+assert_eq!(result, "deep_fried");
+

Without the curly braces, the capture group name first_ would be +used, and since it doesn't exist, it would be replaced with the empty +string.

+

Finally, sometimes you just want to replace a literal string with no +regard for capturing group expansion. This can be done by wrapping a +byte string with NoExpand:

+ +
+use regex::NoExpand;
+
+let re = Regex::new(r"(?P<last>[^,\s]+),\s+(\S+)").unwrap();
+let result = re.replace("Springsteen, Bruce", NoExpand("$2 $last"));
+assert_eq!(result, "$2 $last");
+

pub fn replace_all<'t, R: Replacer>(
    &self,
    text: &'t str,
    rep: R
) -> Cow<'t, str>
[src]

Replaces all non-overlapping matches in text with the replacement +provided. This is the same as calling replacen with limit set to +0.

+

See the documentation for replace for details on how to access +capturing group matches in the replacement string.

+

pub fn replacen<'t, R: Replacer>(
    &self,
    text: &'t str,
    limit: usize,
    rep: R
) -> Cow<'t, str>
[src]

Replaces at most limit non-overlapping matches in text with the +replacement provided. If limit is 0, then all non-overlapping matches +are replaced.

+

See the documentation for replace for details on how to access +capturing group matches in the replacement string.

+

impl Regex[src]

Advanced or "lower level" search methods.

+

pub fn shortest_match(&self, text: &str) -> Option<usize>[src]

Returns the end location of a match in the text given.

+

This method may have the same performance characteristics as +is_match, except it provides an end location for a match. In +particular, the location returned may be shorter than the proper end +of the leftmost-first match.

+

Example

+

Typically, a+ would match the entire first sequence of a in some +text, but shortest_match can give up as soon as it sees the first +a.

+ +
+let text = "aaaaa";
+let pos = Regex::new(r"a+").unwrap().shortest_match(text);
+assert_eq!(pos, Some(1));
+

pub fn shortest_match_at(&self, text: &str, start: usize) -> Option<usize>[src]

Returns the same as shortest_match, but starts the search at the given +offset.

+

The significance of the starting point is that it takes the surrounding +context into consideration. For example, the \A anchor can only +match when start == 0.

+

pub fn is_match_at(&self, text: &str, start: usize) -> bool[src]

Returns the same as is_match, but starts the search at the given +offset.

+

The significance of the starting point is that it takes the surrounding +context into consideration. For example, the \A anchor can only +match when start == 0.

+

pub fn find_at<'t>(&self, text: &'t str, start: usize) -> Option<Match<'t>>[src]

Returns the same as find, but starts the search at the given +offset.

+

The significance of the starting point is that it takes the surrounding +context into consideration. For example, the \A anchor can only +match when start == 0.

+

pub fn captures_read<'t>(
    &self,
    locs: &mut CaptureLocations,
    text: &'t str
) -> Option<Match<'t>>
[src]

This is like captures, but uses +CaptureLocations +instead of +Captures in order to amortize allocations.

+

To create a CaptureLocations value, use the +Regex::capture_locations method.

+

This returns the overall match if this was successful, which is always +equivalence to the 0th capture group.

+

pub fn captures_read_at<'t>(
    &self,
    locs: &mut CaptureLocations,
    text: &'t str,
    start: usize
) -> Option<Match<'t>>
[src]

Returns the same as captures, but starts the search at the given +offset and populates the capture locations given.

+

The significance of the starting point is that it takes the surrounding +context into consideration. For example, the \A anchor can only +match when start == 0.

+

impl Regex[src]

Auxiliary methods.

+

pub fn as_str(&self) -> &str[src]

Returns the original string of this regex.

+

Important traits for CaptureNames<'r>
pub fn capture_names(&self) -> CaptureNames[src]

Returns an iterator over the capture names.

+

pub fn captures_len(&self) -> usize[src]

Returns the number of captures.

+

pub fn capture_locations(&self) -> CaptureLocations[src]

Returns an empty set of capture locations that can be reused in +multiple calls to captures_read or captures_read_at.

+

Trait Implementations

impl Clone for Regex[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Display for Regex[src]

fn fmt(&self, f: &mut Formatter) -> Result[src]

Shows the original regular expression.

+

impl Debug for Regex[src]

fn fmt(&self, f: &mut Formatter) -> Result[src]

Shows the original regular expression.

+

impl FromStr for Regex[src]

type Err = Error

The associated error which can be returned from parsing.

+

fn from_str(s: &str) -> Result<Regex, Error>[src]

Attempts to parse a string into a regular expression

+

Auto Trait Implementations

impl Send for Regex

impl Sync for Regex

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/struct.RegexBuilder.html b/target/doc/regex/struct.RegexBuilder.html new file mode 100644 index 0000000..4c0f499 --- /dev/null +++ b/target/doc/regex/struct.RegexBuilder.html @@ -0,0 +1,89 @@ +regex::RegexBuilder - Rust

[][src]Struct regex::RegexBuilder

pub struct RegexBuilder(_);

A configurable builder for a regular expression.

+

A builder can be used to configure how the regex is built, for example, by +setting the default flags (which can be overridden in the expression +itself) or setting various limits.

+

Methods

impl RegexBuilder[src]

pub fn new(pattern: &str) -> RegexBuilder[src]

Create a new regular expression builder with the given pattern.

+

If the pattern is invalid, then an error will be returned when +build is called.

+

pub fn build(&self) -> Result<Regex, Error>[src]

Consume the builder and compile the regular expression.

+

Note that calling as_str on the resulting Regex will produce the +pattern given to new verbatim. Notably, it will not incorporate any +of the flags set on this builder.

+

pub fn case_insensitive(&mut self, yes: bool) -> &mut RegexBuilder[src]

Set the value for the case insensitive (i) flag.

+

When enabled, letters in the pattern will match both upper case and +lower case variants.

+

pub fn multi_line(&mut self, yes: bool) -> &mut RegexBuilder[src]

Set the value for the multi-line matching (m) flag.

+

When enabled, ^ matches the beginning of lines and $ matches the +end of lines.

+

By default, they match beginning/end of the input.

+

pub fn dot_matches_new_line(&mut self, yes: bool) -> &mut RegexBuilder[src]

Set the value for the any character (s) flag, where in . matches +anything when s is set and matches anything except for new line when +it is not set (the default).

+

N.B. "matches anything" means "any byte" when Unicode is disabled and +means "any valid UTF-8 encoding of any Unicode scalar value" when +Unicode is enabled.

+

pub fn swap_greed(&mut self, yes: bool) -> &mut RegexBuilder[src]

Set the value for the greedy swap (U) flag.

+

When enabled, a pattern like a* is lazy (tries to find shortest +match) and a*? is greedy (tries to find longest match).

+

By default, a* is greedy and a*? is lazy.

+

pub fn ignore_whitespace(&mut self, yes: bool) -> &mut RegexBuilder[src]

Set the value for the ignore whitespace (x) flag.

+

When enabled, whitespace such as new lines and spaces will be ignored +between expressions of the pattern, and # can be used to start a +comment until the next new line.

+

pub fn unicode(&mut self, yes: bool) -> &mut RegexBuilder[src]

Set the value for the Unicode (u) flag.

+

Enabled by default. When disabled, character classes such as \w only +match ASCII word characters instead of all Unicode word characters.

+

pub fn octal(&mut self, yes: bool) -> &mut RegexBuilder[src]

Whether to support octal syntax or not.

+

Octal syntax is a little-known way of uttering Unicode codepoints in +a regular expression. For example, a, \x61, \u0061 and +\141 are all equivalent regular expressions, where the last example +shows octal syntax.

+

While supporting octal syntax isn't in and of itself a problem, it does +make good error messages harder. That is, in PCRE based regex engines, +syntax like \0 invokes a backreference, which is explicitly +unsupported in Rust's regex engine. However, many users expect it to +be supported. Therefore, when octal support is disabled, the error +message will explicitly mention that backreferences aren't supported.

+

Octal syntax is disabled by default.

+

pub fn size_limit(&mut self, limit: usize) -> &mut RegexBuilder[src]

Set the approximate size limit of the compiled regular expression.

+

This roughly corresponds to the number of bytes occupied by a single +compiled program. If the program exceeds this number, then a +compilation error is returned.

+

pub fn dfa_size_limit(&mut self, limit: usize) -> &mut RegexBuilder[src]

Set the approximate size of the cache used by the DFA.

+

This roughly corresponds to the number of bytes that the DFA will +use while searching.

+

Note that this is a per thread limit. There is no way to set a global +limit. In particular, if a regex is used from multiple threads +simultaneously, then each thread may use up to the number of bytes +specified here.

+

pub fn nest_limit(&mut self, limit: u32) -> &mut RegexBuilder[src]

Set the nesting limit for this parser.

+

The nesting limit controls how deep the abstract syntax tree is allowed +to be. If the AST exceeds the given limit (e.g., with too many nested +groups), then an error is returned by the parser.

+

The purpose of this limit is to act as a heuristic to prevent stack +overflow for consumers that do structural induction on an Ast using +explicit recursion. While this crate never does this (instead using +constant stack space and moving the call stack to the heap), other +crates may.

+

This limit is not checked until the entire Ast is parsed. Therefore, +if callers want to put a limit on the amount of heap space used, then +they should impose a limit on the length, in bytes, of the concrete +pattern string. In particular, this is viable since this parser +implementation will limit itself to heap space proportional to the +length of the pattern string.

+

Note that a nest limit of 0 will return a nest limit error for most +patterns but not all. For example, a nest limit of 0 permits a but +not ab, since ab requires a concatenation, which results in a nest +depth of 1. In general, a nest limit is not something that manifests +in an obvious way in the concrete syntax, therefore, it should not be +used in a granular way.

+

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/struct.RegexSet.html b/target/doc/regex/struct.RegexSet.html new file mode 100644 index 0000000..f637310 --- /dev/null +++ b/target/doc/regex/struct.RegexSet.html @@ -0,0 +1,164 @@ +regex::RegexSet - Rust

[][src]Struct regex::RegexSet

pub struct RegexSet(_);

Match multiple (possibly overlapping) regular expressions in a single scan.

+

A regex set corresponds to the union of two or more regular expressions. +That is, a regex set will match text where at least one of its +constituent regular expressions matches. A regex set as its formulated here +provides a touch more power: it will also report which regular +expressions in the set match. Indeed, this is the key difference between +regex sets and a single Regex with many alternates, since only one +alternate can match at a time.

+

For example, consider regular expressions to match email addresses and +domains: [a-z]+@[a-z]+\.(com|org|net) and [a-z]+\.(com|org|net). If a +regex set is constructed from those regexes, then searching the text +foo@example.com will report both regexes as matching. Of course, one +could accomplish this by compiling each regex on its own and doing two +searches over the text. The key advantage of using a regex set is that it +will report the matching regexes using a single pass through the text. +If one has hundreds or thousands of regexes to match repeatedly (like a URL +router for a complex web application or a user agent matcher), then a regex +set can realize huge performance gains.

+

Example

+

This shows how the above two regexes (for matching email addresses and +domains) might work:

+ +
+let set = RegexSet::new(&[
+    r"[a-z]+@[a-z]+\.(com|org|net)",
+    r"[a-z]+\.(com|org|net)",
+]).unwrap();
+
+// Ask whether any regexes in the set match.
+assert!(set.is_match("foo@example.com"));
+
+// Identify which regexes in the set match.
+let matches: Vec<_> = set.matches("foo@example.com").into_iter().collect();
+assert_eq!(vec![0, 1], matches);
+
+// Try again, but with text that only matches one of the regexes.
+let matches: Vec<_> = set.matches("example.com").into_iter().collect();
+assert_eq!(vec![1], matches);
+
+// Try again, but with text that doesn't match any regex in the set.
+let matches: Vec<_> = set.matches("example").into_iter().collect();
+assert!(matches.is_empty());
+

Note that it would be possible to adapt the above example to using Regex +with an expression like:

+ +
This example is not tested
+(?P<email>[a-z]+@(?P<email_domain>[a-z]+[.](com|org|net)))|(?P<domain>[a-z]+[.](com|org|net))
+

After a match, one could then inspect the capture groups to figure out +which alternates matched. The problem is that it is hard to make this +approach scale when there are many regexes since the overlap between each +alternate isn't always obvious to reason about.

+

Limitations

+

Regex sets are limited to answering the following two questions:

+
    +
  1. Does any regex in the set match?
  2. +
  3. If so, which regexes in the set match?
  4. +
+

As with the main Regex type, it is cheaper to ask (1) instead of (2) +since the matching engines can stop after the first match is found.

+

Other features like finding the location of successive matches or their +sub-captures aren't supported. If you need this functionality, the +recommended approach is to compile each regex in the set independently and +selectively match them based on which regexes in the set matched.

+

Performance

+

A RegexSet has the same performance characteristics as Regex. Namely, +search takes O(mn) time, where m is proportional to the size of the +regex set and n is proportional to the length of the search text.

+

Methods

impl RegexSet[src]

pub fn new<I, S>(exprs: I) -> Result<RegexSet, Error> where
    S: AsRef<str>,
    I: IntoIterator<Item = S>, 
[src]

Create a new regex set with the given regular expressions.

+

This takes an iterator of S, where S is something that can produce +a &str. If any of the strings in the iterator are not valid regular +expressions, then an error is returned.

+

Example

+

Create a new regex set from an iterator of strings:

+ +
+let set = RegexSet::new(&[r"\w+", r"\d+"]).unwrap();
+assert!(set.is_match("foo"));
+

pub fn is_match(&self, text: &str) -> bool[src]

Returns true if and only if one of the regexes in this set matches +the text given.

+

This method should be preferred if you only need to test whether any +of the regexes in the set should match, but don't care about which +regexes matched. This is because the underlying matching engine will +quit immediately after seeing the first match instead of continuing to +find all matches.

+

Note that as with searches using Regex, the expression is unanchored +by default. That is, if the regex does not start with ^ or \A, or +end with $ or \z, then it is permitted to match anywhere in the +text.

+

Example

+

Tests whether a set matches some text:

+ +
+let set = RegexSet::new(&[r"\w+", r"\d+"]).unwrap();
+assert!(set.is_match("foo"));
+assert!(!set.is_match("☃"));
+

pub fn matches(&self, text: &str) -> SetMatches[src]

Returns the set of regular expressions that match in the given text.

+

The set returned contains the index of each regular expression that +matches in the given text. The index is in correspondence with the +order of regular expressions given to RegexSet's constructor.

+

The set can also be used to iterate over the matched indices.

+

Note that as with searches using Regex, the expression is unanchored +by default. That is, if the regex does not start with ^ or \A, or +end with $ or \z, then it is permitted to match anywhere in the +text.

+

Example

+

Tests which regular expressions match the given text:

+ +
+let set = RegexSet::new(&[
+    r"\w+",
+    r"\d+",
+    r"\pL+",
+    r"foo",
+    r"bar",
+    r"barfoo",
+    r"foobar",
+]).unwrap();
+let matches: Vec<_> = set.matches("foobar").into_iter().collect();
+assert_eq!(matches, vec![0, 2, 3, 4, 6]);
+
+// You can also test whether a particular regex matched:
+let matches = set.matches("foobar");
+assert!(!matches.matched(5));
+assert!(matches.matched(6));
+

pub fn len(&self) -> usize[src]

Returns the total number of regular expressions in this set.

+

pub fn patterns(&self) -> &[String][src]

Returns the patterns that this set will match on.

+

This function can be used to determine the pattern for a match. The +slice returned has exactly as many patterns givens to this regex set, +and the order of the slice is the same as the order of the patterns +provided to the set.

+

Example

+
+let set = RegexSet::new(&[
+    r"\w+",
+    r"\d+",
+    r"\pL+",
+    r"foo",
+    r"bar",
+    r"barfoo",
+    r"foobar",
+]).unwrap();
+let matches: Vec<_> = set
+    .matches("foobar")
+    .into_iter()
+    .map(|match_idx| &set.patterns()[match_idx])
+    .collect();
+assert_eq!(matches, vec![r"\w+", r"\pL+", r"foo", r"bar", r"foobar"]);
+

Trait Implementations

impl Clone for RegexSet[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Debug for RegexSet[src]

Auto Trait Implementations

impl Send for RegexSet

impl Sync for RegexSet

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/struct.RegexSetBuilder.html b/target/doc/regex/struct.RegexSetBuilder.html new file mode 100644 index 0000000..b399fc8 --- /dev/null +++ b/target/doc/regex/struct.RegexSetBuilder.html @@ -0,0 +1,73 @@ +regex::RegexSetBuilder - Rust

[][src]Struct regex::RegexSetBuilder

pub struct RegexSetBuilder(_);

A configurable builder for a set of regular expressions.

+

A builder can be used to configure how the regexes are built, for example, +by setting the default flags (which can be overridden in the expression +itself) or setting various limits.

+

Methods

impl RegexSetBuilder[src]

pub fn new<I, S>(patterns: I) -> RegexSetBuilder where
    S: AsRef<str>,
    I: IntoIterator<Item = S>, 
[src]

Create a new regular expression builder with the given pattern.

+

If the pattern is invalid, then an error will be returned when +build is called.

+

pub fn build(&self) -> Result<RegexSet, Error>[src]

Consume the builder and compile the regular expressions into a set.

+

pub fn case_insensitive(&mut self, yes: bool) -> &mut RegexSetBuilder[src]

Set the value for the case insensitive (i) flag.

+

pub fn multi_line(&mut self, yes: bool) -> &mut RegexSetBuilder[src]

Set the value for the multi-line matching (m) flag.

+

pub fn dot_matches_new_line(&mut self, yes: bool) -> &mut RegexSetBuilder[src]

Set the value for the any character (s) flag, where in . matches +anything when s is set and matches anything except for new line when +it is not set (the default).

+

N.B. "matches anything" means "any byte" for regex::bytes::RegexSet +expressions and means "any Unicode scalar value" for regex::RegexSet +expressions.

+

pub fn swap_greed(&mut self, yes: bool) -> &mut RegexSetBuilder[src]

Set the value for the greedy swap (U) flag.

+

pub fn ignore_whitespace(&mut self, yes: bool) -> &mut RegexSetBuilder[src]

Set the value for the ignore whitespace (x) flag.

+

pub fn unicode(&mut self, yes: bool) -> &mut RegexSetBuilder[src]

Set the value for the Unicode (u) flag.

+

pub fn octal(&mut self, yes: bool) -> &mut RegexSetBuilder[src]

Whether to support octal syntax or not.

+

Octal syntax is a little-known way of uttering Unicode codepoints in +a regular expression. For example, a, \x61, \u0061 and +\141 are all equivalent regular expressions, where the last example +shows octal syntax.

+

While supporting octal syntax isn't in and of itself a problem, it does +make good error messages harder. That is, in PCRE based regex engines, +syntax like \0 invokes a backreference, which is explicitly +unsupported in Rust's regex engine. However, many users expect it to +be supported. Therefore, when octal support is disabled, the error +message will explicitly mention that backreferences aren't supported.

+

Octal syntax is disabled by default.

+

pub fn size_limit(&mut self, limit: usize) -> &mut RegexSetBuilder[src]

Set the approximate size limit of the compiled regular expression.

+

This roughly corresponds to the number of bytes occupied by a single +compiled program. If the program exceeds this number, then a +compilation error is returned.

+

pub fn dfa_size_limit(&mut self, limit: usize) -> &mut RegexSetBuilder[src]

Set the approximate size of the cache used by the DFA.

+

This roughly corresponds to the number of bytes that the DFA will +use while searching.

+

Note that this is a per thread limit. There is no way to set a global +limit. In particular, if a regex is used from multiple threads +simultaneously, then each thread may use up to the number of bytes +specified here.

+

pub fn nest_limit(&mut self, limit: u32) -> &mut RegexSetBuilder[src]

Set the nesting limit for this parser.

+

The nesting limit controls how deep the abstract syntax tree is allowed +to be. If the AST exceeds the given limit (e.g., with too many nested +groups), then an error is returned by the parser.

+

The purpose of this limit is to act as a heuristic to prevent stack +overflow for consumers that do structural induction on an Ast using +explicit recursion. While this crate never does this (instead using +constant stack space and moving the call stack to the heap), other +crates may.

+

This limit is not checked until the entire Ast is parsed. Therefore, +if callers want to put a limit on the amount of heap space used, then +they should impose a limit on the length, in bytes, of the concrete +pattern string. In particular, this is viable since this parser +implementation will limit itself to heap space proportional to the +length of the pattern string.

+

Note that a nest limit of 0 will return a nest limit error for most +patterns but not all. For example, a nest limit of 0 permits a but +not ab, since ab requires a concatenation, which results in a nest +depth of 1. In general, a nest limit is not something that manifests +in an obvious way in the concrete syntax, therefore, it should not be +used in a granular way.

+

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/struct.ReplacerRef.html b/target/doc/regex/struct.ReplacerRef.html new file mode 100644 index 0000000..01a0f65 --- /dev/null +++ b/target/doc/regex/struct.ReplacerRef.html @@ -0,0 +1,16 @@ +regex::ReplacerRef - Rust

[][src]Struct regex::ReplacerRef

pub struct ReplacerRef<'a, R: ?Sized + 'a>(_);

By-reference adaptor for a Replacer

+

Returned by Replacer::by_ref.

+

Trait Implementations

impl<'a, R: Replacer + ?Sized + 'a> Replacer for ReplacerRef<'a, R>[src]

fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self>[src]

Return a Replacer that borrows and wraps this Replacer. Read more

+

impl<'a, R: Debug + ?Sized + 'a> Debug for ReplacerRef<'a, R>[src]

Auto Trait Implementations

impl<'a, R: ?Sized> Send for ReplacerRef<'a, R> where
    R: Send

impl<'a, R: ?Sized> Sync for ReplacerRef<'a, R> where
    R: Sync

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/struct.SetMatches.html b/target/doc/regex/struct.SetMatches.html new file mode 100644 index 0000000..85bdecc --- /dev/null +++ b/target/doc/regex/struct.SetMatches.html @@ -0,0 +1,38 @@ +regex::SetMatches - Rust

[][src]Struct regex::SetMatches

pub struct SetMatches { /* fields omitted */ }

A set of matches returned by a regex set.

+

Methods

impl SetMatches[src]

pub fn matched_any(&self) -> bool[src]

Whether this set contains any matches.

+

pub fn matched(&self, regex_index: usize) -> bool[src]

Whether the regex at the given index matched.

+

The index for a regex is determined by its insertion order upon the +initial construction of a RegexSet, starting at 0.

+

Panics

+

If regex_index is greater than or equal to self.len().

+

pub fn len(&self) -> usize[src]

The total number of regexes in the set that created these matches.

+

Important traits for SetMatchesIter<'a>
pub fn iter(&self) -> SetMatchesIter[src]

Returns an iterator over indexes in the regex that matched.

+

This will always produces matches in ascending order of index, where +the index corresponds to the index of the regex that matched with +respect to its position when initially building the set.

+

Trait Implementations

impl Clone for SetMatches[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl IntoIterator for SetMatches[src]

type IntoIter = SetMatchesIntoIter

Which kind of iterator are we turning this into?

+

type Item = usize

The type of the elements being iterated over.

+

impl<'a> IntoIterator for &'a SetMatches[src]

type IntoIter = SetMatchesIter<'a>

Which kind of iterator are we turning this into?

+

type Item = usize

The type of the elements being iterated over.

+

impl Debug for SetMatches[src]

Auto Trait Implementations

impl Send for SetMatches

impl Sync for SetMatches

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/struct.SetMatchesIntoIter.html b/target/doc/regex/struct.SetMatchesIntoIter.html new file mode 100644 index 0000000..29e9e61 --- /dev/null +++ b/target/doc/regex/struct.SetMatchesIntoIter.html @@ -0,0 +1,86 @@ +regex::SetMatchesIntoIter - Rust

[][src]Struct regex::SetMatchesIntoIter

pub struct SetMatchesIntoIter(_);

An owned iterator over the set of matches from a regex set.

+

This will always produces matches in ascending order of index, where the +index corresponds to the index of the regex that matched with respect to +its position when initially building the set.

+

Trait Implementations

impl DoubleEndedIterator for SetMatchesIntoIter[src]

fn nth_back(&mut self, n: usize) -> Option<Self::Item>[src]

🔬 This is a nightly-only experimental API. (iter_nth_back)

Returns the nth element from the end of the iterator. Read more

+

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

This is the reverse version of [try_fold()]: it takes elements starting from the back of the iterator. Read more

+

fn rfold<B, F>(self, accum: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.27.0[src]

An iterator method that reduces the iterator's elements to a single, final value, starting from the back. Read more

+

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.27.0[src]

Searches for an element of an iterator from the back that satisfies a predicate. Read more

+

impl Iterator for SetMatchesIntoIter[src]

type Item = usize

The type of the elements being iterated over.

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/struct.SetMatchesIter.html b/target/doc/regex/struct.SetMatchesIter.html new file mode 100644 index 0000000..9e9ce0c --- /dev/null +++ b/target/doc/regex/struct.SetMatchesIter.html @@ -0,0 +1,93 @@ +regex::SetMatchesIter - Rust

[][src]Struct regex::SetMatchesIter

pub struct SetMatchesIter<'a>(_);

A borrowed iterator over the set of matches from a regex set.

+

The lifetime 'a refers to the lifetime of a SetMatches value.

+

This will always produces matches in ascending order of index, where the +index corresponds to the index of the regex that matched with respect to +its position when initially building the set.

+

Trait Implementations

impl<'a> DoubleEndedIterator for SetMatchesIter<'a>[src]

fn nth_back(&mut self, n: usize) -> Option<Self::Item>[src]

🔬 This is a nightly-only experimental API. (iter_nth_back)

Returns the nth element from the end of the iterator. Read more

+

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

This is the reverse version of [try_fold()]: it takes elements starting from the back of the iterator. Read more

+

fn rfold<B, F>(self, accum: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.27.0[src]

An iterator method that reduces the iterator's elements to a single, final value, starting from the back. Read more

+

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.27.0[src]

Searches for an element of an iterator from the back that satisfies a predicate. Read more

+

impl<'a> Iterator for SetMatchesIter<'a>[src]

type Item = usize

The type of the elements being iterated over.

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

impl<'a> Clone for SetMatchesIter<'a>[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

Auto Trait Implementations

impl<'a> Send for SetMatchesIter<'a>

impl<'a> Sync for SetMatchesIter<'a>

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/struct.Split.html b/target/doc/regex/struct.Split.html new file mode 100644 index 0000000..f9e0f5a --- /dev/null +++ b/target/doc/regex/struct.Split.html @@ -0,0 +1,80 @@ +regex::Split - Rust

[][src]Struct regex::Split

pub struct Split<'r, 't> { /* fields omitted */ }

Yields all substrings delimited by a regular expression match.

+

'r is the lifetime of the compiled regular expression and 't is the +lifetime of the string being split.

+

Trait Implementations

impl<'r, 't> Iterator for Split<'r, 't>[src]

type Item = &'t str

The type of the elements being iterated over.

+

fn size_hint(&self) -> (usize, Option<usize>)1.0.0[src]

Returns the bounds on the remaining length of the iterator. Read more

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

Auto Trait Implementations

impl<'r, 't> !Send for Split<'r, 't>

impl<'r, 't> !Sync for Split<'r, 't>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/struct.SplitN.html b/target/doc/regex/struct.SplitN.html new file mode 100644 index 0000000..c26ce5b --- /dev/null +++ b/target/doc/regex/struct.SplitN.html @@ -0,0 +1,81 @@ +regex::SplitN - Rust

[][src]Struct regex::SplitN

pub struct SplitN<'r, 't> { /* fields omitted */ }

Yields at most N substrings delimited by a regular expression match.

+

The last substring will be whatever remains after splitting.

+

'r is the lifetime of the compiled regular expression and 't is the +lifetime of the string being split.

+

Trait Implementations

impl<'r, 't> Iterator for SplitN<'r, 't>[src]

type Item = &'t str

The type of the elements being iterated over.

+

fn size_hint(&self) -> (usize, Option<usize>)1.0.0[src]

Returns the bounds on the remaining length of the iterator. Read more

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

Auto Trait Implementations

impl<'r, 't> !Send for SplitN<'r, 't>

impl<'r, 't> !Sync for SplitN<'r, 't>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/struct.SubCaptureMatches.html b/target/doc/regex/struct.SubCaptureMatches.html new file mode 100644 index 0000000..93e6903 --- /dev/null +++ b/target/doc/regex/struct.SubCaptureMatches.html @@ -0,0 +1,84 @@ +regex::SubCaptureMatches - Rust

[][src]Struct regex::SubCaptureMatches

pub struct SubCaptureMatches<'c, 't: 'c> { /* fields omitted */ }

An iterator that yields all capturing matches in the order in which they +appear in the regex.

+

If a particular capture group didn't participate in the match, then None +is yielded for that capture. The first match always corresponds to the +overall match of the regex.

+

The lifetime 'c corresponds to the lifetime of the Captures value, and +the lifetime 't corresponds to the originally matched text.

+

Trait Implementations

impl<'c, 't> Iterator for SubCaptureMatches<'c, 't>[src]

type Item = Option<Match<'t>>

The type of the elements being iterated over.

+

fn size_hint(&self) -> (usize, Option<usize>)1.0.0[src]

Returns the bounds on the remaining length of the iterator. Read more

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

Auto Trait Implementations

impl<'c, 't> Send for SubCaptureMatches<'c, 't>

impl<'c, 't> Sync for SubCaptureMatches<'c, 't>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex/trait.Replacer.html b/target/doc/regex/trait.Replacer.html new file mode 100644 index 0000000..a5ea170 --- /dev/null +++ b/target/doc/regex/trait.Replacer.html @@ -0,0 +1,44 @@ +regex::Replacer - Rust

[][src]Trait regex::Replacer

pub trait Replacer {
+    fn replace_append(&mut self, caps: &Captures, dst: &mut String);
+
+    fn no_expansion<'r>(&'r mut self) -> Option<Cow<'r, str>> { ... }
+
fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self> { ... } +}

Replacer describes types that can be used to replace matches in a string.

+

In general, users of this crate shouldn't need to implement this trait, +since implementations are already provided for &str and +FnMut(&Captures) -> String (or any FnMut(&Captures) -> T +where T: AsRef<str>), which covers most use cases.

+
+

Required methods

fn replace_append(&mut self, caps: &Captures, dst: &mut String)

Appends text to dst to replace the current match.

+

The current match is represented by caps, which is guaranteed to +have a match at capture group 0.

+

For example, a no-op replacement would be +dst.extend(caps.get(0).unwrap().as_str()).

+
Loading content... +

Provided methods

fn no_expansion<'r>(&'r mut self) -> Option<Cow<'r, str>>

Return a fixed unchanging replacement string.

+

When doing replacements, if access to Captures is not needed (e.g., +the replacement byte string does not need $ expansion), then it can +be beneficial to avoid finding sub-captures.

+

In general, this is called once for every call to replacen.

+

fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self>

Return a Replacer that borrows and wraps this Replacer.

+

This is useful when you want to take a generic Replacer (which might +not be cloneable) and use it without consuming it, so it can be used +more than once.

+

Example

+
+use regex::{Regex, Replacer};
+
+fn replace_all_twice<R: Replacer>(
+    re: Regex,
+    src: &str,
+    mut rep: R,
+) -> String {
+    let dst = re.replace_all(src, rep.by_ref());
+    let dst = re.replace_all(&dst, rep.by_ref());
+    dst.into_owned()
+}
+
Loading content... +

Implementations on Foreign Types

impl<'a> Replacer for &'a str[src]

fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self>[src]

Loading content... +

Implementors

impl<'a, R: Replacer + ?Sized + 'a> Replacer for ReplacerRef<'a, R>[src]

fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self>[src]

impl<'t> Replacer for NoExpand<'t>[src]

fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self>[src]

impl<F, T> Replacer for F where
    F: FnMut(&Captures) -> T,
    T: AsRef<str>, 
[src]

fn no_expansion<'r>(&'r mut self) -> Option<Cow<'r, str>>[src]

fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self>[src]

Loading content...
\ No newline at end of file diff --git a/target/doc/regex_syntax/all.html b/target/doc/regex_syntax/all.html new file mode 100644 index 0000000..f54ecf0 --- /dev/null +++ b/target/doc/regex_syntax/all.html @@ -0,0 +1,3 @@ +List of all items in this crate

[] + + List of all items

Structs

Enums

Traits

Functions

Typedefs

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.AssertionKind.html b/target/doc/regex_syntax/ast/enum.AssertionKind.html new file mode 100644 index 0000000..fc63a55 --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.AssertionKind.html @@ -0,0 +1,36 @@ +regex_syntax::ast::AssertionKind - Rust

[][src]Enum regex_syntax::ast::AssertionKind

pub enum AssertionKind {
+    StartLine,
+    EndLine,
+    StartText,
+    EndText,
+    WordBoundary,
+    NotWordBoundary,
+}

An assertion kind.

+

+ Variants

+StartLine

^

+
EndLine

$

+
StartText

\A

+
EndText

\z

+
WordBoundary

\b

+
NotWordBoundary

\B

+

Trait Implementations

impl PartialEq<AssertionKind> for AssertionKind[src]

#[must_use] +
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests for !=.

+

impl Clone for AssertionKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for AssertionKind[src]

impl Debug for AssertionKind[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.Ast.html b/target/doc/regex_syntax/ast/enum.Ast.html new file mode 100644 index 0000000..96a2fc2 --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.Ast.html @@ -0,0 +1,61 @@ +regex_syntax::ast::Ast - Rust

[][src]Enum regex_syntax::ast::Ast

pub enum Ast {
+    Empty(Span),
+    Flags(SetFlags),
+    Literal(Literal),
+    Dot(Span),
+    Assertion(Assertion),
+    Class(Class),
+    Repetition(Repetition),
+    Group(Group),
+    Alternation(Alternation),
+    Concat(Concat),
+}

An abstract syntax tree for a single regular expression.

+

An Ast's fmt::Display implementation uses constant stack space and heap +space proportional to the size of the Ast.

+

This type defines its own destructor that uses constant stack space and +heap space proportional to the size of the Ast.

+

+ Variants

+Empty(Span)

An empty regex that matches everything.

+
Flags(SetFlags)

A set of flags, e.g., (?is).

+
Literal(Literal)

A single character literal, which includes escape sequences.

+
Dot(Span)

The "any character" class.

+
Assertion(Assertion)

A single zero-width assertion.

+
Class(Class)

A single character class. This includes all forms of character classes +except for .. e.g., \d, \pN, [a-z] and [[:alpha:]].

+
Repetition(Repetition)

A repetition operator applied to an arbitrary regular expression.

+
Group(Group)

A grouped regular expression.

+
Alternation(Alternation)

An alternation of regular expressions.

+
Concat(Concat)

A concatenation of regular expressions.

+

Methods

impl Ast[src]

pub fn span(&self) -> &Span[src]

Return the span of this abstract syntax tree.

+

pub fn is_empty(&self) -> bool[src]

Return true if and only if this Ast is empty.

+

Trait Implementations

impl PartialEq<Ast> for Ast[src]

impl Clone for Ast[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Ast[src]

impl Drop for Ast[src]

A custom Drop impl is used for Ast such that it uses constant stack +space but heap space proportional to the depth of the Ast.

+

impl Display for Ast[src]

Print a display representation of this Ast.

+

This does not preserve any of the original whitespace formatting that may +have originally been present in the concrete syntax from which this Ast +was generated.

+

This implementation uses constant stack space and heap space proportional +to the size of the Ast.

+

impl Debug for Ast[src]

Auto Trait Implementations

impl Send for Ast

impl Sync for Ast

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.Class.html b/target/doc/regex_syntax/ast/enum.Class.html new file mode 100644 index 0000000..2da1b41 --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.Class.html @@ -0,0 +1,32 @@ +regex_syntax::ast::Class - Rust

[][src]Enum regex_syntax::ast::Class

pub enum Class {
+    Unicode(ClassUnicode),
+    Perl(ClassPerl),
+    Bracketed(ClassBracketed),
+}

A single character class expression.

+

+ Variants

+Unicode(ClassUnicode)

A Unicode character class, e.g., \pL or \p{Greek}.

+
Perl(ClassPerl)

A perl character class, e.g., \d or \W.

+
Bracketed(ClassBracketed)

A bracketed character class set, which may contain zero or more +character ranges and/or zero or more nested classes. e.g., +[a-zA-Z\pL].

+

Methods

impl Class[src]

pub fn span(&self) -> &Span[src]

Return the span of this character class.

+

Trait Implementations

impl PartialEq<Class> for Class[src]

impl Clone for Class[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Class[src]

impl Debug for Class[src]

Auto Trait Implementations

impl Send for Class

impl Sync for Class

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.ClassAsciiKind.html b/target/doc/regex_syntax/ast/enum.ClassAsciiKind.html new file mode 100644 index 0000000..37b8047 --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.ClassAsciiKind.html @@ -0,0 +1,57 @@ +regex_syntax::ast::ClassAsciiKind - Rust

[][src]Enum regex_syntax::ast::ClassAsciiKind

pub enum ClassAsciiKind {
+    Alnum,
+    Alpha,
+    Ascii,
+    Blank,
+    Cntrl,
+    Digit,
+    Graph,
+    Lower,
+    Print,
+    Punct,
+    Space,
+    Upper,
+    Word,
+    Xdigit,
+}

The available ASCII character classes.

+

+ Variants

+Alnum

[0-9A-Za-z]

+
Alpha

[A-Za-z]

+
Ascii

[\x00-\x7F]

+
Blank

[ \t]

+
Cntrl

[\x00-\x1F\x7F]

+
Digit

[0-9]

+
Graph

[!-~]

+
Lower

[a-z]

+
Print

[ -~]

+
Punct

[!-/:-@\[-{-~]`

+
Space

[\t\n\v\f\r ]

+
Upper

[A-Z]

+
Word

[0-9A-Za-z_]

+
Xdigit

[0-9A-Fa-f]

+

Methods

impl ClassAsciiKind[src]

pub fn from_name(name: &str) -> Option<ClassAsciiKind>[src]

Return the corresponding ClassAsciiKind variant for the given name.

+

The name given should correspond to the lowercase version of the +variant name. e.g., cntrl is the name for ClassAsciiKind::Cntrl.

+

If no variant with the corresponding name exists, then None is +returned.

+

Trait Implementations

impl PartialEq<ClassAsciiKind> for ClassAsciiKind[src]

#[must_use] +
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests for !=.

+

impl Clone for ClassAsciiKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for ClassAsciiKind[src]

impl Debug for ClassAsciiKind[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.ClassPerlKind.html b/target/doc/regex_syntax/ast/enum.ClassPerlKind.html new file mode 100644 index 0000000..a263500 --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.ClassPerlKind.html @@ -0,0 +1,30 @@ +regex_syntax::ast::ClassPerlKind - Rust

[][src]Enum regex_syntax::ast::ClassPerlKind

pub enum ClassPerlKind {
+    Digit,
+    Space,
+    Word,
+}

The available Perl character classes.

+

+ Variants

+Digit

Decimal numbers.

+
Space

Whitespace.

+
Word

Word characters.

+

Trait Implementations

impl PartialEq<ClassPerlKind> for ClassPerlKind[src]

#[must_use] +
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests for !=.

+

impl Clone for ClassPerlKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for ClassPerlKind[src]

impl Debug for ClassPerlKind[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.ClassSet.html b/target/doc/regex_syntax/ast/enum.ClassSet.html new file mode 100644 index 0000000..383a528 --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.ClassSet.html @@ -0,0 +1,37 @@ +regex_syntax::ast::ClassSet - Rust

[][src]Enum regex_syntax::ast::ClassSet

pub enum ClassSet {
+    Item(ClassSetItem),
+    BinaryOp(ClassSetBinaryOp),
+}

A character class set.

+

This type corresponds to the internal structure of a bracketed character +class. That is, every bracketed character is one of two types: a union of +items (literals, ranges, other bracketed classes) or a tree of binary set +operations.

+

+ Variants

+Item(ClassSetItem)

An item, which can be a single literal, range, nested character class +or a union of items.

+
BinaryOp(ClassSetBinaryOp)

A single binary operation (i.e., &&, -- or ~~).

+

Methods

impl ClassSet[src]

pub fn union(ast: ClassSetUnion) -> ClassSet[src]

Build a set from a union.

+

pub fn span(&self) -> &Span[src]

Return the span of this character class set.

+

Trait Implementations

impl PartialEq<ClassSet> for ClassSet[src]

impl Clone for ClassSet[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for ClassSet[src]

impl Drop for ClassSet[src]

A custom Drop impl is used for ClassSet such that it uses constant +stack space but heap space proportional to the depth of the ClassSet.

+

impl Debug for ClassSet[src]

Auto Trait Implementations

impl Send for ClassSet

impl Sync for ClassSet

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.ClassSetBinaryOpKind.html b/target/doc/regex_syntax/ast/enum.ClassSetBinaryOpKind.html new file mode 100644 index 0000000..9ac6b03 --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.ClassSetBinaryOpKind.html @@ -0,0 +1,35 @@ +regex_syntax::ast::ClassSetBinaryOpKind - Rust

[][src]Enum regex_syntax::ast::ClassSetBinaryOpKind

pub enum ClassSetBinaryOpKind {
+    Intersection,
+    Difference,
+    SymmetricDifference,
+}

The type of a Unicode character class set operation.

+

Note that this doesn't explicitly represent union since there is no +explicit union operator. Concatenation inside a character class corresponds +to the union operation.

+

+ Variants

+Intersection

The intersection of two sets, e.g., \pN&&[a-z].

+
Difference

The difference of two sets, e.g., \pN--[0-9].

+
SymmetricDifference

The symmetric difference of two sets. The symmetric difference is the +set of elements belonging to one but not both sets. +e.g., [\pL~~[:ascii:]].

+

Trait Implementations

impl PartialEq<ClassSetBinaryOpKind> for ClassSetBinaryOpKind[src]

#[must_use] +
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests for !=.

+

impl Clone for ClassSetBinaryOpKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for ClassSetBinaryOpKind[src]

impl Copy for ClassSetBinaryOpKind[src]

impl Debug for ClassSetBinaryOpKind[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.ClassSetItem.html b/target/doc/regex_syntax/ast/enum.ClassSetItem.html new file mode 100644 index 0000000..661363a --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.ClassSetItem.html @@ -0,0 +1,45 @@ +regex_syntax::ast::ClassSetItem - Rust

[][src]Enum regex_syntax::ast::ClassSetItem

pub enum ClassSetItem {
+    Empty(Span),
+    Literal(Literal),
+    Range(ClassSetRange),
+    Ascii(ClassAscii),
+    Unicode(ClassUnicode),
+    Perl(ClassPerl),
+    Bracketed(Box<ClassBracketed>),
+    Union(ClassSetUnion),
+}

A single component of a character class set.

+

+ Variants

+Empty(Span)

An empty item.

+

Note that a bracketed character class cannot contain a single empty +item. Empty items can appear when using one of the binary operators. +For example, [&&] is the intersection of two empty classes.

+
Literal(Literal)

A single literal.

+
Range(ClassSetRange)

A range between two literals.

+
Ascii(ClassAscii)

An ASCII character class, e.g., [:alnum:] or [:punct:].

+
Unicode(ClassUnicode)

A Unicode character class, e.g., \pL or \p{Greek}.

+
Perl(ClassPerl)

A perl character class, e.g., \d or \W.

+
Bracketed(Box<ClassBracketed>)

A bracketed character class set, which may contain zero or more +character ranges and/or zero or more nested classes. e.g., +[a-zA-Z\pL].

+
Union(ClassSetUnion)

A union of items.

+

Methods

impl ClassSetItem[src]

pub fn span(&self) -> &Span[src]

Return the span of this character class set item.

+

Trait Implementations

impl PartialEq<ClassSetItem> for ClassSetItem[src]

impl Clone for ClassSetItem[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for ClassSetItem[src]

impl Debug for ClassSetItem[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.ClassUnicodeKind.html b/target/doc/regex_syntax/ast/enum.ClassUnicodeKind.html new file mode 100644 index 0000000..63329ce --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.ClassUnicodeKind.html @@ -0,0 +1,37 @@ +regex_syntax::ast::ClassUnicodeKind - Rust

[][src]Enum regex_syntax::ast::ClassUnicodeKind

pub enum ClassUnicodeKind {
+    OneLetter(char),
+    Named(String),
+    NamedValue {
+        op: ClassUnicodeOpKind,
+        name: String,
+        value: String,
+    },
+}

The available forms of Unicode character classes.

+

+ Variants

+OneLetter(char)

A one letter abbreviated class, e.g., \pN.

+
Named(String)

A binary property, general category or script. The string may be +empty.

+
NamedValue

A property name and an associated value.

+

Fields of NamedValue

op: ClassUnicodeOpKind

The type of Unicode op used to associate name with value.

+
name: String

The property name (which may be empty).

+
value: String

The property value (which may be empty).

+

Trait Implementations

impl PartialEq<ClassUnicodeKind> for ClassUnicodeKind[src]

impl Clone for ClassUnicodeKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for ClassUnicodeKind[src]

impl Debug for ClassUnicodeKind[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.ClassUnicodeOpKind.html b/target/doc/regex_syntax/ast/enum.ClassUnicodeOpKind.html new file mode 100644 index 0000000..91a6187 --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.ClassUnicodeOpKind.html @@ -0,0 +1,32 @@ +regex_syntax::ast::ClassUnicodeOpKind - Rust

[][src]Enum regex_syntax::ast::ClassUnicodeOpKind

pub enum ClassUnicodeOpKind {
+    Equal,
+    Colon,
+    NotEqual,
+}

The type of op used in a Unicode character class.

+

+ Variants

+Equal

A property set to a specific value, e.g., \p{scx=Katakana}.

+
Colon

A property set to a specific value using a colon, e.g., +\p{scx:Katakana}.

+
NotEqual

A property that isn't a particular value, e.g., \p{scx!=Katakana}.

+

Methods

impl ClassUnicodeOpKind[src]

pub fn is_equal(&self) -> bool[src]

Whether the op is an equality op or not.

+

Trait Implementations

impl PartialEq<ClassUnicodeOpKind> for ClassUnicodeOpKind[src]

#[must_use] +
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests for !=.

+

impl Clone for ClassUnicodeOpKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for ClassUnicodeOpKind[src]

impl Debug for ClassUnicodeOpKind[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.ErrorKind.html b/target/doc/regex_syntax/ast/enum.ErrorKind.html new file mode 100644 index 0000000..a9d7a32 --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.ErrorKind.html @@ -0,0 +1,123 @@ +regex_syntax::ast::ErrorKind - Rust

[][src]Enum regex_syntax::ast::ErrorKind

pub enum ErrorKind {
+    CaptureLimitExceeded,
+    ClassEscapeInvalid,
+    ClassRangeInvalid,
+    ClassRangeLiteral,
+    ClassUnclosed,
+    DecimalEmpty,
+    DecimalInvalid,
+    EscapeHexEmpty,
+    EscapeHexInvalid,
+    EscapeHexInvalidDigit,
+    EscapeUnexpectedEof,
+    EscapeUnrecognized,
+    FlagDanglingNegation,
+    FlagDuplicate {
+        original: Span,
+    },
+    FlagRepeatedNegation {
+        original: Span,
+    },
+    FlagUnexpectedEof,
+    FlagUnrecognized,
+    GroupNameDuplicate {
+        original: Span,
+    },
+    GroupNameEmpty,
+    GroupNameInvalid,
+    GroupNameUnexpectedEof,
+    GroupUnclosed,
+    GroupUnopened,
+    NestLimitExceeded(u32),
+    RepetitionCountInvalid,
+    RepetitionCountDecimalEmpty,
+    RepetitionCountUnclosed,
+    RepetitionMissing,
+    UnsupportedBackreference,
+    UnsupportedLookAround,
+    // some variants omitted
+}

The type of an error that occurred while building an AST.

+

+ Variants

+CaptureLimitExceeded

The capturing group limit was exceeded.

+

Note that this represents a limit on the total number of capturing +groups in a regex and not necessarily the number of nested capturing +groups. That is, the nest limit can be low and it is still possible for +this error to occur.

+
ClassEscapeInvalid

An invalid escape sequence was found in a character class set.

+
ClassRangeInvalid

An invalid character class range was found. An invalid range is any +range where the start is greater than the end.

+
ClassRangeLiteral

An invalid range boundary was found in a character class. Range +boundaries must be a single literal codepoint, but this error indicates +that something else was found, such as a nested class.

+
ClassUnclosed

An opening [ was found with no corresponding closing ].

+
DecimalEmpty

Note that this error variant is no longer used. Namely, a decimal +number can only appear as a repetition quantifier. When the number +in a repetition quantifier is empty, then it gets its own specialized +error, RepetitionCountDecimalEmpty.

+
DecimalInvalid

An invalid decimal number was given where one was expected.

+
EscapeHexEmpty

A bracketed hex literal was empty.

+
EscapeHexInvalid

A bracketed hex literal did not correspond to a Unicode scalar value.

+
EscapeHexInvalidDigit

An invalid hexadecimal digit was found.

+
EscapeUnexpectedEof

EOF was found before an escape sequence was completed.

+
EscapeUnrecognized

An unrecognized escape sequence.

+
FlagDanglingNegation

A dangling negation was used when setting flags, e.g., i-.

+
FlagDuplicate

A flag was used twice, e.g., i-i.

+

Fields of FlagDuplicate

original: Span

The position of the original flag. The error position +points to the duplicate flag.

+
FlagRepeatedNegation

The negation operator was used twice, e.g., -i-s.

+

Fields of FlagRepeatedNegation

original: Span

The position of the original negation operator. The error position +points to the duplicate negation operator.

+
FlagUnexpectedEof

Expected a flag but got EOF, e.g., (?.

+
FlagUnrecognized

Unrecognized flag, e.g., a.

+
GroupNameDuplicate

A duplicate capture name was found.

+

Fields of GroupNameDuplicate

original: Span

The position of the initial occurrence of the capture name. The +error position itself points to the duplicate occurrence.

+
GroupNameEmpty

A capture group name is empty, e.g., (?P<>abc).

+
GroupNameInvalid

An invalid character was seen for a capture group name. This includes +errors where the first character is a digit (even though subsequent +characters are allowed to be digits).

+
GroupNameUnexpectedEof

A closing > could not be found for a capture group name.

+
GroupUnclosed

An unclosed group, e.g., (ab.

+

The span of this error corresponds to the unclosed parenthesis.

+
GroupUnopened

An unopened group, e.g., ab).

+
NestLimitExceeded(u32)

The nest limit was exceeded. The limit stored here is the limit +configured in the parser.

+
RepetitionCountInvalid

The range provided in a counted repetition operator is invalid. The +range is invalid if the start is greater than the end.

+
RepetitionCountDecimalEmpty

An opening { was not followed by a valid decimal value. +For example, x{} or x{]} would fail.

+
RepetitionCountUnclosed

An opening { was found with no corresponding closing }.

+
RepetitionMissing

A repetition operator was applied to a missing sub-expression. This +occurs, for example, in the regex consisting of just a * or even +(?i)*. It is, however, possible to create a repetition operating on +an empty sub-expression. For example, ()* is still considered valid.

+
UnsupportedBackreference

When octal support is disabled, this error is produced when an octal +escape is used. The octal escape is assumed to be an invocation of +a backreference, which is the common case.

+
UnsupportedLookAround

When syntax similar to PCRE's look-around is used, this error is +returned. Some example syntaxes that are rejected include, but are +not necessarily limited to, (?=re), (?!re), (?<=re) and +(?<!re). Note that all of these syntaxes are otherwise invalid; this +error is used to improve the user experience.

+

Trait Implementations

impl PartialEq<ErrorKind> for ErrorKind[src]

impl Clone for ErrorKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for ErrorKind[src]

impl Display for ErrorKind[src]

impl Debug for ErrorKind[src]

Auto Trait Implementations

impl Send for ErrorKind

impl Sync for ErrorKind

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.Flag.html b/target/doc/regex_syntax/ast/enum.Flag.html new file mode 100644 index 0000000..d07fd52 --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.Flag.html @@ -0,0 +1,36 @@ +regex_syntax::ast::Flag - Rust

[][src]Enum regex_syntax::ast::Flag

pub enum Flag {
+    CaseInsensitive,
+    MultiLine,
+    DotMatchesNewLine,
+    SwapGreed,
+    Unicode,
+    IgnoreWhitespace,
+}

A single flag.

+

+ Variants

+CaseInsensitive

i

+
MultiLine

m

+
DotMatchesNewLine

s

+
SwapGreed

U

+
Unicode

u

+
IgnoreWhitespace

x

+

Trait Implementations

impl PartialEq<Flag> for Flag[src]

#[must_use] +
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests for !=.

+

impl Clone for Flag[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Flag[src]

impl Copy for Flag[src]

impl Debug for Flag[src]

Auto Trait Implementations

impl Send for Flag

impl Sync for Flag

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.FlagsItemKind.html b/target/doc/regex_syntax/ast/enum.FlagsItemKind.html new file mode 100644 index 0000000..4fddbe9 --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.FlagsItemKind.html @@ -0,0 +1,29 @@ +regex_syntax::ast::FlagsItemKind - Rust

[][src]Enum regex_syntax::ast::FlagsItemKind

pub enum FlagsItemKind {
+    Negation,
+    Flag(Flag),
+}

The kind of an item in a group of flags.

+

+ Variants

+Negation

A negation operator applied to all subsequent flags in the enclosing +group.

+
Flag(Flag)

A single flag in a group.

+

Methods

impl FlagsItemKind[src]

pub fn is_negation(&self) -> bool[src]

Returns true if and only if this item is a negation operator.

+

Trait Implementations

impl PartialEq<FlagsItemKind> for FlagsItemKind[src]

impl Clone for FlagsItemKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for FlagsItemKind[src]

impl Debug for FlagsItemKind[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.GroupKind.html b/target/doc/regex_syntax/ast/enum.GroupKind.html new file mode 100644 index 0000000..29a6781 --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.GroupKind.html @@ -0,0 +1,29 @@ +regex_syntax::ast::GroupKind - Rust

[][src]Enum regex_syntax::ast::GroupKind

pub enum GroupKind {
+    CaptureIndex(u32),
+    CaptureName(CaptureName),
+    NonCapturing(Flags),
+}

The kind of a group.

+

+ Variants

+CaptureIndex(u32)

(a)

+
CaptureName(CaptureName)

(?P<name>a)

+
NonCapturing(Flags)

(?:a) and (?i:a)

+

Trait Implementations

impl PartialEq<GroupKind> for GroupKind[src]

impl Clone for GroupKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for GroupKind[src]

impl Debug for GroupKind[src]

Auto Trait Implementations

impl Send for GroupKind

impl Sync for GroupKind

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.HexLiteralKind.html b/target/doc/regex_syntax/ast/enum.HexLiteralKind.html new file mode 100644 index 0000000..00ec8db --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.HexLiteralKind.html @@ -0,0 +1,39 @@ +regex_syntax::ast::HexLiteralKind - Rust

[][src]Enum regex_syntax::ast::HexLiteralKind

pub enum HexLiteralKind {
+    X,
+    UnicodeShort,
+    UnicodeLong,
+}

The type of a Unicode hex literal.

+

Note that all variants behave the same when used with brackets. They only +differ when used without brackets in the number of hex digits that must +follow.

+

+ Variants

+X

A \x prefix. When used without brackets, this form is limited to +two digits.

+
UnicodeShort

A \u prefix. When used without brackets, this form is limited to +four digits.

+
UnicodeLong

A \U prefix. When used without brackets, this form is limited to +eight digits.

+

Methods

impl HexLiteralKind[src]

pub fn digits(&self) -> u32[src]

The number of digits that must be used with this literal form when +used without brackets. When used with brackets, there is no +restriction on the number of digits.

+

Trait Implementations

impl PartialEq<HexLiteralKind> for HexLiteralKind[src]

#[must_use] +
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests for !=.

+

impl Clone for HexLiteralKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for HexLiteralKind[src]

impl Debug for HexLiteralKind[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.LiteralKind.html b/target/doc/regex_syntax/ast/enum.LiteralKind.html new file mode 100644 index 0000000..2df92ce --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.LiteralKind.html @@ -0,0 +1,41 @@ +regex_syntax::ast::LiteralKind - Rust

[][src]Enum regex_syntax::ast::LiteralKind

pub enum LiteralKind {
+    Verbatim,
+    Punctuation,
+    Octal,
+    HexFixed(HexLiteralKind),
+    HexBrace(HexLiteralKind),
+    Special(SpecialLiteralKind),
+}

The kind of a single literal expression.

+

+ Variants

+Verbatim

The literal is written verbatim, e.g., a or .

+
Punctuation

The literal is written as an escape because it is punctuation, e.g., +* or [.

+
Octal

The literal is written as an octal escape, e.g., \141.

+
HexFixed(HexLiteralKind)

The literal is written as a hex code with a fixed number of digits +depending on the type of the escape, e.g., \x61 or or \u0061 or +\U00000061.

+
HexBrace(HexLiteralKind)

The literal is written as a hex code with a bracketed number of +digits. The only restriction is that the bracketed hex code must refer +to a valid Unicode scalar value.

+
Special(SpecialLiteralKind)

The literal is written as a specially recognized escape, e.g., \f +or \n.

+

Trait Implementations

impl PartialEq<LiteralKind> for LiteralKind[src]

impl Clone for LiteralKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for LiteralKind[src]

impl Debug for LiteralKind[src]

Auto Trait Implementations

impl Send for LiteralKind

impl Sync for LiteralKind

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.RepetitionKind.html b/target/doc/regex_syntax/ast/enum.RepetitionKind.html new file mode 100644 index 0000000..af86d61 --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.RepetitionKind.html @@ -0,0 +1,31 @@ +regex_syntax::ast::RepetitionKind - Rust

[][src]Enum regex_syntax::ast::RepetitionKind

pub enum RepetitionKind {
+    ZeroOrOne,
+    ZeroOrMore,
+    OneOrMore,
+    Range(RepetitionRange),
+}

The kind of a repetition operator.

+

+ Variants

+ZeroOrOne

?

+
ZeroOrMore

*

+
OneOrMore

+

+
Range(RepetitionRange)

{m,n}

+

Trait Implementations

impl PartialEq<RepetitionKind> for RepetitionKind[src]

impl Clone for RepetitionKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for RepetitionKind[src]

impl Debug for RepetitionKind[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.RepetitionRange.html b/target/doc/regex_syntax/ast/enum.RepetitionRange.html new file mode 100644 index 0000000..41409e4 --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.RepetitionRange.html @@ -0,0 +1,32 @@ +regex_syntax::ast::RepetitionRange - Rust

[][src]Enum regex_syntax::ast::RepetitionRange

pub enum RepetitionRange {
+    Exactly(u32),
+    AtLeast(u32),
+    Bounded(u32u32),
+}

A range repetition operator.

+

+ Variants

+Exactly(u32)

{m}

+
AtLeast(u32)

{m,}

+
Bounded(u32u32)

{m,n}

+

Methods

impl RepetitionRange[src]

pub fn is_valid(&self) -> bool[src]

Returns true if and only if this repetition range is valid.

+

The only case where a repetition range is invalid is if it is bounded +and its start is greater than its end.

+

Trait Implementations

impl PartialEq<RepetitionRange> for RepetitionRange[src]

impl Clone for RepetitionRange[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for RepetitionRange[src]

impl Debug for RepetitionRange[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/enum.SpecialLiteralKind.html b/target/doc/regex_syntax/ast/enum.SpecialLiteralKind.html new file mode 100644 index 0000000..9719540 --- /dev/null +++ b/target/doc/regex_syntax/ast/enum.SpecialLiteralKind.html @@ -0,0 +1,41 @@ +regex_syntax::ast::SpecialLiteralKind - Rust

[][src]Enum regex_syntax::ast::SpecialLiteralKind

pub enum SpecialLiteralKind {
+    Bell,
+    FormFeed,
+    Tab,
+    LineFeed,
+    CarriageReturn,
+    VerticalTab,
+    Space,
+}

The type of a special literal.

+

A special literal is a special escape sequence recognized by the regex +parser, e.g., \f or \n.

+

+ Variants

+Bell

Bell, spelled \a (\x07).

+
FormFeed

Form feed, spelled \f (\x0C).

+
Tab

Tab, spelled \t (\x09).

+
LineFeed

Line feed, spelled \n (\x0A).

+
CarriageReturn

Carriage return, spelled \r (\x0D).

+
VerticalTab

Vertical tab, spelled \v (\x0B).

+
Space

Space, spelled \ (\x20). Note that this can only appear when +parsing in verbose mode.

+

Trait Implementations

impl PartialEq<SpecialLiteralKind> for SpecialLiteralKind[src]

#[must_use] +
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests for !=.

+

impl Clone for SpecialLiteralKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for SpecialLiteralKind[src]

impl Debug for SpecialLiteralKind[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/fn.visit.html b/target/doc/regex_syntax/ast/fn.visit.html new file mode 100644 index 0000000..c7f9beb --- /dev/null +++ b/target/doc/regex_syntax/ast/fn.visit.html @@ -0,0 +1,13 @@ +regex_syntax::ast::visit - Rust

[][src]Function regex_syntax::ast::visit

pub fn visit<V: Visitor>(ast: &Ast, visitor: V) -> Result<V::Output, V::Err>

Executes an implementation of Visitor in constant stack space.

+

This function will visit every node in the given Ast while calling the +appropriate methods provided by the +Visitor trait.

+

The primary use case for this method is when one wants to perform case +analysis over an Ast without using a stack size proportional to the depth +of the Ast. Namely, this method will instead use constant stack size, but +will use heap space proportional to the size of the Ast. This may be +desirable in cases where the size of Ast is proportional to end user +input.

+

If the visitor returns an error at any point, then visiting is stopped and +the error is returned.

+
\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/index.html b/target/doc/regex_syntax/ast/index.html new file mode 100644 index 0000000..07639a8 --- /dev/null +++ b/target/doc/regex_syntax/ast/index.html @@ -0,0 +1,55 @@ +regex_syntax::ast - Rust

[][src]Module regex_syntax::ast

Defines an abstract syntax for regular expressions.

+

Modules

+
parse

This module provides a regular expression parser.

+
print

This module provides a regular expression printer for Ast.

+

Structs

+
Alternation

An alternation of regular expressions.

+
Assertion

A single zero-width assertion.

+
CaptureName

A capture name.

+
ClassAscii

An ASCII character class.

+
ClassBracketed

A bracketed character class, e.g., [a-z0-9].

+
ClassPerl

A Perl character class.

+
ClassSetBinaryOp

A Unicode character class set operation.

+
ClassSetRange

A single character class range in a set.

+
ClassSetUnion

A union of items inside a character class set.

+
ClassUnicode

A Unicode character class.

+
Comment

A comment from a regular expression with an associated span.

+
Concat

A concatenation of regular expressions.

+
Error

An error that occurred while parsing a regular expression into an abstract +syntax tree.

+
Flags

A group of flags.

+
FlagsItem

A single item in a group of flags.

+
Group

A grouped regular expression.

+
Literal

A single literal expression.

+
Position

A single position in a regular expression.

+
Repetition

A repetition operation applied to a regular expression.

+
RepetitionOp

The repetition operator itself.

+
SetFlags

A group of flags that is not applied to a particular regular expression.

+
Span

Span represents the position information of a single AST item.

+
WithComments

An abstract syntax tree for a singular expression along with comments +found.

+

Enums

+
AssertionKind

An assertion kind.

+
Ast

An abstract syntax tree for a single regular expression.

+
Class

A single character class expression.

+
ClassAsciiKind

The available ASCII character classes.

+
ClassPerlKind

The available Perl character classes.

+
ClassSet

A character class set.

+
ClassSetBinaryOpKind

The type of a Unicode character class set operation.

+
ClassSetItem

A single component of a character class set.

+
ClassUnicodeKind

The available forms of Unicode character classes.

+
ClassUnicodeOpKind

The type of op used in a Unicode character class.

+
ErrorKind

The type of an error that occurred while building an AST.

+
Flag

A single flag.

+
FlagsItemKind

The kind of an item in a group of flags.

+
GroupKind

The kind of a group.

+
HexLiteralKind

The type of a Unicode hex literal.

+
LiteralKind

The kind of a single literal expression.

+
RepetitionKind

The kind of a repetition operator.

+
RepetitionRange

A range repetition operator.

+
SpecialLiteralKind

The type of a special literal.

+

Traits

+
Visitor

A trait for visiting an abstract syntax tree (AST) in depth first order.

+

Functions

+
visit

Executes an implementation of Visitor in constant stack space.

+
\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/parse/index.html b/target/doc/regex_syntax/ast/parse/index.html new file mode 100644 index 0000000..abda522 --- /dev/null +++ b/target/doc/regex_syntax/ast/parse/index.html @@ -0,0 +1,5 @@ +regex_syntax::ast::parse - Rust

[][src]Module regex_syntax::ast::parse

This module provides a regular expression parser.

+

Structs

+
Parser

A regular expression parser.

+
ParserBuilder

A builder for a regular expression parser.

+
\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/parse/sidebar-items.js b/target/doc/regex_syntax/ast/parse/sidebar-items.js new file mode 100644 index 0000000..d779309 --- /dev/null +++ b/target/doc/regex_syntax/ast/parse/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["Parser","A regular expression parser."],["ParserBuilder","A builder for a regular expression parser."]]}); \ No newline at end of file diff --git a/target/doc/regex_syntax/ast/parse/struct.Parser.html b/target/doc/regex_syntax/ast/parse/struct.Parser.html new file mode 100644 index 0000000..9e437c6 --- /dev/null +++ b/target/doc/regex_syntax/ast/parse/struct.Parser.html @@ -0,0 +1,31 @@ +regex_syntax::ast::parse::Parser - Rust

[][src]Struct regex_syntax::ast::parse::Parser

pub struct Parser { /* fields omitted */ }

A regular expression parser.

+

This parses a string representation of a regular expression into an +abstract syntax tree. The size of the tree is proportional to the length +of the regular expression pattern.

+

A Parser can be configured in more detail via a +ParserBuilder.

+

Methods

impl Parser[src]

pub fn new() -> Parser[src]

Create a new parser with a default configuration.

+

The parser can be run with either the parse or parse_with_comments +methods. The parse methods return an abstract syntax tree.

+

To set configuration options on the parser, use +ParserBuilder.

+

pub fn parse(&mut self, pattern: &str) -> Result<Ast, Error>[src]

Parse the regular expression into an abstract syntax tree.

+

pub fn parse_with_comments(
    &mut self,
    pattern: &str
) -> Result<WithComments, Error>
[src]

Parse the regular expression and return an abstract syntax tree with +all of the comments found in the pattern.

+

Trait Implementations

impl Clone for Parser[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Debug for Parser[src]

Auto Trait Implementations

impl Send for Parser

impl !Sync for Parser

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/parse/struct.ParserBuilder.html b/target/doc/regex_syntax/ast/parse/struct.ParserBuilder.html new file mode 100644 index 0000000..9d9abe2 --- /dev/null +++ b/target/doc/regex_syntax/ast/parse/struct.ParserBuilder.html @@ -0,0 +1,61 @@ +regex_syntax::ast::parse::ParserBuilder - Rust

[][src]Struct regex_syntax::ast::parse::ParserBuilder

pub struct ParserBuilder { /* fields omitted */ }

A builder for a regular expression parser.

+

This builder permits modifying configuration options for the parser.

+

Methods

impl ParserBuilder[src]

pub fn new() -> ParserBuilder[src]

Create a new parser builder with a default configuration.

+

pub fn build(&self) -> Parser[src]

Build a parser from this configuration with the given pattern.

+

pub fn nest_limit(&mut self, limit: u32) -> &mut ParserBuilder[src]

Set the nesting limit for this parser.

+

The nesting limit controls how deep the abstract syntax tree is allowed +to be. If the AST exceeds the given limit (e.g., with too many nested +groups), then an error is returned by the parser.

+

The purpose of this limit is to act as a heuristic to prevent stack +overflow for consumers that do structural induction on an Ast using +explicit recursion. While this crate never does this (instead using +constant stack space and moving the call stack to the heap), other +crates may.

+

This limit is not checked until the entire Ast is parsed. Therefore, +if callers want to put a limit on the amount of heap space used, then +they should impose a limit on the length, in bytes, of the concrete +pattern string. In particular, this is viable since this parser +implementation will limit itself to heap space proportional to the +lenth of the pattern string.

+

Note that a nest limit of 0 will return a nest limit error for most +patterns but not all. For example, a nest limit of 0 permits a but +not ab, since ab requires a concatenation, which results in a nest +depth of 1. In general, a nest limit is not something that manifests +in an obvious way in the concrete syntax, therefore, it should not be +used in a granular way.

+

pub fn octal(&mut self, yes: bool) -> &mut ParserBuilder[src]

Whether to support octal syntax or not.

+

Octal syntax is a little-known way of uttering Unicode codepoints in +a regular expression. For example, a, \x61, \u0061 and +\141 are all equivalent regular expressions, where the last example +shows octal syntax.

+

While supporting octal syntax isn't in and of itself a problem, it does +make good error messages harder. That is, in PCRE based regex engines, +syntax like \0 invokes a backreference, which is explicitly +unsupported in Rust's regex engine. However, many users expect it to +be supported. Therefore, when octal support is disabled, the error +message will explicitly mention that backreferences aren't supported.

+

Octal syntax is disabled by default.

+

pub fn ignore_whitespace(&mut self, yes: bool) -> &mut ParserBuilder[src]

Enable verbose mode in the regular expression.

+

When enabled, verbose mode permits insigificant whitespace in many +places in the regular expression, as well as comments. Comments are +started using # and continue until the end of the line.

+

By default, this is disabled. It may be selectively enabled in the +regular expression by using the x flag regardless of this setting.

+

Trait Implementations

impl Clone for ParserBuilder[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Default for ParserBuilder[src]

impl Debug for ParserBuilder[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/print/index.html b/target/doc/regex_syntax/ast/print/index.html new file mode 100644 index 0000000..90cdd7d --- /dev/null +++ b/target/doc/regex_syntax/ast/print/index.html @@ -0,0 +1,4 @@ +regex_syntax::ast::print - Rust

[][src]Module regex_syntax::ast::print

This module provides a regular expression printer for Ast.

+

Structs

+
Printer

A printer for a regular expression abstract syntax tree.

+
\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/print/sidebar-items.js b/target/doc/regex_syntax/ast/print/sidebar-items.js new file mode 100644 index 0000000..ff36f31 --- /dev/null +++ b/target/doc/regex_syntax/ast/print/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["Printer","A printer for a regular expression abstract syntax tree."]]}); \ No newline at end of file diff --git a/target/doc/regex_syntax/ast/print/struct.Printer.html b/target/doc/regex_syntax/ast/print/struct.Printer.html new file mode 100644 index 0000000..e0ca704 --- /dev/null +++ b/target/doc/regex_syntax/ast/print/struct.Printer.html @@ -0,0 +1,23 @@ +regex_syntax::ast::print::Printer - Rust

[][src]Struct regex_syntax::ast::print::Printer

pub struct Printer { /* fields omitted */ }

A printer for a regular expression abstract syntax tree.

+

A printer converts an abstract syntax tree (AST) to a regular expression +pattern string. This particular printer uses constant stack space and heap +space proportional to the size of the AST.

+

This printer will not necessarily preserve the original formatting of the +regular expression pattern string. For example, all whitespace and comments +are ignored.

+

Methods

impl Printer[src]

pub fn new() -> Printer[src]

Create a new printer.

+

pub fn print<W: Write>(&mut self, ast: &Ast, wtr: W) -> Result[src]

Print the given Ast to the given writer. The writer must implement +fmt::Write. Typical implementations of fmt::Write that can be used +here are a fmt::Formatter (which is available in fmt::Display +implementations) or a &mut String.

+

Trait Implementations

impl Debug for Printer[src]

Auto Trait Implementations

impl Send for Printer

impl Sync for Printer

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/sidebar-items.js b/target/doc/regex_syntax/ast/sidebar-items.js new file mode 100644 index 0000000..696ba7a --- /dev/null +++ b/target/doc/regex_syntax/ast/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"enum":[["AssertionKind","An assertion kind."],["Ast","An abstract syntax tree for a single regular expression."],["Class","A single character class expression."],["ClassAsciiKind","The available ASCII character classes."],["ClassPerlKind","The available Perl character classes."],["ClassSet","A character class set."],["ClassSetBinaryOpKind","The type of a Unicode character class set operation."],["ClassSetItem","A single component of a character class set."],["ClassUnicodeKind","The available forms of Unicode character classes."],["ClassUnicodeOpKind","The type of op used in a Unicode character class."],["ErrorKind","The type of an error that occurred while building an AST."],["Flag","A single flag."],["FlagsItemKind","The kind of an item in a group of flags."],["GroupKind","The kind of a group."],["HexLiteralKind","The type of a Unicode hex literal."],["LiteralKind","The kind of a single literal expression."],["RepetitionKind","The kind of a repetition operator."],["RepetitionRange","A range repetition operator."],["SpecialLiteralKind","The type of a special literal."]],"fn":[["visit","Executes an implementation of `Visitor` in constant stack space."]],"mod":[["parse","This module provides a regular expression parser."],["print","This module provides a regular expression printer for `Ast`."]],"struct":[["Alternation","An alternation of regular expressions."],["Assertion","A single zero-width assertion."],["CaptureName","A capture name."],["ClassAscii","An ASCII character class."],["ClassBracketed","A bracketed character class, e.g., `[a-z0-9]`."],["ClassPerl","A Perl character class."],["ClassSetBinaryOp","A Unicode character class set operation."],["ClassSetRange","A single character class range in a set."],["ClassSetUnion","A union of items inside a character class set."],["ClassUnicode","A Unicode character class."],["Comment","A comment from a regular expression with an associated span."],["Concat","A concatenation of regular expressions."],["Error","An error that occurred while parsing a regular expression into an abstract syntax tree."],["Flags","A group of flags."],["FlagsItem","A single item in a group of flags."],["Group","A grouped regular expression."],["Literal","A single literal expression."],["Position","A single position in a regular expression."],["Repetition","A repetition operation applied to a regular expression."],["RepetitionOp","The repetition operator itself."],["SetFlags","A group of flags that is not applied to a particular regular expression."],["Span","Span represents the position information of a single AST item."],["WithComments","An abstract syntax tree for a singular expression along with comments found."]],"trait":[["Visitor","A trait for visiting an abstract syntax tree (AST) in depth first order."]]}); \ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.Alternation.html b/target/doc/regex_syntax/ast/struct.Alternation.html new file mode 100644 index 0000000..0b5b77e --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.Alternation.html @@ -0,0 +1,30 @@ +regex_syntax::ast::Alternation - Rust

[][src]Struct regex_syntax::ast::Alternation

pub struct Alternation {
+    pub span: Span,
+    pub asts: Vec<Ast>,
+}

An alternation of regular expressions.

+

+ Fields

span: Span

The span of this alternation.

+
asts: Vec<Ast>

The alternate regular expressions.

+

Methods

impl Alternation[src]

pub fn into_ast(self) -> Ast[src]

Return this alternation as an AST.

+

If this alternation contains zero ASTs, then Ast::Empty is +returned. If this alternation contains exactly 1 AST, then the +corresponding AST is returned. Otherwise, Ast::Alternation is returned.

+

Trait Implementations

impl PartialEq<Alternation> for Alternation[src]

impl Clone for Alternation[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Alternation[src]

impl Debug for Alternation[src]

Auto Trait Implementations

impl Send for Alternation

impl Sync for Alternation

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.Assertion.html b/target/doc/regex_syntax/ast/struct.Assertion.html new file mode 100644 index 0000000..5419618 --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.Assertion.html @@ -0,0 +1,26 @@ +regex_syntax::ast::Assertion - Rust

[][src]Struct regex_syntax::ast::Assertion

pub struct Assertion {
+    pub span: Span,
+    pub kind: AssertionKind,
+}

A single zero-width assertion.

+

+ Fields

span: Span

The span of this assertion.

+
kind: AssertionKind

The assertion kind, e.g., \b or ^.

+

Trait Implementations

impl PartialEq<Assertion> for Assertion[src]

impl Clone for Assertion[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Assertion[src]

impl Debug for Assertion[src]

Auto Trait Implementations

impl Send for Assertion

impl Sync for Assertion

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.CaptureName.html b/target/doc/regex_syntax/ast/struct.CaptureName.html new file mode 100644 index 0000000..a3036c6 --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.CaptureName.html @@ -0,0 +1,30 @@ +regex_syntax::ast::CaptureName - Rust

[][src]Struct regex_syntax::ast::CaptureName

pub struct CaptureName {
+    pub span: Span,
+    pub name: String,
+    pub index: u32,
+}

A capture name.

+

This corresponds to the name itself between the angle brackets in, e.g., +(?P<foo>expr).

+

+ Fields

span: Span

The span of this capture name.

+
name: String

The capture name.

+
index: u32

The capture index.

+

Trait Implementations

impl PartialEq<CaptureName> for CaptureName[src]

impl Clone for CaptureName[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for CaptureName[src]

impl Debug for CaptureName[src]

Auto Trait Implementations

impl Send for CaptureName

impl Sync for CaptureName

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.ClassAscii.html b/target/doc/regex_syntax/ast/struct.ClassAscii.html new file mode 100644 index 0000000..294bfda --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.ClassAscii.html @@ -0,0 +1,29 @@ +regex_syntax::ast::ClassAscii - Rust

[][src]Struct regex_syntax::ast::ClassAscii

pub struct ClassAscii {
+    pub span: Span,
+    pub kind: ClassAsciiKind,
+    pub negated: bool,
+}

An ASCII character class.

+

+ Fields

span: Span

The span of this class.

+
kind: ClassAsciiKind

The kind of ASCII class.

+
negated: bool

Whether the class is negated or not. e.g., [[:alpha:]] is not negated +but [[:^alpha:]] is.

+

Trait Implementations

impl PartialEq<ClassAscii> for ClassAscii[src]

impl Clone for ClassAscii[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for ClassAscii[src]

impl Debug for ClassAscii[src]

Auto Trait Implementations

impl Send for ClassAscii

impl Sync for ClassAscii

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.ClassBracketed.html b/target/doc/regex_syntax/ast/struct.ClassBracketed.html new file mode 100644 index 0000000..e854fa7 --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.ClassBracketed.html @@ -0,0 +1,30 @@ +regex_syntax::ast::ClassBracketed - Rust

[][src]Struct regex_syntax::ast::ClassBracketed

pub struct ClassBracketed {
+    pub span: Span,
+    pub negated: bool,
+    pub kind: ClassSet,
+}

A bracketed character class, e.g., [a-z0-9].

+

+ Fields

span: Span

The span of this class.

+
negated: bool

Whether this class is negated or not. e.g., [a] is not negated but +[^a] is.

+
kind: ClassSet

The type of this set. A set is either a normal union of things, e.g., +[abc] or a result of applying set operations, e.g., [\pL--c].

+

Trait Implementations

impl PartialEq<ClassBracketed> for ClassBracketed[src]

impl Clone for ClassBracketed[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for ClassBracketed[src]

impl Debug for ClassBracketed[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.ClassPerl.html b/target/doc/regex_syntax/ast/struct.ClassPerl.html new file mode 100644 index 0000000..ef40569 --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.ClassPerl.html @@ -0,0 +1,29 @@ +regex_syntax::ast::ClassPerl - Rust

[][src]Struct regex_syntax::ast::ClassPerl

pub struct ClassPerl {
+    pub span: Span,
+    pub kind: ClassPerlKind,
+    pub negated: bool,
+}

A Perl character class.

+

+ Fields

span: Span

The span of this class.

+
kind: ClassPerlKind

The kind of Perl class.

+
negated: bool

Whether the class is negated or not. e.g., \d is not negated but +\D is.

+

Trait Implementations

impl PartialEq<ClassPerl> for ClassPerl[src]

impl Clone for ClassPerl[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for ClassPerl[src]

impl Debug for ClassPerl[src]

Auto Trait Implementations

impl Send for ClassPerl

impl Sync for ClassPerl

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.ClassSetBinaryOp.html b/target/doc/regex_syntax/ast/struct.ClassSetBinaryOp.html new file mode 100644 index 0000000..888c6d4 --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.ClassSetBinaryOp.html @@ -0,0 +1,30 @@ +regex_syntax::ast::ClassSetBinaryOp - Rust

[][src]Struct regex_syntax::ast::ClassSetBinaryOp

pub struct ClassSetBinaryOp {
+    pub span: Span,
+    pub kind: ClassSetBinaryOpKind,
+    pub lhs: Box<ClassSet>,
+    pub rhs: Box<ClassSet>,
+}

A Unicode character class set operation.

+

+ Fields

span: Span

The span of this operation. e.g., the a-z--[h-p] in [a-z--h-p].

+
kind: ClassSetBinaryOpKind

The type of this set operation.

+
lhs: Box<ClassSet>

The left hand side of the operation.

+
rhs: Box<ClassSet>

The right hand side of the operation.

+

Trait Implementations

impl PartialEq<ClassSetBinaryOp> for ClassSetBinaryOp[src]

impl Clone for ClassSetBinaryOp[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for ClassSetBinaryOp[src]

impl Debug for ClassSetBinaryOp[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.ClassSetRange.html b/target/doc/regex_syntax/ast/struct.ClassSetRange.html new file mode 100644 index 0000000..b2be3c5 --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.ClassSetRange.html @@ -0,0 +1,31 @@ +regex_syntax::ast::ClassSetRange - Rust

[][src]Struct regex_syntax::ast::ClassSetRange

pub struct ClassSetRange {
+    pub span: Span,
+    pub start: Literal,
+    pub end: Literal,
+}

A single character class range in a set.

+

+ Fields

span: Span

The span of this range.

+
start: Literal

The start of this range.

+
end: Literal

The end of this range.

+

Methods

impl ClassSetRange[src]

pub fn is_valid(&self) -> bool[src]

Returns true if and only if this character class range is valid.

+

The only case where a range is invalid is if its start is greater than +its end.

+

Trait Implementations

impl PartialEq<ClassSetRange> for ClassSetRange[src]

impl Clone for ClassSetRange[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for ClassSetRange[src]

impl Debug for ClassSetRange[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.ClassSetUnion.html b/target/doc/regex_syntax/ast/struct.ClassSetUnion.html new file mode 100644 index 0000000..0a0823b --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.ClassSetUnion.html @@ -0,0 +1,40 @@ +regex_syntax::ast::ClassSetUnion - Rust

[][src]Struct regex_syntax::ast::ClassSetUnion

pub struct ClassSetUnion {
+    pub span: Span,
+    pub items: Vec<ClassSetItem>,
+}

A union of items inside a character class set.

+

+ Fields

span: Span

The span of the items in this operation. e.g., the a-z0-9 in +[^a-z0-9]

+
items: Vec<ClassSetItem>

The sequence of items that make up this union.

+

Methods

impl ClassSetUnion[src]

pub fn push(&mut self, item: ClassSetItem)[src]

Push a new item in this union.

+

The ending position of this union's span is updated to the ending +position of the span of the item given. If the union is empty, then +the starting position of this union is set to the starting position +of this item.

+

In other words, if you only use this method to add items to a union +and you set the spans on each item correctly, then you should never +need to adjust the span of the union directly.

+

pub fn into_item(self) -> ClassSetItem[src]

Return this union as a character class set item.

+

If this union contains zero items, then an empty union is +returned. If this concatenation contains exactly 1 item, then the +corresponding item is returned. Otherwise, ClassSetItem::Union is +returned.

+

Trait Implementations

impl PartialEq<ClassSetUnion> for ClassSetUnion[src]

impl Clone for ClassSetUnion[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for ClassSetUnion[src]

impl Debug for ClassSetUnion[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.ClassUnicode.html b/target/doc/regex_syntax/ast/struct.ClassUnicode.html new file mode 100644 index 0000000..85d4335 --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.ClassUnicode.html @@ -0,0 +1,38 @@ +regex_syntax::ast::ClassUnicode - Rust

[][src]Struct regex_syntax::ast::ClassUnicode

pub struct ClassUnicode {
+    pub span: Span,
+    pub negated: bool,
+    pub kind: ClassUnicodeKind,
+}

A Unicode character class.

+

+ Fields

span: Span

The span of this class.

+
negated: bool

Whether this class is negated or not.

+

Note: be careful when using this attribute. This specifically refers +to whether the class is written as \p or \P, where the latter +is negated = true. However, it also possible to write something like +\P{scx!=Katakana} which is actually equivalent to +\p{scx=Katakana} and is therefore not actually negated even though +negated = true here. To test whether this class is truly negated +or not, use the is_negated method.

+
kind: ClassUnicodeKind

The kind of Unicode class.

+

Methods

impl ClassUnicode[src]

pub fn is_negated(&self) -> bool[src]

Returns true if this class has been negated.

+

Note that this takes the Unicode op into account, if it's present. +e.g., is_negated for \P{scx!=Katakana} will return false.

+

Trait Implementations

impl PartialEq<ClassUnicode> for ClassUnicode[src]

impl Clone for ClassUnicode[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for ClassUnicode[src]

impl Debug for ClassUnicode[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.Comment.html b/target/doc/regex_syntax/ast/struct.Comment.html new file mode 100644 index 0000000..a4e03dd --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.Comment.html @@ -0,0 +1,29 @@ +regex_syntax::ast::Comment - Rust

[][src]Struct regex_syntax::ast::Comment

pub struct Comment {
+    pub span: Span,
+    pub comment: String,
+}

A comment from a regular expression with an associated span.

+

A regular expression can only contain comments when the x flag is +enabled.

+

+ Fields

span: Span

The span of this comment, including the beginning # and ending \n.

+
comment: String

The comment text, starting with the first character following the # +and ending with the last character preceding the \n.

+

Trait Implementations

impl PartialEq<Comment> for Comment[src]

impl Clone for Comment[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Comment[src]

impl Debug for Comment[src]

Auto Trait Implementations

impl Send for Comment

impl Sync for Comment

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.Concat.html b/target/doc/regex_syntax/ast/struct.Concat.html new file mode 100644 index 0000000..39db317 --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.Concat.html @@ -0,0 +1,30 @@ +regex_syntax::ast::Concat - Rust

[][src]Struct regex_syntax::ast::Concat

pub struct Concat {
+    pub span: Span,
+    pub asts: Vec<Ast>,
+}

A concatenation of regular expressions.

+

+ Fields

span: Span

The span of this concatenation.

+
asts: Vec<Ast>

The concatenation regular expressions.

+

Methods

impl Concat[src]

pub fn into_ast(self) -> Ast[src]

Return this concatenation as an AST.

+

If this concatenation contains zero ASTs, then Ast::Empty is +returned. If this concatenation contains exactly 1 AST, then the +corresponding AST is returned. Otherwise, Ast::Concat is returned.

+

Trait Implementations

impl PartialEq<Concat> for Concat[src]

impl Clone for Concat[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Concat[src]

impl Debug for Concat[src]

Auto Trait Implementations

impl Send for Concat

impl Sync for Concat

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.Error.html b/target/doc/regex_syntax/ast/struct.Error.html new file mode 100644 index 0000000..02b4604 --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.Error.html @@ -0,0 +1,41 @@ +regex_syntax::ast::Error - Rust

[][src]Struct regex_syntax::ast::Error

pub struct Error { /* fields omitted */ }

An error that occurred while parsing a regular expression into an abstract +syntax tree.

+

Note that note all ASTs represents a valid regular expression. For example, +an AST is constructed without error for \p{Quux}, but Quux is not a +valid Unicode property name. That particular error is reported when +translating an AST to the high-level intermediate representation (HIR).

+

Methods

impl Error[src]

pub fn kind(&self) -> &ErrorKind[src]

Return the type of this error.

+

pub fn pattern(&self) -> &str[src]

The original pattern string in which this error occurred.

+

Every span reported by this error is reported in terms of this string.

+

pub fn span(&self) -> &Span[src]

Return the span at which this error occurred.

+

pub fn auxiliary_span(&self) -> Option<&Span>[src]

Return an auxiliary span. This span exists only for some errors that +benefit from being able to point to two locations in the original +regular expression. For example, "duplicate" errors will have the +main error position set to the duplicate occurrence while its +auxiliary span will be set to the initial occurrence.

+

Trait Implementations

impl PartialEq<Error> for Error[src]

impl From<Error> for Error[src]

impl Clone for Error[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Error[src]

impl Display for Error[src]

impl Debug for Error[src]

impl Error for Error[src]

fn cause(&self) -> Option<&dyn Error>1.0.0[src]

Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

+

The lower-level cause of this error, if any. Read more

+

fn source(&self) -> Option<&(dyn Error + 'static)>1.30.0[src]

The lower-level source of this error, if any. Read more

+

Auto Trait Implementations

impl Send for Error

impl Sync for Error

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.Flags.html b/target/doc/regex_syntax/ast/struct.Flags.html new file mode 100644 index 0000000..4be7106 --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.Flags.html @@ -0,0 +1,38 @@ +regex_syntax::ast::Flags - Rust

[][src]Struct regex_syntax::ast::Flags

pub struct Flags {
+    pub span: Span,
+    pub items: Vec<FlagsItem>,
+}

A group of flags.

+

This corresponds only to the sequence of flags themselves, e.g., is-u.

+

+ Fields

span: Span

The span of this group of flags.

+
items: Vec<FlagsItem>

A sequence of flag items. Each item is either a flag or a negation +operator.

+

Methods

impl Flags[src]

pub fn add_item(&mut self, item: FlagsItem) -> Option<usize>[src]

Add the given item to this sequence of flags.

+

If the item was added successfully, then None is returned. If the +given item is a duplicate, then Some(i) is returned, where +items[i].kind == item.kind.

+

pub fn flag_state(&self, flag: Flag) -> Option<bool>[src]

Returns the state of the given flag in this set.

+

If the given flag is in the set but is negated, then Some(false) is +returned.

+

If the given flag is in the set and is not negated, then Some(true) +is returned.

+

Otherwise, None is returned.

+

Trait Implementations

impl PartialEq<Flags> for Flags[src]

impl Clone for Flags[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Flags[src]

impl Debug for Flags[src]

Auto Trait Implementations

impl Send for Flags

impl Sync for Flags

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.FlagsItem.html b/target/doc/regex_syntax/ast/struct.FlagsItem.html new file mode 100644 index 0000000..612d946 --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.FlagsItem.html @@ -0,0 +1,26 @@ +regex_syntax::ast::FlagsItem - Rust

[][src]Struct regex_syntax::ast::FlagsItem

pub struct FlagsItem {
+    pub span: Span,
+    pub kind: FlagsItemKind,
+}

A single item in a group of flags.

+

+ Fields

span: Span

The span of this item.

+
kind: FlagsItemKind

The kind of this item.

+

Trait Implementations

impl PartialEq<FlagsItem> for FlagsItem[src]

impl Clone for FlagsItem[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for FlagsItem[src]

impl Debug for FlagsItem[src]

Auto Trait Implementations

impl Send for FlagsItem

impl Sync for FlagsItem

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.Group.html b/target/doc/regex_syntax/ast/struct.Group.html new file mode 100644 index 0000000..5857c2b --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.Group.html @@ -0,0 +1,37 @@ +regex_syntax::ast::Group - Rust

[][src]Struct regex_syntax::ast::Group

pub struct Group {
+    pub span: Span,
+    pub kind: GroupKind,
+    pub ast: Box<Ast>,
+}

A grouped regular expression.

+

This includes both capturing and non-capturing groups. This does not +include flag-only groups like (?is), but does contain any group that +contains a sub-expression, e.g., (a), (?P<name>a), (?:a) and +(?is:a).

+

+ Fields

span: Span

The span of this group.

+
kind: GroupKind

The kind of this group.

+
ast: Box<Ast>

The regular expression in this group.

+

Methods

impl Group[src]

pub fn flags(&self) -> Option<&Flags>[src]

If this group is non-capturing, then this returns the (possibly empty) +set of flags. Otherwise, None is returned.

+

pub fn is_capturing(&self) -> bool[src]

Returns true if and only if this group is capturing.

+

pub fn capture_index(&self) -> Option<u32>[src]

Returns the capture index of this group, if this is a capturing group.

+

This returns a capture index precisely when is_capturing is true.

+

Trait Implementations

impl PartialEq<Group> for Group[src]

impl Clone for Group[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Group[src]

impl Debug for Group[src]

Auto Trait Implementations

impl Send for Group

impl Sync for Group

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.Literal.html b/target/doc/regex_syntax/ast/struct.Literal.html new file mode 100644 index 0000000..48ff8c7 --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.Literal.html @@ -0,0 +1,33 @@ +regex_syntax::ast::Literal - Rust

[][src]Struct regex_syntax::ast::Literal

pub struct Literal {
+    pub span: Span,
+    pub kind: LiteralKind,
+    pub c: char,
+}

A single literal expression.

+

A literal corresponds to a single Unicode scalar value. Literals may be +represented in their literal form, e.g., a or in their escaped form, +e.g., \x61.

+

+ Fields

span: Span

The span of this literal.

+
kind: LiteralKind

The kind of this literal.

+
c: char

The Unicode scalar value corresponding to this literal.

+

Methods

impl Literal[src]

pub fn byte(&self) -> Option<u8>[src]

If this literal was written as a \x hex escape, then this returns +the corresponding byte value. Otherwise, this returns None.

+

Trait Implementations

impl PartialEq<Literal> for Literal[src]

impl Clone for Literal[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Literal[src]

impl Debug for Literal[src]

Auto Trait Implementations

impl Send for Literal

impl Sync for Literal

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.Position.html b/target/doc/regex_syntax/ast/struct.Position.html new file mode 100644 index 0000000..2317dd9 --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.Position.html @@ -0,0 +1,49 @@ +regex_syntax::ast::Position - Rust

[][src]Struct regex_syntax::ast::Position

pub struct Position {
+    pub offset: usize,
+    pub line: usize,
+    pub column: usize,
+}

A single position in a regular expression.

+

A position encodes one half of a span, and include the byte offset, line +number and column number.

+

+ Fields

offset: usize

The absolute offset of this position, starting at 0 from the +beginning of the regular expression pattern string.

+
line: usize

The line number, starting at 1.

+
column: usize

The approximate column number, starting at 1.

+

Methods

impl Position[src]

pub fn new(offset: usize, line: usize, column: usize) -> Position[src]

Create a new position with the given information.

+

offset is the absolute offset of the position, starting at 0 from +the beginning of the regular expression pattern string.

+

line is the line number, starting at 1.

+

column is the approximate column number, starting at 1.

+

Trait Implementations

impl PartialEq<Position> for Position[src]

impl Clone for Position[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Ord for Position[src]

fn max(self, other: Self) -> Self1.21.0[src]

Compares and returns the maximum of two values. Read more

+

fn min(self, other: Self) -> Self1.21.0[src]

Compares and returns the minimum of two values. Read more

+

fn clamp(self, min: Self, max: Self) -> Self[src]

🔬 This is a nightly-only experimental API. (clamp)

Restrict a value to a certain interval. Read more

+

impl Eq for Position[src]

impl Copy for Position[src]

impl PartialOrd<Position> for Position[src]

#[must_use] +
fn lt(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests less than (for self and other) and is used by the < operator. Read more

+

#[must_use] +
fn le(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more

+

#[must_use] +
fn gt(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests greater than (for self and other) and is used by the > operator. Read more

+

#[must_use] +
fn ge(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more

+

impl Debug for Position[src]

Auto Trait Implementations

impl Send for Position

impl Sync for Position

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.Repetition.html b/target/doc/regex_syntax/ast/struct.Repetition.html new file mode 100644 index 0000000..83f51e4 --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.Repetition.html @@ -0,0 +1,30 @@ +regex_syntax::ast::Repetition - Rust

[][src]Struct regex_syntax::ast::Repetition

pub struct Repetition {
+    pub span: Span,
+    pub op: RepetitionOp,
+    pub greedy: bool,
+    pub ast: Box<Ast>,
+}

A repetition operation applied to a regular expression.

+

+ Fields

span: Span

The span of this operation.

+
op: RepetitionOp

The actual operation.

+
greedy: bool

Whether this operation was applied greedily or not.

+
ast: Box<Ast>

The regular expression under repetition.

+

Trait Implementations

impl PartialEq<Repetition> for Repetition[src]

impl Clone for Repetition[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Repetition[src]

impl Debug for Repetition[src]

Auto Trait Implementations

impl Send for Repetition

impl Sync for Repetition

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.RepetitionOp.html b/target/doc/regex_syntax/ast/struct.RepetitionOp.html new file mode 100644 index 0000000..603a635 --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.RepetitionOp.html @@ -0,0 +1,27 @@ +regex_syntax::ast::RepetitionOp - Rust

[][src]Struct regex_syntax::ast::RepetitionOp

pub struct RepetitionOp {
+    pub span: Span,
+    pub kind: RepetitionKind,
+}

The repetition operator itself.

+

+ Fields

span: Span

The span of this operator. This includes things like +, *? and +{m,n}.

+
kind: RepetitionKind

The type of operation.

+

Trait Implementations

impl PartialEq<RepetitionOp> for RepetitionOp[src]

impl Clone for RepetitionOp[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for RepetitionOp[src]

impl Debug for RepetitionOp[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.SetFlags.html b/target/doc/regex_syntax/ast/struct.SetFlags.html new file mode 100644 index 0000000..04fa3da --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.SetFlags.html @@ -0,0 +1,26 @@ +regex_syntax::ast::SetFlags - Rust

[][src]Struct regex_syntax::ast::SetFlags

pub struct SetFlags {
+    pub span: Span,
+    pub flags: Flags,
+}

A group of flags that is not applied to a particular regular expression.

+

+ Fields

span: Span

The span of these flags, including the grouping parentheses.

+
flags: Flags

The actual sequence of flags.

+

Trait Implementations

impl PartialEq<SetFlags> for SetFlags[src]

impl Clone for SetFlags[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for SetFlags[src]

impl Debug for SetFlags[src]

Auto Trait Implementations

impl Send for SetFlags

impl Sync for SetFlags

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.Span.html b/target/doc/regex_syntax/ast/struct.Span.html new file mode 100644 index 0000000..372bb1c --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.Span.html @@ -0,0 +1,50 @@ +regex_syntax::ast::Span - Rust

[][src]Struct regex_syntax::ast::Span

pub struct Span {
+    pub start: Position,
+    pub end: Position,
+}

Span represents the position information of a single AST item.

+

All span positions are absolute byte offsets that can be used on the +original regular expression that was parsed.

+

+ Fields

start: Position

The start byte offset.

+
end: Position

The end byte offset.

+

Methods

impl Span[src]

pub fn new(start: Position, end: Position) -> Span[src]

Create a new span with the given positions.

+

pub fn splat(pos: Position) -> Span[src]

Create a new span using the given position as the start and end.

+

pub fn with_start(self, pos: Position) -> Span[src]

Create a new span by replacing the starting the position with the one +given.

+

pub fn with_end(self, pos: Position) -> Span[src]

Create a new span by replacing the ending the position with the one +given.

+

pub fn is_one_line(&self) -> bool[src]

Returns true if and only if this span occurs on a single line.

+

pub fn is_empty(&self) -> bool[src]

Returns true if and only if this span is empty. That is, it points to +a single position in the concrete syntax of a regular expression.

+

Trait Implementations

impl PartialEq<Span> for Span[src]

impl Clone for Span[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Ord for Span[src]

fn max(self, other: Self) -> Self1.21.0[src]

Compares and returns the maximum of two values. Read more

+

fn min(self, other: Self) -> Self1.21.0[src]

Compares and returns the minimum of two values. Read more

+

fn clamp(self, min: Self, max: Self) -> Self[src]

🔬 This is a nightly-only experimental API. (clamp)

Restrict a value to a certain interval. Read more

+

impl Eq for Span[src]

impl Copy for Span[src]

impl PartialOrd<Span> for Span[src]

#[must_use] +
fn lt(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests less than (for self and other) and is used by the < operator. Read more

+

#[must_use] +
fn le(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more

+

#[must_use] +
fn gt(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests greater than (for self and other) and is used by the > operator. Read more

+

#[must_use] +
fn ge(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more

+

impl Debug for Span[src]

Auto Trait Implementations

impl Send for Span

impl Sync for Span

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/struct.WithComments.html b/target/doc/regex_syntax/ast/struct.WithComments.html new file mode 100644 index 0000000..d915b90 --- /dev/null +++ b/target/doc/regex_syntax/ast/struct.WithComments.html @@ -0,0 +1,30 @@ +regex_syntax::ast::WithComments - Rust

[][src]Struct regex_syntax::ast::WithComments

pub struct WithComments {
+    pub ast: Ast,
+    pub comments: Vec<Comment>,
+}

An abstract syntax tree for a singular expression along with comments +found.

+

Comments are not stored in the tree itself to avoid complexity. Each +comment contains a span of precisely where it occurred in the original +regular expression.

+

+ Fields

ast: Ast

The actual ast.

+
comments: Vec<Comment>

All comments found in the original regular expression.

+

Trait Implementations

impl PartialEq<WithComments> for WithComments[src]

impl Clone for WithComments[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for WithComments[src]

impl Debug for WithComments[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/trait.Visitor.html b/target/doc/regex_syntax/ast/trait.Visitor.html new file mode 100644 index 0000000..568e718 --- /dev/null +++ b/target/doc/regex_syntax/ast/trait.Visitor.html @@ -0,0 +1,61 @@ +regex_syntax::ast::Visitor - Rust

[][src]Trait regex_syntax::ast::Visitor

pub trait Visitor {
+    type Output;
+    type Err;
+    fn finish(self) -> Result<Self::Output, Self::Err>;
+
+    fn start(&mut self) { ... }
+
fn visit_pre(&mut self, _ast: &Ast) -> Result<(), Self::Err> { ... } +
fn visit_post(&mut self, _ast: &Ast) -> Result<(), Self::Err> { ... } +
fn visit_alternation_in(&mut self) -> Result<(), Self::Err> { ... } +
fn visit_class_set_item_pre(
        &mut self,
        _ast: &ClassSetItem
    ) -> Result<(), Self::Err> { ... } +
fn visit_class_set_item_post(
        &mut self,
        _ast: &ClassSetItem
    ) -> Result<(), Self::Err> { ... } +
fn visit_class_set_binary_op_pre(
        &mut self,
        _ast: &ClassSetBinaryOp
    ) -> Result<(), Self::Err> { ... } +
fn visit_class_set_binary_op_post(
        &mut self,
        _ast: &ClassSetBinaryOp
    ) -> Result<(), Self::Err> { ... } +
fn visit_class_set_binary_op_in(
        &mut self,
        _ast: &ClassSetBinaryOp
    ) -> Result<(), Self::Err> { ... } +}

A trait for visiting an abstract syntax tree (AST) in depth first order.

+

The principle aim of this trait is to enable callers to perform case +analysis on an abstract syntax tree without necessarily using recursion. +In particular, this permits callers to do case analysis with constant stack +usage, which can be important since the size of an abstract syntax tree +may be proportional to end user input.

+

Typical usage of this trait involves providing an implementation and then +running it using the visit function.

+

Note that the abstract syntax tree for a regular expression is quite +complex. Unless you specifically need it, you might be able to use the +much simpler +high-level intermediate representation +and its +corresponding Visitor trait +instead.

+
+

Associated Types

type Output

The result of visiting an AST.

+

type Err

An error that visiting an AST might return.

+
Loading content... +

Required methods

fn finish(self) -> Result<Self::Output, Self::Err>

All implementors of Visitor must provide a finish method, which +yields the result of visiting the AST or an error.

+
Loading content... +

Provided methods

fn start(&mut self)

This method is called before beginning traversal of the AST.

+

fn visit_pre(&mut self, _ast: &Ast) -> Result<(), Self::Err>

This method is called on an Ast before descending into child Ast +nodes.

+

fn visit_post(&mut self, _ast: &Ast) -> Result<(), Self::Err>

This method is called on an Ast after descending all of its child +Ast nodes.

+

fn visit_alternation_in(&mut self) -> Result<(), Self::Err>

This method is called between child nodes of an +Alternation.

+

fn visit_class_set_item_pre(
    &mut self,
    _ast: &ClassSetItem
) -> Result<(), Self::Err>

This method is called on every +ClassSetItem +before descending into child nodes.

+

fn visit_class_set_item_post(
    &mut self,
    _ast: &ClassSetItem
) -> Result<(), Self::Err>

This method is called on every +ClassSetItem +after descending into child nodes.

+

fn visit_class_set_binary_op_pre(
    &mut self,
    _ast: &ClassSetBinaryOp
) -> Result<(), Self::Err>

This method is called on every +ClassSetBinaryOp +before descending into child nodes.

+

fn visit_class_set_binary_op_post(
    &mut self,
    _ast: &ClassSetBinaryOp
) -> Result<(), Self::Err>

This method is called on every +ClassSetBinaryOp +after descending into child nodes.

+

fn visit_class_set_binary_op_in(
    &mut self,
    _ast: &ClassSetBinaryOp
) -> Result<(), Self::Err>

This method is called between the left hand and right hand child nodes +of a ClassSetBinaryOp.

+
Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/regex_syntax/ast/visitor/fn.visit.html b/target/doc/regex_syntax/ast/visitor/fn.visit.html new file mode 100644 index 0000000..899f672 --- /dev/null +++ b/target/doc/regex_syntax/ast/visitor/fn.visit.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../regex_syntax/ast/fn.visit.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex_syntax/ast/visitor/trait.Visitor.html b/target/doc/regex_syntax/ast/visitor/trait.Visitor.html new file mode 100644 index 0000000..9f0bae0 --- /dev/null +++ b/target/doc/regex_syntax/ast/visitor/trait.Visitor.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../regex_syntax/ast/trait.Visitor.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex_syntax/enum.Error.html b/target/doc/regex_syntax/enum.Error.html new file mode 100644 index 0000000..95b35f3 --- /dev/null +++ b/target/doc/regex_syntax/enum.Error.html @@ -0,0 +1,38 @@ +regex_syntax::Error - Rust

[][src]Enum regex_syntax::Error

pub enum Error {
+    Parse(Error),
+    Translate(Error),
+    // some variants omitted
+}

This error type encompasses any error that can be returned by this crate.

+

+ Variants

+Parse(Error)

An error that occurred while translating concrete syntax into abstract +syntax (AST).

+
Translate(Error)

An error that occurred while translating abstract syntax into a high +level intermediate representation (HIR).

+

Trait Implementations

impl PartialEq<Error> for Error[src]

impl From<Error> for Error[src]

impl From<Error> for Error[src]

impl Clone for Error[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Error[src]

impl Display for Error[src]

impl Debug for Error[src]

impl Error for Error[src]

fn cause(&self) -> Option<&dyn Error>1.0.0[src]

Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

+

The lower-level cause of this error, if any. Read more

+

fn source(&self) -> Option<&(dyn Error + 'static)>1.30.0[src]

The lower-level source of this error, if any. Read more

+

Auto Trait Implementations

impl Send for Error

impl Sync for Error

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/error/enum.Error.html b/target/doc/regex_syntax/error/enum.Error.html new file mode 100644 index 0000000..2ab401b --- /dev/null +++ b/target/doc/regex_syntax/error/enum.Error.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex_syntax/enum.Error.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex_syntax/error/type.Result.html b/target/doc/regex_syntax/error/type.Result.html new file mode 100644 index 0000000..88a072b --- /dev/null +++ b/target/doc/regex_syntax/error/type.Result.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex_syntax/type.Result.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex_syntax/fn.escape.html b/target/doc/regex_syntax/fn.escape.html new file mode 100644 index 0000000..94c3be2 --- /dev/null +++ b/target/doc/regex_syntax/fn.escape.html @@ -0,0 +1,4 @@ +regex_syntax::escape - Rust

[][src]Function regex_syntax::escape

pub fn escape(text: &str) -> String

Escapes all regular expression meta characters in text.

+

The string returned may be safely used as a literal in a regular +expression.

+
\ No newline at end of file diff --git a/target/doc/regex_syntax/fn.escape_into.html b/target/doc/regex_syntax/fn.escape_into.html new file mode 100644 index 0000000..51b6cb5 --- /dev/null +++ b/target/doc/regex_syntax/fn.escape_into.html @@ -0,0 +1,4 @@ +regex_syntax::escape_into - Rust

[][src]Function regex_syntax::escape_into

pub fn escape_into(text: &str, buf: &mut String)

Escapes all meta characters in text and writes the result into buf.

+

This will append escape characters into the given buffer. The characters +that are appended are safe to use as a literal in a regular expression.

+
\ No newline at end of file diff --git a/target/doc/regex_syntax/fn.is_meta_character.html b/target/doc/regex_syntax/fn.is_meta_character.html new file mode 100644 index 0000000..77c4279 --- /dev/null +++ b/target/doc/regex_syntax/fn.is_meta_character.html @@ -0,0 +1,8 @@ +regex_syntax::is_meta_character - Rust

[][src]Function regex_syntax::is_meta_character

pub fn is_meta_character(c: char) -> bool

Returns true if the give character has significance in a regex.

+

These are the only characters that are allowed to be escaped, with one +exception: an ASCII space character may be escaped when extended mode (with +the x flag) is enabld. In particular, is_meta_character(' ') returns +false.

+

Note that the set of characters for which this function returns true or +false is fixed and won't change in a semver compatible release.

+
\ No newline at end of file diff --git a/target/doc/regex_syntax/fn.is_word_byte.html b/target/doc/regex_syntax/fn.is_word_byte.html new file mode 100644 index 0000000..1eeb8e7 --- /dev/null +++ b/target/doc/regex_syntax/fn.is_word_byte.html @@ -0,0 +1,4 @@ +regex_syntax::is_word_byte - Rust

[][src]Function regex_syntax::is_word_byte

pub fn is_word_byte(c: u8) -> bool

Returns true if and only if the given character is an ASCII word character.

+

An ASCII word character is defined by the following character class: +`[_0-9a-zA-Z]'.

+
\ No newline at end of file diff --git a/target/doc/regex_syntax/fn.is_word_character.html b/target/doc/regex_syntax/fn.is_word_character.html new file mode 100644 index 0000000..e53d27a --- /dev/null +++ b/target/doc/regex_syntax/fn.is_word_character.html @@ -0,0 +1,9 @@ +regex_syntax::is_word_character - Rust

[][src]Function regex_syntax::is_word_character

pub fn is_word_character(c: char) -> bool

Returns true if and only if the given character is a Unicode word +character.

+

A Unicode word character is defined by +UTS#18 Annex C. +In particular, a character +is considered a word character if it is in either of the Alphabetic or +Join_Control properties, or is in one of the Decimal_Number, Mark +or Connector_Punctuation general categories.

+
\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/enum.Anchor.html b/target/doc/regex_syntax/hir/enum.Anchor.html new file mode 100644 index 0000000..df0b0dd --- /dev/null +++ b/target/doc/regex_syntax/hir/enum.Anchor.html @@ -0,0 +1,39 @@ +regex_syntax::hir::Anchor - Rust

[][src]Enum regex_syntax::hir::Anchor

pub enum Anchor {
+    StartLine,
+    EndLine,
+    StartText,
+    EndText,
+}

The high-level intermediate representation for an anchor assertion.

+

A matching anchor assertion is always zero-length.

+

+ Variants

+StartLine

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.

+
EndLine

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.

+
StartText

Match the beginning of text. Specifically, this matches at the starting +position of the input.

+
EndText

Match the end of text. Specifically, this matches at the ending +position of the input.

+

Trait Implementations

impl PartialEq<Anchor> for Anchor[src]

#[must_use] +
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests for !=.

+

impl Clone for Anchor[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Anchor[src]

impl Debug for Anchor[src]

Auto Trait Implementations

impl Send for Anchor

impl Sync for Anchor

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/enum.Class.html b/target/doc/regex_syntax/hir/enum.Class.html new file mode 100644 index 0000000..5c08ae4 --- /dev/null +++ b/target/doc/regex_syntax/hir/enum.Class.html @@ -0,0 +1,59 @@ +regex_syntax::hir::Class - Rust

[][src]Enum regex_syntax::hir::Class

pub enum Class {
+    Unicode(ClassUnicode),
+    Bytes(ClassBytes),
+}

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 unlike Literal, a 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.

+

+ Variants

+Unicode(ClassUnicode)

A set of characters represented by Unicode scalar values.

+
Bytes(ClassBytes)

A set of characters represented by arbitrary bytes (one byte per +character).

+

Methods

impl Class[src]

pub fn case_fold_simple(&mut self)[src]

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.

+

pub fn negate(&mut self)[src]

Negate this character class in place.

+

After completion, this character class will contain precisely the +characters that weren't previously in the class.

+

pub fn is_always_utf8(&self) -> bool[src]

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. +
  3. Unicode mode (via the u flag) was disabled either in the concrete +syntax or in the parser builder. By default, Unicode mode is +enabled.
  4. +
+

Trait Implementations

impl PartialEq<Class> for Class[src]

impl Clone for Class[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Class[src]

impl Debug for Class[src]

Auto Trait Implementations

impl Send for Class

impl Sync for Class

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/enum.ErrorKind.html b/target/doc/regex_syntax/hir/enum.ErrorKind.html new file mode 100644 index 0000000..02466a5 --- /dev/null +++ b/target/doc/regex_syntax/hir/enum.ErrorKind.html @@ -0,0 +1,44 @@ +regex_syntax::hir::ErrorKind - Rust

[][src]Enum regex_syntax::hir::ErrorKind

pub enum ErrorKind {
+    UnicodeNotAllowed,
+    InvalidUtf8,
+    UnicodePropertyNotFound,
+    UnicodePropertyValueNotFound,
+    EmptyClassNotAllowed,
+    // some variants omitted
+}

The type of an error that occurred while building an Hir.

+

+ Variants

+UnicodeNotAllowed

This error occurs when a Unicode feature is used when Unicode +support is disabled. For example (?-u:\pL) would trigger this error.

+
InvalidUtf8

This error occurs when translating a pattern that could match a byte +sequence that isn't UTF-8 and allow_invalid_utf8 was disabled.

+
UnicodePropertyNotFound

This occurs when an unrecognized Unicode property name could not +be found.

+
UnicodePropertyValueNotFound

This occurs when an unrecognized Unicode property value could not +be found.

+
EmptyClassNotAllowed

This occurs when the translator attempts to construct a character class +that is empty.

+

Note that this restriction in the translator may be removed in the +future.

+

Trait Implementations

impl PartialEq<ErrorKind> for ErrorKind[src]

#[must_use] +
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests for !=.

+

impl Clone for ErrorKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for ErrorKind[src]

impl Display for ErrorKind[src]

impl Debug for ErrorKind[src]

Auto Trait Implementations

impl Send for ErrorKind

impl Sync for ErrorKind

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/enum.GroupKind.html b/target/doc/regex_syntax/hir/enum.GroupKind.html new file mode 100644 index 0000000..9c20a26 --- /dev/null +++ b/target/doc/regex_syntax/hir/enum.GroupKind.html @@ -0,0 +1,35 @@ +regex_syntax::hir::GroupKind - Rust

[][src]Enum regex_syntax::hir::GroupKind

pub enum GroupKind {
+    CaptureIndex(u32),
+    CaptureName {
+        name: String,
+        index: u32,
+    },
+    NonCapturing,
+}

The kind of group.

+

+ Variants

+CaptureIndex(u32)

A normal unnamed capturing group.

+

The value is the capture index of the group.

+
CaptureName

A named capturing group.

+

Fields of CaptureName

name: String

The name of the group.

+
index: u32

The capture index of the group.

+
NonCapturing

A non-capturing group.

+

Trait Implementations

impl PartialEq<GroupKind> for GroupKind[src]

impl Clone for GroupKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for GroupKind[src]

impl Debug for GroupKind[src]

Auto Trait Implementations

impl Send for GroupKind

impl Sync for GroupKind

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/enum.HirKind.html b/target/doc/regex_syntax/hir/enum.HirKind.html new file mode 100644 index 0000000..7bca496 --- /dev/null +++ b/target/doc/regex_syntax/hir/enum.HirKind.html @@ -0,0 +1,57 @@ +regex_syntax::hir::HirKind - Rust

[][src]Enum regex_syntax::hir::HirKind

pub enum HirKind {
+    Empty,
+    Literal(Literal),
+    Class(Class),
+    Anchor(Anchor),
+    WordBoundary(WordBoundary),
+    Repetition(Repetition),
+    Group(Group),
+    Concat(Vec<Hir>),
+    Alternation(Vec<Hir>),
+}

The kind of an arbitrary Hir expression.

+

+ Variants

+Empty

The empty regular expression, which matches everything, including the +empty string.

+
Literal(Literal)

A single literal character that matches exactly this character.

+
Class(Class)

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.

+
Anchor(Anchor)

An anchor assertion. An anchor assertion match always has zero length.

+
WordBoundary(WordBoundary)

A word boundary assertion, which may or may not be Unicode aware. A +word boundary assertion match always has zero length.

+
Repetition(Repetition)

A repetition operation applied to a child expression.

+
Group(Group)

A possibly capturing group, which contains a child expression.

+
Concat(Vec<Hir>)

A concatenation of expressions. A concatenation always has at least two +child expressions.

+

A concatenation matches only if each of its child expression matches +one after the other.

+
Alternation(Vec<Hir>)

An alternation of expressions. An alternation always has at least two +child expressions.

+

An alternation matches only if at least one of its child expression +matches. If multiple expressions match, then the leftmost is preferred.

+

Methods

impl HirKind[src]

pub fn is_empty(&self) -> bool[src]

Return true if and only if this HIR is the empty regular expression.

+

Note that this is not defined inductively. That is, it only tests if +this kind is the Empty variant. To get the inductive definition, +use the is_match_empty method on Hir.

+

pub fn has_subexprs(&self) -> bool[src]

Returns true if and only if this kind has any (including possibly +empty) subexpressions.

+

Trait Implementations

impl PartialEq<HirKind> for HirKind[src]

impl Clone for HirKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for HirKind[src]

impl Debug for HirKind[src]

Auto Trait Implementations

impl Send for HirKind

impl Sync for HirKind

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/enum.Literal.html b/target/doc/regex_syntax/hir/enum.Literal.html new file mode 100644 index 0000000..d56301e --- /dev/null +++ b/target/doc/regex_syntax/hir/enum.Literal.html @@ -0,0 +1,33 @@ +regex_syntax::hir::Literal - Rust

[][src]Enum regex_syntax::hir::Literal

pub enum Literal {
+    Unicode(char),
+    Byte(u8),
+}

The high-level intermediate representation of a literal.

+

A literal corresponds to a single character, where a character is either +defined by a Unicode scalar value or an arbitrary byte. Unicode characters +are preferred whenever possible. In particular, a Byte variant is only +ever produced when it could match invalid UTF-8.

+

+ Variants

+Unicode(char)

A single character represented by a Unicode scalar value.

+
Byte(u8)

A single character represented by an arbitrary byte.

+

Methods

impl Literal[src]

pub fn is_unicode(&self) -> bool[src]

Returns true if and only if this literal corresponds to a Unicode +scalar value.

+

Trait Implementations

impl PartialEq<Literal> for Literal[src]

impl Clone for Literal[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Literal[src]

impl Debug for Literal[src]

Auto Trait Implementations

impl Send for Literal

impl Sync for Literal

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/enum.RepetitionKind.html b/target/doc/regex_syntax/hir/enum.RepetitionKind.html new file mode 100644 index 0000000..ffdd9b7 --- /dev/null +++ b/target/doc/regex_syntax/hir/enum.RepetitionKind.html @@ -0,0 +1,31 @@ +regex_syntax::hir::RepetitionKind - Rust

[][src]Enum regex_syntax::hir::RepetitionKind

pub enum RepetitionKind {
+    ZeroOrOne,
+    ZeroOrMore,
+    OneOrMore,
+    Range(RepetitionRange),
+}

The kind of a repetition operator.

+

+ Variants

+ZeroOrOne

Matches a sub-expression zero or one times.

+
ZeroOrMore

Matches a sub-expression zero or more times.

+
OneOrMore

Matches a sub-expression one or more times.

+
Range(RepetitionRange)

Matches a sub-expression within a bounded range of times.

+

Trait Implementations

impl PartialEq<RepetitionKind> for RepetitionKind[src]

impl Clone for RepetitionKind[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for RepetitionKind[src]

impl Debug for RepetitionKind[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/enum.RepetitionRange.html b/target/doc/regex_syntax/hir/enum.RepetitionRange.html new file mode 100644 index 0000000..087b8bf --- /dev/null +++ b/target/doc/regex_syntax/hir/enum.RepetitionRange.html @@ -0,0 +1,29 @@ +regex_syntax::hir::RepetitionRange - Rust

[][src]Enum regex_syntax::hir::RepetitionRange

pub enum RepetitionRange {
+    Exactly(u32),
+    AtLeast(u32),
+    Bounded(u32u32),
+}

The kind of a counted repetition operator.

+

+ Variants

+Exactly(u32)

Matches a sub-expression exactly this many times.

+
AtLeast(u32)

Matches a sub-expression at least this many times.

+
Bounded(u32u32)

Matches a sub-expression at least m times and at most n times.

+

Trait Implementations

impl PartialEq<RepetitionRange> for RepetitionRange[src]

impl Clone for RepetitionRange[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for RepetitionRange[src]

impl Debug for RepetitionRange[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/enum.WordBoundary.html b/target/doc/regex_syntax/hir/enum.WordBoundary.html new file mode 100644 index 0000000..dbf0718 --- /dev/null +++ b/target/doc/regex_syntax/hir/enum.WordBoundary.html @@ -0,0 +1,38 @@ +regex_syntax::hir::WordBoundary - Rust

[][src]Enum regex_syntax::hir::WordBoundary

pub enum WordBoundary {
+    Unicode,
+    UnicodeNegate,
+    Ascii,
+    AsciiNegate,
+}

The high-level intermediate representation for a word-boundary assertion.

+

A matching word boundary assertion is always zero-length.

+

+ Variants

+Unicode

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.

+
UnicodeNegate

Match a Unicode-aware negation of a word boundary.

+
Ascii

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.

+
AsciiNegate

Match an ASCII-only negation of a word boundary.

+

Methods

impl WordBoundary[src]

pub fn is_negated(&self) -> bool[src]

Returns true if and only if this word boundary assertion is negated.

+

Trait Implementations

impl PartialEq<WordBoundary> for WordBoundary[src]

#[must_use] +
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests for !=.

+

impl Clone for WordBoundary[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for WordBoundary[src]

impl Debug for WordBoundary[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/fn.visit.html b/target/doc/regex_syntax/hir/fn.visit.html new file mode 100644 index 0000000..c39932d --- /dev/null +++ b/target/doc/regex_syntax/hir/fn.visit.html @@ -0,0 +1,13 @@ +regex_syntax::hir::visit - Rust

[][src]Function regex_syntax::hir::visit

pub fn visit<V: Visitor>(hir: &Hir, visitor: V) -> Result<V::Output, V::Err>

Executes an implementation of Visitor in constant stack space.

+

This function will visit every node in the given Hir while calling +appropriate methods provided by the +Visitor trait.

+

The primary use case for this method is when one wants to perform case +analysis over an Hir without using a stack size proportional to the depth +of the Hir. Namely, this method will instead use constant stack space, +but will use heap space proportional to the size of the Hir. This may be +desirable in cases where the size of Hir is proportional to end user +input.

+

If the visitor returns an error at any point, then visiting is stopped and +the error is returned.

+
\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/index.html b/target/doc/regex_syntax/hir/index.html new file mode 100644 index 0000000..029ebda --- /dev/null +++ b/target/doc/regex_syntax/hir/index.html @@ -0,0 +1,32 @@ +regex_syntax::hir - Rust

[][src]Module regex_syntax::hir

Defines a high-level intermediate representation for regular expressions.

+

Modules

+
literal

Provides routines for extracting literal prefixes and suffixes from an Hir.

+
print

This module provides a regular expression printer for Hir.

+
translate

Defines a translator that converts an Ast to an Hir.

+

Structs

+
ClassBytes

A set of characters represented by arbitrary bytes (where one byte +corresponds to one character).

+
ClassBytesIter

An iterator over all ranges in a byte character class.

+
ClassBytesRange

A single range of characters represented by arbitrary bytes.

+
ClassUnicode

A set of characters represented by Unicode scalar values.

+
ClassUnicodeIter

An iterator over all ranges in a Unicode character class.

+
ClassUnicodeRange

A single range of characters represented by Unicode scalar values.

+
Error

An error that can occur while translating an Ast to a Hir.

+
Group

The high-level intermediate representation for a group.

+
Hir

A high-level intermediate representation (HIR) for a regular expression.

+
Repetition

The high-level intermediate representation of a repetition operator.

+

Enums

+
Anchor

The high-level intermediate representation for an anchor assertion.

+
Class

The high-level intermediate representation of a character class.

+
ErrorKind

The type of an error that occurred while building an Hir.

+
GroupKind

The kind of group.

+
HirKind

The kind of an arbitrary Hir expression.

+
Literal

The high-level intermediate representation of a literal.

+
RepetitionKind

The kind of a repetition operator.

+
RepetitionRange

The kind of a counted repetition operator.

+
WordBoundary

The high-level intermediate representation for a word-boundary assertion.

+

Traits

+
Visitor

A trait for visiting the high-level IR (HIR) in depth first order.

+

Functions

+
visit

Executes an implementation of Visitor in constant stack space.

+
\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/literal/index.html b/target/doc/regex_syntax/hir/literal/index.html new file mode 100644 index 0000000..9fd7cdf --- /dev/null +++ b/target/doc/regex_syntax/hir/literal/index.html @@ -0,0 +1,5 @@ +regex_syntax::hir::literal - Rust

[][src]Module regex_syntax::hir::literal

Provides routines for extracting literal prefixes and suffixes from an Hir.

+

Structs

+
Literal

A single member of a set of literals extracted from a regular expression.

+
Literals

A set of literal byte strings extracted from a regular expression.

+
\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/literal/sidebar-items.js b/target/doc/regex_syntax/hir/literal/sidebar-items.js new file mode 100644 index 0000000..8f4e565 --- /dev/null +++ b/target/doc/regex_syntax/hir/literal/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["Literal","A single member of a set of literals extracted from a regular expression."],["Literals","A set of literal byte strings extracted from a regular expression."]]}); \ No newline at end of file diff --git a/target/doc/regex_syntax/hir/literal/struct.Literal.html b/target/doc/regex_syntax/hir/literal/struct.Literal.html new file mode 100644 index 0000000..3a83c8b --- /dev/null +++ b/target/doc/regex_syntax/hir/literal/struct.Literal.html @@ -0,0 +1,550 @@ +regex_syntax::hir::literal::Literal - Rust

[][src]Struct regex_syntax::hir::literal::Literal

pub struct Literal { /* fields omitted */ }

A single member of a set of literals extracted from a regular expression.

+

This type has Deref and DerefMut impls to Vec<u8> so that all slice +and Vec operations are available.

+

Methods

impl Literal[src]

pub fn new(bytes: Vec<u8>) -> Literal[src]

Returns a new complete literal with the bytes given.

+

pub fn empty() -> Literal[src]

Returns a new complete empty literal.

+

pub fn is_cut(&self) -> bool[src]

Returns true if this literal was "cut."

+

pub fn cut(&mut self)[src]

Cuts this literal.

+

Methods from Deref<Target = Vec<u8>>

pub fn capacity(&self) -> usize1.0.0[src]

Returns the number of elements the vector can hold without +reallocating.

+

Examples

+
+let vec: Vec<i32> = Vec::with_capacity(10);
+assert_eq!(vec.capacity(), 10);
+

pub fn reserve(&mut self, additional: usize)1.0.0[src]

Reserves capacity for at least additional more elements to be inserted +in the given Vec<T>. The collection may reserve more space to avoid +frequent reallocations. After calling reserve, capacity will be +greater than or equal to self.len() + additional. Does nothing if +capacity is already sufficient.

+

Panics

+

Panics if the new capacity overflows usize.

+

Examples

+
+let mut vec = vec![1];
+vec.reserve(10);
+assert!(vec.capacity() >= 11);
+

pub fn reserve_exact(&mut self, additional: usize)1.0.0[src]

Reserves the minimum capacity for exactly additional more elements to +be inserted in the given Vec<T>. After calling reserve_exact, +capacity will be greater than or equal to self.len() + additional. +Does nothing if the capacity is already sufficient.

+

Note that the allocator may give the collection more space than it +requests. Therefore, capacity can not be relied upon to be precisely +minimal. Prefer reserve if future insertions are expected.

+

Panics

+

Panics if the new capacity overflows usize.

+

Examples

+
+let mut vec = vec![1];
+vec.reserve_exact(10);
+assert!(vec.capacity() >= 11);
+

pub fn try_reserve(
    &mut self,
    additional: usize
) -> Result<(), CollectionAllocErr>
[src]

🔬 This is a nightly-only experimental API. (try_reserve)

new API

+

Tries to reserve capacity for at least additional more elements to be inserted +in the given Vec<T>. The collection may reserve more space to avoid +frequent reallocations. After calling reserve, capacity will be +greater than or equal to self.len() + additional. Does nothing if +capacity is already sufficient.

+

Errors

+

If the capacity overflows, or the allocator reports a failure, then an error +is returned.

+

Examples

+
+#![feature(try_reserve)]
+use std::collections::CollectionAllocErr;
+
+fn process_data(data: &[u32]) -> Result<Vec<u32>, CollectionAllocErr> {
+    let mut output = Vec::new();
+
+    // Pre-reserve the memory, exiting if we can't
+    output.try_reserve(data.len())?;
+
+    // Now we know this can't OOM in the middle of our complex work
+    output.extend(data.iter().map(|&val| {
+        val * 2 + 5 // very complicated
+    }));
+
+    Ok(output)
+}
+

pub fn try_reserve_exact(
    &mut self,
    additional: usize
) -> Result<(), CollectionAllocErr>
[src]

🔬 This is a nightly-only experimental API. (try_reserve)

new API

+

Tries to reserves the minimum capacity for exactly additional more elements to +be inserted in the given Vec<T>. After calling reserve_exact, +capacity will be greater than or equal to self.len() + additional. +Does nothing if the capacity is already sufficient.

+

Note that the allocator may give the collection more space than it +requests. Therefore, capacity can not be relied upon to be precisely +minimal. Prefer reserve if future insertions are expected.

+

Errors

+

If the capacity overflows, or the allocator reports a failure, then an error +is returned.

+

Examples

+
+#![feature(try_reserve)]
+use std::collections::CollectionAllocErr;
+
+fn process_data(data: &[u32]) -> Result<Vec<u32>, CollectionAllocErr> {
+    let mut output = Vec::new();
+
+    // Pre-reserve the memory, exiting if we can't
+    output.try_reserve(data.len())?;
+
+    // Now we know this can't OOM in the middle of our complex work
+    output.extend(data.iter().map(|&val| {
+        val * 2 + 5 // very complicated
+    }));
+
+    Ok(output)
+}
+

pub fn shrink_to_fit(&mut self)1.0.0[src]

Shrinks the capacity of the vector as much as possible.

+

It will drop down as close as possible to the length but the allocator +may still inform the vector that there is space for a few more elements.

+

Examples

+
+let mut vec = Vec::with_capacity(10);
+vec.extend([1, 2, 3].iter().cloned());
+assert_eq!(vec.capacity(), 10);
+vec.shrink_to_fit();
+assert!(vec.capacity() >= 3);
+

pub fn shrink_to(&mut self, min_capacity: usize)[src]

🔬 This is a nightly-only experimental API. (shrink_to)

new API

+

Shrinks the capacity of the vector with a lower bound.

+

The capacity will remain at least as large as both the length +and the supplied value.

+

Panics if the current capacity is smaller than the supplied +minimum capacity.

+

Examples

+
+#![feature(shrink_to)]
+let mut vec = Vec::with_capacity(10);
+vec.extend([1, 2, 3].iter().cloned());
+assert_eq!(vec.capacity(), 10);
+vec.shrink_to(4);
+assert!(vec.capacity() >= 4);
+vec.shrink_to(0);
+assert!(vec.capacity() >= 3);
+

pub fn truncate(&mut self, len: usize)1.0.0[src]

Shortens the vector, keeping the first len elements and dropping +the rest.

+

If len is greater than the vector's current length, this has no +effect.

+

The drain method can emulate truncate, but causes the excess +elements to be returned instead of dropped.

+

Note that this method has no effect on the allocated capacity +of the vector.

+

Examples

+

Truncating a five element vector to two elements:

+ +
+let mut vec = vec![1, 2, 3, 4, 5];
+vec.truncate(2);
+assert_eq!(vec, [1, 2]);
+

No truncation occurs when len is greater than the vector's current +length:

+ +
+let mut vec = vec![1, 2, 3];
+vec.truncate(8);
+assert_eq!(vec, [1, 2, 3]);
+

Truncating when len == 0 is equivalent to calling the clear +method.

+ +
+let mut vec = vec![1, 2, 3];
+vec.truncate(0);
+assert_eq!(vec, []);
+

pub fn as_slice(&self) -> &[T]1.7.0[src]

Extracts a slice containing the entire vector.

+

Equivalent to &s[..].

+

Examples

+
+use std::io::{self, Write};
+let buffer = vec![1, 2, 3, 5, 8];
+io::sink().write(buffer.as_slice()).unwrap();
+

pub fn as_mut_slice(&mut self) -> &mut [T]1.7.0[src]

Extracts a mutable slice of the entire vector.

+

Equivalent to &mut s[..].

+

Examples

+
+use std::io::{self, Read};
+let mut buffer = vec![0; 3];
+io::repeat(0b101).read_exact(buffer.as_mut_slice()).unwrap();
+

pub unsafe fn set_len(&mut self, new_len: usize)1.0.0[src]

Forces the length of the vector to new_len.

+

This is a low-level operation that maintains none of the normal +invariants of the type. Normally changing the length of a vector +is done using one of the safe operations instead, such as +truncate, resize, extend, or clear.

+

Safety

+
    +
  • new_len must be less than or equal to capacity().
  • +
  • The elements at old_len..new_len must be initialized.
  • +
+

Examples

+

This method can be useful for situations in which the vector +is serving as a buffer for other code, particularly over FFI:

+ +
+pub fn get_dictionary(&self) -> Option<Vec<u8>> {
+    // Per the FFI method's docs, "32768 bytes is always enough".
+    let mut dict = Vec::with_capacity(32_768);
+    let mut dict_length = 0;
+    // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that:
+    // 1. `dict_length` elements were initialized.
+    // 2. `dict_length` <= the capacity (32_768)
+    // which makes `set_len` safe to call.
+    unsafe {
+        // Make the FFI call...
+        let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length);
+        if r == Z_OK {
+            // ...and update the length to what was initialized.
+            dict.set_len(dict_length);
+            Some(dict)
+        } else {
+            None
+        }
+    }
+}
+

While the following example is sound, there is a memory leak since +the inner vectors were not freed prior to the set_len call:

+ +
+let mut vec = vec![vec![1, 0, 0],
+                   vec![0, 1, 0],
+                   vec![0, 0, 1]];
+// SAFETY:
+// 1. `old_len..0` is empty so no elements need to be initialized.
+// 2. `0 <= capacity` always holds whatever `capacity` is.
+unsafe {
+    vec.set_len(0);
+}
+

Normally, here, one would use clear instead to correctly drop +the contents and thus not leak memory.

+

pub fn swap_remove(&mut self, index: usize) -> T1.0.0[src]

Removes an element from the vector and returns it.

+

The removed element is replaced by the last element of the vector.

+

This does not preserve ordering, but is O(1).

+

Panics

+

Panics if index is out of bounds.

+

Examples

+
+let mut v = vec!["foo", "bar", "baz", "qux"];
+
+assert_eq!(v.swap_remove(1), "bar");
+assert_eq!(v, ["foo", "qux", "baz"]);
+
+assert_eq!(v.swap_remove(0), "foo");
+assert_eq!(v, ["baz", "qux"]);
+

pub fn insert(&mut self, index: usize, element: T)1.0.0[src]

Inserts an element at position index within the vector, shifting all +elements after it to the right.

+

Panics

+

Panics if index > len.

+

Examples

+
+let mut vec = vec![1, 2, 3];
+vec.insert(1, 4);
+assert_eq!(vec, [1, 4, 2, 3]);
+vec.insert(4, 5);
+assert_eq!(vec, [1, 4, 2, 3, 5]);
+

pub fn remove(&mut self, index: usize) -> T1.0.0[src]

Removes and returns the element at position index within the vector, +shifting all elements after it to the left.

+

Panics

+

Panics if index is out of bounds.

+

Examples

+
+let mut v = vec![1, 2, 3];
+assert_eq!(v.remove(1), 2);
+assert_eq!(v, [1, 3]);
+

pub fn retain<F>(&mut self, f: F) where
    F: FnMut(&T) -> bool
1.0.0[src]

Retains only the elements specified by the predicate.

+

In other words, remove all elements e such that f(&e) returns false. +This method operates in place, visiting each element exactly once in the +original order, and preserves the order of the retained elements.

+

Examples

+
+let mut vec = vec![1, 2, 3, 4];
+vec.retain(|&x| x%2 == 0);
+assert_eq!(vec, [2, 4]);
+

The exact order may be useful for tracking external state, like an index.

+ +
+let mut vec = vec![1, 2, 3, 4, 5];
+let keep = [false, true, true, false, true];
+let mut i = 0;
+vec.retain(|_| (keep[i], i += 1).0);
+assert_eq!(vec, [2, 3, 5]);
+

pub fn dedup_by_key<F, K>(&mut self, key: F) where
    F: FnMut(&mut T) -> K,
    K: PartialEq<K>, 
1.16.0[src]

Removes all but the first of consecutive elements in the vector that resolve to the same +key.

+

If the vector is sorted, this removes all duplicates.

+

Examples

+
+let mut vec = vec![10, 20, 21, 30, 20];
+
+vec.dedup_by_key(|i| *i / 10);
+
+assert_eq!(vec, [10, 20, 30, 20]);
+

pub fn dedup_by<F>(&mut self, same_bucket: F) where
    F: FnMut(&mut T, &mut T) -> bool
1.16.0[src]

Removes all but the first of consecutive elements in the vector satisfying a given equality +relation.

+

The same_bucket function is passed references to two elements from the vector and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is removed.

+

If the vector is sorted, this removes all duplicates.

+

Examples

+
+let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
+
+vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
+

pub fn push(&mut self, value: T)1.0.0[src]

Appends an element to the back of a collection.

+

Panics

+

Panics if the number of elements in the vector overflows a usize.

+

Examples

+
+let mut vec = vec![1, 2];
+vec.push(3);
+assert_eq!(vec, [1, 2, 3]);
+

pub fn pop(&mut self) -> Option<T>1.0.0[src]

Removes the last element from a vector and returns it, or None if it +is empty.

+

Examples

+
+let mut vec = vec![1, 2, 3];
+assert_eq!(vec.pop(), Some(3));
+assert_eq!(vec, [1, 2]);
+

pub fn append(&mut self, other: &mut Vec<T>)1.4.0[src]

Moves all the elements of other into Self, leaving other empty.

+

Panics

+

Panics if the number of elements in the vector overflows a usize.

+

Examples

+
+let mut vec = vec![1, 2, 3];
+let mut vec2 = vec![4, 5, 6];
+vec.append(&mut vec2);
+assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
+assert_eq!(vec2, []);
+

pub fn drain<R>(&mut self, range: R) -> Drain<T> where
    R: RangeBounds<usize>, 
1.6.0[src]

Creates a draining iterator that removes the specified range in the vector +and yields the removed items.

+

Note 1: The element range is removed even if the iterator is only +partially consumed or not consumed at all.

+

Note 2: It is unspecified how many elements are removed from the vector +if the Drain value is leaked.

+

Panics

+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+

Examples

+
+let mut v = vec![1, 2, 3];
+let u: Vec<_> = v.drain(1..).collect();
+assert_eq!(v, &[1]);
+assert_eq!(u, &[2, 3]);
+
+// A full range clears the vector
+v.drain(..);
+assert_eq!(v, &[]);
+

pub fn clear(&mut self)1.0.0[src]

Clears the vector, removing all values.

+

Note that this method has no effect on the allocated capacity +of the vector.

+

Examples

+
+let mut v = vec![1, 2, 3];
+
+v.clear();
+
+assert!(v.is_empty());
+

pub fn len(&self) -> usize1.0.0[src]

Returns the number of elements in the vector, also referred to +as its 'length'.

+

Examples

+
+let a = vec![1, 2, 3];
+assert_eq!(a.len(), 3);
+

pub fn is_empty(&self) -> bool1.0.0[src]

Returns true if the vector contains no elements.

+

Examples

+
+let mut v = Vec::new();
+assert!(v.is_empty());
+
+v.push(1);
+assert!(!v.is_empty());
+

pub fn split_off(&mut self, at: usize) -> Vec<T>1.4.0[src]

Splits the collection into two at the given index.

+

Returns a newly allocated Self. self contains elements [0, at), +and the returned Self contains elements [at, len).

+

Note that the capacity of self does not change.

+

Panics

+

Panics if at > len.

+

Examples

+
+let mut vec = vec![1,2,3];
+let vec2 = vec.split_off(1);
+assert_eq!(vec, [1]);
+assert_eq!(vec2, [2, 3]);
+

pub fn resize_with<F>(&mut self, new_len: usize, f: F) where
    F: FnMut() -> T, 
1.33.0[src]

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with the result of +calling the closure f. The return values from f will end up +in the Vec in the order they have been generated.

+

If new_len is less than len, the Vec is simply truncated.

+

This method uses a closure to create new values on every push. If +you'd rather Clone a given value, use resize. If you want +to use the [Default] trait to generate values, you can pass +[Default::default()] as the second argument.

+

Examples

+
+let mut vec = vec![1, 2, 3];
+vec.resize_with(5, Default::default);
+assert_eq!(vec, [1, 2, 3, 0, 0]);
+
+let mut vec = vec![];
+let mut p = 1;
+vec.resize_with(4, || { p *= 2; p });
+assert_eq!(vec, [2, 4, 8, 16]);
+

pub fn resize(&mut self, new_len: usize, value: T)1.5.0[src]

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with value. +If new_len is less than len, the Vec is simply truncated.

+

This method requires Clone to be able clone the passed value. If +you need more flexibility (or want to rely on Default instead of +Clone), use resize_with.

+

Examples

+
+let mut vec = vec!["hello"];
+vec.resize(3, "world");
+assert_eq!(vec, ["hello", "world", "world"]);
+
+let mut vec = vec![1, 2, 3, 4];
+vec.resize(2, 0);
+assert_eq!(vec, [1, 2]);
+

pub fn extend_from_slice(&mut self, other: &[T])1.6.0[src]

Clones and appends all elements in a slice to the Vec.

+

Iterates over the slice other, clones each element, and then appends +it to this Vec. The other vector is traversed in-order.

+

Note that this function is same as extend except that it is +specialized to work with slices instead. If and when Rust gets +specialization this function will likely be deprecated (but still +available).

+

Examples

+
+let mut vec = vec![1];
+vec.extend_from_slice(&[2, 3, 4]);
+assert_eq!(vec, [1, 2, 3, 4]);
+

pub fn resize_default(&mut self, new_len: usize)[src]

Deprecated since 1.33.0:

This is moving towards being removed in favor of .resize_with(Default::default). If you disagree, please comment in the tracking issue.

+
🔬 This is a nightly-only experimental API. (vec_resize_default)

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with Default::default(). +If new_len is less than len, the Vec is simply truncated.

+

This method uses Default to create new values on every push. If +you'd rather Clone a given value, use resize.

+

Examples

+
+#![feature(vec_resize_default)]
+
+let mut vec = vec![1, 2, 3];
+vec.resize_default(5);
+assert_eq!(vec, [1, 2, 3, 0, 0]);
+
+let mut vec = vec![1, 2, 3, 4];
+vec.resize_default(2);
+assert_eq!(vec, [1, 2]);
+

pub fn dedup(&mut self)1.0.0[src]

Removes consecutive repeated elements in the vector according to the +[PartialEq] trait implementation.

+

If the vector is sorted, this removes all duplicates.

+

Examples

+
+let mut vec = vec![1, 2, 2, 3, 2];
+
+vec.dedup();
+
+assert_eq!(vec, [1, 2, 3, 2]);
+

pub fn remove_item(&mut self, item: &T) -> Option<T>[src]

🔬 This is a nightly-only experimental API. (vec_remove_item)

recently added

+

Removes the first instance of item from the vector if the item exists.

+

Examples

+
+let mut vec = vec![1, 2, 3, 1];
+
+vec.remove_item(&1);
+
+assert_eq!(vec, vec![2, 3, 1]);
+

pub fn splice<R, I>(
    &mut self,
    range: R,
    replace_with: I
) -> Splice<<I as IntoIterator>::IntoIter> where
    I: IntoIterator<Item = T>,
    R: RangeBounds<usize>, 
1.21.0[src]

Creates a splicing iterator that replaces the specified range in the vector +with the given replace_with iterator and yields the removed items. +replace_with does not need to be the same length as range.

+

Note 1: The element range is removed even if the iterator is not +consumed until the end.

+

Note 2: It is unspecified how many elements are removed from the vector, +if the Splice value is leaked.

+

Note 3: The input iterator replace_with is only consumed +when the Splice value is dropped.

+

Note 4: This is optimal if:

+
    +
  • The tail (elements in the vector after range) is empty,
  • +
  • or replace_with yields fewer elements than range’s length
  • +
  • or the lower bound of its size_hint() is exact.
  • +
+

Otherwise, a temporary vector is allocated and the tail is moved twice.

+

Panics

+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+

Examples

+
+let mut v = vec![1, 2, 3];
+let new = [7, 8];
+let u: Vec<_> = v.splice(..2, new.iter().cloned()).collect();
+assert_eq!(v, &[7, 8, 3]);
+assert_eq!(u, &[1, 2]);
+

pub fn drain_filter<F>(&mut self, filter: F) -> DrainFilter<T, F> where
    F: FnMut(&mut T) -> bool
[src]

🔬 This is a nightly-only experimental API. (drain_filter)

recently added

+

Creates an iterator which uses a closure to determine if an element should be removed.

+

If the closure returns true, then the element is removed and yielded. +If the closure returns false, the element will remain in the vector and will not be yielded +by the iterator.

+

Using this method is equivalent to the following code:

+ +
+let mut i = 0;
+while i != vec.len() {
+    if some_predicate(&mut vec[i]) {
+        let val = vec.remove(i);
+        // your code here
+    } else {
+        i += 1;
+    }
+}
+
+

But drain_filter is easier to use. drain_filter is also more efficient, +because it can backshift the elements of the array in bulk.

+

Note that drain_filter also lets you mutate every element in the filter closure, +regardless of whether you choose to keep or remove it.

+

Examples

+

Splitting an array into evens and odds, reusing the original allocation:

+ +
+#![feature(drain_filter)]
+let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];
+
+let evens = numbers.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
+let odds = numbers;
+
+assert_eq!(evens, vec![2, 4, 6, 8, 14]);
+assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]);
+

Trait Implementations

impl PartialEq<Literal> for Literal[src]

#[must_use] +
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests for !=.

+

impl AsRef<[u8]> for Literal[src]

impl Clone for Literal[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Ord for Literal[src]

fn max(self, other: Self) -> Self1.21.0[src]

Compares and returns the maximum of two values. Read more

+

fn min(self, other: Self) -> Self1.21.0[src]

Compares and returns the minimum of two values. Read more

+

fn clamp(self, min: Self, max: Self) -> Self[src]

🔬 This is a nightly-only experimental API. (clamp)

Restrict a value to a certain interval. Read more

+

impl Eq for Literal[src]

impl PartialOrd<Literal> for Literal[src]

#[must_use] +
fn lt(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests less than (for self and other) and is used by the < operator. Read more

+

#[must_use] +
fn le(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more

+

#[must_use] +
fn gt(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests greater than (for self and other) and is used by the > operator. Read more

+

#[must_use] +
fn ge(&self, other: &Rhs) -> bool
1.0.0[src]

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more

+

impl Deref for Literal[src]

type Target = Vec<u8>

The resulting type after dereferencing.

+

impl DerefMut for Literal[src]

impl Debug for Literal[src]

Auto Trait Implementations

impl Send for Literal

impl Sync for Literal

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/literal/struct.Literals.html b/target/doc/regex_syntax/hir/literal/struct.Literals.html new file mode 100644 index 0000000..1f41e54 --- /dev/null +++ b/target/doc/regex_syntax/hir/literal/struct.Literals.html @@ -0,0 +1,124 @@ +regex_syntax::hir::literal::Literals - Rust

[][src]Struct regex_syntax::hir::literal::Literals

pub struct Literals { /* fields omitted */ }

A set of literal byte strings extracted from a regular expression.

+

Every member of the set is a Literal, which is represented by a +Vec<u8>. (Notably, it may contain invalid UTF-8.) Every member is +said to be either complete or cut. A complete literal means that +it extends until the beginning (or end) of the regular expression. In +some circumstances, this can be used to indicate a match in the regular +expression.

+

A key aspect of literal extraction is knowing when to stop. It is not +feasible to blindly extract all literals from a regular expression, even if +there are finitely many. For example, the regular expression [0-9]{10} +has 10^10 distinct literals. For this reason, literal extraction is +bounded to some low number by default using heuristics, but the limits can +be tweaked.

+

WARNING: Literal extraction uses stack space proportional to the size +of the Hir expression. At some point, this drawback will be eliminated. +To protect yourself, set a reasonable +nest_limit on your Parser. +This is done for you by default.

+

Methods

impl Literals[src]

pub fn empty() -> Literals[src]

Returns a new empty set of literals using default limits.

+

pub fn prefixes(expr: &Hir) -> Literals[src]

Returns a set of literal prefixes extracted from the given Hir.

+

pub fn suffixes(expr: &Hir) -> Literals[src]

Returns a set of literal suffixes extracted from the given Hir.

+

pub fn limit_size(&self) -> usize[src]

Get the approximate size limit (in bytes) of this set.

+

pub fn set_limit_size(&mut self, size: usize) -> &mut Literals[src]

Set the approximate size limit (in bytes) of this set.

+

If extracting a literal would put the set over this limit, then +extraction stops.

+

The new limits will only apply to additions to this set. Existing +members remain unchanged, even if the set exceeds the new limit.

+

pub fn limit_class(&self) -> usize[src]

Get the character class size limit for this set.

+

pub fn set_limit_class(&mut self, size: usize) -> &mut Literals[src]

Limits the size of character(or byte) classes considered.

+

A value of 0 prevents all character classes from being considered.

+

This limit also applies to case insensitive literals, since each +character in the case insensitive literal is converted to a class, and +then case folded.

+

The new limits will only apply to additions to this set. Existing +members remain unchanged, even if the set exceeds the new limit.

+

pub fn literals(&self) -> &[Literal][src]

Returns the set of literals as a slice. Its order is unspecified.

+

pub fn min_len(&self) -> Option<usize>[src]

Returns the length of the smallest literal.

+

Returns None is there are no literals in the set.

+

pub fn all_complete(&self) -> bool[src]

Returns true if all members in this set are complete.

+

pub fn any_complete(&self) -> bool[src]

Returns true if any member in this set is complete.

+

pub fn contains_empty(&self) -> bool[src]

Returns true if this set contains an empty literal.

+

pub fn is_empty(&self) -> bool[src]

Returns true if this set is empty or if all of its members is empty.

+

pub fn to_empty(&self) -> Literals[src]

Returns a new empty set of literals using this set's limits.

+

pub fn longest_common_prefix(&self) -> &[u8][src]

Returns the longest common prefix of all members in this set.

+

pub fn longest_common_suffix(&self) -> &[u8][src]

Returns the longest common suffix of all members in this set.

+

pub fn trim_suffix(&self, num_bytes: usize) -> Option<Literals>[src]

Returns a new set of literals with the given number of bytes trimmed +from the suffix of each literal.

+

If any literal would be cut out completely by trimming, then None is +returned.

+

Any duplicates that are created as a result of this transformation are +removed.

+

pub fn unambiguous_prefixes(&self) -> Literals[src]

Returns a new set of prefixes of this set of literals that are +guaranteed to be unambiguous.

+

Any substring match with a member of the set is returned is guaranteed +to never overlap with a substring match of another member of the set +at the same starting position.

+

Given any two members of the returned set, neither is a substring of +the other.

+

pub fn unambiguous_suffixes(&self) -> Literals[src]

Returns a new set of suffixes of this set of literals that are +guaranteed to be unambiguous.

+

Any substring match with a member of the set is returned is guaranteed +to never overlap with a substring match of another member of the set +at the same ending position.

+

Given any two members of the returned set, neither is a substring of +the other.

+

pub fn union_prefixes(&mut self, expr: &Hir) -> bool[src]

Unions the prefixes from the given expression to this set.

+

If prefixes could not be added (for example, this set would exceed its +size limits or the set of prefixes from expr includes the empty +string), then false is returned.

+

Note that prefix literals extracted from expr are said to be complete +if and only if the literal extends from the beginning of expr to the +end of expr.

+

pub fn union_suffixes(&mut self, expr: &Hir) -> bool[src]

Unions the suffixes from the given expression to this set.

+

If suffixes could not be added (for example, this set would exceed its +size limits or the set of suffixes from expr includes the empty +string), then false is returned.

+

Note that prefix literals extracted from expr are said to be complete +if and only if the literal extends from the end of expr to the +beginning of expr.

+

pub fn union(&mut self, lits: Literals) -> bool[src]

Unions this set with another set.

+

If the union would cause the set to exceed its limits, then the union +is skipped and it returns false. Otherwise, if the union succeeds, it +returns true.

+

pub fn cross_product(&mut self, lits: &Literals) -> bool[src]

Extends this set with another set.

+

The set of literals is extended via a cross product.

+

If a cross product would cause this set to exceed its limits, then the +cross product is skipped and it returns false. Otherwise, if the cross +product succeeds, it returns true.

+

pub fn cross_add(&mut self, bytes: &[u8]) -> bool[src]

Extends each literal in this set with the bytes given.

+

If the set is empty, then the given literal is added to the set.

+

If adding any number of bytes to all members of this set causes a limit +to be exceeded, then no bytes are added and false is returned. If a +prefix of bytes can be fit into this set, then it is used and all +resulting literals are cut.

+

pub fn add(&mut self, lit: Literal) -> bool[src]

Adds the given literal to this set.

+

Returns false if adding this literal would cause the class to be too +big.

+

pub fn add_char_class(&mut self, cls: &ClassUnicode) -> bool[src]

Extends each literal in this set with the character class given.

+

Returns false if the character class was too big to add.

+

pub fn add_byte_class(&mut self, cls: &ClassBytes) -> bool[src]

Extends each literal in this set with the byte class given.

+

Returns false if the byte class was too big to add.

+

pub fn cut(&mut self)[src]

Cuts every member of this set. When a member is cut, it can never +be extended.

+

pub fn reverse(&mut self)[src]

Reverses all members in place.

+

pub fn clear(&mut self)[src]

Clears this set of all members.

+

Trait Implementations

impl PartialEq<Literals> for Literals[src]

impl Clone for Literals[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Literals[src]

impl Debug for Literals[src]

Auto Trait Implementations

impl Send for Literals

impl Sync for Literals

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/print/index.html b/target/doc/regex_syntax/hir/print/index.html new file mode 100644 index 0000000..002b971 --- /dev/null +++ b/target/doc/regex_syntax/hir/print/index.html @@ -0,0 +1,5 @@ +regex_syntax::hir::print - Rust

[][src]Module regex_syntax::hir::print

This module provides a regular expression printer for Hir.

+

Structs

+
Printer

A printer for a regular expression's high-level intermediate +representation.

+
\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/print/sidebar-items.js b/target/doc/regex_syntax/hir/print/sidebar-items.js new file mode 100644 index 0000000..5c4fc7a --- /dev/null +++ b/target/doc/regex_syntax/hir/print/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["Printer","A printer for a regular expression's high-level intermediate representation."]]}); \ No newline at end of file diff --git a/target/doc/regex_syntax/hir/print/struct.Printer.html b/target/doc/regex_syntax/hir/print/struct.Printer.html new file mode 100644 index 0000000..6419587 --- /dev/null +++ b/target/doc/regex_syntax/hir/print/struct.Printer.html @@ -0,0 +1,29 @@ +regex_syntax::hir::print::Printer - Rust

[][src]Struct regex_syntax::hir::print::Printer

pub struct Printer { /* fields omitted */ }

A printer for a regular expression's high-level intermediate +representation.

+

A printer converts a high-level intermediate representation (HIR) to a +regular expression pattern string. This particular printer uses constant +stack space and heap space proportional to the size of the HIR.

+

Since this printer is only using the HIR, the pattern it prints will likely +not resemble the original pattern at all. For example, a pattern like +\pL will have its entire class written out.

+

The purpose of this printer is to provide a means to mutate an HIR and then +build a regular expression from the result of that mutation. (A regex +library could provide a constructor from this HIR explicitly, but that +creates an unnecessary public coupling between the regex library and this +specific HIR representation.)

+

Methods

impl Printer[src]

pub fn new() -> Printer[src]

Create a new printer.

+

pub fn print<W: Write>(&mut self, hir: &Hir, wtr: W) -> Result[src]

Print the given Ast to the given writer. The writer must implement +fmt::Write. Typical implementations of fmt::Write that can be used +here are a fmt::Formatter (which is available in fmt::Display +implementations) or a &mut String.

+

Trait Implementations

impl Debug for Printer[src]

Auto Trait Implementations

impl Send for Printer

impl Sync for Printer

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/sidebar-items.js b/target/doc/regex_syntax/hir/sidebar-items.js new file mode 100644 index 0000000..035f004 --- /dev/null +++ b/target/doc/regex_syntax/hir/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"enum":[["Anchor","The high-level intermediate representation for an anchor assertion."],["Class","The high-level intermediate representation of a character class."],["ErrorKind","The type of an error that occurred while building an `Hir`."],["GroupKind","The kind of group."],["HirKind","The kind of an arbitrary `Hir` expression."],["Literal","The high-level intermediate representation of a literal."],["RepetitionKind","The kind of a repetition operator."],["RepetitionRange","The kind of a counted repetition operator."],["WordBoundary","The high-level intermediate representation for a word-boundary assertion."]],"fn":[["visit","Executes an implementation of `Visitor` in constant stack space."]],"mod":[["literal","Provides routines for extracting literal prefixes and suffixes from an `Hir`."],["print","This module provides a regular expression printer for `Hir`."],["translate","Defines a translator that converts an `Ast` to an `Hir`."]],"struct":[["ClassBytes","A set of characters represented by arbitrary bytes (where one byte corresponds to one character)."],["ClassBytesIter","An iterator over all ranges in a byte character class."],["ClassBytesRange","A single range of characters represented by arbitrary bytes."],["ClassUnicode","A set of characters represented by Unicode scalar values."],["ClassUnicodeIter","An iterator over all ranges in a Unicode character class."],["ClassUnicodeRange","A single range of characters represented by Unicode scalar values."],["Error","An error that can occur while translating an `Ast` to a `Hir`."],["Group","The high-level intermediate representation for a group."],["Hir","A high-level intermediate representation (HIR) for a regular expression."],["Repetition","The high-level intermediate representation of a repetition operator."]],"trait":[["Visitor","A trait for visiting the high-level IR (HIR) in depth first order."]]}); \ No newline at end of file diff --git a/target/doc/regex_syntax/hir/struct.ClassBytes.html b/target/doc/regex_syntax/hir/struct.ClassBytes.html new file mode 100644 index 0000000..be746a7 --- /dev/null +++ b/target/doc/regex_syntax/hir/struct.ClassBytes.html @@ -0,0 +1,50 @@ +regex_syntax::hir::ClassBytes - Rust

[][src]Struct regex_syntax::hir::ClassBytes

pub struct ClassBytes { /* fields omitted */ }

A set of characters represented by arbitrary bytes (where one byte +corresponds to one character).

+

Methods

impl ClassBytes[src]

pub fn new<I>(ranges: I) -> ClassBytes where
    I: IntoIterator<Item = ClassBytesRange>, 
[src]

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.

+

pub fn empty() -> ClassBytes[src]

Create a new class with no ranges.

+

pub fn push(&mut self, range: ClassBytesRange)[src]

Add a new range to this set.

+

Important traits for ClassBytesIter<'a>
pub fn iter(&self) -> ClassBytesIter[src]

Return an iterator over all ranges in this class.

+

The iterator yields ranges in ascending order.

+

pub fn ranges(&self) -> &[ClassBytesRange][src]

Return the underlying ranges as a slice.

+

pub fn case_fold_simple(&mut self)[src]

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.

+

pub fn negate(&mut self)[src]

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.

+

pub fn union(&mut self, other: &ClassBytes)[src]

Union this byte class with the given byte class, in place.

+

pub fn intersect(&mut self, other: &ClassBytes)[src]

Intersect this byte class with the given byte class, in place.

+

pub fn difference(&mut self, other: &ClassBytes)[src]

Subtract the given byte class from this byte class, in place.

+

pub fn symmetric_difference(&mut self, other: &ClassBytes)[src]

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'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.

+

pub fn is_all_ascii(&self) -> bool[src]

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.

+

Trait Implementations

impl PartialEq<ClassBytes> for ClassBytes[src]

impl Clone for ClassBytes[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for ClassBytes[src]

impl Debug for ClassBytes[src]

Auto Trait Implementations

impl Send for ClassBytes

impl Sync for ClassBytes

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/struct.ClassBytesIter.html b/target/doc/regex_syntax/hir/struct.ClassBytesIter.html new file mode 100644 index 0000000..0094693 --- /dev/null +++ b/target/doc/regex_syntax/hir/struct.ClassBytesIter.html @@ -0,0 +1,80 @@ +regex_syntax::hir::ClassBytesIter - Rust

[][src]Struct regex_syntax::hir::ClassBytesIter

pub struct ClassBytesIter<'a>(_);

An iterator over all ranges in a byte character class.

+

The lifetime 'a refers to the lifetime of the underlying class.

+

Trait Implementations

impl<'a> Iterator for ClassBytesIter<'a>[src]

type Item = &'a ClassBytesRange

The type of the elements being iterated over.

+

fn size_hint(&self) -> (usize, Option<usize>)1.0.0[src]

Returns the bounds on the remaining length of the iterator. Read more

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

impl<'a> Debug for ClassBytesIter<'a>[src]

Auto Trait Implementations

impl<'a> Send for ClassBytesIter<'a>

impl<'a> Sync for ClassBytesIter<'a>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/struct.ClassBytesRange.html b/target/doc/regex_syntax/hir/struct.ClassBytesRange.html new file mode 100644 index 0000000..72214a1 --- /dev/null +++ b/target/doc/regex_syntax/hir/struct.ClassBytesRange.html @@ -0,0 +1,41 @@ +regex_syntax::hir::ClassBytesRange - Rust

[][src]Struct regex_syntax::hir::ClassBytesRange

pub struct ClassBytesRange { /* fields omitted */ }

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.

+

Methods

impl ClassBytesRange[src]

pub fn new(start: u8, end: u8) -> ClassBytesRange[src]

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 <= end.

+

pub fn start(&self) -> u8[src]

Return the start of this range.

+

The start of a range is always less than or equal to the end of the +range.

+

pub fn end(&self) -> u8[src]

Return the end of this range.

+

The end of a range is always greater than or equal to the start of the +range.

+

Trait Implementations

impl PartialEq<ClassBytesRange> for ClassBytesRange[src]

impl Clone for ClassBytesRange[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Ord for ClassBytesRange[src]

fn max(self, other: Self) -> Self1.21.0[src]

Compares and returns the maximum of two values. Read more

+

fn min(self, other: Self) -> Self1.21.0[src]

Compares and returns the minimum of two values. Read more

+

fn clamp(self, min: Self, max: Self) -> Self[src]

🔬 This is a nightly-only experimental API. (clamp)

Restrict a value to a certain interval. Read more

+

impl Default for ClassBytesRange[src]

impl Eq for ClassBytesRange[src]

impl Copy for ClassBytesRange[src]

impl PartialOrd<ClassBytesRange> for ClassBytesRange[src]

impl Debug for ClassBytesRange[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/struct.ClassUnicode.html b/target/doc/regex_syntax/hir/struct.ClassUnicode.html new file mode 100644 index 0000000..b3ef351 --- /dev/null +++ b/target/doc/regex_syntax/hir/struct.ClassUnicode.html @@ -0,0 +1,46 @@ +regex_syntax::hir::ClassUnicode - Rust

[][src]Struct regex_syntax::hir::ClassUnicode

pub struct ClassUnicode { /* fields omitted */ }

A set of characters represented by Unicode scalar values.

+

Methods

impl ClassUnicode[src]

pub fn new<I>(ranges: I) -> ClassUnicode where
    I: IntoIterator<Item = ClassUnicodeRange>, 
[src]

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.

+

pub fn empty() -> ClassUnicode[src]

Create a new class with no ranges.

+

pub fn push(&mut self, range: ClassUnicodeRange)[src]

Add a new range to this set.

+

Important traits for ClassUnicodeIter<'a>
pub fn iter(&self) -> ClassUnicodeIter[src]

Return an iterator over all ranges in this class.

+

The iterator yields ranges in ascending order.

+

pub fn ranges(&self) -> &[ClassUnicodeRange][src]

Return the underlying ranges as a slice.

+

pub fn case_fold_simple(&mut self)[src]

Expand this character class such that it contains all case folded +characters, according to Unicode's "simple" 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.

+

pub fn negate(&mut self)[src]

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.

+

pub fn union(&mut self, other: &ClassUnicode)[src]

Union this character class with the given character class, in place.

+

pub fn intersect(&mut self, other: &ClassUnicode)[src]

Intersect this character class with the given character class, in +place.

+

pub fn difference(&mut self, other: &ClassUnicode)[src]

Subtract the given character class from this character class, in place.

+

pub fn symmetric_difference(&mut self, other: &ClassUnicode)[src]

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'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.

+

Trait Implementations

impl PartialEq<ClassUnicode> for ClassUnicode[src]

impl Clone for ClassUnicode[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for ClassUnicode[src]

impl Debug for ClassUnicode[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/struct.ClassUnicodeIter.html b/target/doc/regex_syntax/hir/struct.ClassUnicodeIter.html new file mode 100644 index 0000000..5a9ccbb --- /dev/null +++ b/target/doc/regex_syntax/hir/struct.ClassUnicodeIter.html @@ -0,0 +1,80 @@ +regex_syntax::hir::ClassUnicodeIter - Rust

[][src]Struct regex_syntax::hir::ClassUnicodeIter

pub struct ClassUnicodeIter<'a>(_);

An iterator over all ranges in a Unicode character class.

+

The lifetime 'a refers to the lifetime of the underlying class.

+

Trait Implementations

impl<'a> Iterator for ClassUnicodeIter<'a>[src]

type Item = &'a ClassUnicodeRange

The type of the elements being iterated over.

+

fn size_hint(&self) -> (usize, Option<usize>)1.0.0[src]

Returns the bounds on the remaining length of the iterator. Read more

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

impl<'a> Debug for ClassUnicodeIter<'a>[src]

Auto Trait Implementations

impl<'a> Send for ClassUnicodeIter<'a>

impl<'a> Sync for ClassUnicodeIter<'a>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/struct.ClassUnicodeRange.html b/target/doc/regex_syntax/hir/struct.ClassUnicodeRange.html new file mode 100644 index 0000000..0e772b3 --- /dev/null +++ b/target/doc/regex_syntax/hir/struct.ClassUnicodeRange.html @@ -0,0 +1,41 @@ +regex_syntax::hir::ClassUnicodeRange - Rust

[][src]Struct regex_syntax::hir::ClassUnicodeRange

pub struct ClassUnicodeRange { /* fields omitted */ }

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.

+

Methods

impl ClassUnicodeRange[src]

pub fn new(start: char, end: char) -> ClassUnicodeRange[src]

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 <= end.

+

pub fn start(&self) -> char[src]

Return the start of this range.

+

The start of a range is always less than or equal to the end of the +range.

+

pub fn end(&self) -> char[src]

Return the end of this range.

+

The end of a range is always greater than or equal to the start of the +range.

+

Trait Implementations

impl PartialEq<ClassUnicodeRange> for ClassUnicodeRange[src]

impl Clone for ClassUnicodeRange[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Ord for ClassUnicodeRange[src]

fn max(self, other: Self) -> Self1.21.0[src]

Compares and returns the maximum of two values. Read more

+

fn min(self, other: Self) -> Self1.21.0[src]

Compares and returns the minimum of two values. Read more

+

fn clamp(self, min: Self, max: Self) -> Self[src]

🔬 This is a nightly-only experimental API. (clamp)

Restrict a value to a certain interval. Read more

+

impl Default for ClassUnicodeRange[src]

impl Eq for ClassUnicodeRange[src]

impl Copy for ClassUnicodeRange[src]

impl PartialOrd<ClassUnicodeRange> for ClassUnicodeRange[src]

impl Debug for ClassUnicodeRange[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/struct.Error.html b/target/doc/regex_syntax/hir/struct.Error.html new file mode 100644 index 0000000..aa36fea --- /dev/null +++ b/target/doc/regex_syntax/hir/struct.Error.html @@ -0,0 +1,31 @@ +regex_syntax::hir::Error - Rust

[][src]Struct regex_syntax::hir::Error

pub struct Error { /* fields omitted */ }

An error that can occur while translating an Ast to a Hir.

+

Methods

impl Error[src]

pub fn kind(&self) -> &ErrorKind[src]

Return the type of this error.

+

pub fn pattern(&self) -> &str[src]

The original pattern string in which this error occurred.

+

Every span reported by this error is reported in terms of this string.

+

pub fn span(&self) -> &Span[src]

Return the span at which this error occurred.

+

Trait Implementations

impl PartialEq<Error> for Error[src]

impl From<Error> for Error[src]

impl Clone for Error[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Error[src]

impl Display for Error[src]

impl Debug for Error[src]

impl Error for Error[src]

fn cause(&self) -> Option<&dyn Error>1.0.0[src]

Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

+

The lower-level cause of this error, if any. Read more

+

fn source(&self) -> Option<&(dyn Error + 'static)>1.30.0[src]

The lower-level source of this error, if any. Read more

+

Auto Trait Implementations

impl Send for Error

impl Sync for Error

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/struct.Group.html b/target/doc/regex_syntax/hir/struct.Group.html new file mode 100644 index 0000000..feba08b --- /dev/null +++ b/target/doc/regex_syntax/hir/struct.Group.html @@ -0,0 +1,34 @@ +regex_syntax::hir::Group - Rust

[][src]Struct regex_syntax::hir::Group

pub struct Group {
+    pub kind: GroupKind,
+    pub hir: Box<Hir>,
+}

The high-level intermediate representation for a group.

+

This represents one of three possible group types:

+
    +
  1. A non-capturing group (e.g., (?:expr)).
  2. +
  3. A capturing group (e.g., (expr)).
  4. +
  5. A named capturing group (e.g., (?P<name>expr)).
  6. +
+

+ Fields

kind: GroupKind

The kind of this group. If it is a capturing group, then the kind +contains the capture group index (and the name, if it is a named +group).

+
hir: Box<Hir>

The expression inside the capturing group, which may be empty.

+

Trait Implementations

impl PartialEq<Group> for Group[src]

impl Clone for Group[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Group[src]

impl Debug for Group[src]

Auto Trait Implementations

impl Send for Group

impl Sync for Group

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/struct.Hir.html b/target/doc/regex_syntax/hir/struct.Hir.html new file mode 100644 index 0000000..0b269cb --- /dev/null +++ b/target/doc/regex_syntax/hir/struct.Hir.html @@ -0,0 +1,142 @@ +regex_syntax::hir::Hir - Rust

[][src]Struct regex_syntax::hir::Hir

pub struct Hir { /* fields omitted */ }

A high-level intermediate representation (HIR) for a regular expression.

+

The HIR of a regular expression represents an intermediate step between its +abstract syntax (a structured description of the concrete syntax) and +compiled byte codes. 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 "compile away" 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]).

+

If the HIR was produced by a translator that disallows invalid UTF-8, then +the HIR is guaranteed to match UTF-8 exclusively.

+

This type defines its own destructor that uses constant stack space and +heap space proportional to the size of the HIR.

+

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 "concatenations +always consist of two or more sub-expressions."
  2. +
  3. 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 text.
  4. +
+

Also, an Hir'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.

+

Methods

impl Hir[src]

pub fn kind(&self) -> &HirKind[src]

Returns a reference to the underlying HIR kind.

+

pub fn into_kind(self) -> HirKind[src]

Consumes ownership of this HIR expression and returns its underlying +HirKind.

+

pub fn empty() -> Hir[src]

Returns an empty HIR expression.

+

An empty HIR expression always matches, including the empty string.

+

pub fn literal(lit: Literal) -> Hir[src]

Creates a literal HIR expression.

+

If the given literal has a Byte variant with an ASCII byte, then this +method panics. This enforces the invariant that Byte variants are +only used to express matching of invalid UTF-8.

+

pub fn class(class: Class) -> Hir[src]

Creates a class HIR expression.

+

pub fn anchor(anchor: Anchor) -> Hir[src]

Creates an anchor assertion HIR expression.

+

pub fn word_boundary(word_boundary: WordBoundary) -> Hir[src]

Creates a word boundary assertion HIR expression.

+

pub fn repetition(rep: Repetition) -> Hir[src]

Creates a repetition HIR expression.

+

pub fn group(group: Group) -> Hir[src]

Creates a group HIR expression.

+

pub fn concat(exprs: Vec<Hir>) -> Hir[src]

Returns the concatenation of the given expressions.

+

This flattens the concatenation as appropriate.

+

pub fn alternation(exprs: Vec<Hir>) -> Hir[src]

Returns the alternation of the given expressions.

+

This flattens the alternation as appropriate.

+

pub fn dot(bytes: bool) -> Hir[src]

Build an HIR expression for ..

+

A . expression matches any character except for \n. To build an +expression that matches any character, including \n, use the any +method.

+

If bytes is true, then this assumes characters are limited to a +single byte.

+

pub fn any(bytes: bool) -> Hir[src]

Build an HIR expression for (?s)..

+

A (?s). expression matches any character, including \n. To build an +expression that matches any character except for \n, then use the +dot method.

+

If bytes is true, then this assumes characters are limited to a +single byte.

+

pub fn is_always_utf8(&self) -> bool[src]

Return true if and only if this HIR will always match valid UTF-8.

+

When this returns false, then it is possible for this HIR expression +to match invalid UTF-8.

+

pub fn is_all_assertions(&self) -> bool[src]

Returns true if and only if this entire HIR expression is made up of +zero-width assertions.

+

This includes expressions like ^$\b\A\z and even ((\b)+())*^, but +not ^a.

+

pub fn is_anchored_start(&self) -> bool[src]

Return true if and only if this HIR is required to match from the +beginning of text. This includes expressions like ^foo, ^(foo|bar), +^foo|^bar but not ^foo|bar.

+

pub fn is_anchored_end(&self) -> bool[src]

Return true if and only if this HIR is required to match at the end +of text. This includes expressions like foo$, (foo|bar)$, +foo$|bar$ but not foo$|bar.

+

pub fn is_line_anchored_start(&self) -> bool[src]

Return true if and only if this HIR is required to match from the +beginning of text or the beginning of a line. This includes expressions +like ^foo, (?m)^foo, ^(foo|bar), ^(foo|bar), (?m)^foo|^bar +but not ^foo|bar or (?m)^foo|bar.

+

Note that if is_anchored_start is true, then +is_line_anchored_start will also be true. The reverse implication +is not true. For example, (?m)^foo is line anchored, but not +is_anchored_start.

+

pub fn is_line_anchored_end(&self) -> bool[src]

Return true if and only if this HIR is required to match at the +end of text or the end of a line. This includes expressions like +foo$, (?m)foo$, (foo|bar)$, (?m)(foo|bar)$, foo$|bar$, +(?m)(foo|bar)$, but not foo$|bar or (?m)foo$|bar.

+

Note that if is_anchored_end is true, then +is_line_anchored_end will also be true. The reverse implication +is not true. For example, (?m)foo$ is line anchored, but not +is_anchored_end.

+

pub fn is_any_anchored_start(&self) -> bool[src]

Return true if and only if this HIR contains any sub-expression that +is required to match at the beginning of text. Specifically, this +returns true if the ^ symbol (when multiline mode is disabled) or the +\A escape appear anywhere in the regex.

+

pub fn is_any_anchored_end(&self) -> bool[src]

Return true if and only if this HIR contains any sub-expression that is +required to match at the end of text. Specifically, this returns true +if the $ symbol (when multiline mode is disabled) or the \z escape +appear anywhere in the regex.

+

pub fn is_match_empty(&self) -> bool[src]

Return true if and only if the empty string is part of the language +matched by this regular expression.

+

This includes a*, a?b*, a{0}, (), ()+, ^$, a|b?, \B, +but not a, a+ or \b.

+

pub fn is_literal(&self) -> bool[src]

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 Literals.

+

For example, f and foo are literals, but f+, (foo), foo() +are not (even though that contain sub-expressions that are literals).

+

pub fn is_alternation_literal(&self) -> bool[src]

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 Literals or an alternation of only Literals.

+

For example, f, foo, a|b|c, and foo|bar|baz are alternaiton +literals, but f+, (foo), foo() +are not (even though that contain sub-expressions that are literals).

+

Trait Implementations

impl PartialEq<Hir> for Hir[src]

impl Clone for Hir[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Hir[src]

impl Drop for Hir[src]

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.

+

impl Display for Hir[src]

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.

+

impl Debug for Hir[src]

Auto Trait Implementations

impl Send for Hir

impl Sync for Hir

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/struct.Repetition.html b/target/doc/regex_syntax/hir/struct.Repetition.html new file mode 100644 index 0000000..9dd2ab4 --- /dev/null +++ b/target/doc/regex_syntax/hir/struct.Repetition.html @@ -0,0 +1,43 @@ +regex_syntax::hir::Repetition - Rust

[][src]Struct regex_syntax::hir::Repetition

pub struct Repetition {
+    pub kind: RepetitionKind,
+    pub greedy: bool,
+    pub hir: Box<Hir>,
+}

The high-level intermediate representation of a repetition operator.

+

A repetition operator permits the repetition of an arbitrary +sub-expression.

+

+ Fields

kind: RepetitionKind

The kind of this repetition operator.

+
greedy: bool

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 "ungreedy" flag.

+
hir: Box<Hir>

The expression being repeated.

+

Methods

impl Repetition[src]

pub fn is_match_empty(&self) -> bool[src]

Returns true if and only if this repetition operator makes it possible +to match the empty string.

+

Note that this is not defined inductively. For example, while a* +will report true, ()+ will not, even though () matches the empty +string and one or more occurrences of something that matches the empty +string will always match the empty string. In order to get the +inductive definition, see the corresponding method on +Hir.

+

Trait Implementations

impl PartialEq<Repetition> for Repetition[src]

impl Clone for Repetition[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Repetition[src]

impl Debug for Repetition[src]

Auto Trait Implementations

impl Send for Repetition

impl Sync for Repetition

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/trait.Visitor.html b/target/doc/regex_syntax/hir/trait.Visitor.html new file mode 100644 index 0000000..8404800 --- /dev/null +++ b/target/doc/regex_syntax/hir/trait.Visitor.html @@ -0,0 +1,34 @@ +regex_syntax::hir::Visitor - Rust

[][src]Trait regex_syntax::hir::Visitor

pub trait Visitor {
+    type Output;
+    type Err;
+    fn finish(self) -> Result<Self::Output, Self::Err>;
+
+    fn start(&mut self) { ... }
+
fn visit_pre(&mut self, _hir: &Hir) -> Result<(), Self::Err> { ... } +
fn visit_post(&mut self, _hir: &Hir) -> Result<(), Self::Err> { ... } +
fn visit_alternation_in(&mut self) -> Result<(), Self::Err> { ... } +}

A trait for visiting the high-level IR (HIR) in depth first order.

+

The principle aim of this trait is to enable callers to perform case +analysis on a high-level intermediate representation of a regular +expression without necessarily using recursion. In particular, this permits +callers to do case analysis with constant stack usage, which can be +important since the size of an HIR may be proportional to end user input.

+

Typical usage of this trait involves providing an implementation and then +running it using the visit function.

+
+

Associated Types

type Output

The result of visiting an HIR.

+

type Err

An error that visiting an HIR might return.

+
Loading content... +

Required methods

fn finish(self) -> Result<Self::Output, Self::Err>

All implementors of Visitor must provide a finish method, which +yields the result of visiting the HIR or an error.

+
Loading content... +

Provided methods

fn start(&mut self)

This method is called before beginning traversal of the HIR.

+

fn visit_pre(&mut self, _hir: &Hir) -> Result<(), Self::Err>

This method is called on an Hir before descending into child Hir +nodes.

+

fn visit_post(&mut self, _hir: &Hir) -> Result<(), Self::Err>

This method is called on an Hir after descending all of its child +Hir nodes.

+

fn visit_alternation_in(&mut self) -> Result<(), Self::Err>

This method is called between child nodes of an alternation.

+
Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/translate/index.html b/target/doc/regex_syntax/hir/translate/index.html new file mode 100644 index 0000000..b0d39b2 --- /dev/null +++ b/target/doc/regex_syntax/hir/translate/index.html @@ -0,0 +1,6 @@ +regex_syntax::hir::translate - Rust

[][src]Module regex_syntax::hir::translate

Defines a translator that converts an Ast to an Hir.

+

Structs

+
Translator

A translator maps abstract syntax to a high level intermediate +representation.

+
TranslatorBuilder

A builder for constructing an AST->HIR translator.

+
\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/translate/sidebar-items.js b/target/doc/regex_syntax/hir/translate/sidebar-items.js new file mode 100644 index 0000000..dedca84 --- /dev/null +++ b/target/doc/regex_syntax/hir/translate/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["Translator","A translator maps abstract syntax to a high level intermediate representation."],["TranslatorBuilder","A builder for constructing an AST->HIR translator."]]}); \ No newline at end of file diff --git a/target/doc/regex_syntax/hir/translate/struct.Translator.html b/target/doc/regex_syntax/hir/translate/struct.Translator.html new file mode 100644 index 0000000..6bbeaef --- /dev/null +++ b/target/doc/regex_syntax/hir/translate/struct.Translator.html @@ -0,0 +1,31 @@ +regex_syntax::hir::translate::Translator - Rust

[][src]Struct regex_syntax::hir::translate::Translator

pub struct Translator { /* fields omitted */ }

A translator maps abstract syntax to a high level intermediate +representation.

+

A translator may be benefit from reuse. That is, a translator can translate +many abstract syntax trees.

+

A Translator can be configured in more detail via a +TranslatorBuilder.

+

Methods

impl Translator[src]

pub fn new() -> Translator[src]

Create a new translator using the default configuration.

+

pub fn translate(&mut self, pattern: &str, ast: &Ast) -> Result<Hir, Error>[src]

Translate the given abstract syntax tree (AST) into a high level +intermediate representation (HIR).

+

If there was a problem doing the translation, then an HIR-specific +error is returned.

+

The original pattern string used to produce the Ast must also be +provided. The translator does not use the pattern string during any +correct translation, but is used for error reporting.

+

Trait Implementations

impl Clone for Translator[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Debug for Translator[src]

Auto Trait Implementations

impl Send for Translator

impl !Sync for Translator

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/translate/struct.TranslatorBuilder.html b/target/doc/regex_syntax/hir/translate/struct.TranslatorBuilder.html new file mode 100644 index 0000000..0a2feb8 --- /dev/null +++ b/target/doc/regex_syntax/hir/translate/struct.TranslatorBuilder.html @@ -0,0 +1,36 @@ +regex_syntax::hir::translate::TranslatorBuilder - Rust

[][src]Struct regex_syntax::hir::translate::TranslatorBuilder

pub struct TranslatorBuilder { /* fields omitted */ }

A builder for constructing an AST->HIR translator.

+

Methods

impl TranslatorBuilder[src]

pub fn new() -> TranslatorBuilder[src]

Create a new translator builder with a default c onfiguration.

+

pub fn build(&self) -> Translator[src]

Build a translator using the current configuration.

+

pub fn allow_invalid_utf8(&mut self, yes: bool) -> &mut TranslatorBuilder[src]

When enabled, translation will permit the construction of a regular +expression that may match invalid UTF-8.

+

When disabled (the default), the translator is guaranteed to produce +an expression that will only ever match valid UTF-8 (otherwise, the +translator will return an error).

+

Perhaps surprisingly, when invalid UTF-8 isn't allowed, a negated ASCII +word boundary (uttered as (?-u:\B) in the concrete syntax) will cause +the parser to return an error. Namely, a negated ASCII word boundary +can result in matching positions that aren't valid UTF-8 boundaries.

+

pub fn case_insensitive(&mut self, yes: bool) -> &mut TranslatorBuilder[src]

Enable or disable the case insensitive flag (i) by default.

+

pub fn multi_line(&mut self, yes: bool) -> &mut TranslatorBuilder[src]

Enable or disable the multi-line matching flag (m) by default.

+

pub fn dot_matches_new_line(&mut self, yes: bool) -> &mut TranslatorBuilder[src]

Enable or disable the "dot matches any character" flag (s) by +default.

+

pub fn swap_greed(&mut self, yes: bool) -> &mut TranslatorBuilder[src]

Enable or disable the "swap greed" flag (U) by default.

+

pub fn unicode(&mut self, yes: bool) -> &mut TranslatorBuilder[src]

Enable or disable the Unicode flag (u) by default.

+

Trait Implementations

impl Clone for TranslatorBuilder[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Default for TranslatorBuilder[src]

impl Debug for TranslatorBuilder[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/hir/visitor/fn.visit.html b/target/doc/regex_syntax/hir/visitor/fn.visit.html new file mode 100644 index 0000000..92be9c1 --- /dev/null +++ b/target/doc/regex_syntax/hir/visitor/fn.visit.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../regex_syntax/hir/fn.visit.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex_syntax/hir/visitor/trait.Visitor.html b/target/doc/regex_syntax/hir/visitor/trait.Visitor.html new file mode 100644 index 0000000..c8f8499 --- /dev/null +++ b/target/doc/regex_syntax/hir/visitor/trait.Visitor.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../regex_syntax/hir/trait.Visitor.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex_syntax/index.html b/target/doc/regex_syntax/index.html new file mode 100644 index 0000000..3d5d960 --- /dev/null +++ b/target/doc/regex_syntax/index.html @@ -0,0 +1,93 @@ +regex_syntax - Rust

[][src]Crate regex_syntax

This crate provides a robust regular expression parser.

+

This crate defines two primary types:

+
    +
  • Ast is the abstract syntax of a regular expression. +An abstract syntax corresponds to a structured representation of the +concrete syntax of a regular expression, where the concrete syntax is the +pattern string itself (e.g., foo(bar)+). Given some abstract syntax, it +can be converted back to the original concrete syntax (modulo some details, +like whitespace). To a first approximation, the abstract syntax is complex +and difficult to analyze.
  • +
  • Hir is the high-level intermediate representation +("HIR" or "high-level IR" for short) of regular expression. It corresponds to +an intermediate state of a regular expression that sits between the abstract +syntax and the low level compiled opcodes that are eventually responsible for +executing a regular expression search. Given some high-level IR, it is not +possible to produce the original concrete syntax (although it is possible to +produce an equivalent concrete syntax, but it will likely scarcely resemble +the original pattern). To a first approximation, the high-level IR is simple +and easy to analyze.
  • +
+

These two types come with conversion routines:

+ +

As a convenience, the above two conversion routines are combined into one via +the top-level Parser type. This Parser will first +convert your pattern to an Ast and then convert the Ast to an Hir.

+

Example

+

This example shows how to parse a pattern string into its HIR:

+ +
+use regex_syntax::Parser;
+use regex_syntax::hir::{self, Hir};
+
+let hir = Parser::new().parse("a|b").unwrap();
+assert_eq!(hir, Hir::alternation(vec![
+    Hir::literal(hir::Literal::Unicode('a')),
+    Hir::literal(hir::Literal::Unicode('b')),
+]));
+

Concrete syntax supported

+

The concrete syntax is documented as part of the public API of the +regex crate.

+

Input safety

+

A key feature of this library is that it is safe to use with end user facing +input. This plays a significant role in the internal implementation. In +particular:

+
    +
  1. Parsers provide a nest_limit option that permits callers to control how +deeply nested a regular expression is allowed to be. This makes it possible +to do case analysis over an Ast or an Hir using recursion without +worrying about stack overflow.
  2. +
  3. Since relying on a particular stack size is brittle, this crate goes to +great lengths to ensure that all interactions with both the Ast and the +Hir do not use recursion. Namely, they use constant stack space and heap +space proportional to the size of the original pattern string (in bytes). +This includes the type's corresponding destructors. (One exception to this +is literal extraction, but this will eventually get fixed.)
  4. +
+

Error reporting

+

The Display implementations on all Error types exposed in this library +provide nice human readable errors that are suitable for showing to end users +in a monospace font.

+

Literal extraction

+

This crate provides limited support for +literal extraction from Hir values. +Be warned that literal extraction currently uses recursion, and therefore, +stack size proportional to the size of the Hir.

+

The purpose of literal extraction is to speed up searches. That is, if you +know a regular expression must match a prefix or suffix literal, then it is +often quicker to search for instances of that literal, and then confirm or deny +the match using the full regular expression engine. These optimizations are +done automatically in the regex crate.

+

Modules

+
ast

Defines an abstract syntax for regular expressions.

+
hir

Defines a high-level intermediate representation for regular expressions.

+

Structs

+
Parser

A convenience parser for regular expressions.

+
ParserBuilder

A builder for a regular expression parser.

+

Enums

+
Error

This error type encompasses any error that can be returned by this crate.

+

Functions

+
escape

Escapes all regular expression meta characters in text.

+
escape_into

Escapes all meta characters in text and writes the result into buf.

+
is_meta_character

Returns true if the give character has significance in a regex.

+
is_word_byte

Returns true if and only if the given character is an ASCII word character.

+
is_word_character

Returns true if and only if the given character is a Unicode word +character.

+

Type Definitions

+
Result

A type alias for dealing with errors returned by this crate.

+
\ No newline at end of file diff --git a/target/doc/regex_syntax/parser/struct.Parser.html b/target/doc/regex_syntax/parser/struct.Parser.html new file mode 100644 index 0000000..aa4290e --- /dev/null +++ b/target/doc/regex_syntax/parser/struct.Parser.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex_syntax/struct.Parser.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex_syntax/parser/struct.ParserBuilder.html b/target/doc/regex_syntax/parser/struct.ParserBuilder.html new file mode 100644 index 0000000..85622b6 --- /dev/null +++ b/target/doc/regex_syntax/parser/struct.ParserBuilder.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../regex_syntax/struct.ParserBuilder.html...

+ + + \ No newline at end of file diff --git a/target/doc/regex_syntax/sidebar-items.js b/target/doc/regex_syntax/sidebar-items.js new file mode 100644 index 0000000..655a02a --- /dev/null +++ b/target/doc/regex_syntax/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"enum":[["Error","This error type encompasses any error that can be returned by this crate."]],"fn":[["escape","Escapes all regular expression meta characters in `text`."],["escape_into","Escapes all meta characters in `text` and writes the result into `buf`."],["is_meta_character","Returns true if the give character has significance in a regex."],["is_word_byte","Returns true if and only if the given character is an ASCII word character."],["is_word_character","Returns true if and only if the given character is a Unicode word character."]],"mod":[["ast","Defines an abstract syntax for regular expressions."],["hir","Defines a high-level intermediate representation for regular expressions."]],"struct":[["Parser","A convenience parser for regular expressions."],["ParserBuilder","A builder for a regular expression parser."]],"type":[["Result","A type alias for dealing with errors returned by this crate."]]}); \ No newline at end of file diff --git a/target/doc/regex_syntax/struct.Parser.html b/target/doc/regex_syntax/struct.Parser.html new file mode 100644 index 0000000..f6554dd --- /dev/null +++ b/target/doc/regex_syntax/struct.Parser.html @@ -0,0 +1,36 @@ +regex_syntax::Parser - Rust

[][src]Struct regex_syntax::Parser

pub struct Parser { /* fields omitted */ }

A convenience parser for regular expressions.

+

This parser takes as input a regular expression pattern string (the +"concrete syntax") and returns a high-level intermediate representation +(the HIR) suitable for most types of analysis. In particular, this parser +hides the intermediate state of producing an AST (the "abstract syntax"). +The AST is itself far more complex than the HIR, so this parser serves as a +convenience for never having to deal with it at all.

+

If callers have more fine grained use cases that need an AST, then please +see the ast::parse module.

+

A Parser can be configured in more detail via a +ParserBuilder.

+

Methods

impl Parser[src]

pub fn new() -> Parser[src]

Create a new parser with a default configuration.

+

The parser can be run with parse method. The parse method returns +a high level intermediate representation of the given regular +expression.

+

To set configuration options on the parser, use +ParserBuilder.

+

pub fn parse(&mut self, pattern: &str) -> Result<Hir>[src]

Parse the regular expression into a high level intermediate +representation.

+

Trait Implementations

impl Clone for Parser[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Debug for Parser[src]

Auto Trait Implementations

impl Send for Parser

impl !Sync for Parser

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/struct.ParserBuilder.html b/target/doc/regex_syntax/struct.ParserBuilder.html new file mode 100644 index 0000000..561403b --- /dev/null +++ b/target/doc/regex_syntax/struct.ParserBuilder.html @@ -0,0 +1,92 @@ +regex_syntax::ParserBuilder - Rust

[][src]Struct regex_syntax::ParserBuilder

pub struct ParserBuilder { /* fields omitted */ }

A builder for a regular expression parser.

+

This builder permits modifying configuration options for the parser.

+

This type combines the builder options for both the +AST ParserBuilder +and the +HIR TranslatorBuilder.

+

Methods

impl ParserBuilder[src]

pub fn new() -> ParserBuilder[src]

Create a new parser builder with a default configuration.

+

pub fn build(&self) -> Parser[src]

Build a parser from this configuration with the given pattern.

+

pub fn nest_limit(&mut self, limit: u32) -> &mut ParserBuilder[src]

Set the nesting limit for this parser.

+

The nesting limit controls how deep the abstract syntax tree is allowed +to be. If the AST exceeds the given limit (e.g., with too many nested +groups), then an error is returned by the parser.

+

The purpose of this limit is to act as a heuristic to prevent stack +overflow for consumers that do structural induction on an Ast using +explicit recursion. While this crate never does this (instead using +constant stack space and moving the call stack to the heap), other +crates may.

+

This limit is not checked until the entire Ast is parsed. Therefore, +if callers want to put a limit on the amount of heap space used, then +they should impose a limit on the length, in bytes, of the concrete +pattern string. In particular, this is viable since this parser +implementation will limit itself to heap space proportional to the +lenth of the pattern string.

+

Note that a nest limit of 0 will return a nest limit error for most +patterns but not all. For example, a nest limit of 0 permits a but +not ab, since ab requires a concatenation, which results in a nest +depth of 1. In general, a nest limit is not something that manifests +in an obvious way in the concrete syntax, therefore, it should not be +used in a granular way.

+

pub fn octal(&mut self, yes: bool) -> &mut ParserBuilder[src]

Whether to support octal syntax or not.

+

Octal syntax is a little-known way of uttering Unicode codepoints in +a regular expression. For example, a, \x61, \u0061 and +\141 are all equivalent regular expressions, where the last example +shows octal syntax.

+

While supporting octal syntax isn't in and of itself a problem, it does +make good error messages harder. That is, in PCRE based regex engines, +syntax like \0 invokes a backreference, which is explicitly +unsupported in Rust's regex engine. However, many users expect it to +be supported. Therefore, when octal support is disabled, the error +message will explicitly mention that backreferences aren't supported.

+

Octal syntax is disabled by default.

+

pub fn allow_invalid_utf8(&mut self, yes: bool) -> &mut ParserBuilder[src]

When enabled, the parser will permit the construction of a regular +expression that may match invalid UTF-8.

+

When disabled (the default), the parser is guaranteed to produce +an expression that will only ever match valid UTF-8 (otherwise, the +parser will return an error).

+

Perhaps surprisingly, when invalid UTF-8 isn't allowed, a negated ASCII +word boundary (uttered as (?-u:\B) in the concrete syntax) will cause +the parser to return an error. Namely, a negated ASCII word boundary +can result in matching positions that aren't valid UTF-8 boundaries.

+

pub fn ignore_whitespace(&mut self, yes: bool) -> &mut ParserBuilder[src]

Enable verbose mode in the regular expression.

+

When enabled, verbose mode permits insigificant whitespace in many +places in the regular expression, as well as comments. Comments are +started using # and continue until the end of the line.

+

By default, this is disabled. It may be selectively enabled in the +regular expression by using the x flag regardless of this setting.

+

pub fn case_insensitive(&mut self, yes: bool) -> &mut ParserBuilder[src]

Enable or disable the case insensitive flag by default.

+

By default this is disabled. It may alternatively be selectively +enabled in the regular expression itself via the i flag.

+

pub fn multi_line(&mut self, yes: bool) -> &mut ParserBuilder[src]

Enable or disable the multi-line matching flag by default.

+

By default this is disabled. It may alternatively be selectively +enabled in the regular expression itself via the m flag.

+

pub fn dot_matches_new_line(&mut self, yes: bool) -> &mut ParserBuilder[src]

Enable or disable the "dot matches any character" flag by default.

+

By default this is disabled. It may alternatively be selectively +enabled in the regular expression itself via the s flag.

+

pub fn swap_greed(&mut self, yes: bool) -> &mut ParserBuilder[src]

Enable or disable the "swap greed" flag by default.

+

By default this is disabled. It may alternatively be selectively +enabled in the regular expression itself via the U flag.

+

pub fn unicode(&mut self, yes: bool) -> &mut ParserBuilder[src]

Enable or disable the Unicode flag (u) by default.

+

By default this is enabled. It may alternatively be selectively +disabled in the regular expression itself via the u flag.

+

Note that unless allow_invalid_utf8 is enabled (it's disabled by +default), a regular expression will fail to parse if Unicode mode is +disabled and a sub-expression could possibly match invalid UTF-8.

+

Trait Implementations

impl Clone for ParserBuilder[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Default for ParserBuilder[src]

impl Debug for ParserBuilder[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/regex_syntax/type.Result.html b/target/doc/regex_syntax/type.Result.html new file mode 100644 index 0000000..318f46f --- /dev/null +++ b/target/doc/regex_syntax/type.Result.html @@ -0,0 +1,2 @@ +regex_syntax::Result - Rust

[][src]Type Definition regex_syntax::Result

type Result<T> = Result<T, Error>;

A type alias for dealing with errors returned by this crate.

+
\ No newline at end of file diff --git a/target/doc/rust-logo.png b/target/doc/rust-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..74b4bd695045ebc52c21af95301adc9311ca881c GIT binary patch literal 5758 zcmV-^7J=!BP)rlOar#xVHcKR}urj-85WU}*d52ce!FO;4x1(Dd{rLvS^kzaz+Qg+43&c`E^ z2A4h%FgKT)L-C6=0SiO%&803L%dQ&ad>le)iUzvAtx3hUp3qiqE4OmtpW{`0v8nBU z+vNFwgO#K7`BHl6Lk5HT&J zd0%5WX?GeMO2>h@YkR3UyYLB!%U`9zGx2pv`bl*gj{l2(jn1Mg!nL1jDhv@mJF-Z) z67J}KBA8uxsR*X=Sf`PpG*`ff8oxRCuGi#KZ;di+0mQR!BHISEExW1CGQBlHFEkNU z(hzW6fL~TqN}IfE{LRuTaMO61)5uVoEy2s0>}~aTd9vJ#3c3NFB;T~tqib}0T!03k zRgt=rZq*e6NSNg`GPKSp8t`0%sVfTb6iOXlX|k6#hX|N!eoNB^SLi}PkbuM0isxjy z)5uUb6|B7};Xr|h82+jxduUULfQwjMPa@4>-q38f5EGn6hWupPwaF{BhvVvGa)^K@ zX|>ns>X7FY7!n%W4tV3VU&m`b2j6q4zfYf_ujx$xnS4s6M$Tce%Fe$?pCG$c!>Hop z#?j*z!PbLgoZbtiBT7$|)|75(J=<@U1f0m=D|O^qtPFkyy`D~>hq97Bm~?7zZ;%T} z8~GfW&%P^pLJ%^7Od!{jl`1wwhao}S-B~I$U^|6yiKp9x6@U^ z9zfH$!pSPMb+)nuLoTjXL7Lv!-A_+SN{tY*DG~mHtPe-SxM*{NK7?`^%<$xScZYA$WuF!hmCsQ!r$to142By6i zR=<@Ur#d=6p?*&(k|W8E5R4!7oD1TUpQKR0^3WRd4*U)$s}T6UY~iUid|pbuC%>g% ztS(Jv{65eSeo$>r$QQ{oi4?F`D;Px6XYictg4f9s*3A!1gwGnUOKM4zj3oDxHRQj^ z)Y|ewE+M-TDG+UftD4PDC(A&81g*Sp;M-cjZ~8nL?KCKmQDj*X1=ym1{JWE7Aak*; z{PEuWO-_RYxhatXum${RZk_%8)>(zw`RU#nOvckw=~mI%iMqS$*5^2V5b!xEwgCDJ zTbMI7p7Q)p_h$REg5zp|-_AR`mgVQ~06z}?UGfE|j{^Au`M($iEN4Y^r1A<~=1JAJ z`wxo2C|lL}v1#}W{7t0I>BE4FcoWu6k?{)(aAXKz50K7!5&Fq3(ZaKFm0!|oM+J=BV z@cK=A9~X7g-jtW|b@($CC^*T$$Dp^o)=L6%<&j$_46L;SbQL22`rOa~tt7n-U&#{u zrBn*$=(BWw3$nw8%B@${-o)(ZZ)1sp`u9C_BX{9LQYiRE=sd2qs>8n3-LH1%w~21I ztbb@XnQ3RO$HycRaDXy~M)FV%-k}Fq4cy1xI69TwNMFU^`75a#dJJF$s%t(C zO=(0;O{Cyx>kMPSd0sp5jidvQBe+tnpA)`sp6&7sP>T5-_n9h5ZNQ&MAoRC?1S zUIq3Ye!N21VA6<+UJFO+tZsLB1pbsr4x}#URq3-=OBt2YCcG|Y1SkUtWJINUb&rBG zpsSU%v+c(8TM+_Qgy=F0F4Xz#D41Qz{dpYv0KRGe6%Fv&6Z|O1X#LGZEP9`_bMKC0 zad85`o{6gtEsuJnaxd_p{OkP0ygl`}j?L-42?UVpls-yIX3%3=@E-o8MZhDLc5KI8 z>^oFjUZCQtme-31_B8W<4!ej~04VQ0qrMRgVt(O4+&6VTLd&ndbOe#GeesUXSm8$RWFTOJ5A{O=@B~*BwBR%g{)Lt!v@)3hHyZ** zxF1zXz(ewi&saJbnid~%HyCdu2KkX0F5w6_Km}OFe~knMt1Ge|(d^I-Q!dR?A1qMBEgLCH$8m~@I` zW8)`UHbBK@M1VUKy^N}Z|AM||e|L50m-VcHzQJ9N?H;VQ0wR`I0p$`?MAw@W^XbE% z0CkUaK#dWsPTH#&jo!~a1+7J8A^J)Luecm((N=Q*l;AIhrc8VpOZodcg6!$NZw7@Vt9Sv>Q1PKh1suQvr~p@K?GQ;-*;lb75_c3#v~b4b$4kE6`N;8FRN# z#pMG&P^?dpfyv{l%ee{k!B&RhKZZ|Bx#7Y_K@ZVzS4AuGk4)P>V(<+C{3?!(=VV#> z^uj~n1wk!JR1DGnF6JDOSb% zGeWo~$o;(HkpumGK(A{V1Y=-nC# zSe8n_Tgc9lEOVr)03X!-J|2+lI6Q>7w*=6QM|gK-0;(?k(<-X1i|(kAg4UFjUS_|k z?lAwRDe!=RMd_F9es>|>NJ&p!kUK0UxQ&L&22?!0(=Y)2nw9XJ2 zM3(Y;LRC{?#sj*@fXW1*j0j+vzpVxWev_EO0cevocA$EKQUfS_dpb6;PCiAKvAQqY z%4mO@6dFdrK(wt|0@#`RC#29Se>Htj^~t>*g=!f!QmtS819hLdap+ACyvAd zmfrO>=s=Kg{WUT8ngY+(i}l!5ouN^*i&#^iK6^z*)aEsifWNPSfN#gH_R%g0SicNt zFMQmEM*;!M%p^D#<0cdu57Q}ru0n=?T6K1(R7Jo5^mYvtTok%?Jlc>pf|x5)MSy7= zV%tcYOghMrXj52VD*#qvXfMO7JbIUa84&_T z*PWsilgpg&Z*n|lg*z7&DvhK49A;0Ef!=${pG?33Xk*=JMh4_^(g#2boSwqpeZ56C zg^UP2kbrxWf*G-v;IX>XjO5Q1hCSEw5}D5qZClr(M+J!O4fGE9WCE_PJ54Be3BCpT zflTPS;?Rl&ankMu_ohDFz&-3yJ9OkjQu}N!0Cwh-k z{>TgmtNVpHyYBan4ValaIP!;j({2$(+F}ZF2VPAcB@-(>E#}f=Xa}7~J6*9u3+hc5 zsK;>v^dEKAeqM+W(~0J}9quu55TxfIwmjO7VZlrs{&F+{{S*4<4CGw&FNjtg9~jNf zIlrfLSZ+>5FUHCro*U)MDG#pwxxoQso6rGX8KMNd&8DXMSzttMm!+>?SapE5?ZbnU z-c_vTt5M?kVwXMrivlzfeW=x6zFJ_dE9AGZ>~`--0@{wQMdzV0XlN*Q7SV4!IaESt zq50^yT>Z4%=JZNHL#)BFH_)%y`0p7gVDUrI3RC(yD1B)D?786cYTGe#J-aMEudb4m zw?RA5M~POrS9TRa|CVs4577(gH4DD+{&;~w!GWx+r2=%Y?xPtT=ly7DPK*xZDlcQ} zg@86xX!bzVcj(EOHG=T{%<3PYe$dPjW65No9OJYM*vG$eG7l&~-4zMY-7*KN=O61`#I`)1j!(y@ljGTzM0}?fVGLU$?Ln?9Cp(w9{d0?T7RNXl z2W!ggYCU#%Ym)Kvp$oJXpNfumPe-TY>39~oh#p(_R$4i!S}3&YV#F!osZFVjGo6eB z`i%tpXejpgN(1C4H-7w+Z>5!GAoF=`%0YVoA}U1iW+a>U$?V+eWExm$Z;|&sJ`_LI zHh#!j;e@l>PEio>Dyv13f$;E4ijXX~ z)1$sxGlVn+IcQ_M3rB`Bv`(txE_9%iVL;!|2KK@b;a7|Mf#0X5^HlrgJ6Q$xjGdYx zlzr^H@e-ap>;Rq3n{uW}I?l;3pxboH8__2<{6cPrr~+y}6ADQ!^v%vG_vV|)Q`JQ( za8DalZWWmtjG?EX`=vXg`U>A;Q&1TM2J@QSPK(-3G$A*XNk{H2xSwZ?vptlbofYsq zJ^i#DRxK;6D>uuL!b1`8*^M4#Q=P;28TznX2U~#AZQ6O=>}^Ne0lW*3#`Et`9Okk4 z?6%d-uk`gFA9$<0JLwfzj1{n0MTqeWY*A}@eu<`|QML8%*%iOcZPE7Kq-RKwmC=KC z|Lx!ke5bq0+BV@uC#w(~o?q&(rZ9wr8d>J~8En^y% z2znU%-$b*zNVnsnRnr>n~(ysag2rk-8fK73;m5*i>~l;9b}t zQ}yxS#iX^df3QGjgtk=z2bAl9Bq3+RPpi$90mEnHh=R=zKNKnEvBos^FE+f{UU+Ar zEodh)7J-))&=7~3uG}HG<~P;c$vXo4o$glI!1YW7{J zD9;i!RSHsE(xB`27I`%rpE6d4-(xi|mf66RwXOsx{JgT!i&sSD8cr7J-NLi% zT3|NiA>VWRl^ zwH5xSEz5vNcWCqFXGBN$dQ~;_^F8y#*}t=G0_mnXOTUitSBgJnJj3a~p>T9zV$3!y zu`0$gJXjL5ksX=G7&pk+A!NCw>`M|T?$3X_n;iTp`d`V`o4;5i<3pQt9IxY>*jcj8 z@c#DxcsVHqgM$ymU-NbO%^{PyNdN!jgQ56lze}k42l=i#eB47}N?|*bK2`Mp2a}$;#7RWswg3PC07*qoM6N<$g8zmuE&u=k literal 0 HcmV?d00001 diff --git a/target/doc/rustdoc.css b/target/doc/rustdoc.css new file mode 100644 index 0000000..b81f78a --- /dev/null +++ b/target/doc/rustdoc.css @@ -0,0 +1 @@ + @font-face {font-family:'Fira Sans';font-style:normal;font-weight:400;src:local('Fira Sans'),url("FiraSans-Regular.woff") format('woff');}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:500;src:local('Fira Sans Medium'),url("FiraSans-Medium.woff") format('woff');}@font-face {font-family:'Source Serif Pro';font-style:normal;font-weight:400;src:local('Source Serif Pro'),url("SourceSerifPro-Regular.ttf.woff") format('woff');}@font-face {font-family:'Source Serif Pro';font-style:italic;font-weight:400;src:local('Source Serif Pro Italic'),url("SourceSerifPro-It.ttf.woff") format('woff');}@font-face {font-family:'Source Serif Pro';font-style:normal;font-weight:700;src:local('Source Serif Pro Bold'),url("SourceSerifPro-Bold.ttf.woff") format('woff');}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;src:url("SourceCodePro-Regular.woff") format('woff');}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:600;src:url("SourceCodePro-Semibold.woff") format('woff');}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}body{font:16px/1.4 "Source Serif Pro",serif;margin:0;position:relative;padding:10px 15px 20px 15px;-webkit-font-feature-settings:"kern","liga";-moz-font-feature-settings:"kern","liga";font-feature-settings:"kern","liga";}h1{font-size:1.5em;}h2{font-size:1.4em;}h3{font-size:1.3em;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod):not(.important),h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant){font-weight:500;margin:20px 0 15px 0;padding-bottom:6px;}h1.fqn{border-bottom:1px dashed;margin-top:0;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant){border-bottom:1px solid;}h3.impl,h3.method,h4.method,h3.type,h4.type,h4.associatedconstant{flex-basis:100%;font-weight:600;margin-top:16px;margin-bottom:10px;position:relative;}h3.impl,h3.method,h3.type{padding-left:15px;}h1,h2,h3,h4,.sidebar,a.source,.search-input,.content table :not(code)>a,.collapse-toggle,div.item-list .out-of-band,#source-sidebar,#sidebar-toggle{font-family:"Fira Sans",sans-serif;}ol,ul{padding-left:25px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.6em;}p{margin:0 0 .6em 0;}summary{outline:none;}code,pre{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.1em;}.docblock pre code,.docblock-short pre code,.docblock code.spotlight{padding:0;}.docblock code.spotlight :last-child{padding-bottom:0.6em;}pre{padding:14px;}.source .content pre{padding:20px;}img{max-width:100%;}.source .content{margin-top:50px;max-width:none;overflow:visible;margin-left:0px;min-width:70em;}nav.sub{font-size:16px;text-transform:uppercase;}.sidebar{width:200px;position:fixed;left:0;top:0;height:100vh;overflow:auto;}.sidebar .block>ul>li{margin-right:-10px;}.content,nav{max-width:960px;}.js-only,.hidden{display:none !important;}.logo-container{height:100px;width:100px;position:relative;margin:20px auto;display:block;margin-top:10px;}.logo-container>img{max-width:100px;max-height:100px;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:block;}.sidebar .location{border:1px solid;font-size:17px;margin:30px 10px 20px 10px;text-align:center;word-wrap:break-word;}.sidebar .version{font-size:15px;text-align:center;border-bottom:1px solid;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word;}.location:empty{border:none;}.location a:first-child{font-weight:500;}.block{padding:0;margin-bottom:14px;}.block h2,.block h3{margin-top:0;margin-bottom:8px;text-align:center;}.block ul,.block li{margin:0 10px;padding:0;list-style:none;}.block a{display:block;text-overflow:ellipsis;overflow:hidden;line-height:15px;padding:7px 5px;font-size:14px;font-weight:300;transition:border 500ms ease-out;}.sidebar-title{border-top:1px solid;border-bottom:1px solid;text-align:center;font-size:17px;margin-bottom:5px;}.sidebar-links{margin-bottom:15px;}.sidebar-links>a{padding-left:10px;width:100%;}.sidebar-menu{display:none;}.content{padding:15px 0;}.source .content pre.rust{white-space:pre;overflow:auto;padding-left:0;}.rustdoc:not(.source) .example-wrap{display:inline-flex;margin-bottom:10px;}.example-wrap{width:100%;}.example-wrap>pre.line-number{overflow:initial;border:1px solid;border-top-left-radius:5px;border-bottom-left-radius:5px;padding:13px 8px;text-align:right;}.rustdoc:not(.source) .example-wrap>pre.rust{width:100%;overflow-x:auto;}.rustdoc:not(.source) .example-wrap>pre{margin:0;}#search{margin-left:230px;position:relative;}#results{position:absolute;right:0;left:0;overflow:auto;}#results>table{width:100%;table-layout:fixed;}.content pre.line-numbers{float:left;border:none;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.line-numbers span{cursor:pointer;}.docblock-short p{display:inline;}.docblock-short.nowrap{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.docblock-short p{overflow:hidden;text-overflow:ellipsis;margin:0;}.docblock-short code{white-space:pre-wrap;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom:1px solid;}#main>.docblock h1{font-size:1.3em;}#main>.docblock h2{font-size:1.15em;}#main>.docblock h3,#main>.docblock h4,#main>.docblock h5{font-size:1em;}#main>h2+div,#main>h2+h3,#main>h3+div{display:none;flex-wrap:wrap;}.docblock h1{font-size:1em;}.docblock h2{font-size:0.95em;}.docblock h3,.docblock h4,.docblock h5{font-size:0.9em;}.docblock{margin-left:24px;position:relative;}.content .out-of-band{float:right;font-size:23px;margin:0px;padding:0px;font-weight:normal;}h3.impl>.out-of-band{font-size:21px;}h4.method>.out-of-band{font-size:19px;}h4>code,h3>code,.invisible>code{max-width:calc(100% - 41px);display:block;}.invisible{width:100%;display:inline-block;}.content .in-band{margin:0px;padding:0px;}.in-band>code{display:inline-block;}#main{position:relative;}#main>.since{top:inherit;font-family:"Fira Sans",sans-serif;}.content table:not(.table-display){border-spacing:0 5px;}.content td{vertical-align:top;}.content td:first-child{padding-right:20px;}.content td p:first-child{margin-top:0;}.content td h1,.content td h2{margin-left:0;font-size:1.1em;}.content tr:first-child td{border-top:0;}.docblock table{margin:.5em 0;width:calc(100% - 2px);border:1px dashed;}.docblock table td{padding:.5em;border:1px dashed;}.docblock table th{padding:.5em;text-align:left;border:1px solid;}.fields+table{margin-bottom:1em;}.content .item-list{list-style-type:none;padding:0;}.content .multi-column{-moz-column-count:5;-moz-column-gap:2.5em;-webkit-column-count:5;-webkit-column-gap:2.5em;column-count:5;column-gap:2.5em;}.content .multi-column li{width:100%;display:inline-block;}.content .method{font-size:1em;position:relative;}.content .method .where,.content .fn .where,.content .where.fmt-newline{display:block;font-size:0.8em;}.content .methods>div:not(.important-traits){margin-left:40px;margin-bottom:15px;}.content .docblock>.impl-items{margin-left:20px;margin-top:-34px;}.content .docblock>.impl-items>h4{border-bottom:0;}.content .docblock>.impl-items .table-display{margin:0;}.content .docblock>.impl-items table td{padding:0;}.toggle-wrapper.marg-left>.collapse-toggle{left:-24px;}.content .docblock>.impl-items .table-display,.impl-items table td{border:none;}.content .stability code{font-size:90%;}.content .stability{position:relative;margin-left:33px;margin-top:-13px;}.sub-variant>div>.stability{margin-top:initial;}.content .stability::before{content:'˪';font-size:30px;position:absolute;top:-9px;left:-13px;}.content .impl-items .method,.content .impl-items>.type,.impl-items>.associatedconstant{margin-left:20px;}.content .impl-items .docblock,.content .impl-items .stability{margin-bottom:.6em;}.content .impl-items>.stability{margin-left:40px;}.methods>.stability,.content .impl-items>.stability{margin-top:-8px;}.impl-items{flex-basis:100%;}#main>.stability{margin-top:0;}nav{border-bottom:1px solid;padding-bottom:10px;margin-bottom:10px;}nav.main{padding:20px 0;text-align:center;}nav.main .current{border-top:1px solid;border-bottom:1px solid;}nav.main .separator{border:1px solid;display:inline-block;height:23px;margin:0 20px;}nav.sum{text-align:right;}nav.sub form{display:inline;}nav.sub,.content{margin-left:230px;}a{text-decoration:none;background:transparent;}.small-section-header:hover>.anchor{display:initial;}.in-band:hover>.anchor{display:inline-block;position:absolute;}.anchor{display:none;position:absolute;left:-7px;}.anchor.field{left:-5px;}.small-section-header>.anchor{left:-28px;padding-right:10px;}.anchor:before{content:'\2002\00a7\2002';}.docblock a:not(.srclink):not(.test-arrow):hover,.docblock-short a:not(.srclink):not(.test-arrow):hover,.stability a{text-decoration:underline;}.invisible>.srclink,h4>code+.srclink{position:absolute;top:0;right:0;font-size:17px;font-weight:normal;}.block a.current.crate{font-weight:500;}.search-container{position:relative;}.search-container>div{display:inline-flex;width:calc(100% - 34px);}#crate-search{margin-top:5px;padding:6px;padding-right:19px;border:0;border-right:0;border-radius:4px 0 0 4px;outline:none;cursor:pointer;border-right:1px solid;-moz-appearance:none;-webkit-appearance:none;text-indent:0.01px;text-overflow:"";background-repeat:no-repeat;background-color:transparent;background-size:20px;background-position:calc(100% - 1px) 56%;}.search-container>.top-button{position:absolute;right:0;top:10px;}.search-input{-moz-box-sizing:border-box !important;box-sizing:border-box !important;outline:none;border:none;border-radius:1px;margin-top:5px;padding:10px 16px;font-size:17px;transition:border-color 300ms ease;transition:border-radius 300ms ease-in-out;transition:box-shadow 300ms ease-in-out;width:100%;}#crate-search+.search-input{border-radius:0 1px 1px 0;width:calc(100% - 32px);}.search-input:focus{border-radius:2px;border:0;outline:0;}.search-results .desc{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;display:block;}.search-results a{display:block;}.content .search-results td:first-child{padding-right:0;width:50%;}.content .search-results td:first-child a{padding-right:10px;}.content .search-results td:first-child a:after{clear:both;content:"";display:block;}.content .search-results td:first-child a span{float:left;}tr.result span.primitive::after{content:' (primitive type)';font-style:italic;}tr.result span.keyword::after{content:' (keyword)';font-style:italic;}body.blur>:not(#help){filter:blur(8px);-webkit-filter:blur(8px);opacity:.7;}#help{width:100%;height:100vh;position:fixed;top:0;left:0;display:flex;justify-content:center;align-items:center;}#help>div{flex:0 0 auto;box-shadow:0 0 6px rgba(0,0,0,.2);width:550px;height:auto;border:1px solid;}#help dt{float:left;clear:left;display:block;}#help dd{margin:5px 35px;}#help .infos{padding-left:0;}#help h1,#help h2{margin-top:0;}#help>div div{width:50%;float:left;padding:20px;padding-left:17px;}.stab{display:table;border-width:1px;border-style:solid;padding:3px;margin-bottom:5px;font-size:90%;}.stab p{display:inline;}.stab summary{display:list-item;}.stab .emoji{font-size:1.5em;}.module-item .stab{border-radius:3px;display:inline-block;font-size:80%;line-height:1.2;margin-bottom:0;margin-right:.3em;padding:2px;vertical-align:text-bottom;}.module-item.unstable{opacity:0.65;}.since{font-weight:normal;font-size:initial;position:absolute;right:0;top:0;}.impl-items .since,.impl .since{flex-grow:0;padding-left:12px;padding-right:2px;position:initial;}.impl-items .srclink,.impl .srclink{flex-grow:0;font-size:17px;font-weight:normal;}.impl-items code,.impl code{flex-grow:1;}.impl-items h4,h4.impl,h3.impl{display:flex;flex-basis:100%;font-size:16px;margin-bottom:12px;justify-content:space-between;}.variants_table{width:100%;}.variants_table tbody tr td:first-child{width:1%;}td.summary-column{width:100%;}.summary{padding-right:0px;}pre.rust .question-mark{font-weight:bold;}a.test-arrow{display:inline-block;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:130%;top:5px;right:5px;}a.test-arrow:hover{text-decoration:none;}.section-header:hover a:before{position:absolute;left:-25px;padding-right:10px;content:'\2002\00a7\2002';}.section-header:hover a{text-decoration:none;}.section-header a{color:inherit;}.collapse-toggle{font-weight:300;position:absolute;left:-23px;top:0;}h3>.collapse-toggle,h4>.collapse-toggle{font-size:0.8em;top:5px;}.toggle-wrapper>.collapse-toggle{left:-24px;margin-top:0px;}.toggle-wrapper{position:relative;margin-top:0;}.toggle-wrapper.collapsed{height:25px;transition:height .2s;margin-bottom:.6em;}.collapse-toggle>.inner{display:inline-block;width:1.2ch;text-align:center;}.collapse-toggle.hidden-default{position:relative;margin-left:20px;}.since+.srclink{display:table-cell;padding-left:10px;}.item-spacer{width:100%;height:12px;}.out-of-band>span.since{position:initial;font-size:20px;margin-right:5px;}.toggle-wrapper>.collapse-toggle{left:0;}.variant+.toggle-wrapper+.docblock>p{margin-top:5px;}.sub-variant,.sub-variant>h3{margin-top:1px !important;}#main>.sub-variant>h3{font-size:15px;margin-left:25px;margin-bottom:5px;}.sub-variant>div{margin-left:20px;margin-bottom:10px;}.sub-variant>div>span{display:block;position:relative;}.toggle-label{display:inline-block;margin-left:4px;margin-top:3px;}.enum>.toggle-wrapper+.docblock,.struct>.toggle-wrapper+.docblock{margin-left:30px;margin-bottom:20px;margin-top:5px;}.docblock>.section-header:first-child{margin-left:15px;margin-top:0;}.docblock>.section-header:first-child:hover>a:before{left:-10px;}.enum>.collapsed,.struct>.collapsed{margin-bottom:25px;}#main>.variant,#main>.structfield{display:block;}.attributes{display:block;margin-top:0px !important;margin-right:0px;margin-bottom:0px !important;margin-left:30px;}.toggle-attributes.collapsed{margin-bottom:0;}.impl-items>.toggle-attributes{margin-left:20px;}.impl-items .attributes{font-weight:500;}:target>code{opacity:1;}.information{position:absolute;left:-20px;margin-top:7px;z-index:1;}.tooltip{position:relative;display:inline-block;cursor:pointer;}.tooltip .tooltiptext{width:120px;display:none;text-align:center;padding:5px 3px;border-radius:6px;margin-left:5px;top:-5px;left:105%;z-index:10;}.tooltip:hover .tooltiptext{display:inline;}.tooltip .tooltiptext::after{content:" ";position:absolute;top:50%;left:11px;margin-top:-5px;border-width:5px;border-style:solid;}.important-traits .tooltip .tooltiptext{border:1px solid;}pre.rust{position:relative;tab-width:4;-moz-tab-width:4;}.search-failed{text-align:center;margin-top:20px;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#titles{height:35px;}#titles>div{float:left;width:33.3%;text-align:center;font-size:18px;cursor:pointer;border-top:2px solid;}#titles>div:not(:last-child){margin-right:1px;width:calc(33.3% - 1px);}#titles>div>div.count{display:inline-block;font-size:16px;}.important-traits{cursor:pointer;z-index:2;}h4>.important-traits{position:absolute;left:-44px;top:2px;}#all-types{text-align:center;border:1px solid;margin:0 10px;margin-bottom:10px;display:block;border-radius:7px;}#all-types>p{margin:5px 0;}#sidebar-toggle{position:fixed;top:30px;left:300px;z-index:10;padding:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;cursor:pointer;font-weight:bold;transition:left .5s;font-size:1.2em;border:1px solid;border-left:0;}#source-sidebar{position:fixed;top:0;bottom:0;left:0;width:300px;z-index:1;overflow:auto;transition:left .5s;border-right:1px solid;}#source-sidebar>.title{font-size:1.5em;text-align:center;border-bottom:1px solid;margin-bottom:6px;}.theme-picker{position:absolute;left:211px;top:19px;}.theme-picker button{outline:none;}#settings-menu{position:absolute;right:0;top:10px;outline:none;}#theme-picker,#settings-menu{padding:4px;width:27px;height:29px;border:1px solid;border-radius:3px;cursor:pointer;}#theme-choices{display:none;position:absolute;left:0;top:28px;border:1px solid;border-radius:3px;z-index:1;cursor:pointer;}#theme-choices>button{border:none;width:100%;padding:4px;text-align:center;background:rgba(0,0,0,0);}#theme-choices>button:not(:first-child){border-top:1px solid;}@media (max-width:700px){body{padding-top:0px;}.rustdoc>.sidebar{height:45px;min-height:40px;margin:0;margin-left:-15px;padding:0 15px;position:static;z-index:11;}.sidebar>.location{float:right;margin:0px;margin-top:2px;padding:3px 10px 1px 10px;min-height:39px;background:inherit;text-align:left;font-size:24px;}.sidebar .location:empty{padding:0;}.sidebar .logo-container{width:35px;height:35px;margin-top:5px;margin-bottom:5px;float:left;margin-left:50px;}.sidebar .logo-container>img{max-width:35px;max-height:35px;}.sidebar-menu{position:fixed;z-index:10;font-size:2rem;cursor:pointer;width:45px;left:0;text-align:center;display:block;border-bottom:1px solid;border-right:1px solid;height:45px;}.rustdoc.source>.sidebar>.sidebar-menu{display:none;}.sidebar-elems{position:fixed;z-index:1;left:0;top:45px;bottom:0;overflow-y:auto;border-right:1px solid;display:none;}.sidebar>.block.version{border-bottom:none;margin-top:12px;}nav.sub{width:calc(100% - 32px);float:right;}.content{margin-left:0px;}#main{margin-top:45px;padding:0;}.content .in-band{width:100%;}.content h4>.out-of-band{position:inherit;}.toggle-wrapper>.collapse-toggle{left:0px;}.toggle-wrapper{height:1.5em;}#search{margin-left:0;}.content .impl-items .method,.content .impl-items>.type,.impl-items>.associatedconstant{display:flex;}.anchor{display:none !important;}h1.fqn{overflow:initial;}.theme-picker{left:10px;top:54px;z-index:1;}h4>.important-traits{position:absolute;left:-22px;top:24px;}#titles>div>div.count{float:left;width:100%;}#titles{height:50px;}.sidebar.mobile{position:fixed;width:100%;margin-left:0;background-color:rgba(0,0,0,0);height:100%;}.sidebar{width:calc(100% + 30px);}.show-it{display:block;width:246px;}.show-it>.block.items{margin:8px 0;}.show-it>.block.items>ul{margin:0;}.show-it>.block.items>ul>li{text-align:center;margin:2px 0;}.show-it>.block.items>ul>li>a{font-size:21px;}#sidebar-filler{position:fixed;left:45px;width:calc(100% - 45px);top:0;height:45px;z-index:-1;border-bottom:1px solid;}.collapse-toggle{left:-20px;}.impl>.collapse-toggle{left:-10px;}#all-types{margin:10px;}#sidebar-toggle{top:100px;width:30px;font-size:1.5rem;text-align:center;padding:0;}#source-sidebar{z-index:11;}#main>.line-numbers{margin-top:0;}}@media print{nav.sub,.content .out-of-band,.collapse-toggle{display:none;}}@media (max-width:416px){#titles{height:73px;}#titles>div{height:73px;}}.modal{position:fixed;width:100vw;height:100vh;z-index:10000;top:0;left:0;}.modal-content{display:block;max-width:60%;min-width:200px;padding:8px;top:40%;position:absolute;left:50%;transform:translate(-50%,-40%);border:1px solid;border-radius:4px;border-top-right-radius:0;}.modal-content>.docblock{margin:0;}h3.important{margin:0;margin-bottom:13px;font-size:19px;}.modal-content>.docblock>code.content{margin:0;padding:0;font-size:20px;}.modal-content>.close{position:absolute;font-weight:900;right:-25px;top:-1px;font-size:18px;width:25px;padding-right:2px;border-top-right-radius:5px;border-bottom-right-radius:5px;text-align:center;border:1px solid;border-right:0;cursor:pointer;}.modal-content>.whiter{height:25px;position:absolute;width:3px;right:-2px;top:0px;}#main>div.important-traits{position:absolute;left:-24px;margin-top:16px;}.content>.methods>.method>div.important-traits{position:absolute;font-weight:400;left:-42px;margin-top:2px;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px;border-radius:3px;box-shadow:inset 0 -1px 0;cursor:default;}.hidden-by-impl-hider,.hidden-by-usual-hider{display:none !important;}#implementations-list>h3>span.in-band{width:100%;}.table-display{width:100%;border:0;border-collapse:collapse;border-spacing:0;font-size:16px;}.table-display tr td:first-child{padding-right:0;}.table-display tr td:last-child{float:right;}.table-display .out-of-band{position:relative;font-size:19px;display:block;}#implementors-list>.impl-items .table-display .out-of-band{font-size:17px;}.table-display td:hover .anchor{display:block;top:2px;left:-5px;}#main>ul{padding-left:10px;}#main>ul>li{list-style:none;}.non-exhaustive{margin-bottom:1em;}div.children{padding-left:27px;display:none;}div.name{cursor:pointer;position:relative;margin-left:16px;}div.files>a{display:block;padding:0 3px;}div.files>a:hover,div.name:hover{background-color:#a14b4b;}div.name.expand+.children{display:block;}div.name::before{content:"\25B6";padding-left:4px;font-size:0.7em;position:absolute;left:-16px;top:4px;}div.name.expand::before{transform:rotate(90deg);left:-15px;top:2px;}.type-decl>pre>.toggle-wrapper.toggle-attributes.top-attr{margin-left:0 !important;}.type-decl>pre>.docblock.attributes.top-attr{margin-left:1.8em !important;}.type-decl>pre>.toggle-attributes{margin-left:2.2em;}.type-decl>pre>.docblock.attributes{margin-left:4em;} \ No newline at end of file diff --git a/target/doc/search-index.js b/target/doc/search-index.js new file mode 100644 index 0000000..c80dcfe --- /dev/null +++ b/target/doc/search-index.js @@ -0,0 +1,19 @@ +var N=null,E="",T="t",U="u",searchIndex={}; +var R=["cfg_if","lazy_static","string","option","propertyvalues","new128","split128","ppv_lite86","extract","insert","Generate only the basic implementations necessary to be…","ppv_lite86::x86_64","try_from","try_into","borrow_mut","result","type_id","borrow","typeid","instance","vec128_storage","vec256_storage","vec512_storage","default","RotateEachWord32","RotateEachWord64","UnsafeFrom","LaneWords4","MultiLane","StoreBytes","SseMachine","Avx2Machine","to_owned","clone_into","utf8sequence","utf8range","formatter","Utf8Range","Utf8Sequence","Utf8Sequences","getrandom","nonzerou32","Returns the element for the current thread, or creates it…","Returns the element for the current thread, if it exists.","get_or_try","iter_mut","Returns a mutable iterator over the local values of all…","Removes all thread-specific values from the `ThreadLocal`,…","get_default","Returns the element for the current thread, or creates a…","into_iter","size_hint","threadlocal","cachedthreadlocal","ThreadLocal","CachedThreadLocal","IntoIter","An iterator over all occurrences of the needles in a…","An iterator over all occurrences of the needle in a…","memchr2","memchr3","memchr","Creates a new iterator that yields all positions of needle…","next_back","Machine","u32x4x2","u64x2x2","u32x4x4","u64x2x4","unpack","read_le","read_be","A wrapper type implementing [`RngCore`] for some type…","The core part of the RNG, implementing the `generate`…","Create a new `BlockRng` from an existing RNG implementing…","Get the index into the result buffer.","Reset the number of available results. This will force a…","generate_and_set","Generate a new set of results immediately, setting the…","rand_core","Implement `fill_bytes` by reading chunks from the output…","to_string","rand_core::block","next_u32","next_u64","fill_bytes","try_fill_bytes","from_seed","seed_from_u64","from_rng","rngcore","blockrng","blockrng64","BlockRng","BlockRng64","BlockRngCore","SeedableRng","aho_corasick","aho_corasick::ErrorKind","ahocorasick","Build an Aho-Corasick automaton using the configuration…","ahocorasickbuilder","match_kind","matchkind","errorkind","MatchKind","ErrorKind","AhoCorasick","AhoCorasickBuilder","FindOverlappingIter","StreamFindIter","A cryptographically secure random number generator that…","get_word_pos","Get the offset from the start of the stream, in 32-bit…","set_word_pos","Set the offset from the start of the stream, in 32-bit…","set_stream","Set the stream number.","ChaCha with 20 rounds","chacha20core","chacha12core","chacha8core","generate","ChaCha20Rng","ChaCha12Rng","ChaCha8Rng","ChaCha12Core","ChaCha20Core","ChaCha8Core","The span of this class.","regex_syntax::ast","regex_syntax::ast::ErrorKind","original","Assertion","A single zero-width assertion.","Repetition","A grouped regular expression.","Alternation","An alternation of regular expressions.","A concatenation of regular expressions.","A Unicode character class, e.g., `\\pL` or `\\p{Greek}`.","A perl character class, e.g., `\\d` or `\\W`.","Bracketed","A bracketed character class set, which may contain zero or…","CaptureName","ParserBuilder","A builder for a regular expression parser.","parserbuilder","withcomments","classsetitem","classsetbinaryop","position","is_empty","classasciikind","regex_syntax","ClassUnicode","WordBoundary","A set of characters represented by Unicode scalar values.","StartLine","StartText","Unicode","GroupKind","CaptureIndex","NonCapturing","regex_syntax::hir","RepetitionKind","The kind of a repetition operator.","ZeroOrOne","ZeroOrMore","OneOrMore","RepetitionRange","Executes an implementation of `Visitor` in constant stack…","Literal","literals","Create a new printer.","Print the given `Ast` to the given writer. The writer must…","translatorbuilder","translator","translate","All implementors of `Visitor` must provide a `finish`…","visit_pre","visit_post","visit_alternation_in","Return the type of this error.","The original pattern string in which this error occurred.","Return the span at which this error occurred.","literal","repetition","Return true if and only if this HIR is required to match…","Return true if and only if this HIR contains any…","is_always_utf8","classunicode","case_fold_simple","classunicoderange","Create a new class from a sequence of ranges.","classbytes","Create a new class with no ranges.","Add a new range to this set.","Return an iterator over all ranges in this class.","Return the underlying ranges as a slice.","Expand this character class such that it contains all case…","intersect","difference","symmetric_difference","classbytesrange","Return the start of this range.","Return the end of this range.","is_negated","is_match_empty","Create a new parser builder with a default configuration.","Build a parser from this configuration with the given…","nest_limit","Set the nesting limit for this parser.","Whether to support octal syntax or not.","allow_invalid_utf8","ignore_whitespace","Enable verbose mode in the regular expression.","case_insensitive","multi_line","dot_matches_new_line","swap_greed","Enable or disable the Unicode flag (`u`) by default.","Create a new parser with a default configuration.","regex_syntax::ast::parse","regex_syntax::ast::print","regex_syntax::hir::literal","regex_syntax::hir::print","regex_syntax::hir::translate","alternation","literalkind","classperl","classascii","classunicodekind","classbracketed","classset","classsetrange","classsetunion","assertion","repetitionop","repetitionkind","repetitionrange","groupkind","capturename","flagsitem","flagsitemkind","wordboundary","specialliteralkind","hexliteralkind","classperlkind","classunicodeopkind","classsetbinaryopkind","assertionkind","setflags","ordering","partial_cmp","description","This method is called before beginning traversal of the AST.","This method is called on an `Ast` before descending into…","This method is called on an `Ast` after descending all of…","This method is called between child nodes of an…","visit_class_set_item_pre","This method is called on every `ClassSetItem` before…","visit_class_set_item_post","This method is called on every `ClassSetItem` after…","visit_class_set_binary_op_pre","This method is called on every `ClassSetBinaryOp` before…","visit_class_set_binary_op_post","This method is called on every `ClassSetBinaryOp` after…","visit_class_set_binary_op_in","This method is called between the left hand and right hand…","This method is called before beginning traversal of the HIR.","This method is called on an `Hir` before descending into…","This method is called on an `Hir` after descending all of…","This method is called between child nodes of an alternation.","WithComments","ClassPerl","ClassAscii","ClassBracketed","ClassSetRange","ClassSetUnion","ClassSetBinaryOp","RepetitionOp","FlagsItem","LiteralKind","SpecialLiteralKind","HexLiteralKind","ClassPerlKind","ClassAsciiKind","ClassUnicodeKind","ClassUnicodeOpKind","ClassSetItem","ClassSetBinaryOpKind","AssertionKind","FlagsItemKind","TranslatorBuilder","Translator","ClassUnicodeRange","ClassBytes","ClassBytesRange","ClassUnicodeIter","ClassBytesIter","A distribution to sample floating point numbers uniformly…","Sample values uniformly between two bounds.","new_inclusive","Create a new `Uniform` instance which samples uniformly…","rand::distributions","bernoulli","bernoullierror","WeightedIndex","A distribution using weighted sampling to pick a…","weightederror","rand::distributions::weighted","weightedindex","dirichlet","rand::rngs","rand::seq","choose_multiple","sample_iter","Fill `dest` entirely with random bytes (uniform value…","rand::distributions::uniform","rand::distributions::weighted::alias_method","rand::rngs::adapter","rand::rngs::mock","rand::seq::index","sample_single","uniform","unitspheresurface","unitcircle","chisquared","lognormal","triangular","threadrng","indexvec","indexvecintoiter","BernoulliError","SampleUniform","UniformSampler","SampleBorrow","Bernoulli","WeightedError","UnitSphereSurface","UnitCircle","ChiSquared","LogNormal","Dirichlet","Triangular","Distribution","ReseedingRng","EntropyRng","SliceRandom","IteratorRandom","AsByteSliceMut","Alphanumeric","OpenClosed01","StandardNormal","Standard","UniformInt","UniformFloat","UniformDuration","ThreadRng","ReadError","SliceChooseIter","IndexVecIter","IndexVecIntoIter","Error type of random number generators","Construct from any type supporting `std::error::Error`","Reference the inner error (`std` only)","take_inner","Unwrap the inner error (`std` only)","Retrieve the error code, if any.","The core of a random number generator.","Return the next random `u32`.","Return the next random `u64`.","Fill `dest` with random data.","Fill `dest` entirely with random data.","CryptoRng","A marker trait used to indicate that an [`RngCore`] or…","A random number generator that can be explicitly seeded.","Seed type, which is restricted to types…","Create a new PRNG using the given seed.","Create a new PRNG using a `u64` seed.","Create a new PRNG seeded from another `Rng`.","from_entropy","Creates a new instance of the RNG seeded via [`getrandom`].","RegexBuilder","A configurable builder for a regular expression.","RegexSetBuilder","A configurable builder for a set of regular expressions.","Match represents a single match of a regex in a haystack.","An iterator over all non-overlapping matches for a…","CaptureMatches","An iterator that yields all non-overlapping capture groups…","Yields all substrings delimited by a regular expression…","Yields at most `N` substrings delimited by a regular…","CaptureNames","An iterator over the names of all possible captures.","CaptureLocations","CaptureLocations is a low level representation of the raw…","SubCaptureMatches","An iterator that yields all capturing matches in the order…","ReplacerRef","By-reference adaptor for a `Replacer`","Match multiple (possibly overlapping) regular expressions…","SetMatches","A set of matches returned by a regex set.","SetMatchesIntoIter","An owned iterator over the set of matches from a regex set.","SetMatchesIter","A borrowed iterator over the set of matches from a regex…","regexbuilder","Create a new regular expression builder with the given…","Consume the builder and compile the regular expression.","Set the value for the case insensitive (`i`) flag.","Set the value for the multi-line matching (`m`) flag.","Set the value for the any character (`s`) flag, where in…","Set the value for the greedy swap (`U`) flag.","Set the value for the ignore whitespace (`x`) flag.","Set the value for the Unicode (`u`) flag.","size_limit","Set the approximate size limit of the compiled regular…","dfa_size_limit","Set the approximate size of the cache used by the DFA.","regex::bytes","regexsetbuilder","Consume the builder and compile the regular expressions…","regexset","no_expansion","Return a fixed unchanging replacement byte string.","Return a `Replacer` that borrows and wraps this `Replacer`.","replacerref","find_iter","captures","replace_all","replacer","capturelocations","is_match","Create a new regex set with the given regular expressions.","Returns true if and only if one of the regexes in this set…","Returns the set of regular expressions that match in the…","setmatches","Returns the total number of regular expressions in this set.","Returns the patterns that this set will match on.","matched_any","Whether this set contains any matches.","Whether the regex at the given index matched.","The total number of regexes in the set that created these…","Returns an iterator over indexes in the regex that matched.","setmatchesiter","Returns the starting byte offset of the match in the…","Returns the ending byte offset of the match in the haystack.","Returns the matched text.","Compiles a regular expression. Once compiled, it can be…","Returns true if and only if the regex matches the string…","Returns the start and end byte range of the leftmost-first…","Returns an iterator for each successive non-overlapping…","Returns the capture groups corresponding to the…","captures_iter","Returns an iterator over all the non-overlapping capture…","capturematches","Returns an iterator of substrings of `text` delimited by a…","Returns an iterator of at most `limit` substrings of…","Replaces the leftmost-first match with the replacement…","Replaces all non-overlapping matches in `text` with the…","Replaces at most `limit` non-overlapping matches in `text`…","shortest_match","Returns the end location of a match in the text given.","shortest_match_at","Returns the same as shortest_match, but starts the search…","is_match_at","Returns the same as is_match, but starts the search at the…","Returns the same as find, but starts the search at the…","captures_read","This is like `captures`, but uses `CaptureLocations`…","captures_read_at","Returns the original string of this regex.","capture_names","Returns an iterator over the capture names.","capturenames","captures_len","Returns the number of captures.","capture_locations","Returns an empty set of capture locations that can be…","Returns the start and end positions of the Nth capture…","Returns the total number of capturing groups.","Returns the match associated with the capture group at…","Returns the match for the capture group named `name`. If…","subcapturematches","Expands all instances of `$name` in `replacement` to the…","Returns the number of captured groups.","Replacer describes types that can be used to replace…","replace_append","Appends text to `dst` to replace the current match.","Shows the original regular expression.","Attempts to parse a string into a regular expression","Return a fixed unchanging replacement string.","NoExpand","Replacer","Captures","RegexSet","Escapes all regular expression meta characters in `text`.","unicode","matches","OwOifiable"]; +searchIndex["aho_corasick"]={"doc":"A library for finding occurrences of many patterns at…","i":[[3,R[107],R[97],"An automaton for searching multiple strings in linear time.",N,N],[3,R[108],E,"A builder for configuring an Aho-Corasick automaton.",N,N],[3,"FindIter",E,"An iterator of non-overlapping matches in a particular…",N,N],[3,R[109],E,"An iterator of overlapping matches in a particular haystack.",N,N],[3,R[110],E,"An iterator that reports Aho-Corasick matches in a stream.",N,N],[3,"Error",E,"An error that occurred during the construction of an…",N,N],[3,"Match",E,"A representation of a match reported by an Aho-Corasick…",N,N],[4,R[105],E,"A knob for controlling the match semantics of an…",N,N],[13,R[355],E,"Use standard match semantics, which support overlapping…",0,N],[13,"LeftmostFirst",E,"Use leftmost-first match semantics, which reports leftmost…",0,N],[13,"LeftmostLongest",E,"Use leftmost-longest match semantics, which reports…",0,N],[4,R[106],E,"The kind of error that occurred.",N,N],[13,"StateIDOverflow",E,"An error that occurs when constructing an automaton would…",1,N],[12,"max",R[98],"The maximum possible state ID.",1,N],[13,"PremultiplyOverflow",R[97],"An error that occurs when premultiplication of state IDs…",1,N],[12,"max",R[98],"The maximum possible state id.",1,N],[12,"requested_max",E,"The maximum ID required by premultiplication.",1,N],[11,"new",R[97],"Create a new Aho-Corasick automaton using the default…",2,[[["i"]],[R[99]]]],[11,"new_auto_configured",E,"Build an Aho-Corasick automaton with an automatically…",2,[[],[R[99]]]],[11,R[435],E,"Returns true if and only if this automaton matches the…",2,[[["self"],["asref"]],["bool"]]],[11,"earliest_find",E,"Returns the location of the first detected match in…",2,[[["self"],["asref"]],[[R[3],["match"]],["match"]]]],[11,"find",E,"Returns the location of the first match according to the…",2,[[["self"],["asref"]],[[R[3],["match"]],["match"]]]],[11,R[430],E,"Returns an iterator of non-overlapping matches, using the…",2,[[["b"],["self"]],["finditer"]]],[11,"find_overlapping_iter",E,"Returns an iterator of overlapping matches in the given…",2,[[["b"],["self"]],["findoverlappingiter"]]],[11,R[432],E,"Replace all matches with a corresponding value in the…",2,[[["self"],["str"]],[R[2]]]],[11,"replace_all_bytes",E,"Replace all matches using raw bytes with a corresponding…",2,[[["self"]],[["u8"],["vec",["u8"]]]]],[11,"replace_all_with",E,"Replace all matches using a closure called on each match.…",2,[[[R[2]],["str"],["self"],["f"]]]],[11,"replace_all_with_bytes",E,"Replace all matches using raw bytes with a closure called…",2,[[["vec"],["self"],["f"]]]],[11,"stream_find_iter",E,"Returns an iterator of non-overlapping matches in the…",2,[[["read"],["self"]],[["read"],["streamfinditer"]]]],[11,"stream_replace_all",E,"Search for and replace all matches of this automaton in…",2,[[["w"],["self"],["r"]],[R[15]]]],[11,"stream_replace_all_with",E,"Search the given reader and replace all matches of this…",2,[[["w"],["self"],["f"],["r"]],[R[15]]]],[11,R[102],E,"Returns the match kind used by this automaton.",2,[[["self"]],[R[103]]]],[11,"max_pattern_len",E,"Returns the length of the longest pattern matched by this…",2,[[["self"]],["usize"]]],[11,"pattern_count",E,"Return the total number of patterns matched by this…",2,[[["self"]],["usize"]]],[11,"supports_overlapping",E,"Returns true if and only if this automaton supports…",2,[[["self"]],["bool"]]],[11,"supports_stream",E,"Returns true if and only if this automaton supports stream…",2,[[["self"]],["bool"]]],[11,"heap_bytes",E,"Returns the total amount of heap used by this automaton,…",2,[[["self"]],["usize"]]],[11,"new",E,"Create a new builder for configuring an Aho-Corasick…",3,[[],[R[101]]]],[11,"build",E,R[100],3,[[["self"],["i"]],[R[99]]]],[11,"build_with_size",E,R[100],3,[[["self"],["i"]],[[R[99]],[R[15],[R[99],"error"]],["error"]]]],[11,"auto_configure",E,"Automatically configure the settings on this builder…",3,[[["self"]],[R[101]]]],[11,R[102],E,"Set the desired match semantics.",3,[[["self"],[R[103]]],[R[101]]]],[11,"ascii_case_insensitive",E,"Enable ASCII-aware case insensitive matching.",3,[[["self"],["bool"]],[R[101]]]],[11,"dense_depth",E,"Set the limit on how many NFA states use a dense…",3,[[["self"],["usize"]],[R[101]]]],[11,"dfa",E,"Compile the standard Aho-Corasick automaton into a…",3,[[["self"],["bool"]],[R[101]]]],[11,"prefilter",E,"Enable heuristic prefilter optimizations.",3,[[["self"],["bool"]],[R[101]]]],[11,"byte_classes",E,"Shrink the size of the transition alphabet by mapping…",3,[[["self"],["bool"]],[R[101]]]],[11,"premultiply",E,"Premultiply state identifiers in the transition table.…",3,[[["self"],["bool"]],[R[101]]]],[11,"kind",E,"Return the kind of this error.",4,[[["self"]],[R[104]]]],[8,"StateID",E,"A trait describing the representation of an automaton's…",N,N],[10,"from_usize",E,"Convert from a `usize` to this implementation's…",5,[[["usize"]],["self"]]],[10,"to_usize",E,"Convert this implementation's representation to a `usize`.",5,[[],["usize"]]],[10,"max_id",E,"Return the maximum state identifier supported by this…",5,[[],["usize"]]],[11,"pattern",E,"Returns the identifier of the pattern that matched.",6,[[["self"]],["usize"]]],[11,"start",E,"The starting position of the match.",6,[[["self"]],["usize"]]],[11,"end",E,"The ending position of the match.",6,[[["self"]],["usize"]]],[11,R[152],E,"Returns true if and only if this match is empty. That is,…",6,[[["self"]],["bool"]]],[11,"from",E,E,2,[[[T]],[T]]],[11,R[32],E,E,2,[[["self"]],[T]]],[11,R[33],E,E,2,[[[T],["self"]]]],[11,"into",E,E,2,[[],[U]]],[11,R[12],E,E,2,[[[U]],[R[15]]]],[11,R[13],E,E,2,[[],[R[15]]]],[11,R[14],E,E,2,[[["self"]],[T]]],[11,R[17],E,E,2,[[["self"]],[T]]],[11,R[16],E,E,2,[[["self"]],[R[18]]]],[11,"from",E,E,3,[[[T]],[T]]],[11,R[32],E,E,3,[[["self"]],[T]]],[11,R[33],E,E,3,[[[T],["self"]]]],[11,"into",E,E,3,[[],[U]]],[11,R[12],E,E,3,[[[U]],[R[15]]]],[11,R[13],E,E,3,[[],[R[15]]]],[11,R[14],E,E,3,[[["self"]],[T]]],[11,R[17],E,E,3,[[["self"]],[T]]],[11,R[16],E,E,3,[[["self"]],[R[18]]]],[11,"from",E,E,7,[[[T]],[T]]],[11,R[50],E,E,7,[[],["i"]]],[11,"into",E,E,7,[[],[U]]],[11,R[12],E,E,7,[[[U]],[R[15]]]],[11,R[13],E,E,7,[[],[R[15]]]],[11,R[14],E,E,7,[[["self"]],[T]]],[11,R[17],E,E,7,[[["self"]],[T]]],[11,R[16],E,E,7,[[["self"]],[R[18]]]],[11,"from",E,E,8,[[[T]],[T]]],[11,R[50],E,E,8,[[],["i"]]],[11,"into",E,E,8,[[],[U]]],[11,R[12],E,E,8,[[[U]],[R[15]]]],[11,R[13],E,E,8,[[],[R[15]]]],[11,R[14],E,E,8,[[["self"]],[T]]],[11,R[17],E,E,8,[[["self"]],[T]]],[11,R[16],E,E,8,[[["self"]],[R[18]]]],[11,"from",E,E,9,[[[T]],[T]]],[11,R[50],E,E,9,[[],["i"]]],[11,"into",E,E,9,[[],[U]]],[11,R[12],E,E,9,[[[U]],[R[15]]]],[11,R[13],E,E,9,[[],[R[15]]]],[11,R[14],E,E,9,[[["self"]],[T]]],[11,R[17],E,E,9,[[["self"]],[T]]],[11,R[16],E,E,9,[[["self"]],[R[18]]]],[11,"from",E,E,4,[[[T]],[T]]],[11,R[32],E,E,4,[[["self"]],[T]]],[11,R[33],E,E,4,[[[T],["self"]]]],[11,R[81],E,E,4,[[["self"]],[R[2]]]],[11,"into",E,E,4,[[],[U]]],[11,R[12],E,E,4,[[[U]],[R[15]]]],[11,R[13],E,E,4,[[],[R[15]]]],[11,R[14],E,E,4,[[["self"]],[T]]],[11,R[17],E,E,4,[[["self"]],[T]]],[11,R[16],E,E,4,[[["self"]],[R[18]]]],[11,"from",E,E,6,[[[T]],[T]]],[11,R[32],E,E,6,[[["self"]],[T]]],[11,R[33],E,E,6,[[[T],["self"]]]],[11,"into",E,E,6,[[],[U]]],[11,R[12],E,E,6,[[[U]],[R[15]]]],[11,R[13],E,E,6,[[],[R[15]]]],[11,R[14],E,E,6,[[["self"]],[T]]],[11,R[17],E,E,6,[[["self"]],[T]]],[11,R[16],E,E,6,[[["self"]],[R[18]]]],[11,"from",E,E,0,[[[T]],[T]]],[11,R[32],E,E,0,[[["self"]],[T]]],[11,R[33],E,E,0,[[[T],["self"]]]],[11,"into",E,E,0,[[],[U]]],[11,R[12],E,E,0,[[[U]],[R[15]]]],[11,R[13],E,E,0,[[],[R[15]]]],[11,R[14],E,E,0,[[["self"]],[T]]],[11,R[17],E,E,0,[[["self"]],[T]]],[11,R[16],E,E,0,[[["self"]],[R[18]]]],[11,"from",E,E,1,[[[T]],[T]]],[11,R[32],E,E,1,[[["self"]],[T]]],[11,R[33],E,E,1,[[[T],["self"]]]],[11,"into",E,E,1,[[],[U]]],[11,R[12],E,E,1,[[[U]],[R[15]]]],[11,R[13],E,E,1,[[],[R[15]]]],[11,R[14],E,E,1,[[["self"]],[T]]],[11,R[17],E,E,1,[[["self"]],[T]]],[11,R[16],E,E,1,[[["self"]],[R[18]]]],[11,"next",E,E,7,[[["self"]],[[R[3],["match"]],["match"]]]],[11,"next",E,E,8,[[["self"]],[[R[3],["match"]],["match"]]]],[11,"next",E,E,9,[[["self"]],[[R[3],[R[15]]],[R[15],["match"]]]]],[11,"eq",E,E,0,[[[R[103]],["self"]],["bool"]]],[11,"eq",E,E,6,[[["self"],["match"]],["bool"]]],[11,"ne",E,E,6,[[["self"],["match"]],["bool"]]],[11,"clone",E,E,2,[[["self"]],[R[99]]]],[11,"clone",E,E,3,[[["self"]],[R[101]]]],[11,"clone",E,E,0,[[["self"]],[R[103]]]],[11,"clone",E,E,4,[[["self"]],["error"]]],[11,"clone",E,E,1,[[["self"]],[R[104]]]],[11,"clone",E,E,6,[[["self"]],["match"]]],[11,R[23],E,E,3,[[],[R[101]]]],[11,R[23],E,E,0,[[],[R[103]]]],[11,"fmt",E,E,4,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,2,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,7,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,8,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,9,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,3,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,0,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,4,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,1,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,6,[[["self"],[R[36]]],[R[15]]]],[11,"hash",E,E,6,[[["self"],["__h"]]]],[11,R[255],E,E,4,[[["self"]],["str"]]]],"p":[[4,R[105]],[4,R[106]],[3,R[107]],[3,R[108]],[3,"Error"],[8,"StateID"],[3,"Match"],[3,"FindIter"],[3,R[109]],[3,R[110]]]}; +searchIndex["c2_chacha"]={"doc":"Pure Rust ChaCha with SIMD optimizations.","i":[[0,"guts","c2_chacha",E,N,N],[8,R[64],"c2_chacha::guts",E,N,N],[16,"u32x4",E,E,0,N],[16,"u64x2",E,E,0,N],[16,"u128x1",E,E,0,N],[16,R[65],E,E,0,N],[16,R[66],E,E,0,N],[16,"u64x4",E,E,0,N],[16,"u128x2",E,E,0,N],[16,R[67],E,E,0,N],[16,R[68],E,E,0,N],[16,"u128x4",E,E,0,N],[11,R[69],E,E,0,[[["s"]],["v"]]],[11,"vec",E,E,0,[[["a"]],["v"]]],[11,R[70],E,E,0,[[],["v"]]],[11,R[71],E,E,0,[[],["v"]]],[10,R[19],E,E,0,[[],["self"]]],[3,"ChaCha",E,E,N,N],[3,"State",E,E,N,N],[11,"new",E,E,1,[[],["self"]]],[11,"refill4",E,"Produce 4 blocks of output, advancing the state",1,[[["self"],["u32"]]]],[11,"refill",E,"Produce a block of output, advancing the state",1,[[["self"],["u32"]]]],[11,"set_stream_param",E,E,1,[[["self"],["u32"],["u64"]]]],[11,"get_stream_param",E,E,1,[[["self"],["u32"]],["u64"]]],[11,"from",E,E,1,[[[T]],[T]]],[11,R[32],E,E,1,[[["self"]],[T]]],[11,R[33],E,E,1,[[[T],["self"]]]],[11,"into",E,E,1,[[],[U]]],[11,R[12],E,E,1,[[[U]],[R[15]]]],[11,R[13],E,E,1,[[],[R[15]]]],[11,R[14],E,E,1,[[["self"]],[T]]],[11,R[17],E,E,1,[[["self"]],[T]]],[11,R[16],E,E,1,[[["self"]],[R[18]]]],[11,"vzip",E,E,1,[[],["v"]]],[11,"from",E,E,2,[[[T]],[T]]],[11,R[32],E,E,2,[[["self"]],[T]]],[11,R[33],E,E,2,[[[T],["self"]]]],[11,"into",E,E,2,[[],[U]]],[11,R[12],E,E,2,[[[U]],[R[15]]]],[11,R[13],E,E,2,[[],[R[15]]]],[11,R[14],E,E,2,[[["self"]],[T]]],[11,R[17],E,E,2,[[["self"]],[T]]],[11,R[16],E,E,2,[[["self"]],[R[18]]]],[11,"vzip",E,E,2,[[],["v"]]],[11,"clone",E,E,1,[[["self"]],["chacha"]]],[11,"clone",E,E,2,[[["self"]],["state"]]]],"p":[[8,R[64]],[3,"ChaCha"],[3,"State"]]}; +searchIndex["cfg_if"]={"doc":"A macro for defining `#[cfg]` if-else statements.","i":[[14,R[0],R[0],"The main macro provided by this crate. See crate…",N,N]],"p":[]}; +searchIndex["getrandom"]={"doc":"Interface to the random number generator of the operating…","i":[[3,"Error",R[40],"A small and `no_std` compatible error type.",N,N],[5,R[40],E,"Fill `dest` with random bytes from the system's preferred…",N,[[],[[R[15],["error"]],["error"]]]],[18,"UNKNOWN",E,E,0,N],[18,"UNAVAILABLE",E,E,0,N],[18,"INTERNAL_START",E,"Codes below this point represent OS Errors (i.e. positive…",0,N],[18,"CUSTOM_START",E,"Codes at or above this point can be used by users to…",0,N],[11,"raw_os_error",E,"Extract the raw OS error code (if this error came from the…",0,[[["self"]],[[R[3],["i32"]],["i32"]]]],[11,"code",E,"Extract the bare error code.",0,[[["self"]],[R[41]]]],[11,"from",E,E,0,[[[T]],[T]]],[11,R[12],E,E,0,[[[U]],[R[15]]]],[11,"into",E,E,0,[[],[U]]],[11,R[13],E,E,0,[[],[R[15]]]],[11,R[17],E,E,0,[[["self"]],[T]]],[11,R[14],E,E,0,[[["self"]],[T]]],[11,R[16],E,E,0,[[["self"]],[R[18]]]],[11,R[32],E,E,0,[[["self"]],[T]]],[11,R[33],E,E,0,[[[T],["self"]]]],[11,R[81],E,E,0,[[["self"]],[R[2]]]],[11,"eq",E,E,0,[[["self"],["error"]],["bool"]]],[11,"ne",E,E,0,[[["self"],["error"]],["bool"]]],[11,"from",E,E,0,[[[R[41]]],["self"]]],[11,"from",E,E,0,[[["error"]],["self"]]],[11,"fmt",E,E,0,[[[R[36]],["self"]],[R[15]]]],[11,"fmt",E,E,0,[[[R[36]],["self"]],[R[15]]]],[11,"clone",E,E,0,[[["self"]],["error"]]]],"p":[[3,"Error"]]}; +searchIndex["lazy_static"]={"doc":"A macro for declaring lazily evaluated statics.","i":[[5,"initialize",R[1],"Takes a shared reference to a lazy static and initializes…",N,[[[T]]]],[8,"LazyStatic",E,"Support trait for enabling a few common operation on lazy…",N,N],[14,R[1],E,E,N,N]],"p":[]}; +searchIndex["memchr"]={"doc":"The `memchr` crate provides heavily optimized routines for…","i":[[3,"Memchr",R[61],"An iterator for `memchr`.",N,N],[3,"Memchr2",E,"An iterator for `memchr2`.",N,N],[3,"Memchr3",E,"An iterator for `memchr3`.",N,N],[5,"memchr_iter",E,R[58],N,[[["u8"]],[R[61]]]],[5,"memchr2_iter",E,R[57],N,[[["u8"]],[R[59]]]],[5,"memchr3_iter",E,R[57],N,[[["u8"]],[R[60]]]],[5,"memrchr_iter",E,R[58],N,[[["u8"]],[["rev",[R[61]]],[R[61]]]]],[5,"memrchr2_iter",E,R[57],N,[[["u8"]],[["rev",[R[59]]],[R[59]]]]],[5,"memrchr3_iter",E,R[57],N,[[["u8"]],[["rev",[R[60]]],[R[60]]]]],[5,R[61],E,"Search for the first occurrence of a byte in a slice.",N,[[["u8"]],[[R[3],["usize"]],["usize"]]]],[5,R[59],E,"Like `memchr`, but searches for two bytes instead of one.",N,[[["u8"]],[[R[3],["usize"]],["usize"]]]],[5,R[60],E,"Like `memchr`, but searches for three bytes instead of one.",N,[[["u8"]],[[R[3],["usize"]],["usize"]]]],[5,"memrchr",E,"Search for the last occurrence of a byte in a slice.",N,[[["u8"]],[[R[3],["usize"]],["usize"]]]],[5,"memrchr2",E,"Like `memrchr`, but searches for two bytes instead of one.",N,[[["u8"]],[[R[3],["usize"]],["usize"]]]],[5,"memrchr3",E,"Like `memrchr`, but searches for three bytes instead of one.",N,[[["u8"]],[[R[3],["usize"]],["usize"]]]],[11,"new",E,R[62],0,[[["u8"]],[R[61]]]],[11,"new",E,R[62],1,[[["u8"]],[R[59]]]],[11,"new",E,"Create a new `Memchr3` that's initialized to zero with a…",2,[[["u8"]],[R[60]]]],[11,"from",E,E,0,[[[T]],[T]]],[11,R[50],E,E,0,[[],["i"]]],[11,"into",E,E,0,[[],[U]]],[11,R[12],E,E,0,[[[U]],[R[15]]]],[11,R[13],E,E,0,[[],[R[15]]]],[11,R[14],E,E,0,[[["self"]],[T]]],[11,R[17],E,E,0,[[["self"]],[T]]],[11,R[16],E,E,0,[[["self"]],[R[18]]]],[11,"from",E,E,1,[[[T]],[T]]],[11,R[50],E,E,1,[[],["i"]]],[11,"into",E,E,1,[[],[U]]],[11,R[12],E,E,1,[[[U]],[R[15]]]],[11,R[13],E,E,1,[[],[R[15]]]],[11,R[14],E,E,1,[[["self"]],[T]]],[11,R[17],E,E,1,[[["self"]],[T]]],[11,R[16],E,E,1,[[["self"]],[R[18]]]],[11,"from",E,E,2,[[[T]],[T]]],[11,R[50],E,E,2,[[],["i"]]],[11,"into",E,E,2,[[],[U]]],[11,R[12],E,E,2,[[[U]],[R[15]]]],[11,R[13],E,E,2,[[],[R[15]]]],[11,R[14],E,E,2,[[["self"]],[T]]],[11,R[17],E,E,2,[[["self"]],[T]]],[11,R[16],E,E,2,[[["self"]],[R[18]]]],[11,R[63],E,E,0,[[["self"]],[R[3]]]],[11,R[63],E,E,1,[[["self"]],[R[3]]]],[11,R[63],E,E,2,[[["self"]],[R[3]]]],[11,"next",E,E,0,[[["self"]],[[R[3],["usize"]],["usize"]]]],[11,R[51],E,E,0,[[["self"]]]],[11,"next",E,E,1,[[["self"]],[[R[3],["usize"]],["usize"]]]],[11,R[51],E,E,1,[[["self"]]]],[11,"next",E,E,2,[[["self"]],[[R[3],["usize"]],["usize"]]]],[11,R[51],E,E,2,[[["self"]]]]],"p":[[3,"Memchr"],[3,"Memchr2"],[3,"Memchr3"]]}; +searchIndex["owoify"]={"doc":E,"i":[[8,R[502],"owoify",E,N,N],[10,"owoify",E,"The owoification method",0,[[["self"]],["self"]]]],"p":[[8,R[502]]]}; +searchIndex["ppv_lite86"]={"doc":E,"i":[[0,"x86_64",R[7],E,N,N],[3,"YesS3",R[11],E,N,N],[3,"NoS3",E,E,N,N],[3,"YesS4",E,E,N,N],[3,"NoS4",E,E,N,N],[3,"YesA1",E,E,N,N],[3,"NoA1",E,E,N,N],[3,"YesA2",E,E,N,N],[3,"NoA2",E,E,N,N],[3,"YesNI",E,E,N,N],[3,"NoNI",E,E,N,N],[3,R[30],E,E,N,N],[3,R[31],E,E,N,N],[19,R[20],E,"Generic wrapper for unparameterized storage of any of the…",N,N],[19,R[21],E,E,N,N],[19,R[22],E,E,N,N],[6,"SSE2",E,E,N,N],[6,"SSSE3",E,E,N,N],[6,"SSE41",E,E,N,N],[6,"AVX",E,"AVX but not AVX2: only 128-bit integer operations, but use…",N,N],[6,"AVX2",E,E,N,N],[11,R[5],E,E,0,[[],["self"]]],[11,R[6],E,E,0,[[]]],[11,R[5],E,E,1,[[],["self"]]],[11,R[6],E,E,1,[[]]],[8,"AndNot",R[7],E,N,N],[16,"Output",E,E,2,N],[10,"andnot",E,E,2,[[]]],[8,"BSwap",E,E,N,N],[10,"bswap",E,E,3,[[],["self"]]],[8,"ArithOps",E,"Ops that depend on word size",N,N],[8,"BitOps0",E,"Ops that are independent of word size and endian",N,N],[8,"BitOps32",E,E,N,N],[8,"BitOps64",E,E,N,N],[8,"BitOps128",E,E,N,N],[8,R[24],E,E,N,N],[10,"rotate_each_word_right7",E,E,4,[[],["self"]]],[10,"rotate_each_word_right8",E,E,4,[[],["self"]]],[10,"rotate_each_word_right11",E,E,4,[[],["self"]]],[10,"rotate_each_word_right12",E,E,4,[[],["self"]]],[10,"rotate_each_word_right16",E,E,4,[[],["self"]]],[10,"rotate_each_word_right20",E,E,4,[[],["self"]]],[10,"rotate_each_word_right24",E,E,4,[[],["self"]]],[10,"rotate_each_word_right25",E,E,4,[[],["self"]]],[8,R[25],E,E,N,N],[10,"rotate_each_word_right32",E,E,5,[[],["self"]]],[8,"RotateEachWord128",E,E,N,N],[8,R[26],E,E,N,N],[10,"unsafe_from",E,E,6,[[[T]],["self"]]],[8,"Vec2",E,"A vector composed of two elements, which may be words or…",N,N],[10,R[8],E,E,7,[[["u32"]],["w"]]],[10,R[9],E,E,7,[[["w"],["u32"]],["self"]]],[8,"Vec4",E,"A vector composed of four elements, which may be words or…",N,N],[10,R[8],E,E,8,[[["u32"]],["w"]]],[10,R[9],E,E,8,[[["w"],["u32"]],["self"]]],[8,"Words4",E,"A vector composed of four words; depending on their size,…",N,N],[10,"shuffle1230",E,E,9,[[],["self"]]],[10,"shuffle2301",E,E,9,[[],["self"]]],[10,"shuffle3012",E,E,9,[[],["self"]]],[8,R[27],E,"A vector composed one or more lanes each composed of four…",N,N],[10,"shuffle_lane_words1230",E,E,10,[[],["self"]]],[10,"shuffle_lane_words2301",E,E,10,[[],["self"]]],[10,"shuffle_lane_words3012",E,E,10,[[],["self"]]],[8,"Swap64",E,"Exchange neigboring ranges of bits of the specified size",N,N],[10,"swap1",E,E,11,[[],["self"]]],[10,"swap2",E,E,11,[[],["self"]]],[10,"swap4",E,E,11,[[],["self"]]],[10,"swap8",E,E,11,[[],["self"]]],[10,"swap16",E,E,11,[[],["self"]]],[10,"swap32",E,E,11,[[],["self"]]],[10,"swap64",E,E,11,[[],["self"]]],[8,"u32x4",E,E,N,N],[8,"u64x2",E,E,N,N],[8,"u128x1",E,E,N,N],[8,R[65],E,E,N,N],[8,R[66],E,E,N,N],[8,"u64x4",E,E,N,N],[8,"u128x2",E,E,N,N],[8,R[67],E,E,N,N],[8,R[68],E,E,N,N],[8,"u128x4",E,E,N,N],[8,R[28],E,"A vector composed of multiple 128-bit lanes.",N,N],[10,"to_lanes",E,"Split a multi-lane vector into single-lane vectors.",12,[[],["lanes"]]],[10,"from_lanes",E,"Build a multi-lane vector from individual lanes.",12,[[["lanes"]],["self"]]],[8,"VZip",E,"Combine single vectors into a multi-lane vector.",N,N],[10,"vzip",E,E,13,[[],["v"]]],[8,R[64],E,E,N,N],[16,"u32x4",E,E,14,N],[16,"u64x2",E,E,14,N],[16,"u128x1",E,E,14,N],[16,R[65],E,E,14,N],[16,R[66],E,E,14,N],[16,"u64x4",E,E,14,N],[16,"u128x2",E,E,14,N],[16,R[67],E,E,14,N],[16,R[68],E,E,14,N],[16,"u128x4",E,E,14,N],[11,R[69],E,E,14,[[["s"]],["store"]]],[11,"vec",E,E,14,[[["a"]],["v"]]],[11,R[70],E,E,14,[[],["v"]]],[11,R[71],E,E,14,[[],["v"]]],[10,R[19],E,E,14,[[],["self"]]],[8,"Store",E,E,N,N],[10,R[69],E,E,15,[[["s"]],["self"]]],[8,R[29],E,E,N,N],[10,"unsafe_read_le",E,E,16,[[],["self"]]],[10,"unsafe_read_be",E,E,16,[[],["self"]]],[10,"write_le",E,E,16,[[]]],[10,"write_be",E,E,16,[[]]],[14,"dispatch",E,"Generate the full set of optimized implementations to take…",N,N],[14,"dispatch_light128",E,R[10],N,N],[14,"dispatch_light256",E,R[10],N,N],[11,"from",R[11],E,17,[[[T]],[T]]],[11,R[12],E,E,17,[[[U]],[R[15]]]],[11,"into",E,E,17,[[],[U]]],[11,R[13],E,E,17,[[],[R[15]]]],[11,R[17],E,E,17,[[["self"]],[T]]],[11,R[14],E,E,17,[[["self"]],[T]]],[11,R[16],E,E,17,[[["self"]],[R[18]]]],[11,"from",E,E,18,[[[T]],[T]]],[11,R[12],E,E,18,[[[U]],[R[15]]]],[11,"into",E,E,18,[[],[U]]],[11,R[13],E,E,18,[[],[R[15]]]],[11,R[17],E,E,18,[[["self"]],[T]]],[11,R[14],E,E,18,[[["self"]],[T]]],[11,R[16],E,E,18,[[["self"]],[R[18]]]],[11,"from",E,E,19,[[[T]],[T]]],[11,R[12],E,E,19,[[[U]],[R[15]]]],[11,"into",E,E,19,[[],[U]]],[11,R[13],E,E,19,[[],[R[15]]]],[11,R[17],E,E,19,[[["self"]],[T]]],[11,R[14],E,E,19,[[["self"]],[T]]],[11,R[16],E,E,19,[[["self"]],[R[18]]]],[11,"from",E,E,20,[[[T]],[T]]],[11,R[12],E,E,20,[[[U]],[R[15]]]],[11,"into",E,E,20,[[],[U]]],[11,R[13],E,E,20,[[],[R[15]]]],[11,R[17],E,E,20,[[["self"]],[T]]],[11,R[14],E,E,20,[[["self"]],[T]]],[11,R[16],E,E,20,[[["self"]],[R[18]]]],[11,"from",E,E,21,[[[T]],[T]]],[11,R[12],E,E,21,[[[U]],[R[15]]]],[11,"into",E,E,21,[[],[U]]],[11,R[13],E,E,21,[[],[R[15]]]],[11,R[17],E,E,21,[[["self"]],[T]]],[11,R[14],E,E,21,[[["self"]],[T]]],[11,R[16],E,E,21,[[["self"]],[R[18]]]],[11,"from",E,E,22,[[[T]],[T]]],[11,R[12],E,E,22,[[[U]],[R[15]]]],[11,"into",E,E,22,[[],[U]]],[11,R[13],E,E,22,[[],[R[15]]]],[11,R[17],E,E,22,[[["self"]],[T]]],[11,R[14],E,E,22,[[["self"]],[T]]],[11,R[16],E,E,22,[[["self"]],[R[18]]]],[11,"from",E,E,23,[[[T]],[T]]],[11,R[12],E,E,23,[[[U]],[R[15]]]],[11,"into",E,E,23,[[],[U]]],[11,R[13],E,E,23,[[],[R[15]]]],[11,R[17],E,E,23,[[["self"]],[T]]],[11,R[14],E,E,23,[[["self"]],[T]]],[11,R[16],E,E,23,[[["self"]],[R[18]]]],[11,"from",E,E,24,[[[T]],[T]]],[11,R[12],E,E,24,[[[U]],[R[15]]]],[11,"into",E,E,24,[[],[U]]],[11,R[13],E,E,24,[[],[R[15]]]],[11,R[17],E,E,24,[[["self"]],[T]]],[11,R[14],E,E,24,[[["self"]],[T]]],[11,R[16],E,E,24,[[["self"]],[R[18]]]],[11,"from",E,E,25,[[[T]],[T]]],[11,R[12],E,E,25,[[[U]],[R[15]]]],[11,"into",E,E,25,[[],[U]]],[11,R[13],E,E,25,[[],[R[15]]]],[11,R[17],E,E,25,[[["self"]],[T]]],[11,R[14],E,E,25,[[["self"]],[T]]],[11,R[16],E,E,25,[[["self"]],[R[18]]]],[11,"from",E,E,26,[[[T]],[T]]],[11,R[12],E,E,26,[[[U]],[R[15]]]],[11,"into",E,E,26,[[],[U]]],[11,R[13],E,E,26,[[],[R[15]]]],[11,R[17],E,E,26,[[["self"]],[T]]],[11,R[14],E,E,26,[[["self"]],[T]]],[11,R[16],E,E,26,[[["self"]],[R[18]]]],[11,"from",E,E,27,[[[T]],[T]]],[11,R[12],E,E,27,[[[U]],[R[15]]]],[11,"into",E,E,27,[[],[U]]],[11,R[13],E,E,27,[[],[R[15]]]],[11,R[17],E,E,27,[[["self"]],[T]]],[11,R[14],E,E,27,[[["self"]],[T]]],[11,R[16],E,E,27,[[["self"]],[R[18]]]],[11,"from",E,E,28,[[[T]],[T]]],[11,R[12],E,E,28,[[[U]],[R[15]]]],[11,"into",E,E,28,[[],[U]]],[11,R[13],E,E,28,[[],[R[15]]]],[11,R[17],E,E,28,[[["self"]],[T]]],[11,R[14],E,E,28,[[["self"]],[T]]],[11,R[16],E,E,28,[[["self"]],[R[18]]]],[11,"from",E,E,29,[[[T]],[T]]],[11,R[12],E,E,29,[[[U]],[R[15]]]],[11,"into",E,E,29,[[],[U]]],[11,R[13],E,E,29,[[],[R[15]]]],[11,R[17],E,E,29,[[["self"]],[T]]],[11,R[14],E,E,29,[[["self"]],[T]]],[11,R[16],E,E,29,[[["self"]],[R[18]]]],[11,"from",E,E,0,[[[T]],[T]]],[11,R[12],E,E,0,[[[U]],[R[15]]]],[11,"into",E,E,0,[[],[U]]],[11,R[13],E,E,0,[[],[R[15]]]],[11,R[17],E,E,0,[[["self"]],[T]]],[11,R[14],E,E,0,[[["self"]],[T]]],[11,R[16],E,E,0,[[["self"]],[R[18]]]],[11,"from",E,E,1,[[[T]],[T]]],[11,R[12],E,E,1,[[[U]],[R[15]]]],[11,"into",E,E,1,[[],[U]]],[11,R[13],E,E,1,[[],[R[15]]]],[11,R[17],E,E,1,[[["self"]],[T]]],[11,R[14],E,E,1,[[["self"]],[T]]],[11,R[16],E,E,1,[[["self"]],[R[18]]]],[11,R[19],E,E,27,[[],["self"]]],[11,R[19],E,E,28,[[],["self"]]],[11,R[69],E,E,29,[[[R[20]]],["self"]]],[11,"into",E,E,29,[[]]],[11,"into",E,E,29,[[]]],[11,"into",E,E,29,[[]]],[11,"into",E,E,0,[[]]],[11,"into",E,E,0,[[]]],[11,"into",E,E,0,[[]]],[11,"into",E,E,1,[[]]],[11,"into",E,E,1,[[]]],[11,"into",E,E,1,[[]]],[11,"clone",E,E,17,[[["self"]],["yess3"]]],[11,"clone",E,E,18,[[["self"]],["nos3"]]],[11,"clone",E,E,19,[[["self"]],["yess4"]]],[11,"clone",E,E,20,[[["self"]],["nos4"]]],[11,"clone",E,E,21,[[["self"]],["yesa1"]]],[11,"clone",E,E,22,[[["self"]],["noa1"]]],[11,"clone",E,E,23,[[["self"]],["yesa2"]]],[11,"clone",E,E,24,[[["self"]],["noa2"]]],[11,"clone",E,E,25,[[["self"]],["yesni"]]],[11,"clone",E,E,26,[[["self"]],["noni"]]],[11,"clone",E,E,27,[[["self"]],["ssemachine"]]],[11,"clone",E,E,28,[[["self"]],["avx2machine"]]],[11,"clone",E,E,29,[[["self"]],[R[20]]]],[11,"clone",E,E,0,[[["self"]],[R[21]]]],[11,"clone",E,E,1,[[["self"]],[R[22]]]],[11,R[23],E,E,29,[[],["self"]]],[11,R[23],E,E,0,[[],["self"]]],[11,R[23],E,E,1,[[],["self"]]],[11,R[69],R[7],E,14,[[["s"]],["store"]]],[11,"vec",E,E,14,[[["a"]],["v"]]],[11,R[70],E,E,14,[[],["v"]]],[11,R[71],E,E,14,[[],["v"]]]],"p":[[19,R[21]],[19,R[22]],[8,"AndNot"],[8,"BSwap"],[8,R[24]],[8,R[25]],[8,R[26]],[8,"Vec2"],[8,"Vec4"],[8,"Words4"],[8,R[27]],[8,"Swap64"],[8,R[28]],[8,"VZip"],[8,R[64]],[8,"Store"],[8,R[29]],[3,"YesS3"],[3,"NoS3"],[3,"YesS4"],[3,"NoS4"],[3,"YesA1"],[3,"NoA1"],[3,"YesA2"],[3,"NoA2"],[3,"YesNI"],[3,"NoNI"],[3,R[30]],[3,R[31]],[19,R[20]]]}; +searchIndex["rand"]={"doc":"Utilities for random number generation","i":[[8,"RngCore","rand",R[370],N,N],[10,R[83],E,R[371],0,[[["self"]],["u32"]]],[10,R[84],E,R[372],0,[[["self"]],["u64"]]],[10,R[85],E,R[373],0,[[["self"]]]],[10,R[86],E,R[374],0,[[["self"]],[[R[15],["error"]],["error"]]]],[8,R[375],E,R[376],N,N],[8,R[96],E,R[377],N,N],[16,"Seed",E,R[378],1,N],[10,R[87],E,R[379],1,[[],["self"]]],[11,R[88],E,R[380],1,[[["u64"]],["self"]]],[11,R[89],E,R[381],1,[[["r"]],[["error"],[R[15],["error"]]]]],[11,R[382],E,R[383],1,[[],["self"]]],[3,"Error",E,R[364],N,N],[5,"thread_rng",E,"Retrieve the lazily-initialized thread-local random number…",N,[[],[R[331]]]],[5,"random",E,"Generates a random value using the thread-local random…",N,[[],[T]]],[0,"distributions",E,"Generating random samples from probability distributions",N,N],[3,R[352],R[305],"Sample a `char`, uniformly distributed over ASCII letters…",N,N],[3,"Uniform",E,R[302],N,N],[3,R[353],E,R[301],N,N],[3,"Open01",E,R[301],N,N],[3,R[338],E,"The Bernoulli distribution.",N,N],[3,R[340],E,"Samples uniformly from the surface of the unit sphere in…",N,N],[3,R[341],E,"Samples uniformly from the edge of the unit circle in two…",N,N],[3,"Gamma",E,"The Gamma distribution `Gamma(shape, scale)` distribution.",N,N],[3,R[342],E,"The chi-squared distribution `χ²(k)`, where `k` is the…",N,N],[3,"FisherF",E,"The Fisher F distribution `F(m, n)`.",N,N],[3,"StudentT",E,"The Student t distribution, `t(nu)`, where `nu` is the…",N,N],[3,"Beta",E,"The Beta distribution with shape parameters `alpha` and…",N,N],[3,"Normal",E,"The normal distribution `N(mean, std_dev**2)`.",N,N],[3,R[343],E,"The log-normal distribution `ln N(mean, std_dev**2)`.",N,N],[3,R[354],E,"Samples floating-point numbers according to the normal…",N,N],[3,"Exp",E,"The exponential distribution `Exp(lambda)`.",N,N],[3,"Exp1",E,"Samples floating-point numbers according to the…",N,N],[3,"Pareto",E,"Samples floating-point numbers according to the Pareto…",N,N],[3,"Poisson",E,"The Poisson distribution `Poisson(lambda)`.",N,N],[3,"Binomial",E,"The binomial distribution `Binomial(n, p)`.",N,N],[3,"Cauchy",E,"The Cauchy distribution `Cauchy(median, scale)`.",N,N],[3,R[344],E,"The dirichelet distribution `Dirichlet(alpha)`.",N,N],[3,R[345],E,"The triangular distribution.",N,N],[3,"Weibull",E,"Samples floating-point numbers according to the Weibull…",N,N],[3,"DistIter",E,"An iterator that generates random values of `T` with…",N,N],[3,R[355],E,"A generic random value distribution, implemented for many…",N,N],[4,R[334],E,"Error type returned from `Bernoulli::new`.",N,N],[13,"InvalidProbability",E,"`p < 0` or `p > 1`.",2,N],[0,R[325],E,"A distribution uniformly sampling numbers within a given…",N,N],[3,"Uniform",R[319],R[302],N,N],[3,R[356],E,"The back-end implementing [`UniformSampler`] for integer…",N,N],[3,R[357],E,"The back-end implementing [`UniformSampler`] for…",N,N],[3,R[358],E,"The back-end implementing [`UniformSampler`] for `Duration`.",N,N],[8,R[335],E,"Helper trait for creating objects using the correct…",N,N],[16,"Sampler",E,"The `UniformSampler` implementation supporting type `X`.",3,N],[8,R[336],E,"Helper trait handling actual uniform sampling.",N,N],[16,"X",E,"The type sampled by this implementation.",4,N],[10,"new",E,"Construct self, with inclusive lower bound and exclusive…",4,[[["b2"],["b1"]],["self"]]],[10,R[303],E,"Construct self, with inclusive bounds `[low, high]`.",4,[[["b2"],["b1"]],["self"]]],[10,"sample",E,"Sample a value.",4,[[["self"],["r"]]]],[11,R[324],E,"Sample a single value uniformly from a range with…",4,[[["b2"],["b1"],["r"]]]],[8,R[337],E,"Helper trait similar to [`Borrow`] but implemented only…",N,N],[10,R[17],E,"Immutably borrows from an owned value. See…",5,[[["self"]],["borrowed"]]],[11,"new",E,R[304],6,[[["b2"],["b1"]],[R[325]]]],[11,R[303],E,R[304],6,[[["b2"],["b1"]],[R[325]]]],[11,"new",R[305],"Construct a new `Bernoulli` with the given probability of…",7,[[["f64"]],[[R[306]],[R[307]],[R[15],[R[306],R[307]]]]]],[11,"from_ratio",E,"Construct a new `Bernoulli` with the probability of…",7,[[["u32"]],[[R[306]],[R[307]],[R[15],[R[306],R[307]]]]]],[0,"weighted",E,"Weighted index sampling",N,N],[3,R[308],R[311],R[309],N,N],[4,R[339],E,"Error type returned from `WeightedIndex::new`.",N,N],[13,"NoItem",E,"The provided weight collection contains no items.",8,N],[13,"InvalidWeight",E,"A weight is either less than zero, greater than the…",8,N],[13,"AllWeightsZero",E,"All items in the provided weight collection are zero.",8,N],[13,"TooMany",E,"Too many weights are provided (length greater than…",8,N],[0,"alias_method",E,"This module contains an implementation of alias method for…",N,N],[3,R[308],R[320],R[309],N,N],[8,"Weight",E,"Trait that must be implemented for weights, that are used…",N,N],[18,"MAX",E,"Maximum number representable by `Self`.",9,N],[18,"ZERO",E,"Element of `Self` equivalent to 0.",9,N],[10,"try_from_u32_lossy",E,"Produce an instance of `Self` from a `u32` value, or…",9,[[["u32"]],[R[3]]]],[11,"sum",E,"Sums all values in slice `values`.",9,[[],["self"]]],[11,"new",E,"Creates a new [`WeightedIndex`].",10,[[["vec"]],[[R[15],[R[310]]],[R[310]]]]],[11,"new",R[311],"Creates a new a `WeightedIndex` [`Distribution`] using the…",11,[[["i"]],[[R[15],[R[312],R[310]]],[R[312]],[R[310]]]]],[11,"new",R[305],"Construct a new `UnitSphereSurface` distribution.",12,[[],[R[326]]]],[11,"new",E,"Construct a new `UnitCircle` distribution.",13,[[],[R[327]]]],[11,"new",E,"Construct an object representing the `Gamma(shape, scale)`…",14,[[["f64"]],["gamma"]]],[11,"new",E,"Create a new chi-squared distribution with…",15,[[["f64"]],[R[328]]]],[11,"new",E,"Create a new `FisherF` distribution, with the given…",16,[[["f64"]],["fisherf"]]],[11,"new",E,"Create a new Student t distribution with `n` degrees of…",17,[[["f64"]],["studentt"]]],[11,"new",E,"Construct an object representing the `Beta(alpha, beta)`…",18,[[["f64"]],["beta"]]],[11,"new",E,"Construct a new `Normal` distribution with the given mean…",19,[[["f64"]],["normal"]]],[11,"new",E,"Construct a new `LogNormal` distribution with the given…",20,[[["f64"]],[R[329]]]],[11,"new",E,"Construct a new `Exp` with the given shape parameter…",21,[[["f64"]],["exp"]]],[11,"new",E,"Construct a new Pareto distribution with given `scale` and…",22,[[["f64"]],["pareto"]]],[11,"new",E,"Construct a new `Poisson` with the given shape parameter…",23,[[["f64"]],["poisson"]]],[11,"new",E,"Construct a new `Binomial` with the given shape parameters…",24,[[["f64"],["u64"]],["binomial"]]],[11,"new",E,"Construct a new `Cauchy` with the given shape parameters…",25,[[["f64"]],["cauchy"]]],[11,"new",E,"Construct a new `Dirichlet` with the given alpha parameter…",26,[[["into",["vec"]],["vec",["f64"]]],[R[313]]]],[11,"new_with_param",E,"Construct a new `Dirichlet` with the given shape parameter…",26,[[["f64"],["usize"]],[R[313]]]],[11,"new",E,"Construct a new `Triangular` with minimum `min`, maximum…",27,[[["f64"]],[R[330]]]],[11,"new",E,"Construct a new `Weibull` distribution with given `scale`…",28,[[["f64"]],["weibull"]]],[8,R[346],E,"Types (distributions) that can be used to create a random…",N,N],[10,"sample",E,"Generate a random value of `T`, using `rng` as the source…",29,[[["self"],["r"]],[T]]],[11,R[317],E,"Create an iterator that generates random values of `T`,…",29,[[["r"]],["distiter"]]],[0,"prelude","rand","Convenience re-export of common members",N,N],[0,"rngs",E,"Random number generators and adapters",N,N],[3,R[348],R[314],"An interface returning random data from external…",N,N],[3,"StdRng",E,"The standard RNG. The PRNG algorithm in `StdRng` is chosen…",N,N],[3,R[359],E,"The type returned by [`thread_rng`], essentially just a…",N,N],[3,"OsRng",E,"A random number generator that retrieves randomness from…",N,N],[0,"adapter",E,"Wrappers / adapters forming RNGs",N,N],[3,"ReadRng",R[321],"An RNG that reads random bytes straight from any type…",N,N],[3,R[360],E,"`ReadRng` error type",N,N],[3,R[347],E,"A wrapper around any PRNG that implements…",N,N],[11,"new",E,"Create a new `ReadRng` from a `Read`.",30,[[["r"]],["readrng"]]],[11,"new",E,"Create a new `ReseedingRng` from an existing PRNG,…",31,[[["rsdr"],["u64"],["r"]],["self"]]],[11,"reseed",E,"Reseed the internal PRNG.",31,[[["self"]],[[R[15],["error"]],["error"]]]],[11,"new",R[314],"Create a new `EntropyRng`.",32,[[],["self"]]],[0,"mock",E,"Mock random number generator",N,N],[3,"StepRng",R[322],"A simple implementation of `RngCore` for testing purposes.",N,N],[11,"new",E,"Create a `StepRng`, yielding an arithmetic sequence…",33,[[["u64"]],["self"]]],[11,"new",R[314],"Create a new `OsRng`.",34,[[],[["osrng"],["error"],[R[15],["osrng","error"]]]]],[0,"seq","rand","Sequence-related functionality",N,N],[3,R[361],R[315],"An iterator over multiple slice elements.",N,N],[0,"index",E,"Low-level API for sampling indices",N,N],[4,"IndexVec",R[323],"A vector of indices.",N,N],[4,R[362],E,"Return type of `IndexVec::iter`.",N,N],[4,R[363],E,"Return type of `IndexVec::into_iter`.",N,N],[5,"sample",E,"Randomly sample exactly `amount` distinct indices from…",N,[[["r"],["usize"]],[R[332]]]],[11,"len",E,"Returns the number of indices",35,[[["self"]],["usize"]]],[11,"index",E,"Return the value at the given `index`.",35,[[["self"],["usize"]],["usize"]]],[11,"into_vec",E,"Return result as a `Vec`. Conversion may or may not…",35,[[],[["usize"],["vec",["usize"]]]]],[11,"iter",E,"Iterate over the indices as a sequence of `usize` values",35,[[["self"]],["indexveciter"]]],[11,R[50],E,"Convert into an iterator over the indices as a sequence of…",35,[[],[R[333]]]],[8,R[349],R[315],"Extension trait on slices, providing random mutation and…",N,N],[16,"Item",E,"The element type.",36,N],[10,"choose",E,"Returns a reference to one random element of the slice, or…",36,[[["self"],["r"]],[R[3]]]],[10,"choose_mut",E,"Returns a mutable reference to one random element of the…",36,[[["self"],["r"]],[R[3]]]],[10,R[316],E,"Chooses `amount` elements from the slice at random,…",36,[[["self"],["r"],["usize"]],["slicechooseiter"]]],[10,"choose_weighted",E,"Similar to [`choose`], but where the likelihood of each…",36,[[["self"],["r"],["f"]],[[R[310]],[R[15],[R[310]]]]]],[10,"choose_weighted_mut",E,"Similar to [`choose_mut`], but where the likelihood of…",36,[[["self"],["r"],["f"]],[[R[15],[R[310]]],[R[310]]]]],[10,"shuffle",E,"Shuffle a mutable slice in place.",36,[[["self"],["r"]]]],[10,"partial_shuffle",E,"Shuffle a slice in place, but exit early.",36,[[["self"],["r"],["usize"]]]],[8,R[350],E,"Extension trait on iterators, providing random sampling…",N,N],[11,"choose",E,"Choose one element at random from the iterator.",37,[[["r"]],[R[3]]]],[11,"choose_multiple_fill",E,"Collects values at random from the iterator into a…",37,[[["r"]],["usize"]]],[11,R[316],E,"Collects `amount` values at random from the iterator into…",37,[[["r"],["usize"]],["vec"]]],[8,"Rng","rand","An automatically-implemented extension trait on…",N,N],[11,"gen",E,"Return a random value supporting the [`Standard`]…",38,[[["self"]],[T]]],[11,"gen_range",E,"Generate a random value in the range [`low`, `high`), i.e.…",38,[[["self"],["b1"],["b2"]],["sampleuniform"]]],[11,"sample",E,"Sample a new value, using the given distribution.",38,[[["self"],["distribution"]],[T]]],[11,R[317],E,"Create an iterator that generates values using the given…",38,[[["d"]],["distiter"]]],[11,"fill",E,R[318],38,[[["self"],[T]]]],[11,"try_fill",E,R[318],38,[[["self"],[T]],[[R[15],["error"]],["error"]]]],[11,"gen_bool",E,"Return a bool with a probability `p` of being true.",38,[[["self"],["f64"]],["bool"]]],[11,"gen_ratio",E,"Return a bool with a probability of…",38,[[["self"],["u32"]],["bool"]]],[8,R[351],E,"Trait for casting types to byte slices",N,N],[10,"as_byte_slice_mut",E,"Return a mutable reference to self as a byte slice",39,[[["self"]]]],[10,"to_le",E,"Call `to_le` on each element (i.e. byte-swap on Big Endian…",39,[[["self"]]]],[11,"from",E,E,40,[[[T]],[T]]],[11,R[81],E,E,40,[[["self"]],[R[2]]]],[11,"into",E,E,40,[[],[U]]],[11,R[12],E,E,40,[[[U]],[R[15]]]],[11,R[13],E,E,40,[[],[R[15]]]],[11,R[14],E,E,40,[[["self"]],[T]]],[11,R[17],E,E,40,[[["self"]],[T]]],[11,R[16],E,E,40,[[["self"]],[R[18]]]],[11,"vzip",E,E,40,[[],["v"]]],[11,"from",R[305],E,41,[[[T]],[T]]],[11,"into",E,E,41,[[],[U]]],[11,R[12],E,E,41,[[[U]],[R[15]]]],[11,R[13],E,E,41,[[],[R[15]]]],[11,R[14],E,E,41,[[["self"]],[T]]],[11,R[17],E,E,41,[[["self"]],[T]]],[11,R[16],E,E,41,[[["self"]],[R[18]]]],[11,"vzip",E,E,41,[[],["v"]]],[11,"from",R[319],E,6,[[[T]],[T]]],[11,R[32],E,E,6,[[["self"]],[T]]],[11,R[33],E,E,6,[[[T],["self"]]]],[11,"into",E,E,6,[[],[U]]],[11,R[12],E,E,6,[[[U]],[R[15]]]],[11,R[13],E,E,6,[[],[R[15]]]],[11,R[14],E,E,6,[[["self"]],[T]]],[11,R[17],E,E,6,[[["self"]],[T]]],[11,R[16],E,E,6,[[["self"]],[R[18]]]],[11,"vzip",E,E,6,[[],["v"]]],[11,"from",R[305],E,42,[[[T]],[T]]],[11,R[32],E,E,42,[[["self"]],[T]]],[11,R[33],E,E,42,[[[T],["self"]]]],[11,"into",E,E,42,[[],[U]]],[11,R[12],E,E,42,[[[U]],[R[15]]]],[11,R[13],E,E,42,[[],[R[15]]]],[11,R[14],E,E,42,[[["self"]],[T]]],[11,R[17],E,E,42,[[["self"]],[T]]],[11,R[16],E,E,42,[[["self"]],[R[18]]]],[11,"vzip",E,E,42,[[],["v"]]],[11,"from",E,E,43,[[[T]],[T]]],[11,R[32],E,E,43,[[["self"]],[T]]],[11,R[33],E,E,43,[[[T],["self"]]]],[11,"into",E,E,43,[[],[U]]],[11,R[12],E,E,43,[[[U]],[R[15]]]],[11,R[13],E,E,43,[[],[R[15]]]],[11,R[14],E,E,43,[[["self"]],[T]]],[11,R[17],E,E,43,[[["self"]],[T]]],[11,R[16],E,E,43,[[["self"]],[R[18]]]],[11,"vzip",E,E,43,[[],["v"]]],[11,"from",E,E,7,[[[T]],[T]]],[11,R[32],E,E,7,[[["self"]],[T]]],[11,R[33],E,E,7,[[[T],["self"]]]],[11,"into",E,E,7,[[],[U]]],[11,R[12],E,E,7,[[[U]],[R[15]]]],[11,R[13],E,E,7,[[],[R[15]]]],[11,R[14],E,E,7,[[["self"]],[T]]],[11,R[17],E,E,7,[[["self"]],[T]]],[11,R[16],E,E,7,[[["self"]],[R[18]]]],[11,"vzip",E,E,7,[[],["v"]]],[11,"from",E,E,12,[[[T]],[T]]],[11,R[32],E,E,12,[[["self"]],[T]]],[11,R[33],E,E,12,[[[T],["self"]]]],[11,"into",E,E,12,[[],[U]]],[11,R[12],E,E,12,[[[U]],[R[15]]]],[11,R[13],E,E,12,[[],[R[15]]]],[11,R[14],E,E,12,[[["self"]],[T]]],[11,R[17],E,E,12,[[["self"]],[T]]],[11,R[16],E,E,12,[[["self"]],[R[18]]]],[11,"vzip",E,E,12,[[],["v"]]],[11,"from",E,E,13,[[[T]],[T]]],[11,R[32],E,E,13,[[["self"]],[T]]],[11,R[33],E,E,13,[[[T],["self"]]]],[11,"into",E,E,13,[[],[U]]],[11,R[12],E,E,13,[[[U]],[R[15]]]],[11,R[13],E,E,13,[[],[R[15]]]],[11,R[14],E,E,13,[[["self"]],[T]]],[11,R[17],E,E,13,[[["self"]],[T]]],[11,R[16],E,E,13,[[["self"]],[R[18]]]],[11,"vzip",E,E,13,[[],["v"]]],[11,"from",E,E,14,[[[T]],[T]]],[11,R[32],E,E,14,[[["self"]],[T]]],[11,R[33],E,E,14,[[[T],["self"]]]],[11,"into",E,E,14,[[],[U]]],[11,R[12],E,E,14,[[[U]],[R[15]]]],[11,R[13],E,E,14,[[],[R[15]]]],[11,R[14],E,E,14,[[["self"]],[T]]],[11,R[17],E,E,14,[[["self"]],[T]]],[11,R[16],E,E,14,[[["self"]],[R[18]]]],[11,"vzip",E,E,14,[[],["v"]]],[11,"from",E,E,15,[[[T]],[T]]],[11,R[32],E,E,15,[[["self"]],[T]]],[11,R[33],E,E,15,[[[T],["self"]]]],[11,"into",E,E,15,[[],[U]]],[11,R[12],E,E,15,[[[U]],[R[15]]]],[11,R[13],E,E,15,[[],[R[15]]]],[11,R[14],E,E,15,[[["self"]],[T]]],[11,R[17],E,E,15,[[["self"]],[T]]],[11,R[16],E,E,15,[[["self"]],[R[18]]]],[11,"vzip",E,E,15,[[],["v"]]],[11,"from",E,E,16,[[[T]],[T]]],[11,R[32],E,E,16,[[["self"]],[T]]],[11,R[33],E,E,16,[[[T],["self"]]]],[11,"into",E,E,16,[[],[U]]],[11,R[12],E,E,16,[[[U]],[R[15]]]],[11,R[13],E,E,16,[[],[R[15]]]],[11,R[14],E,E,16,[[["self"]],[T]]],[11,R[17],E,E,16,[[["self"]],[T]]],[11,R[16],E,E,16,[[["self"]],[R[18]]]],[11,"vzip",E,E,16,[[],["v"]]],[11,"from",E,E,17,[[[T]],[T]]],[11,R[32],E,E,17,[[["self"]],[T]]],[11,R[33],E,E,17,[[[T],["self"]]]],[11,"into",E,E,17,[[],[U]]],[11,R[12],E,E,17,[[[U]],[R[15]]]],[11,R[13],E,E,17,[[],[R[15]]]],[11,R[14],E,E,17,[[["self"]],[T]]],[11,R[17],E,E,17,[[["self"]],[T]]],[11,R[16],E,E,17,[[["self"]],[R[18]]]],[11,"vzip",E,E,17,[[],["v"]]],[11,"from",E,E,18,[[[T]],[T]]],[11,R[32],E,E,18,[[["self"]],[T]]],[11,R[33],E,E,18,[[[T],["self"]]]],[11,"into",E,E,18,[[],[U]]],[11,R[12],E,E,18,[[[U]],[R[15]]]],[11,R[13],E,E,18,[[],[R[15]]]],[11,R[14],E,E,18,[[["self"]],[T]]],[11,R[17],E,E,18,[[["self"]],[T]]],[11,R[16],E,E,18,[[["self"]],[R[18]]]],[11,"vzip",E,E,18,[[],["v"]]],[11,"from",E,E,19,[[[T]],[T]]],[11,R[32],E,E,19,[[["self"]],[T]]],[11,R[33],E,E,19,[[[T],["self"]]]],[11,"into",E,E,19,[[],[U]]],[11,R[12],E,E,19,[[[U]],[R[15]]]],[11,R[13],E,E,19,[[],[R[15]]]],[11,R[14],E,E,19,[[["self"]],[T]]],[11,R[17],E,E,19,[[["self"]],[T]]],[11,R[16],E,E,19,[[["self"]],[R[18]]]],[11,"vzip",E,E,19,[[],["v"]]],[11,"from",E,E,20,[[[T]],[T]]],[11,R[32],E,E,20,[[["self"]],[T]]],[11,R[33],E,E,20,[[[T],["self"]]]],[11,"into",E,E,20,[[],[U]]],[11,R[12],E,E,20,[[[U]],[R[15]]]],[11,R[13],E,E,20,[[],[R[15]]]],[11,R[14],E,E,20,[[["self"]],[T]]],[11,R[17],E,E,20,[[["self"]],[T]]],[11,R[16],E,E,20,[[["self"]],[R[18]]]],[11,"vzip",E,E,20,[[],["v"]]],[11,"from",E,E,44,[[[T]],[T]]],[11,R[32],E,E,44,[[["self"]],[T]]],[11,R[33],E,E,44,[[[T],["self"]]]],[11,"into",E,E,44,[[],[U]]],[11,R[12],E,E,44,[[[U]],[R[15]]]],[11,R[13],E,E,44,[[],[R[15]]]],[11,R[14],E,E,44,[[["self"]],[T]]],[11,R[17],E,E,44,[[["self"]],[T]]],[11,R[16],E,E,44,[[["self"]],[R[18]]]],[11,"vzip",E,E,44,[[],["v"]]],[11,"from",E,E,21,[[[T]],[T]]],[11,R[32],E,E,21,[[["self"]],[T]]],[11,R[33],E,E,21,[[[T],["self"]]]],[11,"into",E,E,21,[[],[U]]],[11,R[12],E,E,21,[[[U]],[R[15]]]],[11,R[13],E,E,21,[[],[R[15]]]],[11,R[14],E,E,21,[[["self"]],[T]]],[11,R[17],E,E,21,[[["self"]],[T]]],[11,R[16],E,E,21,[[["self"]],[R[18]]]],[11,"vzip",E,E,21,[[],["v"]]],[11,"from",E,E,45,[[[T]],[T]]],[11,R[32],E,E,45,[[["self"]],[T]]],[11,R[33],E,E,45,[[[T],["self"]]]],[11,"into",E,E,45,[[],[U]]],[11,R[12],E,E,45,[[[U]],[R[15]]]],[11,R[13],E,E,45,[[],[R[15]]]],[11,R[14],E,E,45,[[["self"]],[T]]],[11,R[17],E,E,45,[[["self"]],[T]]],[11,R[16],E,E,45,[[["self"]],[R[18]]]],[11,"vzip",E,E,45,[[],["v"]]],[11,"from",E,E,22,[[[T]],[T]]],[11,R[32],E,E,22,[[["self"]],[T]]],[11,R[33],E,E,22,[[[T],["self"]]]],[11,"into",E,E,22,[[],[U]]],[11,R[12],E,E,22,[[[U]],[R[15]]]],[11,R[13],E,E,22,[[],[R[15]]]],[11,R[14],E,E,22,[[["self"]],[T]]],[11,R[17],E,E,22,[[["self"]],[T]]],[11,R[16],E,E,22,[[["self"]],[R[18]]]],[11,"vzip",E,E,22,[[],["v"]]],[11,"from",E,E,23,[[[T]],[T]]],[11,R[32],E,E,23,[[["self"]],[T]]],[11,R[33],E,E,23,[[[T],["self"]]]],[11,"into",E,E,23,[[],[U]]],[11,R[12],E,E,23,[[[U]],[R[15]]]],[11,R[13],E,E,23,[[],[R[15]]]],[11,R[14],E,E,23,[[["self"]],[T]]],[11,R[17],E,E,23,[[["self"]],[T]]],[11,R[16],E,E,23,[[["self"]],[R[18]]]],[11,"vzip",E,E,23,[[],["v"]]],[11,"from",E,E,24,[[[T]],[T]]],[11,R[32],E,E,24,[[["self"]],[T]]],[11,R[33],E,E,24,[[[T],["self"]]]],[11,"into",E,E,24,[[],[U]]],[11,R[12],E,E,24,[[[U]],[R[15]]]],[11,R[13],E,E,24,[[],[R[15]]]],[11,R[14],E,E,24,[[["self"]],[T]]],[11,R[17],E,E,24,[[["self"]],[T]]],[11,R[16],E,E,24,[[["self"]],[R[18]]]],[11,"vzip",E,E,24,[[],["v"]]],[11,"from",E,E,25,[[[T]],[T]]],[11,R[32],E,E,25,[[["self"]],[T]]],[11,R[33],E,E,25,[[[T],["self"]]]],[11,"into",E,E,25,[[],[U]]],[11,R[12],E,E,25,[[[U]],[R[15]]]],[11,R[13],E,E,25,[[],[R[15]]]],[11,R[14],E,E,25,[[["self"]],[T]]],[11,R[17],E,E,25,[[["self"]],[T]]],[11,R[16],E,E,25,[[["self"]],[R[18]]]],[11,"vzip",E,E,25,[[],["v"]]],[11,"from",E,E,26,[[[T]],[T]]],[11,R[32],E,E,26,[[["self"]],[T]]],[11,R[33],E,E,26,[[[T],["self"]]]],[11,"into",E,E,26,[[],[U]]],[11,R[12],E,E,26,[[[U]],[R[15]]]],[11,R[13],E,E,26,[[],[R[15]]]],[11,R[14],E,E,26,[[["self"]],[T]]],[11,R[17],E,E,26,[[["self"]],[T]]],[11,R[16],E,E,26,[[["self"]],[R[18]]]],[11,"vzip",E,E,26,[[],["v"]]],[11,"from",E,E,27,[[[T]],[T]]],[11,R[32],E,E,27,[[["self"]],[T]]],[11,R[33],E,E,27,[[[T],["self"]]]],[11,"into",E,E,27,[[],[U]]],[11,R[12],E,E,27,[[[U]],[R[15]]]],[11,R[13],E,E,27,[[],[R[15]]]],[11,R[14],E,E,27,[[["self"]],[T]]],[11,R[17],E,E,27,[[["self"]],[T]]],[11,R[16],E,E,27,[[["self"]],[R[18]]]],[11,"vzip",E,E,27,[[],["v"]]],[11,"from",E,E,28,[[[T]],[T]]],[11,R[32],E,E,28,[[["self"]],[T]]],[11,R[33],E,E,28,[[[T],["self"]]]],[11,"into",E,E,28,[[],[U]]],[11,R[12],E,E,28,[[[U]],[R[15]]]],[11,R[13],E,E,28,[[],[R[15]]]],[11,R[14],E,E,28,[[["self"]],[T]]],[11,R[17],E,E,28,[[["self"]],[T]]],[11,R[16],E,E,28,[[["self"]],[R[18]]]],[11,"vzip",E,E,28,[[],["v"]]],[11,"from",E,E,46,[[[T]],[T]]],[11,R[50],E,E,46,[[],["i"]]],[11,"into",E,E,46,[[],[U]]],[11,R[12],E,E,46,[[[U]],[R[15]]]],[11,R[13],E,E,46,[[],[R[15]]]],[11,R[14],E,E,46,[[["self"]],[T]]],[11,R[17],E,E,46,[[["self"]],[T]]],[11,R[16],E,E,46,[[["self"]],[R[18]]]],[11,"vzip",E,E,46,[[],["v"]]],[11,"from",E,E,47,[[[T]],[T]]],[11,R[32],E,E,47,[[["self"]],[T]]],[11,R[33],E,E,47,[[[T],["self"]]]],[11,"into",E,E,47,[[],[U]]],[11,R[12],E,E,47,[[[U]],[R[15]]]],[11,R[13],E,E,47,[[],[R[15]]]],[11,R[14],E,E,47,[[["self"]],[T]]],[11,R[17],E,E,47,[[["self"]],[T]]],[11,R[16],E,E,47,[[["self"]],[R[18]]]],[11,"vzip",E,E,47,[[],["v"]]],[11,"from",E,E,2,[[[T]],[T]]],[11,R[32],E,E,2,[[["self"]],[T]]],[11,R[33],E,E,2,[[[T],["self"]]]],[11,"into",E,E,2,[[],[U]]],[11,R[12],E,E,2,[[[U]],[R[15]]]],[11,R[13],E,E,2,[[],[R[15]]]],[11,R[14],E,E,2,[[["self"]],[T]]],[11,R[17],E,E,2,[[["self"]],[T]]],[11,R[16],E,E,2,[[["self"]],[R[18]]]],[11,"vzip",E,E,2,[[],["v"]]],[11,"from",R[319],E,48,[[[T]],[T]]],[11,R[32],E,E,48,[[["self"]],[T]]],[11,R[33],E,E,48,[[[T],["self"]]]],[11,"into",E,E,48,[[],[U]]],[11,R[12],E,E,48,[[[U]],[R[15]]]],[11,R[13],E,E,48,[[],[R[15]]]],[11,R[14],E,E,48,[[["self"]],[T]]],[11,R[17],E,E,48,[[["self"]],[T]]],[11,R[16],E,E,48,[[["self"]],[R[18]]]],[11,"vzip",E,E,48,[[],["v"]]],[11,"from",E,E,49,[[[T]],[T]]],[11,R[32],E,E,49,[[["self"]],[T]]],[11,R[33],E,E,49,[[[T],["self"]]]],[11,"into",E,E,49,[[],[U]]],[11,R[12],E,E,49,[[[U]],[R[15]]]],[11,R[13],E,E,49,[[],[R[15]]]],[11,R[14],E,E,49,[[["self"]],[T]]],[11,R[17],E,E,49,[[["self"]],[T]]],[11,R[16],E,E,49,[[["self"]],[R[18]]]],[11,"vzip",E,E,49,[[],["v"]]],[11,"from",E,E,50,[[[T]],[T]]],[11,R[32],E,E,50,[[["self"]],[T]]],[11,R[33],E,E,50,[[[T],["self"]]]],[11,"into",E,E,50,[[],[U]]],[11,R[12],E,E,50,[[[U]],[R[15]]]],[11,R[13],E,E,50,[[],[R[15]]]],[11,R[14],E,E,50,[[["self"]],[T]]],[11,R[17],E,E,50,[[["self"]],[T]]],[11,R[16],E,E,50,[[["self"]],[R[18]]]],[11,"vzip",E,E,50,[[],["v"]]],[11,"from",R[311],E,11,[[[T]],[T]]],[11,R[32],E,E,11,[[["self"]],[T]]],[11,R[33],E,E,11,[[[T],["self"]]]],[11,"into",E,E,11,[[],[U]]],[11,R[12],E,E,11,[[[U]],[R[15]]]],[11,R[13],E,E,11,[[],[R[15]]]],[11,R[14],E,E,11,[[["self"]],[T]]],[11,R[17],E,E,11,[[["self"]],[T]]],[11,R[16],E,E,11,[[["self"]],[R[18]]]],[11,"vzip",E,E,11,[[],["v"]]],[11,"from",E,E,8,[[[T]],[T]]],[11,R[32],E,E,8,[[["self"]],[T]]],[11,R[33],E,E,8,[[[T],["self"]]]],[11,R[81],E,E,8,[[["self"]],[R[2]]]],[11,"into",E,E,8,[[],[U]]],[11,R[12],E,E,8,[[[U]],[R[15]]]],[11,R[13],E,E,8,[[],[R[15]]]],[11,R[14],E,E,8,[[["self"]],[T]]],[11,R[17],E,E,8,[[["self"]],[T]]],[11,R[16],E,E,8,[[["self"]],[R[18]]]],[11,"vzip",E,E,8,[[],["v"]]],[11,"from",R[320],E,10,[[[T]],[T]]],[11,R[32],E,E,10,[[["self"]],[T]]],[11,R[33],E,E,10,[[[T],["self"]]]],[11,"into",E,E,10,[[],[U]]],[11,R[12],E,E,10,[[[U]],[R[15]]]],[11,R[13],E,E,10,[[],[R[15]]]],[11,R[14],E,E,10,[[["self"]],[T]]],[11,R[17],E,E,10,[[["self"]],[T]]],[11,R[16],E,E,10,[[["self"]],[R[18]]]],[11,"vzip",E,E,10,[[],["v"]]],[11,"from",R[314],E,32,[[[T]],[T]]],[11,"into",E,E,32,[[],[U]]],[11,R[12],E,E,32,[[[U]],[R[15]]]],[11,R[13],E,E,32,[[],[R[15]]]],[11,R[14],E,E,32,[[["self"]],[T]]],[11,R[17],E,E,32,[[["self"]],[T]]],[11,R[16],E,E,32,[[["self"]],[R[18]]]],[11,"vzip",E,E,32,[[],["v"]]],[11,"from",E,E,51,[[[T]],[T]]],[11,R[32],E,E,51,[[["self"]],[T]]],[11,R[33],E,E,51,[[[T],["self"]]]],[11,"into",E,E,51,[[],[U]]],[11,R[12],E,E,51,[[[U]],[R[15]]]],[11,R[13],E,E,51,[[],[R[15]]]],[11,R[14],E,E,51,[[["self"]],[T]]],[11,R[17],E,E,51,[[["self"]],[T]]],[11,R[16],E,E,51,[[["self"]],[R[18]]]],[11,"vzip",E,E,51,[[],["v"]]],[11,"from",E,E,52,[[[T]],[T]]],[11,R[32],E,E,52,[[["self"]],[T]]],[11,R[33],E,E,52,[[[T],["self"]]]],[11,"into",E,E,52,[[],[U]]],[11,R[12],E,E,52,[[[U]],[R[15]]]],[11,R[13],E,E,52,[[],[R[15]]]],[11,R[14],E,E,52,[[["self"]],[T]]],[11,R[17],E,E,52,[[["self"]],[T]]],[11,R[16],E,E,52,[[["self"]],[R[18]]]],[11,"vzip",E,E,52,[[],["v"]]],[11,"from",E,E,34,[[[T]],[T]]],[11,R[32],E,E,34,[[["self"]],[T]]],[11,R[33],E,E,34,[[[T],["self"]]]],[11,"into",E,E,34,[[],[U]]],[11,R[12],E,E,34,[[[U]],[R[15]]]],[11,R[13],E,E,34,[[],[R[15]]]],[11,R[14],E,E,34,[[["self"]],[T]]],[11,R[17],E,E,34,[[["self"]],[T]]],[11,R[16],E,E,34,[[["self"]],[R[18]]]],[11,"vzip",E,E,34,[[],["v"]]],[11,"from",R[321],E,30,[[[T]],[T]]],[11,"into",E,E,30,[[],[U]]],[11,R[12],E,E,30,[[[U]],[R[15]]]],[11,R[13],E,E,30,[[],[R[15]]]],[11,R[14],E,E,30,[[["self"]],[T]]],[11,R[17],E,E,30,[[["self"]],[T]]],[11,R[16],E,E,30,[[["self"]],[R[18]]]],[11,"vzip",E,E,30,[[],["v"]]],[11,"from",E,E,53,[[[T]],[T]]],[11,R[81],E,E,53,[[["self"]],[R[2]]]],[11,"into",E,E,53,[[],[U]]],[11,R[12],E,E,53,[[[U]],[R[15]]]],[11,R[13],E,E,53,[[],[R[15]]]],[11,R[14],E,E,53,[[["self"]],[T]]],[11,R[17],E,E,53,[[["self"]],[T]]],[11,R[16],E,E,53,[[["self"]],[R[18]]]],[11,"vzip",E,E,53,[[],["v"]]],[11,"from",E,E,31,[[[T]],[T]]],[11,R[32],E,E,31,[[["self"]],[T]]],[11,R[33],E,E,31,[[[T],["self"]]]],[11,"into",E,E,31,[[],[U]]],[11,R[12],E,E,31,[[[U]],[R[15]]]],[11,R[13],E,E,31,[[],[R[15]]]],[11,R[14],E,E,31,[[["self"]],[T]]],[11,R[17],E,E,31,[[["self"]],[T]]],[11,R[16],E,E,31,[[["self"]],[R[18]]]],[11,"vzip",E,E,31,[[],["v"]]],[11,"from",R[322],E,33,[[[T]],[T]]],[11,R[32],E,E,33,[[["self"]],[T]]],[11,R[33],E,E,33,[[[T],["self"]]]],[11,"into",E,E,33,[[],[U]]],[11,R[12],E,E,33,[[[U]],[R[15]]]],[11,R[13],E,E,33,[[],[R[15]]]],[11,R[14],E,E,33,[[["self"]],[T]]],[11,R[17],E,E,33,[[["self"]],[T]]],[11,R[16],E,E,33,[[["self"]],[R[18]]]],[11,"vzip",E,E,33,[[],["v"]]],[11,"from",R[315],E,54,[[[T]],[T]]],[11,R[50],E,E,54,[[],["i"]]],[11,"into",E,E,54,[[],[U]]],[11,R[12],E,E,54,[[[U]],[R[15]]]],[11,R[13],E,E,54,[[],[R[15]]]],[11,R[14],E,E,54,[[["self"]],[T]]],[11,R[17],E,E,54,[[["self"]],[T]]],[11,R[16],E,E,54,[[["self"]],[R[18]]]],[11,"vzip",E,E,54,[[],["v"]]],[11,"from",R[323],E,35,[[[T]],[T]]],[11,R[32],E,E,35,[[["self"]],[T]]],[11,R[33],E,E,35,[[[T],["self"]]]],[11,"into",E,E,35,[[],[U]]],[11,R[12],E,E,35,[[[U]],[R[15]]]],[11,R[13],E,E,35,[[],[R[15]]]],[11,R[14],E,E,35,[[["self"]],[T]]],[11,R[17],E,E,35,[[["self"]],[T]]],[11,R[16],E,E,35,[[["self"]],[R[18]]]],[11,"vzip",E,E,35,[[],["v"]]],[11,"from",E,E,55,[[[T]],[T]]],[11,R[50],E,E,55,[[],["i"]]],[11,"into",E,E,55,[[],[U]]],[11,R[12],E,E,55,[[[U]],[R[15]]]],[11,R[13],E,E,55,[[],[R[15]]]],[11,R[14],E,E,55,[[["self"]],[T]]],[11,R[17],E,E,55,[[["self"]],[T]]],[11,R[16],E,E,55,[[["self"]],[R[18]]]],[11,"vzip",E,E,55,[[],["v"]]],[11,"from",E,E,56,[[[T]],[T]]],[11,R[32],E,E,56,[[["self"]],[T]]],[11,R[33],E,E,56,[[[T],["self"]]]],[11,R[50],E,E,56,[[],["i"]]],[11,"into",E,E,56,[[],[U]]],[11,R[12],E,E,56,[[[U]],[R[15]]]],[11,R[13],E,E,56,[[],[R[15]]]],[11,R[14],E,E,56,[[["self"]],[T]]],[11,R[17],E,E,56,[[["self"]],[T]]],[11,R[16],E,E,56,[[["self"]],[R[18]]]],[11,"vzip",E,E,56,[[],["v"]]],[11,"fmt","rand",E,40,[[["self"],[R[36]]],[["error"],[R[15],["error"]]]]],[11,"fmt",E,E,40,[[["self"],[R[36]]],[["error"],[R[15],["error"]]]]],[11,"from",E,E,40,[[[R[41]]],["error"]]],[11,"from",E,E,40,[[["error"]],["error"]]],[11,"source",E,E,40,[[["self"]],[[R[3],["error"]],["error"]]]],[11,"read",E,E,0,[[["self"]],[[R[15],["usize","error"]],["usize"],["error"]]]],[11,"new",R[319],E,48,[[["b2"],["b1"]],["self"]]],[11,R[303],E,E,48,[[["b2"],["b1"]],["self"]]],[11,"sample",E,E,48,[[["self"],["r"]]]],[11,R[324],E,E,48,[[["b2"],["b1"],["r"]]]],[11,"new",E,E,48,[[["b2"],["b1"]],["self"]]],[11,R[303],E,E,48,[[["b2"],["b1"]],["self"]]],[11,"sample",E,E,48,[[["self"],["r"]]]],[11,R[324],E,E,48,[[["b2"],["b1"],["r"]]]],[11,"new",E,E,48,[[["b2"],["b1"]],["self"]]],[11,R[303],E,E,48,[[["b2"],["b1"]],["self"]]],[11,"sample",E,E,48,[[["self"],["r"]]]],[11,R[324],E,E,48,[[["b2"],["b1"],["r"]]]],[11,"new",E,E,48,[[["b2"],["b1"]],["self"]]],[11,R[303],E,E,48,[[["b2"],["b1"]],["self"]]],[11,"sample",E,E,48,[[["self"],["r"]]]],[11,R[324],E,E,48,[[["b2"],["b1"],["r"]]]],[11,"new",E,E,48,[[["b2"],["b1"]],["self"]]],[11,R[303],E,E,48,[[["b2"],["b1"]],["self"]]],[11,"sample",E,E,48,[[["self"],["r"]]]],[11,R[324],E,E,48,[[["b2"],["b1"],["r"]]]],[11,"new",E,E,48,[[["b2"],["b1"]],["self"]]],[11,R[303],E,E,48,[[["b2"],["b1"]],["self"]]],[11,"sample",E,E,48,[[["self"],["r"]]]],[11,R[324],E,E,48,[[["b2"],["b1"],["r"]]]],[11,"new",E,E,48,[[["b2"],["b1"]],["self"]]],[11,R[303],E,E,48,[[["b2"],["b1"]],["self"]]],[11,"sample",E,E,48,[[["self"],["r"]]]],[11,R[324],E,E,48,[[["b2"],["b1"],["r"]]]],[11,"new",E,E,48,[[["b2"],["b1"]],["self"]]],[11,R[303],E,E,48,[[["b2"],["b1"]],["self"]]],[11,"sample",E,E,48,[[["self"],["r"]]]],[11,R[324],E,E,48,[[["b2"],["b1"],["r"]]]],[11,"new",E,E,48,[[["b2"],["b1"]],["self"]]],[11,R[303],E,E,48,[[["b2"],["b1"]],["self"]]],[11,"sample",E,E,48,[[["self"],["r"]]]],[11,R[324],E,E,48,[[["b2"],["b1"],["r"]]]],[11,"new",E,E,48,[[["b2"],["b1"]],["self"]]],[11,R[303],E,E,48,[[["b2"],["b1"]],["self"]]],[11,"sample",E,E,48,[[["self"],["r"]]]],[11,R[324],E,E,48,[[["b2"],["b1"],["r"]]]],[11,"new",E,E,48,[[["b2"],["b1"]],["self"]]],[11,R[303],E,E,48,[[["b2"],["b1"]],["self"]]],[11,"sample",E,E,48,[[["self"],["r"]]]],[11,R[324],E,E,48,[[["b2"],["b1"],["r"]]]],[11,"new",E,E,48,[[["b2"],["b1"]],["self"]]],[11,R[303],E,E,48,[[["b2"],["b1"]],["self"]]],[11,"sample",E,E,48,[[["self"],["r"]]]],[11,R[324],E,E,48,[[["b2"],["b1"],["r"]]]],[11,"new",E,E,49,[[["b2"],["b1"]],["self"]]],[11,R[303],E,E,49,[[["b2"],["b1"]],["self"]]],[11,"sample",E,E,49,[[["self"],["r"]]]],[11,R[324],E,E,49,[[["b2"],["b1"],["r"]]]],[11,"new",E,E,49,[[["b2"],["b1"]],["self"]]],[11,R[303],E,E,49,[[["b2"],["b1"]],["self"]]],[11,"sample",E,E,49,[[["self"],["r"]]]],[11,R[324],E,E,49,[[["b2"],["b1"],["r"]]]],[11,"new",E,E,50,[[["b2"],["b1"]],["self"]]],[11,R[303],E,E,50,[[["b2"],["b1"]],["self"]]],[11,"sample",E,E,50,[[["self"],["r"]],["duration"]]],[11,"sample",E,E,6,[[["self"],["r"]],["x"]]],[11,"sample",R[305],E,7,[[["self"],["r"]],["bool"]]],[11,"sample",R[320],E,10,[[["self"],["r"]],["usize"]]],[11,"sample",R[311],E,11,[[["self"],["r"]],["usize"]]],[11,"sample",R[305],E,12,[[["self"],["r"]]]],[11,"sample",E,E,13,[[["self"],["r"]]]],[11,"sample",E,E,14,[[["self"],["r"]],["f64"]]],[11,"sample",E,E,15,[[["self"],["r"]],["f64"]]],[11,"sample",E,E,16,[[["self"],["r"]],["f64"]]],[11,"sample",E,E,17,[[["self"],["r"]],["f64"]]],[11,"sample",E,E,18,[[["self"],["r"]],["f64"]]],[11,"sample",E,E,44,[[["self"],["r"]],["f64"]]],[11,"sample",E,E,19,[[["self"],["r"]],["f64"]]],[11,"sample",E,E,20,[[["self"],["r"]],["f64"]]],[11,"sample",E,E,45,[[["self"],["r"]],["f64"]]],[11,"sample",E,E,21,[[["self"],["r"]],["f64"]]],[11,"sample",E,E,22,[[["self"],["r"]],["f64"]]],[11,"sample",E,E,23,[[["self"],["r"]],["u64"]]],[11,"sample",E,E,24,[[["self"],["r"]],["u64"]]],[11,"sample",E,E,25,[[["self"],["r"]],["f64"]]],[11,"sample",E,E,26,[[["self"],["r"]],[["vec",["f64"]],["f64"]]]],[11,"sample",E,E,27,[[["self"],["r"]],["f64"]]],[11,"sample",E,E,28,[[["self"],["r"]],["f64"]]],[11,"sample",E,E,47,[[["self"],["r"]],["f32"]]],[11,"sample",E,E,42,[[["self"],["r"]],["f32"]]],[11,"sample",E,E,43,[[["self"],["r"]],["f32"]]],[11,"sample",E,E,47,[[["self"],["r"]],["f64"]]],[11,"sample",E,E,42,[[["self"],["r"]],["f64"]]],[11,"sample",E,E,43,[[["self"],["r"]],["f64"]]],[11,"sample",E,E,47,[[["self"],["r"]],["u8"]]],[11,"sample",E,E,47,[[["self"],["r"]],["u16"]]],[11,"sample",E,E,47,[[["self"],["r"]],["u32"]]],[11,"sample",E,E,47,[[["self"],["r"]],["u64"]]],[11,"sample",E,E,47,[[["self"],["r"]],["u128"]]],[11,"sample",E,E,47,[[["self"],["r"]],["usize"]]],[11,"sample",E,E,47,[[["self"],["r"]],["i8"]]],[11,"sample",E,E,47,[[["self"],["r"]],["i16"]]],[11,"sample",E,E,47,[[["self"],["r"]],["i32"]]],[11,"sample",E,E,47,[[["self"],["r"]],["i64"]]],[11,"sample",E,E,47,[[["self"],["r"]],["i128"]]],[11,"sample",E,E,47,[[["self"],["r"]],["isize"]]],[11,"sample",E,E,47,[[["self"],["r"]],["nonzerou8"]]],[11,"sample",E,E,47,[[["self"],["r"]],["nonzerou16"]]],[11,"sample",E,E,47,[[["self"],["r"]],[R[41]]]],[11,"sample",E,E,47,[[["self"],["r"]],["nonzerou64"]]],[11,"sample",E,E,47,[[["self"],["r"]],["nonzerou128"]]],[11,"sample",E,E,47,[[["self"],["r"]],["nonzerousize"]]],[11,"sample",E,E,47,[[["self"],["r"]],["char"]]],[11,"sample",E,E,41,[[["self"],["r"]],["char"]]],[11,"sample",E,E,47,[[["self"],["r"]],["bool"]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]]]],[11,"sample",E,E,47,[[["self"],["r"]],[R[3]]]],[11,"sample",E,E,47,[[["self"],["r"]],["wrapping"]]],[11,"next",E,E,46,[[["self"]],[R[3]]]],[11,R[51],E,E,46,[[["self"]]]],[11,"next",R[323],E,55,[[["self"]],[[R[3],["usize"]],["usize"]]]],[11,R[51],E,E,55,[[["self"]]]],[11,"next",E,E,56,[[["self"]],[R[3]]]],[11,R[51],E,E,56,[[["self"]]]],[11,"next",R[315],E,54,[[["self"]],[R[3]]]],[11,R[51],E,E,54,[[["self"]]]],[11,"eq",R[305],E,2,[[["self"],[R[307]]],["bool"]]],[11,"eq",R[311],E,8,[[[R[310]],["self"]],["bool"]]],[11,"eq",R[323],E,35,[[[R[332]],["self"]],["bool"]]],[11,"from",R[319],E,6,[[["range"]],[R[325]]]],[11,"from",E,E,6,[[["rangeinclusive"]],[R[325]]]],[11,"from",R[323],E,35,[[["u32"],["vec",["u32"]]],["self"]]],[11,"from",E,E,35,[[["usize"],["vec",["usize"]]],["self"]]],[11,"clone",R[319],E,6,[[["self"]],[R[325]]]],[11,"clone",E,E,48,[[["self"]],["uniformint"]]],[11,"clone",E,E,49,[[["self"]],["uniformfloat"]]],[11,"clone",E,E,50,[[["self"]],["uniformduration"]]],[11,"clone",R[305],E,7,[[["self"]],[R[306]]]],[11,"clone",E,E,2,[[["self"]],[R[307]]]],[11,"clone",R[320],E,10,[[["self"]],["self"]]],[11,"clone",R[311],E,11,[[["self"]],[R[312]]]],[11,"clone",E,E,8,[[["self"]],[R[310]]]],[11,"clone",R[305],E,12,[[["self"]],[R[326]]]],[11,"clone",E,E,13,[[["self"]],[R[327]]]],[11,"clone",E,E,14,[[["self"]],["gamma"]]],[11,"clone",E,E,15,[[["self"]],[R[328]]]],[11,"clone",E,E,16,[[["self"]],["fisherf"]]],[11,"clone",E,E,17,[[["self"]],["studentt"]]],[11,"clone",E,E,18,[[["self"]],["beta"]]],[11,"clone",E,E,44,[[["self"]],["standardnormal"]]],[11,"clone",E,E,19,[[["self"]],["normal"]]],[11,"clone",E,E,20,[[["self"]],[R[329]]]],[11,"clone",E,E,45,[[["self"]],["exp1"]]],[11,"clone",E,E,21,[[["self"]],["exp"]]],[11,"clone",E,E,22,[[["self"]],["pareto"]]],[11,"clone",E,E,23,[[["self"]],["poisson"]]],[11,"clone",E,E,24,[[["self"]],["binomial"]]],[11,"clone",E,E,25,[[["self"]],["cauchy"]]],[11,"clone",E,E,26,[[["self"]],[R[313]]]],[11,"clone",E,E,27,[[["self"]],[R[330]]]],[11,"clone",E,E,28,[[["self"]],["weibull"]]],[11,"clone",E,E,42,[[["self"]],["openclosed01"]]],[11,"clone",E,E,43,[[["self"]],["open01"]]],[11,"clone",E,E,47,[[["self"]],["standard"]]],[11,"clone",R[321],E,31,[[["self"]],["reseedingrng"]]],[11,"clone",R[322],E,33,[[["self"]],["steprng"]]],[11,"clone",R[314],E,51,[[["self"]],["stdrng"]]],[11,"clone",E,E,52,[[["self"]],[R[331]]]],[11,"clone",E,E,34,[[["self"]],["osrng"]]],[11,"clone",R[323],E,35,[[["self"]],[R[332]]]],[11,"clone",E,E,56,[[["self"]],[R[333]]]],[11,R[23],R[314],E,32,[[],["self"]]],[11,R[23],E,E,52,[[],[R[331]]]],[11,R[23],E,E,34,[[],["osrng"]]],[11,"len",R[315],E,54,[[["self"]],["usize"]]],[11,"fmt",R[311],E,8,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[321],E,53,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[319],E,6,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,48,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,49,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,50,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[305],E,7,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,2,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[320],E,10,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[311],E,11,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,8,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[305],E,12,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,13,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,14,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,15,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,16,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,17,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,18,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,44,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,19,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,20,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,45,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,21,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,22,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,23,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,24,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,25,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,26,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,27,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,28,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,42,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,43,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,41,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,46,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,47,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[321],E,30,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,53,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,31,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[314],E,32,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[322],E,33,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[314],E,51,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,52,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,34,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[323],E,35,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,55,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,56,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[315],E,54,[[["self"],[R[36]]],[R[15]]]],[11,R[255],R[311],E,8,[[["self"]],["str"]]],[11,"cause",E,E,8,[[["self"]],[["error"],[R[3],["error"]]]]],[11,"source",R[321],E,53,[[["self"]],[["error"],[R[3],["error"]]]]],[11,R[83],E,E,30,[[["self"]],["u32"]]],[11,R[84],E,E,30,[[["self"]],["u64"]]],[11,R[85],E,E,30,[[["self"]]]],[11,R[86],E,E,30,[[["self"]],[[R[15],["error"]],["error"]]]],[11,R[83],E,E,31,[[["self"]],["u32"]]],[11,R[84],E,E,31,[[["self"]],["u64"]]],[11,R[85],E,E,31,[[["self"]]]],[11,R[86],E,E,31,[[["self"]],[[R[15],["error"]],["error"]]]],[11,R[83],R[314],E,32,[[["self"]],["u32"]]],[11,R[84],E,E,32,[[["self"]],["u64"]]],[11,R[85],E,E,32,[[["self"]]]],[11,R[86],E,E,32,[[["self"]],[[R[15],["error"]],["error"]]]],[11,R[83],R[322],E,33,[[["self"]],["u32"]]],[11,R[84],E,E,33,[[["self"]],["u64"]]],[11,R[85],E,E,33,[[["self"]]]],[11,R[86],E,E,33,[[["self"]],[[R[15],["error"]],["error"]]]],[11,R[83],R[314],E,51,[[["self"]],["u32"]]],[11,R[84],E,E,51,[[["self"]],["u64"]]],[11,R[85],E,E,51,[[["self"]]]],[11,R[86],E,E,51,[[["self"]],[[R[15],["error"]],["error"]]]],[11,R[83],E,E,52,[[["self"]],["u32"]]],[11,R[84],E,E,52,[[["self"]],["u64"]]],[11,R[85],E,E,52,[[["self"]]]],[11,R[86],E,E,52,[[["self"]],[[R[15],["error"]],["error"]]]],[11,R[83],E,E,34,[[["self"]],["u32"]]],[11,R[84],E,E,34,[[["self"]],["u64"]]],[11,R[85],E,E,34,[[["self"]]]],[11,R[86],E,E,34,[[["self"]],[[R[15],["error"]],["error"]]]],[11,R[87],E,E,51,[[],["self"]]],[11,R[89],E,E,51,[[[R[90]]],[["error"],[R[15],["error"]]]]],[11,"new","rand",R[365],40,[[["e"]],["error"]]],[11,"inner",E,R[366],40,[[["self"]],["error"]]],[11,R[367],E,R[368],40,[[],[["box",["error"]],["error"]]]],[11,"code",E,R[369],40,[[["self"]],[[R[41]],[R[3],[R[41]]]]]]],"p":[[8,"RngCore"],[8,R[96]],[4,R[334]],[8,R[335]],[8,R[336]],[8,R[337]],[3,"Uniform"],[3,R[338]],[4,R[339]],[8,"Weight"],[3,R[308]],[3,R[308]],[3,R[340]],[3,R[341]],[3,"Gamma"],[3,R[342]],[3,"FisherF"],[3,"StudentT"],[3,"Beta"],[3,"Normal"],[3,R[343]],[3,"Exp"],[3,"Pareto"],[3,"Poisson"],[3,"Binomial"],[3,"Cauchy"],[3,R[344]],[3,R[345]],[3,"Weibull"],[8,R[346]],[3,"ReadRng"],[3,R[347]],[3,R[348]],[3,"StepRng"],[3,"OsRng"],[4,"IndexVec"],[8,R[349]],[8,R[350]],[8,"Rng"],[8,R[351]],[3,"Error"],[3,R[352]],[3,R[353]],[3,"Open01"],[3,R[354]],[3,"Exp1"],[3,"DistIter"],[3,R[355]],[3,R[356]],[3,R[357]],[3,R[358]],[3,"StdRng"],[3,R[359]],[3,R[360]],[3,R[361]],[4,R[362]],[4,R[363]]]}; +searchIndex["rand_chacha"]={"doc":"The ChaCha random number generator.","i":[[3,R[126],"rand_chacha","ChaCha with 12 rounds",N,N],[3,R[124],E,R[111],N,N],[3,R[127],E,R[118],N,N],[3,R[123],E,R[111],N,N],[3,R[128],E,"ChaCha with 8 rounds",N,N],[3,R[125],E,R[111],N,N],[11,R[112],E,R[113],0,[[["self"]],["u128"]]],[11,R[114],E,R[115],0,[[["self"],["u128"]]]],[11,R[116],E,R[117],0,[[["self"],["u64"]]]],[11,R[112],E,R[113],1,[[["self"]],["u128"]]],[11,R[114],E,R[115],1,[[["self"],["u128"]]]],[11,R[116],E,R[117],1,[[["self"],["u64"]]]],[11,R[112],E,R[113],2,[[["self"]],["u128"]]],[11,R[114],E,R[115],2,[[["self"],["u128"]]]],[11,R[116],E,R[117],2,[[["self"],["u64"]]]],[6,"ChaChaRng",E,R[118],N,N],[6,"ChaChaCore",E,"ChaCha with 20 rounds, low-level interface",N,N],[11,"from",E,E,3,[[[T]],[T]]],[11,R[32],E,E,3,[[["self"]],[T]]],[11,R[33],E,E,3,[[[T],["self"]]]],[11,"into",E,E,3,[[],[U]]],[11,R[12],E,E,3,[[[U]],[R[15]]]],[11,R[13],E,E,3,[[],[R[15]]]],[11,R[14],E,E,3,[[["self"]],[T]]],[11,R[17],E,E,3,[[["self"]],[T]]],[11,R[16],E,E,3,[[["self"]],[R[18]]]],[11,"vzip",E,E,3,[[],["v"]]],[11,"from",E,E,1,[[[T]],[T]]],[11,R[32],E,E,1,[[["self"]],[T]]],[11,R[33],E,E,1,[[[T],["self"]]]],[11,"into",E,E,1,[[],[U]]],[11,R[12],E,E,1,[[[U]],[R[15]]]],[11,R[13],E,E,1,[[],[R[15]]]],[11,R[14],E,E,1,[[["self"]],[T]]],[11,R[17],E,E,1,[[["self"]],[T]]],[11,R[16],E,E,1,[[["self"]],[R[18]]]],[11,"vzip",E,E,1,[[],["v"]]],[11,"from",E,E,4,[[[T]],[T]]],[11,R[32],E,E,4,[[["self"]],[T]]],[11,R[33],E,E,4,[[[T],["self"]]]],[11,"into",E,E,4,[[],[U]]],[11,R[12],E,E,4,[[[U]],[R[15]]]],[11,R[13],E,E,4,[[],[R[15]]]],[11,R[14],E,E,4,[[["self"]],[T]]],[11,R[17],E,E,4,[[["self"]],[T]]],[11,R[16],E,E,4,[[["self"]],[R[18]]]],[11,"vzip",E,E,4,[[],["v"]]],[11,"from",E,E,0,[[[T]],[T]]],[11,R[32],E,E,0,[[["self"]],[T]]],[11,R[33],E,E,0,[[[T],["self"]]]],[11,"into",E,E,0,[[],[U]]],[11,R[12],E,E,0,[[[U]],[R[15]]]],[11,R[13],E,E,0,[[],[R[15]]]],[11,R[14],E,E,0,[[["self"]],[T]]],[11,R[17],E,E,0,[[["self"]],[T]]],[11,R[16],E,E,0,[[["self"]],[R[18]]]],[11,"vzip",E,E,0,[[],["v"]]],[11,"from",E,E,5,[[[T]],[T]]],[11,R[32],E,E,5,[[["self"]],[T]]],[11,R[33],E,E,5,[[[T],["self"]]]],[11,"into",E,E,5,[[],[U]]],[11,R[12],E,E,5,[[[U]],[R[15]]]],[11,R[13],E,E,5,[[],[R[15]]]],[11,R[14],E,E,5,[[["self"]],[T]]],[11,R[17],E,E,5,[[["self"]],[T]]],[11,R[16],E,E,5,[[["self"]],[R[18]]]],[11,"vzip",E,E,5,[[],["v"]]],[11,"from",E,E,2,[[[T]],[T]]],[11,R[32],E,E,2,[[["self"]],[T]]],[11,R[33],E,E,2,[[[T],["self"]]]],[11,"into",E,E,2,[[],[U]]],[11,R[12],E,E,2,[[[U]],[R[15]]]],[11,R[13],E,E,2,[[],[R[15]]]],[11,R[14],E,E,2,[[["self"]],[T]]],[11,R[17],E,E,2,[[["self"]],[T]]],[11,R[16],E,E,2,[[["self"]],[R[18]]]],[11,"vzip",E,E,2,[[],["v"]]],[11,"from",E,E,0,[[[R[119]]],["self"]]],[11,"from",E,E,1,[[[R[120]]],["self"]]],[11,"from",E,E,2,[[[R[121]]],["self"]]],[11,"clone",E,E,4,[[["self"]],[R[119]]]],[11,"clone",E,E,0,[[["self"]],["chacha20rng"]]],[11,"clone",E,E,3,[[["self"]],[R[120]]]],[11,"clone",E,E,1,[[["self"]],["chacha12rng"]]],[11,"clone",E,E,5,[[["self"]],[R[121]]]],[11,"clone",E,E,2,[[["self"]],["chacha8rng"]]],[11,"fmt",E,E,4,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,0,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,3,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,1,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,5,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,2,[[["self"],[R[36]]],[R[15]]]],[11,R[122],E,E,4,[[["self"]]]],[11,R[122],E,E,3,[[["self"]]]],[11,R[122],E,E,5,[[["self"]]]],[11,R[83],E,E,0,[[["self"]],["u32"]]],[11,R[84],E,E,0,[[["self"]],["u64"]]],[11,R[85],E,E,0,[[["self"]]]],[11,R[86],E,E,0,[[["self"]],[[R[15],["error"]],["error"]]]],[11,R[83],E,E,1,[[["self"]],["u32"]]],[11,R[84],E,E,1,[[["self"]],["u64"]]],[11,R[85],E,E,1,[[["self"]]]],[11,R[86],E,E,1,[[["self"]],[[R[15],["error"]],["error"]]]],[11,R[83],E,E,2,[[["self"]],["u32"]]],[11,R[84],E,E,2,[[["self"]],["u64"]]],[11,R[85],E,E,2,[[["self"]]]],[11,R[86],E,E,2,[[["self"]],[[R[15],["error"]],["error"]]]],[11,R[87],E,E,4,[[],["self"]]],[11,R[87],E,E,0,[[],["self"]]],[11,R[87],E,E,3,[[],["self"]]],[11,R[87],E,E,1,[[],["self"]]],[11,R[87],E,E,5,[[],["self"]]],[11,R[87],E,E,2,[[],["self"]]]],"p":[[3,R[123]],[3,R[124]],[3,R[125]],[3,R[126]],[3,R[127]],[3,R[128]]]}; +searchIndex["rand_core"]={"doc":"Random number generation traits","i":[[3,"Error",R[79],R[364],N,N],[11,"new",E,R[365],0,[[["e"]],["self"]]],[11,"inner",E,R[366],0,[[["self"]],["error"]]],[11,R[367],E,R[368],0,[[],[["error"],["box",["error"]]]]],[11,"code",E,R[369],0,[[["self"]],[[R[3],[R[41]]],[R[41]]]]],[0,"block",E,"The `BlockRngCore` trait and implementation helpers",N,N],[3,R[93],R[82],R[72],N,N],[12,"core",E,R[73],1,N],[3,R[94],E,R[72],N,N],[12,"core",E,R[73],2,N],[8,R[95],E,"A trait for RNGs which do not generate random numbers…",N,N],[16,"Item",E,"Results element type, e.g. `u32`.",3,N],[16,"Results",E,"Results type. This is the 'block' an RNG implementing…",3,N],[10,R[122],E,"Generate a new block of results.",3,[[["self"]]]],[11,"new",E,R[74],1,[[["r"]],[R[91]]]],[11,"index",E,R[75],1,[[["self"]],["usize"]]],[11,"reset",E,R[76],1,[[["self"]]]],[11,R[77],E,R[78],1,[[["self"],["usize"]]]],[11,"new",E,R[74],2,[[["r"]],[R[92]]]],[11,"index",E,R[75],2,[[["self"]],["usize"]]],[11,"reset",E,R[76],2,[[["self"]]]],[11,R[77],E,R[78],2,[[["self"],["usize"]]]],[0,"impls",R[79],"Helper functions for implementing `RngCore` functions.",N,N],[5,"next_u64_via_u32","rand_core::impls","Implement `next_u64` via `next_u32`, little-endian order.",N,[[["r"]],["u64"]]],[5,"fill_bytes_via_next",E,"Implement `fill_bytes` via `next_u64` and `next_u32`,…",N,[[["r"]]]],[5,"fill_via_u32_chunks",E,R[80],N,[[]]],[5,"fill_via_u64_chunks",E,R[80],N,[[]]],[5,"next_u32_via_fill",E,"Implement `next_u32` via `fill_bytes`, little-endian order.",N,[[["r"]],["u32"]]],[5,"next_u64_via_fill",E,"Implement `next_u64` via `fill_bytes`, little-endian order.",N,[[["r"]],["u64"]]],[0,"le",R[79],"Little-Endian utilities",N,N],[5,"read_u32_into","rand_core::le","Reads unsigned 32 bit integers from `src` into `dst`.…",N,[[]]],[5,"read_u64_into",E,"Reads unsigned 64 bit integers from `src` into `dst`.…",N,[[]]],[8,"RngCore",R[79],R[370],N,N],[10,R[83],E,R[371],4,[[["self"]],["u32"]]],[10,R[84],E,R[372],4,[[["self"]],["u64"]]],[10,R[85],E,R[373],4,[[["self"]]]],[10,R[86],E,R[374],4,[[["self"]],[["error"],[R[15],["error"]]]]],[8,R[375],E,R[376],N,N],[8,R[96],E,R[377],N,N],[16,"Seed",E,R[378],5,N],[10,R[87],E,R[379],5,[[],["self"]]],[11,R[88],E,R[380],5,[[["u64"]],["self"]]],[11,R[89],E,R[381],5,[[[R[90]]],[["error"],[R[15],["error"]]]]],[11,R[382],E,R[383],5,[[],["self"]]],[11,"from",E,E,0,[[[T]],[T]]],[11,R[81],E,E,0,[[["self"]],[R[2]]]],[11,"into",E,E,0,[[],[U]]],[11,R[12],E,E,0,[[[U]],[R[15]]]],[11,R[13],E,E,0,[[],[R[15]]]],[11,R[14],E,E,0,[[["self"]],[T]]],[11,R[17],E,E,0,[[["self"]],[T]]],[11,R[16],E,E,0,[[["self"]],[R[18]]]],[11,"from",R[82],E,1,[[[T]],[T]]],[11,R[32],E,E,1,[[["self"]],[T]]],[11,R[33],E,E,1,[[[T],["self"]]]],[11,"into",E,E,1,[[],[U]]],[11,R[12],E,E,1,[[[U]],[R[15]]]],[11,R[13],E,E,1,[[],[R[15]]]],[11,R[14],E,E,1,[[["self"]],[T]]],[11,R[17],E,E,1,[[["self"]],[T]]],[11,R[16],E,E,1,[[["self"]],[R[18]]]],[11,"from",E,E,2,[[[T]],[T]]],[11,R[32],E,E,2,[[["self"]],[T]]],[11,R[33],E,E,2,[[[T],["self"]]]],[11,"into",E,E,2,[[],[U]]],[11,R[12],E,E,2,[[[U]],[R[15]]]],[11,R[13],E,E,2,[[],[R[15]]]],[11,R[14],E,E,2,[[["self"]],[T]]],[11,R[17],E,E,2,[[["self"]],[T]]],[11,R[16],E,E,2,[[["self"]],[R[18]]]],[11,R[83],E,E,1,[[["self"]],["u32"]]],[11,R[84],E,E,1,[[["self"]],["u64"]]],[11,R[85],E,E,1,[[["self"]]]],[11,R[86],E,E,1,[[["self"]],[["error"],[R[15],["error"]]]]],[11,R[83],E,E,2,[[["self"]],["u32"]]],[11,R[84],E,E,2,[[["self"]],["u64"]]],[11,R[85],E,E,2,[[["self"]]]],[11,R[86],E,E,2,[[["self"]],[["error"],[R[15],["error"]]]]],[11,R[87],E,E,1,[[],["self"]]],[11,R[88],E,E,1,[[["u64"]],["self"]]],[11,R[89],E,E,1,[[[R[90]]],[["error"],[R[15],["error"]]]]],[11,R[87],E,E,2,[[],["self"]]],[11,R[88],E,E,2,[[["u64"]],["self"]]],[11,R[89],E,E,2,[[[R[90]]],[["error"],[R[15],["error"]]]]],[11,"from",R[79],E,0,[[[R[41]]],["self"]]],[11,"from",E,E,0,[[["error"]],["self"]]],[11,"clone",R[82],E,1,[[["self"]],[R[91]]]],[11,"clone",E,E,2,[[["self"]],[R[92]]]],[11,"fmt",R[79],E,0,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,0,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[82],E,1,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,2,[[["self"],[R[36]]],[R[15]]]],[11,"read",R[79],E,4,[[["self"]],[["error"],["usize"],[R[15],["usize","error"]]]]],[11,"source",E,E,0,[[["self"]],[["error"],[R[3],["error"]]]]]],"p":[[3,"Error"],[3,R[93]],[3,R[94]],[8,R[95]],[8,"RngCore"],[8,R[96]]]}; +searchIndex["regex"]={"doc":"This crate provides a library for parsing, compiling, and…","i":[[3,R[384],"regex",R[385],N,N],[3,R[386],E,R[387],N,N],[3,R[498],E,R[402],N,N],[3,R[403],E,R[404],N,N],[3,R[405],E,R[406],N,N],[3,R[407],E,R[408],N,N],[3,"Regex",E,"A compiled regular expression for matching Unicode strings.",N,N],[3,"Match",E,R[388],N,N],[3,R[497],E,"Captures represents a group of captured strings for a…",N,N],[3,R[394],E,R[395],N,N],[3,"Matches",E,R[389],N,N],[3,R[390],E,R[391],N,N],[3,R[398],E,R[399],N,N],[3,R[396],E,R[397],N,N],[3,R[400],E,R[401],N,N],[3,R[495],E,"`NoExpand` indicates literal string replacement.",N,N],[12,"0",E,E,0,N],[3,"Split",E,R[392],N,N],[3,"SplitN",E,R[393],N,N],[4,"Error",E,"An error that occurred during parsing or compiling a…",N,N],[13,"Syntax",E,"A syntax error.",1,N],[13,"CompiledTooBig",E,"The compiled program exceeded the set size limit. The…",1,N],[5,"escape",E,R[499],N,[[["str"]],[R[2]]]],[0,"bytes",E,"Match regular expressions on arbitrary bytes.",N,N],[3,R[384],R[422],R[385],N,N],[3,R[386],E,R[387],N,N],[3,"Match",E,R[388],N,N],[3,"Regex",E,"A compiled regular expression for matching arbitrary bytes.",N,N],[3,"Matches",E,R[389],N,N],[3,R[390],E,R[391],N,N],[3,"Split",E,R[392],N,N],[3,"SplitN",E,R[393],N,N],[3,R[394],E,R[395],N,N],[3,R[396],E,R[397],N,N],[3,R[497],E,"Captures represents a group of captured byte strings for a…",N,N],[3,R[398],E,R[399],N,N],[3,R[400],E,R[401],N,N],[3,R[495],E,"`NoExpand` indicates literal byte string replacement.",N,N],[12,"0",E,E,2,N],[3,R[498],E,R[402],N,N],[3,R[403],E,R[404],N,N],[3,R[405],E,R[406],N,N],[3,R[407],E,R[408],N,N],[8,R[496],E,R[489],N,N],[10,R[490],E,R[491],3,[[["self"],["vec"],[R[431]]]]],[11,R[426],E,R[427],3,[[["self"]],[["cow"],[R[3],["cow"]]]]],[11,"by_ref",E,R[428],3,[[["self"]],[R[429]]]],[11,"new",E,R[410],4,[[["str"]],[R[409]]]],[11,"build",E,R[411],4,[[["self"]],[[R[15],["regex","error"]],["regex"],["error"]]]],[11,R[217],E,R[412],4,[[["self"],["bool"]],[R[409]]]],[11,R[218],E,R[413],4,[[["self"],["bool"]],[R[409]]]],[11,R[219],E,R[414],4,[[["self"],["bool"]],[R[409]]]],[11,R[220],E,R[415],4,[[["self"],["bool"]],[R[409]]]],[11,R[215],E,R[416],4,[[["self"],["bool"]],[R[409]]]],[11,R[500],E,R[417],4,[[["self"],["bool"]],[R[409]]]],[11,"octal",E,R[213],4,[[["self"],["bool"]],[R[409]]]],[11,R[418],E,R[419],4,[[["self"],["usize"]],[R[409]]]],[11,R[420],E,R[421],4,[[["self"],["usize"]],[R[409]]]],[11,R[211],E,R[212],4,[[["self"],["u32"]],[R[409]]]],[11,"new","regex",R[410],5,[[["str"]],[R[409]]]],[11,"build",E,R[411],5,[[["self"]],[["regex"],[R[15],["regex","error"]],["error"]]]],[11,R[217],E,R[412],5,[[["self"],["bool"]],[R[409]]]],[11,R[218],E,R[413],5,[[["self"],["bool"]],[R[409]]]],[11,R[219],E,R[414],5,[[["self"],["bool"]],[R[409]]]],[11,R[220],E,R[415],5,[[["self"],["bool"]],[R[409]]]],[11,R[215],E,R[416],5,[[["self"],["bool"]],[R[409]]]],[11,R[500],E,R[417],5,[[["self"],["bool"]],[R[409]]]],[11,"octal",E,R[213],5,[[["self"],["bool"]],[R[409]]]],[11,R[418],E,R[419],5,[[["self"],["usize"]],[R[409]]]],[11,R[420],E,R[421],5,[[["self"],["usize"]],[R[409]]]],[11,R[211],E,R[212],5,[[["self"],["u32"]],[R[409]]]],[11,"new",R[422],R[410],6,[[["i"]],[R[423]]]],[11,"build",E,R[424],6,[[["self"]],[[R[425]],["error"],[R[15],[R[425],"error"]]]]],[11,R[217],E,R[412],6,[[["self"],["bool"]],[R[423]]]],[11,R[218],E,R[413],6,[[["self"],["bool"]],[R[423]]]],[11,R[219],E,R[414],6,[[["self"],["bool"]],[R[423]]]],[11,R[220],E,R[415],6,[[["self"],["bool"]],[R[423]]]],[11,R[215],E,R[416],6,[[["self"],["bool"]],[R[423]]]],[11,R[500],E,R[417],6,[[["self"],["bool"]],[R[423]]]],[11,"octal",E,R[213],6,[[["self"],["bool"]],[R[423]]]],[11,R[418],E,R[419],6,[[["self"],["usize"]],[R[423]]]],[11,R[420],E,R[421],6,[[["self"],["usize"]],[R[423]]]],[11,R[211],E,R[212],6,[[["self"],["u32"]],[R[423]]]],[11,"new","regex",R[410],7,[[["i"]],[R[423]]]],[11,"build",E,R[424],7,[[["self"]],[[R[425]],[R[15],[R[425],"error"]],["error"]]]],[11,R[217],E,R[412],7,[[["self"],["bool"]],[R[423]]]],[11,R[218],E,R[413],7,[[["self"],["bool"]],[R[423]]]],[11,R[219],E,R[414],7,[[["self"],["bool"]],[R[423]]]],[11,R[220],E,R[415],7,[[["self"],["bool"]],[R[423]]]],[11,R[215],E,R[416],7,[[["self"],["bool"]],[R[423]]]],[11,R[500],E,R[417],7,[[["self"],["bool"]],[R[423]]]],[11,"octal",E,R[213],7,[[["self"],["bool"]],[R[423]]]],[11,R[418],E,R[419],7,[[["self"],["usize"]],[R[423]]]],[11,R[420],E,R[421],7,[[["self"],["usize"]],[R[423]]]],[11,R[211],E,R[212],7,[[["self"],["u32"]],[R[423]]]],[11,R[426],R[422],R[427],3,[[["self"]],[["cow"],[R[3],["cow"]]]]],[11,"by_ref",E,R[428],3,[[["self"]],[R[429]]]],[11,"start",E,R[448],8,[[["self"]],["usize"]]],[11,"end",E,R[449],8,[[["self"]],["usize"]]],[11,"as_bytes",E,R[450],8,[[["self"]]]],[11,"new",E,R[451],9,[[["str"]],[[R[15],["regex","error"]],["regex"],["error"]]]],[11,R[435],E,R[452],9,[[["self"]],["bool"]]],[11,"find",E,R[453],9,[[["self"]],[[R[3],["match"]],["match"]]]],[11,R[430],E,R[454],9,[[["self"]],[R[501]]]],[11,R[431],E,R[455],9,[[["self"]],[[R[3],[R[431]]],[R[431]]]]],[11,R[456],E,R[457],9,[[["self"]],[R[458]]]],[11,"split",E,R[459],9,[[["self"]],["split"]]],[11,"splitn",E,R[460],9,[[["self"],["usize"]],["splitn"]]],[11,"replace",E,R[461],9,[[["self"],[R[433]]],["cow"]]],[11,R[432],E,R[462],9,[[["self"],[R[433]]],["cow"]]],[11,"replacen",E,R[463],9,[[["usize"],["self"],[R[433]]],["cow"]]],[11,R[464],E,R[465],9,[[["self"]],[[R[3],["usize"]],["usize"]]]],[11,R[466],E,R[467],9,[[["self"],["usize"]],[[R[3],["usize"]],["usize"]]]],[11,R[468],E,R[469],9,[[["self"],["usize"]],["bool"]]],[11,"find_at",E,R[470],9,[[["self"],["usize"]],[[R[3],["match"]],["match"]]]],[11,R[471],E,R[472],9,[[["self"],[R[434]]],[[R[3],["match"]],["match"]]]],[11,R[473],E,"Returns the same as `captures_read`, but starts the search…",9,[[["usize"],["self"],[R[434]]],[[R[3],["match"]],["match"]]]],[11,"as_str",E,R[474],9,[[["self"]],["str"]]],[11,R[475],E,R[476],9,[[["self"]],[R[477]]]],[11,R[478],E,R[479],9,[[["self"]],["usize"]]],[11,R[480],E,R[481],9,[[["self"]],[R[434]]]],[11,"get",E,R[482],10,[[["self"],["usize"]],[R[3]]]],[11,"len",E,R[483],10,[[["self"]],["usize"]]],[11,"get",E,R[484],11,[[["self"],["usize"]],[[R[3],["match"]],["match"]]]],[11,"name",E,R[485],11,[[["self"],["str"]],[[R[3],["match"]],["match"]]]],[11,"iter",E,R[399],11,[[["self"]],[R[486]]]],[11,"expand",E,R[487],11,[[["self"],["vec"]]]],[11,"len",E,R[488],11,[[["self"]],["usize"]]],[11,"new","regex",R[436],12,[[["i"]],[[R[425]],[R[15],[R[425],"error"]],["error"]]]],[11,R[435],E,R[437],12,[[["self"],["str"]],["bool"]]],[11,R[501],E,R[438],12,[[["self"],["str"]],[R[439]]]],[11,"len",E,R[440],12,[[["self"]],["usize"]]],[11,"patterns",E,R[441],12,[[["self"]]]],[11,R[442],E,R[443],13,[[["self"]],["bool"]]],[11,"matched",E,R[444],13,[[["self"],["usize"]],["bool"]]],[11,"len",E,R[445],13,[[["self"]],["usize"]]],[11,"iter",E,R[446],13,[[["self"]],[R[447]]]],[11,"new",R[422],R[436],14,[[["i"]],[[R[425]],["error"],[R[15],[R[425],"error"]]]]],[11,R[435],E,R[437],14,[[["self"]],["bool"]]],[11,R[501],E,R[438],14,[[["self"]],[R[439]]]],[11,"len",E,R[440],14,[[["self"]],["usize"]]],[11,"patterns",E,R[441],14,[[["self"]]]],[11,R[442],E,R[443],15,[[["self"]],["bool"]]],[11,"matched",E,R[444],15,[[["self"],["usize"]],["bool"]]],[11,"len",E,R[445],15,[[["self"]],["usize"]]],[11,"iter",E,R[446],15,[[["self"]],[R[447]]]],[11,"start","regex",R[448],16,[[["self"]],["usize"]]],[11,"end",E,R[449],16,[[["self"]],["usize"]]],[11,"as_str",E,R[450],16,[[["self"]],["str"]]],[11,"new",E,R[451],17,[[["str"]],[["regex"],[R[15],["regex","error"]],["error"]]]],[11,R[435],E,R[452],17,[[["self"],["str"]],["bool"]]],[11,"find",E,R[453],17,[[["str"],["self"]],[[R[3],["match"]],["match"]]]],[11,R[430],E,R[454],17,[[["self"],["str"]],[R[501]]]],[11,R[431],E,R[455],17,[[["str"],["self"]],[[R[431]],[R[3],[R[431]]]]]],[11,R[456],E,R[457],17,[[["self"],["str"]],[R[458]]]],[11,"split",E,R[459],17,[[["self"],["str"]],["split"]]],[11,"splitn",E,R[460],17,[[["self"],["str"],["usize"]],["splitn"]]],[11,"replace",E,R[461],17,[[["str"],["self"],[R[433]]],[["str"],["cow",["str"]]]]],[11,R[432],E,R[462],17,[[["str"],["self"],[R[433]]],[["str"],["cow",["str"]]]]],[11,"replacen",E,R[463],17,[[["usize"],["str"],["self"],[R[433]]],[["str"],["cow",["str"]]]]],[11,R[464],E,R[465],17,[[["self"],["str"]],[[R[3],["usize"]],["usize"]]]],[11,R[466],E,R[467],17,[[["self"],["usize"],["str"]],[[R[3],["usize"]],["usize"]]]],[11,R[468],E,R[469],17,[[["self"],["usize"],["str"]],["bool"]]],[11,"find_at",E,R[470],17,[[["str"],["self"],["usize"]],[[R[3],["match"]],["match"]]]],[11,R[471],E,R[472],17,[[["str"],["self"],[R[434]]],[[R[3],["match"]],["match"]]]],[11,R[473],E,"Returns the same as captures, but starts the search at the…",17,[[["usize"],["str"],["self"],[R[434]]],[[R[3],["match"]],["match"]]]],[11,"as_str",E,R[474],17,[[["self"]],["str"]]],[11,R[475],E,R[476],17,[[["self"]],[R[477]]]],[11,R[478],E,R[479],17,[[["self"]],["usize"]]],[11,R[480],E,R[481],17,[[["self"]],[R[434]]]],[11,"get",E,R[482],18,[[["self"],["usize"]],[R[3]]]],[11,"len",E,R[483],18,[[["self"]],["usize"]]],[11,"get",E,R[484],19,[[["self"],["usize"]],[[R[3],["match"]],["match"]]]],[11,"name",E,R[485],19,[[["self"],["str"]],[[R[3],["match"]],["match"]]]],[11,"iter",E,R[399],19,[[["self"]],[R[486]]]],[11,"expand",E,R[487],19,[[["self"],[R[2]],["str"]]]],[11,"len",E,R[488],19,[[["self"]],["usize"]]],[8,R[496],E,R[489],N,N],[10,R[490],E,R[491],20,[[["self"],[R[431]],[R[2]]]]],[11,R[426],E,R[494],20,[[["self"]],[[R[3],["cow"]],["cow",["str"]]]]],[11,"by_ref",E,R[428],20,[[["self"]],[R[429]]]],[11,"from",E,E,5,[[[T]],[T]]],[11,"into",E,E,5,[[],[U]]],[11,R[12],E,E,5,[[[U]],[R[15]]]],[11,R[13],E,E,5,[[],[R[15]]]],[11,R[14],E,E,5,[[["self"]],[T]]],[11,R[17],E,E,5,[[["self"]],[T]]],[11,R[16],E,E,5,[[["self"]],[R[18]]]],[11,"from",E,E,7,[[[T]],[T]]],[11,"into",E,E,7,[[],[U]]],[11,R[12],E,E,7,[[[U]],[R[15]]]],[11,R[13],E,E,7,[[],[R[15]]]],[11,R[14],E,E,7,[[["self"]],[T]]],[11,R[17],E,E,7,[[["self"]],[T]]],[11,R[16],E,E,7,[[["self"]],[R[18]]]],[11,"from",E,E,12,[[[T]],[T]]],[11,R[32],E,E,12,[[["self"]],[T]]],[11,R[33],E,E,12,[[[T],["self"]]]],[11,"into",E,E,12,[[],[U]]],[11,R[12],E,E,12,[[[U]],[R[15]]]],[11,R[13],E,E,12,[[],[R[15]]]],[11,R[14],E,E,12,[[["self"]],[T]]],[11,R[17],E,E,12,[[["self"]],[T]]],[11,R[16],E,E,12,[[["self"]],[R[18]]]],[11,"from",E,E,13,[[[T]],[T]]],[11,R[32],E,E,13,[[["self"]],[T]]],[11,R[33],E,E,13,[[[T],["self"]]]],[11,R[50],E,E,13,[[],["i"]]],[11,"into",E,E,13,[[],[U]]],[11,R[12],E,E,13,[[[U]],[R[15]]]],[11,R[13],E,E,13,[[],[R[15]]]],[11,R[14],E,E,13,[[["self"]],[T]]],[11,R[17],E,E,13,[[["self"]],[T]]],[11,R[16],E,E,13,[[["self"]],[R[18]]]],[11,"from",E,E,21,[[[T]],[T]]],[11,R[50],E,E,21,[[],["i"]]],[11,"into",E,E,21,[[],[U]]],[11,R[12],E,E,21,[[[U]],[R[15]]]],[11,R[13],E,E,21,[[],[R[15]]]],[11,R[14],E,E,21,[[["self"]],[T]]],[11,R[17],E,E,21,[[["self"]],[T]]],[11,R[16],E,E,21,[[["self"]],[R[18]]]],[11,"from",E,E,22,[[[T]],[T]]],[11,R[32],E,E,22,[[["self"]],[T]]],[11,R[33],E,E,22,[[[T],["self"]]]],[11,R[50],E,E,22,[[],["i"]]],[11,"into",E,E,22,[[],[U]]],[11,R[12],E,E,22,[[[U]],[R[15]]]],[11,R[13],E,E,22,[[],[R[15]]]],[11,R[14],E,E,22,[[["self"]],[T]]],[11,R[17],E,E,22,[[["self"]],[T]]],[11,R[16],E,E,22,[[["self"]],[R[18]]]],[11,"from",E,E,17,[[[T]],[T]]],[11,R[32],E,E,17,[[["self"]],[T]]],[11,R[33],E,E,17,[[[T],["self"]]]],[11,R[81],E,E,17,[[["self"]],[R[2]]]],[11,"into",E,E,17,[[],[U]]],[11,R[12],E,E,17,[[[U]],[R[15]]]],[11,R[13],E,E,17,[[],[R[15]]]],[11,R[14],E,E,17,[[["self"]],[T]]],[11,R[17],E,E,17,[[["self"]],[T]]],[11,R[16],E,E,17,[[["self"]],[R[18]]]],[11,"from",E,E,16,[[[T]],[T]]],[11,R[32],E,E,16,[[["self"]],[T]]],[11,R[33],E,E,16,[[[T],["self"]]]],[11,"into",E,E,16,[[],[U]]],[11,R[12],E,E,16,[[[U]],[R[15]]]],[11,R[13],E,E,16,[[],[R[15]]]],[11,R[14],E,E,16,[[["self"]],[T]]],[11,R[17],E,E,16,[[["self"]],[T]]],[11,R[16],E,E,16,[[["self"]],[R[18]]]],[11,"from",E,E,19,[[[T]],[T]]],[11,"into",E,E,19,[[],[U]]],[11,R[12],E,E,19,[[[U]],[R[15]]]],[11,R[13],E,E,19,[[],[R[15]]]],[11,R[14],E,E,19,[[["self"]],[T]]],[11,R[17],E,E,19,[[["self"]],[T]]],[11,R[16],E,E,19,[[["self"]],[R[18]]]],[11,"from",E,E,23,[[[T]],[T]]],[11,R[50],E,E,23,[[],["i"]]],[11,"into",E,E,23,[[],[U]]],[11,R[12],E,E,23,[[[U]],[R[15]]]],[11,R[13],E,E,23,[[],[R[15]]]],[11,R[14],E,E,23,[[["self"]],[T]]],[11,R[17],E,E,23,[[["self"]],[T]]],[11,R[16],E,E,23,[[["self"]],[R[18]]]],[11,"from",E,E,24,[[[T]],[T]]],[11,R[50],E,E,24,[[],["i"]]],[11,"into",E,E,24,[[],[U]]],[11,R[12],E,E,24,[[[U]],[R[15]]]],[11,R[13],E,E,24,[[],[R[15]]]],[11,R[14],E,E,24,[[["self"]],[T]]],[11,R[17],E,E,24,[[["self"]],[T]]],[11,R[16],E,E,24,[[["self"]],[R[18]]]],[11,"from",E,E,25,[[[T]],[T]]],[11,R[50],E,E,25,[[],["i"]]],[11,"into",E,E,25,[[],[U]]],[11,R[12],E,E,25,[[[U]],[R[15]]]],[11,R[13],E,E,25,[[],[R[15]]]],[11,R[14],E,E,25,[[["self"]],[T]]],[11,R[17],E,E,25,[[["self"]],[T]]],[11,R[16],E,E,25,[[["self"]],[R[18]]]],[11,"from",E,E,26,[[[T]],[T]]],[11,R[50],E,E,26,[[],["i"]]],[11,"into",E,E,26,[[],[U]]],[11,R[12],E,E,26,[[[U]],[R[15]]]],[11,R[13],E,E,26,[[],[R[15]]]],[11,R[14],E,E,26,[[["self"]],[T]]],[11,R[17],E,E,26,[[["self"]],[T]]],[11,R[16],E,E,26,[[["self"]],[R[18]]]],[11,"from",E,E,18,[[[T]],[T]]],[11,R[32],E,E,18,[[["self"]],[T]]],[11,R[33],E,E,18,[[[T],["self"]]]],[11,"into",E,E,18,[[],[U]]],[11,R[12],E,E,18,[[[U]],[R[15]]]],[11,R[13],E,E,18,[[],[R[15]]]],[11,R[14],E,E,18,[[["self"]],[T]]],[11,R[17],E,E,18,[[["self"]],[T]]],[11,R[16],E,E,18,[[["self"]],[R[18]]]],[11,"from",E,E,27,[[[T]],[T]]],[11,"into",E,E,27,[[],[U]]],[11,R[12],E,E,27,[[[U]],[R[15]]]],[11,R[13],E,E,27,[[],[R[15]]]],[11,R[14],E,E,27,[[["self"]],[T]]],[11,R[17],E,E,27,[[["self"]],[T]]],[11,R[16],E,E,27,[[["self"]],[R[18]]]],[11,"from",E,E,0,[[[T]],[T]]],[11,"into",E,E,0,[[],[U]]],[11,R[12],E,E,0,[[[U]],[R[15]]]],[11,R[13],E,E,0,[[],[R[15]]]],[11,R[14],E,E,0,[[["self"]],[T]]],[11,R[17],E,E,0,[[["self"]],[T]]],[11,R[16],E,E,0,[[["self"]],[R[18]]]],[11,"from",E,E,28,[[[T]],[T]]],[11,R[50],E,E,28,[[],["i"]]],[11,"into",E,E,28,[[],[U]]],[11,R[12],E,E,28,[[[U]],[R[15]]]],[11,R[13],E,E,28,[[],[R[15]]]],[11,R[14],E,E,28,[[["self"]],[T]]],[11,R[17],E,E,28,[[["self"]],[T]]],[11,R[16],E,E,28,[[["self"]],[R[18]]]],[11,"from",E,E,29,[[[T]],[T]]],[11,R[50],E,E,29,[[],["i"]]],[11,"into",E,E,29,[[],[U]]],[11,R[12],E,E,29,[[[U]],[R[15]]]],[11,R[13],E,E,29,[[],[R[15]]]],[11,R[14],E,E,29,[[["self"]],[T]]],[11,R[17],E,E,29,[[["self"]],[T]]],[11,R[16],E,E,29,[[["self"]],[R[18]]]],[11,"from",E,E,1,[[[T]],[T]]],[11,R[32],E,E,1,[[["self"]],[T]]],[11,R[33],E,E,1,[[[T],["self"]]]],[11,R[81],E,E,1,[[["self"]],[R[2]]]],[11,"into",E,E,1,[[],[U]]],[11,R[12],E,E,1,[[[U]],[R[15]]]],[11,R[13],E,E,1,[[],[R[15]]]],[11,R[14],E,E,1,[[["self"]],[T]]],[11,R[17],E,E,1,[[["self"]],[T]]],[11,R[16],E,E,1,[[["self"]],[R[18]]]],[11,"from",R[422],E,4,[[[T]],[T]]],[11,"into",E,E,4,[[],[U]]],[11,R[12],E,E,4,[[[U]],[R[15]]]],[11,R[13],E,E,4,[[],[R[15]]]],[11,R[14],E,E,4,[[["self"]],[T]]],[11,R[17],E,E,4,[[["self"]],[T]]],[11,R[16],E,E,4,[[["self"]],[R[18]]]],[11,"from",E,E,6,[[[T]],[T]]],[11,"into",E,E,6,[[],[U]]],[11,R[12],E,E,6,[[[U]],[R[15]]]],[11,R[13],E,E,6,[[],[R[15]]]],[11,R[14],E,E,6,[[["self"]],[T]]],[11,R[17],E,E,6,[[["self"]],[T]]],[11,R[16],E,E,6,[[["self"]],[R[18]]]],[11,"from",E,E,8,[[[T]],[T]]],[11,R[32],E,E,8,[[["self"]],[T]]],[11,R[33],E,E,8,[[[T],["self"]]]],[11,"into",E,E,8,[[],[U]]],[11,R[12],E,E,8,[[[U]],[R[15]]]],[11,R[13],E,E,8,[[],[R[15]]]],[11,R[14],E,E,8,[[["self"]],[T]]],[11,R[17],E,E,8,[[["self"]],[T]]],[11,R[16],E,E,8,[[["self"]],[R[18]]]],[11,"from",E,E,9,[[[T]],[T]]],[11,R[32],E,E,9,[[["self"]],[T]]],[11,R[33],E,E,9,[[[T],["self"]]]],[11,R[81],E,E,9,[[["self"]],[R[2]]]],[11,"into",E,E,9,[[],[U]]],[11,R[12],E,E,9,[[[U]],[R[15]]]],[11,R[13],E,E,9,[[],[R[15]]]],[11,R[14],E,E,9,[[["self"]],[T]]],[11,R[17],E,E,9,[[["self"]],[T]]],[11,R[16],E,E,9,[[["self"]],[R[18]]]],[11,"from",E,E,30,[[[T]],[T]]],[11,R[50],E,E,30,[[],["i"]]],[11,"into",E,E,30,[[],[U]]],[11,R[12],E,E,30,[[[U]],[R[15]]]],[11,R[13],E,E,30,[[],[R[15]]]],[11,R[14],E,E,30,[[["self"]],[T]]],[11,R[17],E,E,30,[[["self"]],[T]]],[11,R[16],E,E,30,[[["self"]],[R[18]]]],[11,"from",E,E,31,[[[T]],[T]]],[11,R[50],E,E,31,[[],["i"]]],[11,"into",E,E,31,[[],[U]]],[11,R[12],E,E,31,[[[U]],[R[15]]]],[11,R[13],E,E,31,[[],[R[15]]]],[11,R[14],E,E,31,[[["self"]],[T]]],[11,R[17],E,E,31,[[["self"]],[T]]],[11,R[16],E,E,31,[[["self"]],[R[18]]]],[11,"from",E,E,32,[[[T]],[T]]],[11,R[50],E,E,32,[[],["i"]]],[11,"into",E,E,32,[[],[U]]],[11,R[12],E,E,32,[[[U]],[R[15]]]],[11,R[13],E,E,32,[[],[R[15]]]],[11,R[14],E,E,32,[[["self"]],[T]]],[11,R[17],E,E,32,[[["self"]],[T]]],[11,R[16],E,E,32,[[["self"]],[R[18]]]],[11,"from",E,E,33,[[[T]],[T]]],[11,R[50],E,E,33,[[],["i"]]],[11,"into",E,E,33,[[],[U]]],[11,R[12],E,E,33,[[[U]],[R[15]]]],[11,R[13],E,E,33,[[],[R[15]]]],[11,R[14],E,E,33,[[["self"]],[T]]],[11,R[17],E,E,33,[[["self"]],[T]]],[11,R[16],E,E,33,[[["self"]],[R[18]]]],[11,"from",E,E,34,[[[T]],[T]]],[11,R[50],E,E,34,[[],["i"]]],[11,"into",E,E,34,[[],[U]]],[11,R[12],E,E,34,[[[U]],[R[15]]]],[11,R[13],E,E,34,[[],[R[15]]]],[11,R[14],E,E,34,[[["self"]],[T]]],[11,R[17],E,E,34,[[["self"]],[T]]],[11,R[16],E,E,34,[[["self"]],[R[18]]]],[11,"from",E,E,10,[[[T]],[T]]],[11,R[32],E,E,10,[[["self"]],[T]]],[11,R[33],E,E,10,[[[T],["self"]]]],[11,"into",E,E,10,[[],[U]]],[11,R[12],E,E,10,[[[U]],[R[15]]]],[11,R[13],E,E,10,[[],[R[15]]]],[11,R[14],E,E,10,[[["self"]],[T]]],[11,R[17],E,E,10,[[["self"]],[T]]],[11,R[16],E,E,10,[[["self"]],[R[18]]]],[11,"from",E,E,11,[[[T]],[T]]],[11,"into",E,E,11,[[],[U]]],[11,R[12],E,E,11,[[[U]],[R[15]]]],[11,R[13],E,E,11,[[],[R[15]]]],[11,R[14],E,E,11,[[["self"]],[T]]],[11,R[17],E,E,11,[[["self"]],[T]]],[11,R[16],E,E,11,[[["self"]],[R[18]]]],[11,"from",E,E,35,[[[T]],[T]]],[11,R[50],E,E,35,[[],["i"]]],[11,"into",E,E,35,[[],[U]]],[11,R[12],E,E,35,[[[U]],[R[15]]]],[11,R[13],E,E,35,[[],[R[15]]]],[11,R[14],E,E,35,[[["self"]],[T]]],[11,R[17],E,E,35,[[["self"]],[T]]],[11,R[16],E,E,35,[[["self"]],[R[18]]]],[11,"from",E,E,36,[[[T]],[T]]],[11,"into",E,E,36,[[],[U]]],[11,R[12],E,E,36,[[[U]],[R[15]]]],[11,R[13],E,E,36,[[],[R[15]]]],[11,R[14],E,E,36,[[["self"]],[T]]],[11,R[17],E,E,36,[[["self"]],[T]]],[11,R[16],E,E,36,[[["self"]],[R[18]]]],[11,"from",E,E,2,[[[T]],[T]]],[11,"into",E,E,2,[[],[U]]],[11,R[12],E,E,2,[[[U]],[R[15]]]],[11,R[13],E,E,2,[[],[R[15]]]],[11,R[14],E,E,2,[[["self"]],[T]]],[11,R[17],E,E,2,[[["self"]],[T]]],[11,R[16],E,E,2,[[["self"]],[R[18]]]],[11,"from",E,E,14,[[[T]],[T]]],[11,R[32],E,E,14,[[["self"]],[T]]],[11,R[33],E,E,14,[[[T],["self"]]]],[11,"into",E,E,14,[[],[U]]],[11,R[12],E,E,14,[[[U]],[R[15]]]],[11,R[13],E,E,14,[[],[R[15]]]],[11,R[14],E,E,14,[[["self"]],[T]]],[11,R[17],E,E,14,[[["self"]],[T]]],[11,R[16],E,E,14,[[["self"]],[R[18]]]],[11,"from",E,E,15,[[[T]],[T]]],[11,R[32],E,E,15,[[["self"]],[T]]],[11,R[33],E,E,15,[[[T],["self"]]]],[11,R[50],E,E,15,[[],["i"]]],[11,"into",E,E,15,[[],[U]]],[11,R[12],E,E,15,[[[U]],[R[15]]]],[11,R[13],E,E,15,[[],[R[15]]]],[11,R[14],E,E,15,[[["self"]],[T]]],[11,R[17],E,E,15,[[["self"]],[T]]],[11,R[16],E,E,15,[[["self"]],[R[18]]]],[11,"from",E,E,37,[[[T]],[T]]],[11,R[50],E,E,37,[[],["i"]]],[11,"into",E,E,37,[[],[U]]],[11,R[12],E,E,37,[[[U]],[R[15]]]],[11,R[13],E,E,37,[[],[R[15]]]],[11,R[14],E,E,37,[[["self"]],[T]]],[11,R[17],E,E,37,[[["self"]],[T]]],[11,R[16],E,E,37,[[["self"]],[R[18]]]],[11,"from",E,E,38,[[[T]],[T]]],[11,R[32],E,E,38,[[["self"]],[T]]],[11,R[33],E,E,38,[[[T],["self"]]]],[11,R[50],E,E,38,[[],["i"]]],[11,"into",E,E,38,[[],[U]]],[11,R[12],E,E,38,[[[U]],[R[15]]]],[11,R[13],E,E,38,[[],[R[15]]]],[11,R[14],E,E,38,[[["self"]],[T]]],[11,R[17],E,E,38,[[["self"]],[T]]],[11,R[16],E,E,38,[[["self"]],[R[18]]]],[11,R[490],E,E,36,[[["self"],["vec"],[R[431]]]]],[11,R[426],E,E,36,[[["self"]],[["cow"],[R[3],["cow"]]]]],[11,R[490],E,E,2,[[["self"],["vec"],[R[431]]]]],[11,R[426],E,E,2,[[["self"]],[["cow"],[R[3],["cow"]]]]],[11,R[490],"regex",E,27,[[["self"],[R[431]],[R[2]]]]],[11,R[426],E,E,27,[[["self"]],[[R[3],["cow"]],["cow",["str"]]]]],[11,R[490],E,E,0,[[["self"],[R[431]],[R[2]]]]],[11,R[426],E,E,0,[[["self"]],[[R[3],["cow"]],["cow",["str"]]]]],[11,R[63],E,E,21,[[["self"]],[[R[3],["usize"]],["usize"]]]],[11,R[63],E,E,22,[[["self"]],[[R[3],["usize"]],["usize"]]]],[11,R[63],R[422],E,37,[[["self"]],[[R[3],["usize"]],["usize"]]]],[11,R[63],E,E,38,[[["self"]],[[R[3],["usize"]],["usize"]]]],[11,"next",E,E,30,[[["self"]],[[R[3],["match"]],["match"]]]],[11,"next",E,E,31,[[["self"]],[[R[3],[R[431]]],[R[431]]]]],[11,"next",E,E,32,[[["self"]],[R[3]]]],[11,"next",E,E,33,[[["self"]],[R[3]]]],[11,"next",E,E,34,[[["self"]],[[R[3],["str"]],[R[3],[R[3]]]]]],[11,R[51],E,E,34,[[["self"]]]],[11,"next",E,E,35,[[["self"]],[[R[3],[R[3]]],[R[3],["match"]]]]],[11,"next","regex",E,21,[[["self"]],[[R[3],["usize"]],["usize"]]]],[11,R[51],E,E,21,[[["self"]]]],[11,"next",E,E,22,[[["self"]],[[R[3],["usize"]],["usize"]]]],[11,R[51],E,E,22,[[["self"]]]],[11,"next",R[422],E,37,[[["self"]],[[R[3],["usize"]],["usize"]]]],[11,R[51],E,E,37,[[["self"]]]],[11,"next",E,E,38,[[["self"]],[[R[3],["usize"]],["usize"]]]],[11,R[51],E,E,38,[[["self"]]]],[11,"next","regex",E,23,[[["self"]],[[R[3],["str"]],[R[3],[R[3]]]]]],[11,R[51],E,E,23,[[["self"]]]],[11,"next",E,E,28,[[["self"]],[["str"],[R[3],["str"]]]]],[11,"next",E,E,29,[[["self"]],[["str"],[R[3],["str"]]]]],[11,"next",E,E,26,[[["self"]],[[R[3],[R[3]]],[R[3],["match"]]]]],[11,"next",E,E,25,[[["self"]],[[R[431]],[R[3],[R[431]]]]]],[11,"next",E,E,24,[[["self"]],[[R[3],["match"]],["match"]]]],[11,"eq",E,E,1,[[["self"],["error"]],["bool"]]],[11,"ne",E,E,1,[[["self"],["error"]],["bool"]]],[11,"eq",R[422],E,8,[[["self"],["match"]],["bool"]]],[11,"ne",E,E,8,[[["self"],["match"]],["bool"]]],[11,"eq","regex",E,16,[[["self"],["match"]],["bool"]]],[11,"ne",E,E,16,[[["self"],["match"]],["bool"]]],[11,"clone",E,E,1,[[["self"]],["error"]]],[11,"clone",R[422],E,8,[[["self"]],["match"]]],[11,"clone",E,E,9,[[["self"]],["regex"]]],[11,"clone",E,E,10,[[["self"]],[R[434]]]],[11,"clone","regex",E,12,[[["self"]],[R[425]]]],[11,"clone",E,E,13,[[["self"]],[R[439]]]],[11,"clone",E,E,22,[[["self"]],[R[447]]]],[11,"clone",R[422],E,14,[[["self"]],[R[425]]]],[11,"clone",E,E,15,[[["self"]],[R[439]]]],[11,"clone",E,E,38,[[["self"]],[R[447]]]],[11,"clone","regex",E,16,[[["self"]],["match"]]],[11,"clone",E,E,17,[[["self"]],["regex"]]],[11,"clone",E,E,18,[[["self"]],[R[434]]]],[11,R[50],E,E,13,[[]]],[11,R[50],R[422],E,15,[[]]],[11,"fmt","regex",E,1,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[422],R[492],9,[[["self"],[R[36]]],[R[15]]]],[11,"fmt","regex",R[492],17,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,1,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[422],E,8,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,R[492],9,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,10,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,11,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,36,[[["self"],[R[36]]],[R[15]]]],[11,"fmt","regex",E,13,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,12,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[422],E,15,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,14,[[["self"],[R[36]]],[R[15]]]],[11,"fmt","regex",E,16,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,R[492],17,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,18,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,19,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,27,[[["self"],[R[36]]],[R[15]]]],[11,"from_str",R[422],R[493],9,[[["str"]],[[R[15],["regex","error"]],["regex"],["error"]]]],[11,"from_str","regex",R[493],17,[[["str"]],[["regex"],[R[15],["regex","error"]],["error"]]]],[11,"index",R[422],E,11,[[["self"],["usize"]]]],[11,"index",E,E,11,[[["str"],["self"]]]],[11,"index","regex",E,19,[[["self"],["usize"]],["str"]]],[11,"index",E,E,19,[[["str"],["self"]],["str"]]],[11,R[255],E,E,1,[[["self"]],["str"]]],[11,R[426],E,R[494],20,[[["self"]],[[R[3],["cow"]],["cow",["str"]]]]],[11,"by_ref",E,R[428],20,[[["self"]],[R[429]]]]],"p":[[3,R[495]],[4,"Error"],[3,R[495]],[8,R[496]],[3,R[384]],[3,R[384]],[3,R[386]],[3,R[386]],[3,"Match"],[3,"Regex"],[3,R[396]],[3,R[497]],[3,R[498]],[3,R[403]],[3,R[498]],[3,R[403]],[3,"Match"],[3,"Regex"],[3,R[396]],[3,R[497]],[8,R[496]],[3,R[405]],[3,R[407]],[3,R[394]],[3,"Matches"],[3,R[390]],[3,R[398]],[3,R[400]],[3,"Split"],[3,"SplitN"],[3,"Matches"],[3,R[390]],[3,"Split"],[3,"SplitN"],[3,R[394]],[3,R[398]],[3,R[400]],[3,R[405]],[3,R[407]]]}; +searchIndex["regex_syntax"]={"doc":"This crate provides a robust regular expression parser.","i":[[3,"Parser",R[154],"A convenience parser for regular expressions.",N,N],[3,R[145],E,R[146],N,N],[4,"Error",E,"This error type encompasses any error that can be returned…",N,N],[13,"Parse",E,"An error that occurred while translating concrete syntax…",0,N],[13,"Translate",E,"An error that occurred while translating abstract syntax…",0,N],[5,"escape",E,R[499],N,[[["str"]],[R[2]]]],[5,"escape_into",E,"Escapes all meta characters in `text` and writes the…",N,[[[R[2]],["str"]]]],[5,"is_meta_character",E,"Returns true if the give character has significance in a…",N,[[["char"]],["bool"]]],[5,"is_word_character",E,"Returns true if and only if the given character is a…",N,[[["char"]],["bool"]]],[5,"is_word_byte",E,"Returns true if and only if the given character is an…",N,[[["u8"]],["bool"]]],[0,"ast",E,"Defines an abstract syntax for regular expressions.",N,N],[3,"Error",R[130],"An error that occurred while parsing a regular expression…",N,N],[3,"Span",E,"Span represents the position information of a single AST…",N,N],[12,"start",E,"The start byte offset.",1,N],[12,"end",E,"The end byte offset.",1,N],[3,"Position",E,"A single position in a regular expression.",N,N],[12,"offset",E,"The absolute offset of this position, starting at `0` from…",2,N],[12,"line",E,"The line number, starting at `1`.",2,N],[12,"column",E,"The approximate column number, starting at `1`.",2,N],[3,R[274],E,"An abstract syntax tree for a singular expression along…",N,N],[12,"ast",E,"The actual ast.",3,N],[12,"comments",E,"All comments found in the original regular expression.",3,N],[3,"Comment",E,"A comment from a regular expression with an associated span.",N,N],[12,"span",E,"The span of this comment, including the beginning `#` and…",4,N],[12,"comment",E,"The comment text, starting with the first character…",4,N],[3,R[137],E,R[138],N,N],[12,"span",E,"The span of this alternation.",5,N],[12,"asts",E,"The alternate regular expressions.",5,N],[3,"Concat",E,R[139],N,N],[12,"span",E,"The span of this concatenation.",6,N],[12,"asts",E,"The concatenation regular expressions.",6,N],[3,R[172],E,"A single literal expression.",N,N],[12,"span",E,"The span of this literal.",7,N],[12,"kind",E,"The kind of this literal.",7,N],[12,"c",E,"The Unicode scalar value corresponding to this literal.",7,N],[3,R[275],E,"A Perl character class.",N,N],[12,"span",E,R[129],8,N],[12,"kind",E,"The kind of Perl class.",8,N],[12,"negated",E,"Whether the class is negated or not. e.g., `\\d` is not…",8,N],[3,R[276],E,"An ASCII character class.",N,N],[12,"span",E,R[129],9,N],[12,"kind",E,"The kind of ASCII class.",9,N],[12,"negated",E,"Whether the class is negated or not. e.g., `[[:alpha:]]`…",9,N],[3,R[155],E,"A Unicode character class.",N,N],[12,"span",E,R[129],10,N],[12,"negated",E,"Whether this class is negated or not.",10,N],[12,"kind",E,"The kind of Unicode class.",10,N],[3,R[277],E,"A bracketed character class, e.g., `[a-z0-9]`.",N,N],[12,"span",E,R[129],11,N],[12,"negated",E,"Whether this class is negated or not. e.g., `[a]` is not…",11,N],[12,"kind",E,"The type of this set. A set is either a normal union of…",11,N],[3,R[278],E,"A single character class range in a set.",N,N],[12,"span",E,"The span of this range.",12,N],[12,"start",E,"The start of this range.",12,N],[12,"end",E,"The end of this range.",12,N],[3,R[279],E,"A union of items inside a character class set.",N,N],[12,"span",E,"The span of the items in this operation. e.g., the…",13,N],[12,"items",E,"The sequence of items that make up this union.",13,N],[3,R[280],E,"A Unicode character class set operation.",N,N],[12,"span",E,"The span of this operation. e.g., the `a-z--[h-p]` in…",14,N],[12,"kind",E,"The type of this set operation.",14,N],[12,"lhs",E,"The left hand side of the operation.",14,N],[12,"rhs",E,"The right hand side of the operation.",14,N],[3,R[133],E,R[134],N,N],[12,"span",E,"The span of this assertion.",15,N],[12,"kind",E,"The assertion kind, e.g., `\\b` or `^`.",15,N],[3,R[135],E,"A repetition operation applied to a regular expression.",N,N],[12,"span",E,"The span of this operation.",16,N],[12,"op",E,"The actual operation.",16,N],[12,"greedy",E,"Whether this operation was applied greedily or not.",16,N],[12,"ast",E,"The regular expression under repetition.",16,N],[3,R[281],E,"The repetition operator itself.",N,N],[12,"span",E,"The span of this operator. This includes things like `+`,…",17,N],[12,"kind",E,"The type of operation.",17,N],[3,"Group",E,R[136],N,N],[12,"span",E,"The span of this group.",18,N],[12,"kind",E,"The kind of this group.",18,N],[12,"ast",E,"The regular expression in this group.",18,N],[3,R[144],E,"A capture name.",N,N],[12,"span",E,"The span of this capture name.",19,N],[12,"name",E,"The capture name.",19,N],[12,"index",E,"The capture index.",19,N],[3,"SetFlags",E,"A group of flags that is not applied to a particular…",N,N],[12,"span",E,"The span of these flags, including the grouping parentheses.",20,N],[12,"flags",E,"The actual sequence of flags.",20,N],[3,"Flags",E,"A group of flags.",N,N],[12,"span",E,"The span of this group of flags.",21,N],[12,"items",E,"A sequence of flag items. Each item is either a flag or a…",21,N],[3,R[282],E,"A single item in a group of flags.",N,N],[12,"span",E,"The span of this item.",22,N],[12,"kind",E,"The kind of this item.",22,N],[4,R[106],E,"The type of an error that occurred while building an AST.",N,N],[13,"CaptureLimitExceeded",E,"The capturing group limit was exceeded.",23,N],[13,"ClassEscapeInvalid",E,"An invalid escape sequence was found in a character class…",23,N],[13,"ClassRangeInvalid",E,"An invalid character class range was found. An invalid…",23,N],[13,"ClassRangeLiteral",E,"An invalid range boundary was found in a character class.…",23,N],[13,"ClassUnclosed",E,"An opening `[` was found with no corresponding closing `]`.",23,N],[13,"DecimalEmpty",E,"Note that this error variant is no longer used. Namely, a…",23,N],[13,"DecimalInvalid",E,"An invalid decimal number was given where one was expected.",23,N],[13,"EscapeHexEmpty",E,"A bracketed hex literal was empty.",23,N],[13,"EscapeHexInvalid",E,"A bracketed hex literal did not correspond to a Unicode…",23,N],[13,"EscapeHexInvalidDigit",E,"An invalid hexadecimal digit was found.",23,N],[13,"EscapeUnexpectedEof",E,"EOF was found before an escape sequence was completed.",23,N],[13,"EscapeUnrecognized",E,"An unrecognized escape sequence.",23,N],[13,"FlagDanglingNegation",E,"A dangling negation was used when setting flags, e.g., `i-`.",23,N],[13,"FlagDuplicate",E,"A flag was used twice, e.g., `i-i`.",23,N],[12,R[132],R[131],"The position of the original flag. The error position…",23,N],[13,"FlagRepeatedNegation",R[130],"The negation operator was used twice, e.g., `-i-s`.",23,N],[12,R[132],R[131],"The position of the original negation operator. The error…",23,N],[13,"FlagUnexpectedEof",R[130],"Expected a flag but got EOF, e.g., `(?`.",23,N],[13,"FlagUnrecognized",E,"Unrecognized flag, e.g., `a`.",23,N],[13,"GroupNameDuplicate",E,"A duplicate capture name was found.",23,N],[12,R[132],R[131],"The position of the initial occurrence of the capture…",23,N],[13,"GroupNameEmpty",R[130],"A capture group name is empty, e.g., `(?P<>abc)`.",23,N],[13,"GroupNameInvalid",E,"An invalid character was seen for a capture group name.…",23,N],[13,"GroupNameUnexpectedEof",E,"A closing `>` could not be found for a capture group name.",23,N],[13,"GroupUnclosed",E,"An unclosed group, e.g., `(ab`.",23,N],[13,"GroupUnopened",E,"An unopened group, e.g., `ab)`.",23,N],[13,"NestLimitExceeded",E,"The nest limit was exceeded. The limit stored here is the…",23,N],[13,"RepetitionCountInvalid",E,"The range provided in a counted repetition operator is…",23,N],[13,"RepetitionCountDecimalEmpty",E,"An opening `{` was not followed by a valid decimal value.…",23,N],[13,"RepetitionCountUnclosed",E,"An opening `{` was found with no corresponding closing `}`.",23,N],[13,"RepetitionMissing",E,"A repetition operator was applied to a missing…",23,N],[13,"UnsupportedBackreference",E,"When octal support is disabled, this error is produced…",23,N],[13,"UnsupportedLookAround",E,"When syntax similar to PCRE's look-around is used, this…",23,N],[4,"Ast",E,"An abstract syntax tree for a single regular expression.",N,N],[13,"Empty",E,"An empty regex that matches everything.",24,N],[13,"Flags",E,"A set of flags, e.g., `(?is)`.",24,N],[13,R[172],E,"A single character literal, which includes escape sequences.",24,N],[13,"Dot",E,"The \"any character\" class.",24,N],[13,R[133],E,R[134],24,N],[13,"Class",E,"A single character class. This includes all forms of…",24,N],[13,R[135],E,"A repetition operator applied to an arbitrary regular…",24,N],[13,"Group",E,R[136],24,N],[13,R[137],E,R[138],24,N],[13,"Concat",E,R[139],24,N],[4,R[283],E,"The kind of a single literal expression.",N,N],[13,"Verbatim",E,"The literal is written verbatim, e.g., `a` or `☃`.",25,N],[13,"Punctuation",E,"The literal is written as an escape because it is…",25,N],[13,"Octal",E,"The literal is written as an octal escape, e.g., `\\141`.",25,N],[13,"HexFixed",E,"The literal is written as a hex code with a fixed number…",25,N],[13,"HexBrace",E,"The literal is written as a hex code with a bracketed…",25,N],[13,"Special",E,"The literal is written as a specially recognized escape,…",25,N],[4,R[284],E,"The type of a special literal.",N,N],[13,"Bell",E,"Bell, spelled `\\a` (`\\x07`).",26,N],[13,"FormFeed",E,"Form feed, spelled `\\f` (`\\x0C`).",26,N],[13,"Tab",E,"Tab, spelled `\\t` (`\\x09`).",26,N],[13,"LineFeed",E,"Line feed, spelled `\\n` (`\\x0A`).",26,N],[13,"CarriageReturn",E,"Carriage return, spelled `\\r` (`\\x0D`).",26,N],[13,"VerticalTab",E,"Vertical tab, spelled `\\v` (`\\x0B`).",26,N],[13,"Space",E,"Space, spelled `\\ ` (`\\x20`). Note that this can only…",26,N],[4,R[285],E,"The type of a Unicode hex literal.",N,N],[13,"X",E,"A `\\x` prefix. When used without brackets, this form is…",27,N],[13,"UnicodeShort",E,"A `\\u` prefix. When used without brackets, this form is…",27,N],[13,"UnicodeLong",E,"A `\\U` prefix. When used without brackets, this form is…",27,N],[4,"Class",E,"A single character class expression.",N,N],[13,R[160],E,R[140],28,N],[13,"Perl",E,R[141],28,N],[13,R[142],E,R[143],28,N],[4,R[286],E,"The available Perl character classes.",N,N],[13,"Digit",E,"Decimal numbers.",29,N],[13,"Space",E,"Whitespace.",29,N],[13,"Word",E,"Word characters.",29,N],[4,R[287],E,"The available ASCII character classes.",N,N],[13,"Alnum",E,"`[0-9A-Za-z]`",30,N],[13,"Alpha",E,"`[A-Za-z]`",30,N],[13,"Ascii",E,"`[\\x00-\\x7F]`",30,N],[13,"Blank",E,"`[ \\t]`",30,N],[13,"Cntrl",E,"`[\\x00-\\x1F\\x7F]`",30,N],[13,"Digit",E,"`[0-9]`",30,N],[13,"Graph",E,"`[!-~]`",30,N],[13,"Lower",E,"`[a-z]`",30,N],[13,"Print",E,"`[ -~]`",30,N],[13,"Punct",E,"`[!-/:-@\\[-`{-~]`",30,N],[13,"Space",E,"`[\\t\\n\\v\\f\\r ]`",30,N],[13,"Upper",E,"`[A-Z]`",30,N],[13,"Word",E,"`[0-9A-Za-z_]`",30,N],[13,"Xdigit",E,"`[0-9A-Fa-f]`",30,N],[4,R[288],E,"The available forms of Unicode character classes.",N,N],[13,"OneLetter",E,"A one letter abbreviated class, e.g., `\\pN`.",31,N],[13,"Named",E,"A binary property, general category or script. The string…",31,N],[13,"NamedValue",E,"A property name and an associated value.",31,N],[12,"op","regex_syntax::ast::ClassUnicodeKind","The type of Unicode op used to associate `name` with…",31,N],[12,"name",E,"The property name (which may be empty).",31,N],[12,"value",E,"The property value (which may be empty).",31,N],[4,R[289],R[130],"The type of op used in a Unicode character class.",N,N],[13,"Equal",E,"A property set to a specific value, e.g.,…",32,N],[13,"Colon",E,"A property set to a specific value using a colon, e.g.,…",32,N],[13,"NotEqual",E,"A property that isn't a particular value, e.g.,…",32,N],[4,"ClassSet",E,"A character class set.",N,N],[13,"Item",E,"An item, which can be a single literal, range, nested…",33,N],[13,"BinaryOp",E,"A single binary operation (i.e., &&, -- or ~~).",33,N],[4,R[290],E,"A single component of a character class set.",N,N],[13,"Empty",E,"An empty item.",34,N],[13,R[172],E,"A single literal.",34,N],[13,"Range",E,"A range between two literals.",34,N],[13,"Ascii",E,"An ASCII character class, e.g., `[:alnum:]` or `[:punct:]`.",34,N],[13,R[160],E,R[140],34,N],[13,"Perl",E,R[141],34,N],[13,R[142],E,R[143],34,N],[13,"Union",E,"A union of items.",34,N],[4,R[291],E,"The type of a Unicode character class set operation.",N,N],[13,"Intersection",E,"The intersection of two sets, e.g., `\\pN&&[a-z]`.",35,N],[13,"Difference",E,"The difference of two sets, e.g., `\\pN--[0-9]`.",35,N],[13,"SymmetricDifference",E,"The symmetric difference of two sets. The symmetric…",35,N],[4,R[292],E,"An assertion kind.",N,N],[13,R[158],E,"`^`",36,N],[13,"EndLine",E,"`$`",36,N],[13,R[159],E,"`\\A`",36,N],[13,"EndText",E,"`\\z`",36,N],[13,R[156],E,"`\\b`",36,N],[13,"NotWordBoundary",E,"`\\B`",36,N],[4,R[165],E,R[166],N,N],[13,R[167],E,"`?`",37,N],[13,R[168],E,"`*`",37,N],[13,R[169],E,"`+`",37,N],[13,"Range",E,"`{m,n}`",37,N],[4,R[170],E,"A range repetition operator.",N,N],[13,"Exactly",E,"`{m}`",38,N],[13,"AtLeast",E,"`{m,}`",38,N],[13,"Bounded",E,"`{m,n}`",38,N],[4,R[161],E,"The kind of a group.",N,N],[13,R[162],E,"`(a)`",39,N],[13,R[144],E,"`(?Pa)`",39,N],[13,R[163],E,"`(?:a)` and `(?i:a)`",39,N],[4,R[293],E,"The kind of an item in a group of flags.",N,N],[13,"Negation",E,"A negation operator applied to all subsequent flags in the…",40,N],[13,"Flag",E,"A single flag in a group.",40,N],[4,"Flag",E,"A single flag.",N,N],[13,"CaseInsensitive",E,"`i`",41,N],[13,"MultiLine",E,"`m`",41,N],[13,"DotMatchesNewLine",E,"`s`",41,N],[13,"SwapGreed",E,"`U`",41,N],[13,R[160],E,"`u`",41,N],[13,"IgnoreWhitespace",E,"`x`",41,N],[5,"visit",E,R[171],N,[[["ast"],["visitor"]],[R[15]]]],[0,"parse",E,"This module provides a regular expression parser.",N,N],[3,R[145],R[223],R[146],N,N],[3,"Parser",E,"A regular expression parser.",N,N],[11,"new",E,R[209],42,[[],[R[147]]]],[11,"build",E,R[210],42,[[["self"]],["parser"]]],[11,R[211],E,R[212],42,[[["self"],["u32"]],[R[147]]]],[11,"octal",E,R[213],42,[[["self"],["bool"]],[R[147]]]],[11,R[215],E,R[216],42,[[["self"],["bool"]],[R[147]]]],[11,"new",E,R[222],43,[[],["parser"]]],[11,"parse",E,"Parse the regular expression into an abstract syntax tree.",43,[[["self"],["str"]],[["error"],[R[15],["ast","error"]],["ast"]]]],[11,"parse_with_comments",E,"Parse the regular expression and return an abstract syntax…",43,[[["self"],["str"]],[[R[15],[R[148],"error"]],[R[148]],["error"]]]],[0,"print",R[130],"This module provides a regular expression printer for `Ast`.",N,N],[3,"Printer",R[224],"A printer for a regular expression abstract syntax tree.",N,N],[11,"new",E,R[174],44,[[],["printer"]]],[11,"print",E,R[175],44,[[["self"],["ast"],["write"]],[R[15]]]],[8,"Visitor",R[130],"A trait for visiting an abstract syntax tree (AST) in…",N,N],[16,"Output",E,"The result of visiting an AST.",45,N],[16,"Err",E,"An error that visiting an AST might return.",45,N],[10,"finish",E,R[179],45,[[],[R[15]]]],[11,"start",E,R[256],45,[[["self"]]]],[11,R[180],E,R[257],45,[[["self"],["ast"]],[R[15]]]],[11,R[181],E,R[258],45,[[["self"],["ast"]],[R[15]]]],[11,R[182],E,R[259],45,[[["self"]],[R[15]]]],[11,R[260],E,R[261],45,[[["self"],[R[149]]],[R[15]]]],[11,R[262],E,R[263],45,[[["self"],[R[149]]],[R[15]]]],[11,R[264],E,R[265],45,[[["self"],[R[150]]],[R[15]]]],[11,R[266],E,R[267],45,[[["self"],[R[150]]],[R[15]]]],[11,R[268],E,R[269],45,[[["self"],[R[150]]],[R[15]]]],[11,"kind",E,R[183],46,[[["self"]],[R[104]]]],[11,"pattern",E,R[184],46,[[["self"]],["str"]]],[11,"span",E,R[185],46,[[["self"]],["span"]]],[11,"auxiliary_span",E,"Return an auxiliary span. This span exists only for some…",46,[[["self"]],[["span"],[R[3],["span"]]]]],[11,"new",E,"Create a new span with the given positions.",1,[[[R[151]]],["span"]]],[11,"splat",E,"Create a new span using the given position as the start…",1,[[[R[151]]],["span"]]],[11,"with_start",E,"Create a new span by replacing the starting the position…",1,[[[R[151]]],["span"]]],[11,"with_end",E,"Create a new span by replacing the ending the position…",1,[[[R[151]]],["span"]]],[11,"is_one_line",E,"Returns true if and only if this span occurs on a single…",1,[[["self"]],["bool"]]],[11,R[152],E,"Returns true if and only if this span is empty. That is,…",1,[[["self"]],["bool"]]],[11,"new",E,"Create a new position with the given information.",2,[[["usize"]],[R[151]]]],[11,"span",E,"Return the span of this abstract syntax tree.",24,[[["self"]],["span"]]],[11,R[152],E,"Return true if and only if this Ast is empty.",24,[[["self"]],["bool"]]],[11,"into_ast",E,"Return this alternation as an AST.",5,[[],["ast"]]],[11,"into_ast",E,"Return this concatenation as an AST.",6,[[],["ast"]]],[11,"byte",E,"If this literal was written as a `\\x` hex escape, then…",7,[[["self"]],[[R[3],["u8"]],["u8"]]]],[11,"digits",E,"The number of digits that must be used with this literal…",27,[[["self"]],["u32"]]],[11,"span",E,"Return the span of this character class.",28,[[["self"]],["span"]]],[11,"from_name",E,"Return the corresponding ClassAsciiKind variant for the…",30,[[["str"]],[[R[153]],[R[3],[R[153]]]]]],[11,R[207],E,"Returns true if this class has been negated.",10,[[["self"]],["bool"]]],[11,"is_equal",E,"Whether the op is an equality op or not.",32,[[["self"]],["bool"]]],[11,"union",E,"Build a set from a union.",33,[[[R[236]]],[R[234]]]],[11,"span",E,"Return the span of this character class set.",33,[[["self"]],["span"]]],[11,"span",E,"Return the span of this character class set item.",34,[[["self"]],["span"]]],[11,"is_valid",E,"Returns true if and only if this character class range is…",12,[[["self"]],["bool"]]],[11,"push",E,"Push a new item in this union.",13,[[["self"],[R[149]]]]],[11,"into_item",E,"Return this union as a character class set item.",13,[[],[R[149]]]],[11,"is_valid",E,"Returns true if and only if this repetition range is valid.",38,[[["self"]],["bool"]]],[11,"flags",E,"If this group is non-capturing, then this returns the…",18,[[["self"]],[["flags"],[R[3],["flags"]]]]],[11,"is_capturing",E,"Returns true if and only if this group is capturing.",18,[[["self"]],["bool"]]],[11,"capture_index",E,"Returns the capture index of this group, if this is a…",18,[[["self"]],[["u32"],[R[3],["u32"]]]]],[11,"add_item",E,"Add the given item to this sequence of flags.",21,[[["self"],[R[243]]],[[R[3],["usize"]],["usize"]]]],[11,"flag_state",E,"Returns the state of the given flag in this set.",21,[[["flag"],["self"]],[[R[3],["bool"]],["bool"]]]],[11,"is_negation",E,"Returns true if and only if this item is a negation…",40,[[["self"]],["bool"]]],[0,"hir",R[154],"Defines a high-level intermediate representation for…",N,N],[3,"Error",R[164],"An error that can occur while translating an `Ast` to a…",N,N],[3,"Hir",E,"A high-level intermediate representation (HIR) for a…",N,N],[3,R[155],E,R[157],N,N],[3,R[299],E,"An iterator over all ranges in a Unicode character class.",N,N],[3,R[296],E,"A single range of characters represented by Unicode scalar…",N,N],[3,R[297],E,"A set of characters represented by arbitrary bytes (where…",N,N],[3,R[300],E,"An iterator over all ranges in a byte character class.",N,N],[3,R[298],E,"A single range of characters represented by arbitrary bytes.",N,N],[3,"Group",E,"The high-level intermediate representation for a group.",N,N],[12,"kind",E,"The kind of this group. If it is a capturing group, then…",47,N],[12,"hir",E,"The expression inside the capturing group, which may be…",47,N],[3,R[135],E,"The high-level intermediate representation of a repetition…",N,N],[12,"kind",E,"The kind of this repetition operator.",48,N],[12,"greedy",E,"Whether this repetition operator is greedy or not. A…",48,N],[12,"hir",E,"The expression being repeated.",48,N],[4,R[106],E,"The type of an error that occurred while building an `Hir`.",N,N],[13,"UnicodeNotAllowed",E,"This error occurs when a Unicode feature is used when…",49,N],[13,"InvalidUtf8",E,"This error occurs when translating a pattern that could…",49,N],[13,"UnicodePropertyNotFound",E,"This occurs when an unrecognized Unicode property name…",49,N],[13,"UnicodePropertyValueNotFound",E,"This occurs when an unrecognized Unicode property value…",49,N],[13,"EmptyClassNotAllowed",E,"This occurs when the translator attempts to construct a…",49,N],[4,"HirKind",E,"The kind of an arbitrary `Hir` expression.",N,N],[13,"Empty",E,"The empty regular expression, which matches everything,…",50,N],[13,R[172],E,"A single literal character that matches exactly this…",50,N],[13,"Class",E,"A single character class that matches any of the…",50,N],[13,"Anchor",E,"An anchor assertion. An anchor assertion match always has…",50,N],[13,R[156],E,"A word boundary assertion, which may or may not be Unicode…",50,N],[13,R[135],E,"A repetition operation applied to a child expression.",50,N],[13,"Group",E,"A possibly capturing group, which contains a child…",50,N],[13,"Concat",E,"A concatenation of expressions. A concatenation always has…",50,N],[13,R[137],E,"An alternation of expressions. An alternation always has…",50,N],[4,R[172],E,"The high-level intermediate representation of a literal.",N,N],[13,R[160],E,"A single character represented by a Unicode scalar value.",51,N],[13,"Byte",E,"A single character represented by an arbitrary byte.",51,N],[4,"Class",E,"The high-level intermediate representation of a character…",N,N],[13,R[160],E,R[157],52,N],[13,"Bytes",E,"A set of characters represented by arbitrary bytes (one…",52,N],[4,"Anchor",E,"The high-level intermediate representation for an anchor…",N,N],[13,R[158],E,"Match the beginning of a line or the beginning of text.…",53,N],[13,"EndLine",E,"Match the end of a line or the end of text. Specifically,…",53,N],[13,R[159],E,"Match the beginning of text. Specifically, this matches at…",53,N],[13,"EndText",E,"Match the end of text. Specifically, this matches at the…",53,N],[4,R[156],E,"The high-level intermediate representation for a…",N,N],[13,R[160],E,"Match a Unicode-aware word boundary. That is, this matches…",54,N],[13,"UnicodeNegate",E,"Match a Unicode-aware negation of a word boundary.",54,N],[13,"Ascii",E,"Match an ASCII-only word boundary. That is, this matches a…",54,N],[13,"AsciiNegate",E,"Match an ASCII-only negation of a word boundary.",54,N],[4,R[161],E,"The kind of group.",N,N],[13,R[162],E,"A normal unnamed capturing group.",55,N],[13,R[144],E,"A named capturing group.",55,N],[12,"name","regex_syntax::hir::GroupKind","The name of the group.",55,N],[12,"index",E,"The capture index of the group.",55,N],[13,R[163],R[164],"A non-capturing group.",55,N],[4,R[165],E,R[166],N,N],[13,R[167],E,"Matches a sub-expression zero or one times.",56,N],[13,R[168],E,"Matches a sub-expression zero or more times.",56,N],[13,R[169],E,"Matches a sub-expression one or more times.",56,N],[13,"Range",E,"Matches a sub-expression within a bounded range of times.",56,N],[4,R[170],E,"The kind of a counted repetition operator.",N,N],[13,"Exactly",E,"Matches a sub-expression exactly this many times.",57,N],[13,"AtLeast",E,"Matches a sub-expression at least this many times.",57,N],[13,"Bounded",E,"Matches a sub-expression at least `m` times and at most…",57,N],[5,"visit",E,R[171],N,[[["hir"],["visitor"]],[R[15]]]],[0,R[186],E,"Provides routines for extracting literal prefixes and…",N,N],[3,"Literals",R[225],"A set of literal byte strings extracted from a regular…",N,N],[3,R[172],E,"A single member of a set of literals extracted from a…",N,N],[11,"empty",E,"Returns a new empty set of literals using default limits.",58,[[],[R[173]]]],[11,"prefixes",E,"Returns a set of literal prefixes extracted from the given…",58,[[["hir"]],[R[173]]]],[11,"suffixes",E,"Returns a set of literal suffixes extracted from the given…",58,[[["hir"]],[R[173]]]],[11,"limit_size",E,"Get the approximate size limit (in bytes) of this set.",58,[[["self"]],["usize"]]],[11,"set_limit_size",E,"Set the approximate size limit (in bytes) of this set.",58,[[["self"],["usize"]],[R[173]]]],[11,"limit_class",E,"Get the character class size limit for this set.",58,[[["self"]],["usize"]]],[11,"set_limit_class",E,"Limits the size of character(or byte) classes considered.",58,[[["self"],["usize"]],[R[173]]]],[11,R[173],E,"Returns the set of literals as a slice. Its order is…",58,[[["self"]]]],[11,"min_len",E,"Returns the length of the smallest literal.",58,[[["self"]],[[R[3],["usize"]],["usize"]]]],[11,"all_complete",E,"Returns true if all members in this set are complete.",58,[[["self"]],["bool"]]],[11,"any_complete",E,"Returns true if any member in this set is complete.",58,[[["self"]],["bool"]]],[11,"contains_empty",E,"Returns true if this set contains an empty literal.",58,[[["self"]],["bool"]]],[11,R[152],E,"Returns true if this set is empty or if all of its members…",58,[[["self"]],["bool"]]],[11,"to_empty",E,"Returns a new empty set of literals using this set's limits.",58,[[["self"]],[R[173]]]],[11,"longest_common_prefix",E,"Returns the longest common prefix of all members in this…",58,[[["self"]]]],[11,"longest_common_suffix",E,"Returns the longest common suffix of all members in this…",58,[[["self"]]]],[11,"trim_suffix",E,"Returns a new set of literals with the given number of…",58,[[["self"],["usize"]],[[R[173]],[R[3],[R[173]]]]]],[11,"unambiguous_prefixes",E,"Returns a new set of prefixes of this set of literals that…",58,[[["self"]],[R[173]]]],[11,"unambiguous_suffixes",E,"Returns a new set of suffixes of this set of literals that…",58,[[["self"]],[R[173]]]],[11,"union_prefixes",E,"Unions the prefixes from the given expression to this set.",58,[[["self"],["hir"]],["bool"]]],[11,"union_suffixes",E,"Unions the suffixes from the given expression to this set.",58,[[["self"],["hir"]],["bool"]]],[11,"union",E,"Unions this set with another set.",58,[[["self"],[R[173]]],["bool"]]],[11,"cross_product",E,"Extends this set with another set.",58,[[["self"],[R[173]]],["bool"]]],[11,"cross_add",E,"Extends each literal in this set with the bytes given.",58,[[["self"]],["bool"]]],[11,"add",E,"Adds the given literal to this set.",58,[[["self"],[R[186]]],["bool"]]],[11,"add_char_class",E,"Extends each literal in this set with the character class…",58,[[["self"],[R[191]]],["bool"]]],[11,"add_byte_class",E,"Extends each literal in this set with the byte class given.",58,[[["self"],[R[195]]],["bool"]]],[11,"cut",E,"Cuts every member of this set. When a member is cut, it…",58,[[["self"]]]],[11,"reverse",E,"Reverses all members in place.",58,[[["self"]]]],[11,"clear",E,"Clears this set of all members.",58,[[["self"]]]],[11,"new",E,"Returns a new complete literal with the bytes given.",59,[[["vec",["u8"]],["u8"]],[R[186]]]],[11,"empty",E,"Returns a new complete empty literal.",59,[[],[R[186]]]],[11,"is_cut",E,"Returns true if this literal was \"cut.\"",59,[[["self"]],["bool"]]],[11,"cut",E,"Cuts this literal.",59,[[["self"]]]],[0,"print",R[164],"This module provides a regular expression printer for `Hir`.",N,N],[3,"Printer",R[226],"A printer for a regular expression's high-level…",N,N],[11,"new",E,R[174],60,[[],["printer"]]],[11,"print",E,R[175],60,[[["self"],["hir"],["write"]],[R[15]]]],[0,R[178],R[164],"Defines a translator that converts an `Ast` to an `Hir`.",N,N],[3,R[294],R[227],"A builder for constructing an AST->HIR translator.",N,N],[3,R[295],E,"A translator maps abstract syntax to a high level…",N,N],[11,"new",E,"Create a new translator builder with a default c…",61,[[],[R[176]]]],[11,"build",E,"Build a translator using the current configuration.",61,[[["self"]],[R[177]]]],[11,R[214],E,"When enabled, translation will permit the construction of…",61,[[["self"],["bool"]],[R[176]]]],[11,R[217],E,"Enable or disable the case insensitive flag (`i`) by…",61,[[["self"],["bool"]],[R[176]]]],[11,R[218],E,"Enable or disable the multi-line matching flag (`m`) by…",61,[[["self"],["bool"]],[R[176]]]],[11,R[219],E,"Enable or disable the \"dot matches any character\" flag…",61,[[["self"],["bool"]],[R[176]]]],[11,R[220],E,"Enable or disable the \"swap greed\" flag (`U`) by default.",61,[[["self"],["bool"]],[R[176]]]],[11,R[500],E,R[221],61,[[["self"],["bool"]],[R[176]]]],[11,"new",E,"Create a new translator using the default configuration.",62,[[],[R[177]]]],[11,R[178],E,"Translate the given abstract syntax tree (AST) into a high…",62,[[["self"],["ast"],["str"]],[[R[15],["hir","error"]],["hir"],["error"]]]],[8,"Visitor",R[164],"A trait for visiting the high-level IR (HIR) in depth…",N,N],[16,"Output",E,"The result of visiting an HIR.",63,N],[16,"Err",E,"An error that visiting an HIR might return.",63,N],[10,"finish",E,R[179],63,[[],[R[15]]]],[11,"start",E,R[270],63,[[["self"]]]],[11,R[180],E,R[271],63,[[["self"],["hir"]],[R[15]]]],[11,R[181],E,R[272],63,[[["self"],["hir"]],[R[15]]]],[11,R[182],E,R[273],63,[[["self"]],[R[15]]]],[11,"kind",E,R[183],64,[[["self"]],[R[104]]]],[11,"pattern",E,R[184],64,[[["self"]],["str"]]],[11,"span",E,R[185],64,[[["self"]],["span"]]],[11,"kind",E,"Returns a reference to the underlying HIR kind.",65,[[["self"]],["hirkind"]]],[11,"into_kind",E,"Consumes ownership of this HIR expression and returns its…",65,[[],["hirkind"]]],[11,"empty",E,"Returns an empty HIR expression.",65,[[],["hir"]]],[11,R[186],E,"Creates a literal HIR expression.",65,[[[R[186]]],["hir"]]],[11,"class",E,"Creates a class HIR expression.",65,[[["class"]],["hir"]]],[11,"anchor",E,"Creates an anchor assertion HIR expression.",65,[[["anchor"]],["hir"]]],[11,"word_boundary",E,"Creates a word boundary assertion HIR expression.",65,[[[R[245]]],["hir"]]],[11,R[187],E,"Creates a repetition HIR expression.",65,[[[R[187]]],["hir"]]],[11,"group",E,"Creates a group HIR expression.",65,[[["group"]],["hir"]]],[11,"concat",E,"Returns the concatenation of the given expressions.",65,[[["hir"],["vec",["hir"]]],["hir"]]],[11,R[228],E,"Returns the alternation of the given expressions.",65,[[["hir"],["vec",["hir"]]],["hir"]]],[11,"dot",E,"Build an HIR expression for `.`.",65,[[["bool"]],["hir"]]],[11,"any",E,"Build an HIR expression for `(?s).`.",65,[[["bool"]],["hir"]]],[11,R[190],E,"Return true if and only if this HIR will always match…",65,[[["self"]],["bool"]]],[11,"is_all_assertions",E,"Returns true if and only if this entire HIR expression is…",65,[[["self"]],["bool"]]],[11,"is_anchored_start",E,R[188],65,[[["self"]],["bool"]]],[11,"is_anchored_end",E,R[188],65,[[["self"]],["bool"]]],[11,"is_line_anchored_start",E,R[188],65,[[["self"]],["bool"]]],[11,"is_line_anchored_end",E,R[188],65,[[["self"]],["bool"]]],[11,"is_any_anchored_start",E,R[189],65,[[["self"]],["bool"]]],[11,"is_any_anchored_end",E,R[189],65,[[["self"]],["bool"]]],[11,R[208],E,"Return true if and only if the empty string is part of the…",65,[[["self"]],["bool"]]],[11,"is_literal",E,"Return true if and only if this HIR is a simple literal.…",65,[[["self"]],["bool"]]],[11,"is_alternation_literal",E,"Return true if and only if this HIR is either a simple…",65,[[["self"]],["bool"]]],[11,R[152],E,"Return true if and only if this HIR is the empty regular…",50,[[["self"]],["bool"]]],[11,"has_subexprs",E,"Returns true if and only if this kind has any (including…",50,[[["self"]],["bool"]]],[11,"is_unicode",E,"Returns true if and only if this literal corresponds to a…",51,[[["self"]],["bool"]]],[11,R[192],E,"Apply Unicode simple case folding to this character class,…",52,[[["self"]]]],[11,"negate",E,"Negate this character class in place.",52,[[["self"]]]],[11,R[190],E,"Returns true if and only if this character class will only…",52,[[["self"]],["bool"]]],[11,"new",E,R[194],66,[[["i"]],[R[191]]]],[11,"empty",E,R[196],66,[[],[R[191]]]],[11,"push",E,R[197],66,[[["self"],[R[193]]]]],[11,"iter",E,R[198],66,[[["self"]],["classunicodeiter"]]],[11,"ranges",E,R[199],66,[[["self"]]]],[11,R[192],E,R[200],66,[[["self"]]]],[11,"negate",E,"Negate this character class.",66,[[["self"]]]],[11,"union",E,"Union this character class with the given character class,…",66,[[["self"],[R[191]]]]],[11,R[201],E,"Intersect this character class with the given character…",66,[[["self"],[R[191]]]]],[11,R[202],E,"Subtract the given character class from this character…",66,[[["self"],[R[191]]]]],[11,R[203],E,"Compute the symmetric difference of the given character…",66,[[["self"],[R[191]]]]],[11,"new",E,"Create a new Unicode scalar value range for a character…",67,[[["char"]],[R[193]]]],[11,"start",E,R[205],67,[[["self"]],["char"]]],[11,"end",E,R[206],67,[[["self"]],["char"]]],[11,"new",E,R[194],68,[[["i"]],[R[195]]]],[11,"empty",E,R[196],68,[[],[R[195]]]],[11,"push",E,R[197],68,[[["self"],[R[204]]]]],[11,"iter",E,R[198],68,[[["self"]],["classbytesiter"]]],[11,"ranges",E,R[199],68,[[["self"]]]],[11,R[192],E,R[200],68,[[["self"]]]],[11,"negate",E,"Negate this byte class.",68,[[["self"]]]],[11,"union",E,"Union this byte class with the given byte class, in place.",68,[[["self"],[R[195]]]]],[11,R[201],E,"Intersect this byte class with the given byte class, in…",68,[[["self"],[R[195]]]]],[11,R[202],E,"Subtract the given byte class from this byte class, in…",68,[[["self"],[R[195]]]]],[11,R[203],E,"Compute the symmetric difference of the given byte…",68,[[["self"],[R[195]]]]],[11,"is_all_ascii",E,"Returns true if and only if this character class will…",68,[[["self"]],["bool"]]],[11,"new",E,"Create a new byte range for a character class.",69,[[["u8"]],[R[204]]]],[11,"start",E,R[205],69,[[["self"]],["u8"]]],[11,"end",E,R[206],69,[[["self"]],["u8"]]],[11,R[207],E,"Returns true if and only if this word boundary assertion…",54,[[["self"]],["bool"]]],[11,R[208],E,"Returns true if and only if this repetition operator makes…",48,[[["self"]],["bool"]]],[11,"new",R[154],R[209],70,[[],[R[147]]]],[11,"build",E,R[210],70,[[["self"]],["parser"]]],[11,R[211],E,R[212],70,[[["self"],["u32"]],[R[147]]]],[11,"octal",E,R[213],70,[[["self"],["bool"]],[R[147]]]],[11,R[214],E,"When enabled, the parser will permit the construction of a…",70,[[["self"],["bool"]],[R[147]]]],[11,R[215],E,R[216],70,[[["self"],["bool"]],[R[147]]]],[11,R[217],E,"Enable or disable the case insensitive flag by default.",70,[[["self"],["bool"]],[R[147]]]],[11,R[218],E,"Enable or disable the multi-line matching flag by default.",70,[[["self"],["bool"]],[R[147]]]],[11,R[219],E,"Enable or disable the \"dot matches any character\" flag by…",70,[[["self"],["bool"]],[R[147]]]],[11,R[220],E,"Enable or disable the \"swap greed\" flag by default.",70,[[["self"],["bool"]],[R[147]]]],[11,R[500],E,R[221],70,[[["self"],["bool"]],[R[147]]]],[11,"new",E,R[222],71,[[],["parser"]]],[11,"parse",E,"Parse the regular expression into a high level…",71,[[["self"],["str"]],[[R[15],["hir"]],["hir"]]]],[6,"Result",E,"A type alias for dealing with errors returned by this crate.",N,N],[11,"from",E,E,71,[[[T]],[T]]],[11,R[32],E,E,71,[[["self"]],[T]]],[11,R[33],E,E,71,[[[T],["self"]]]],[11,"into",E,E,71,[[],[U]]],[11,R[12],E,E,71,[[[U]],[R[15]]]],[11,R[13],E,E,71,[[],[R[15]]]],[11,R[14],E,E,71,[[["self"]],[T]]],[11,R[17],E,E,71,[[["self"]],[T]]],[11,R[16],E,E,71,[[["self"]],[R[18]]]],[11,"from",E,E,70,[[[T]],[T]]],[11,R[32],E,E,70,[[["self"]],[T]]],[11,R[33],E,E,70,[[[T],["self"]]]],[11,"into",E,E,70,[[],[U]]],[11,R[12],E,E,70,[[[U]],[R[15]]]],[11,R[13],E,E,70,[[],[R[15]]]],[11,R[14],E,E,70,[[["self"]],[T]]],[11,R[17],E,E,70,[[["self"]],[T]]],[11,R[16],E,E,70,[[["self"]],[R[18]]]],[11,"from",E,E,0,[[[T]],[T]]],[11,R[32],E,E,0,[[["self"]],[T]]],[11,R[33],E,E,0,[[[T],["self"]]]],[11,R[81],E,E,0,[[["self"]],[R[2]]]],[11,"into",E,E,0,[[],[U]]],[11,R[12],E,E,0,[[[U]],[R[15]]]],[11,R[13],E,E,0,[[],[R[15]]]],[11,R[14],E,E,0,[[["self"]],[T]]],[11,R[17],E,E,0,[[["self"]],[T]]],[11,R[16],E,E,0,[[["self"]],[R[18]]]],[11,"from",R[130],E,46,[[[T]],[T]]],[11,R[32],E,E,46,[[["self"]],[T]]],[11,R[33],E,E,46,[[[T],["self"]]]],[11,R[81],E,E,46,[[["self"]],[R[2]]]],[11,"into",E,E,46,[[],[U]]],[11,R[12],E,E,46,[[[U]],[R[15]]]],[11,R[13],E,E,46,[[],[R[15]]]],[11,R[14],E,E,46,[[["self"]],[T]]],[11,R[17],E,E,46,[[["self"]],[T]]],[11,R[16],E,E,46,[[["self"]],[R[18]]]],[11,"from",E,E,1,[[[T]],[T]]],[11,R[32],E,E,1,[[["self"]],[T]]],[11,R[33],E,E,1,[[[T],["self"]]]],[11,"into",E,E,1,[[],[U]]],[11,R[12],E,E,1,[[[U]],[R[15]]]],[11,R[13],E,E,1,[[],[R[15]]]],[11,R[14],E,E,1,[[["self"]],[T]]],[11,R[17],E,E,1,[[["self"]],[T]]],[11,R[16],E,E,1,[[["self"]],[R[18]]]],[11,"from",E,E,2,[[[T]],[T]]],[11,R[32],E,E,2,[[["self"]],[T]]],[11,R[33],E,E,2,[[[T],["self"]]]],[11,"into",E,E,2,[[],[U]]],[11,R[12],E,E,2,[[[U]],[R[15]]]],[11,R[13],E,E,2,[[],[R[15]]]],[11,R[14],E,E,2,[[["self"]],[T]]],[11,R[17],E,E,2,[[["self"]],[T]]],[11,R[16],E,E,2,[[["self"]],[R[18]]]],[11,"from",E,E,3,[[[T]],[T]]],[11,R[32],E,E,3,[[["self"]],[T]]],[11,R[33],E,E,3,[[[T],["self"]]]],[11,"into",E,E,3,[[],[U]]],[11,R[12],E,E,3,[[[U]],[R[15]]]],[11,R[13],E,E,3,[[],[R[15]]]],[11,R[14],E,E,3,[[["self"]],[T]]],[11,R[17],E,E,3,[[["self"]],[T]]],[11,R[16],E,E,3,[[["self"]],[R[18]]]],[11,"from",E,E,4,[[[T]],[T]]],[11,R[32],E,E,4,[[["self"]],[T]]],[11,R[33],E,E,4,[[[T],["self"]]]],[11,"into",E,E,4,[[],[U]]],[11,R[12],E,E,4,[[[U]],[R[15]]]],[11,R[13],E,E,4,[[],[R[15]]]],[11,R[14],E,E,4,[[["self"]],[T]]],[11,R[17],E,E,4,[[["self"]],[T]]],[11,R[16],E,E,4,[[["self"]],[R[18]]]],[11,"from",E,E,5,[[[T]],[T]]],[11,R[32],E,E,5,[[["self"]],[T]]],[11,R[33],E,E,5,[[[T],["self"]]]],[11,"into",E,E,5,[[],[U]]],[11,R[12],E,E,5,[[[U]],[R[15]]]],[11,R[13],E,E,5,[[],[R[15]]]],[11,R[14],E,E,5,[[["self"]],[T]]],[11,R[17],E,E,5,[[["self"]],[T]]],[11,R[16],E,E,5,[[["self"]],[R[18]]]],[11,"from",E,E,6,[[[T]],[T]]],[11,R[32],E,E,6,[[["self"]],[T]]],[11,R[33],E,E,6,[[[T],["self"]]]],[11,"into",E,E,6,[[],[U]]],[11,R[12],E,E,6,[[[U]],[R[15]]]],[11,R[13],E,E,6,[[],[R[15]]]],[11,R[14],E,E,6,[[["self"]],[T]]],[11,R[17],E,E,6,[[["self"]],[T]]],[11,R[16],E,E,6,[[["self"]],[R[18]]]],[11,"from",E,E,7,[[[T]],[T]]],[11,R[32],E,E,7,[[["self"]],[T]]],[11,R[33],E,E,7,[[[T],["self"]]]],[11,"into",E,E,7,[[],[U]]],[11,R[12],E,E,7,[[[U]],[R[15]]]],[11,R[13],E,E,7,[[],[R[15]]]],[11,R[14],E,E,7,[[["self"]],[T]]],[11,R[17],E,E,7,[[["self"]],[T]]],[11,R[16],E,E,7,[[["self"]],[R[18]]]],[11,"from",E,E,8,[[[T]],[T]]],[11,R[32],E,E,8,[[["self"]],[T]]],[11,R[33],E,E,8,[[[T],["self"]]]],[11,"into",E,E,8,[[],[U]]],[11,R[12],E,E,8,[[[U]],[R[15]]]],[11,R[13],E,E,8,[[],[R[15]]]],[11,R[14],E,E,8,[[["self"]],[T]]],[11,R[17],E,E,8,[[["self"]],[T]]],[11,R[16],E,E,8,[[["self"]],[R[18]]]],[11,"from",E,E,9,[[[T]],[T]]],[11,R[32],E,E,9,[[["self"]],[T]]],[11,R[33],E,E,9,[[[T],["self"]]]],[11,"into",E,E,9,[[],[U]]],[11,R[12],E,E,9,[[[U]],[R[15]]]],[11,R[13],E,E,9,[[],[R[15]]]],[11,R[14],E,E,9,[[["self"]],[T]]],[11,R[17],E,E,9,[[["self"]],[T]]],[11,R[16],E,E,9,[[["self"]],[R[18]]]],[11,"from",E,E,10,[[[T]],[T]]],[11,R[32],E,E,10,[[["self"]],[T]]],[11,R[33],E,E,10,[[[T],["self"]]]],[11,"into",E,E,10,[[],[U]]],[11,R[12],E,E,10,[[[U]],[R[15]]]],[11,R[13],E,E,10,[[],[R[15]]]],[11,R[14],E,E,10,[[["self"]],[T]]],[11,R[17],E,E,10,[[["self"]],[T]]],[11,R[16],E,E,10,[[["self"]],[R[18]]]],[11,"from",E,E,11,[[[T]],[T]]],[11,R[32],E,E,11,[[["self"]],[T]]],[11,R[33],E,E,11,[[[T],["self"]]]],[11,"into",E,E,11,[[],[U]]],[11,R[12],E,E,11,[[[U]],[R[15]]]],[11,R[13],E,E,11,[[],[R[15]]]],[11,R[14],E,E,11,[[["self"]],[T]]],[11,R[17],E,E,11,[[["self"]],[T]]],[11,R[16],E,E,11,[[["self"]],[R[18]]]],[11,"from",E,E,12,[[[T]],[T]]],[11,R[32],E,E,12,[[["self"]],[T]]],[11,R[33],E,E,12,[[[T],["self"]]]],[11,"into",E,E,12,[[],[U]]],[11,R[12],E,E,12,[[[U]],[R[15]]]],[11,R[13],E,E,12,[[],[R[15]]]],[11,R[14],E,E,12,[[["self"]],[T]]],[11,R[17],E,E,12,[[["self"]],[T]]],[11,R[16],E,E,12,[[["self"]],[R[18]]]],[11,"from",E,E,13,[[[T]],[T]]],[11,R[32],E,E,13,[[["self"]],[T]]],[11,R[33],E,E,13,[[[T],["self"]]]],[11,"into",E,E,13,[[],[U]]],[11,R[12],E,E,13,[[[U]],[R[15]]]],[11,R[13],E,E,13,[[],[R[15]]]],[11,R[14],E,E,13,[[["self"]],[T]]],[11,R[17],E,E,13,[[["self"]],[T]]],[11,R[16],E,E,13,[[["self"]],[R[18]]]],[11,"from",E,E,14,[[[T]],[T]]],[11,R[32],E,E,14,[[["self"]],[T]]],[11,R[33],E,E,14,[[[T],["self"]]]],[11,"into",E,E,14,[[],[U]]],[11,R[12],E,E,14,[[[U]],[R[15]]]],[11,R[13],E,E,14,[[],[R[15]]]],[11,R[14],E,E,14,[[["self"]],[T]]],[11,R[17],E,E,14,[[["self"]],[T]]],[11,R[16],E,E,14,[[["self"]],[R[18]]]],[11,"from",E,E,15,[[[T]],[T]]],[11,R[32],E,E,15,[[["self"]],[T]]],[11,R[33],E,E,15,[[[T],["self"]]]],[11,"into",E,E,15,[[],[U]]],[11,R[12],E,E,15,[[[U]],[R[15]]]],[11,R[13],E,E,15,[[],[R[15]]]],[11,R[14],E,E,15,[[["self"]],[T]]],[11,R[17],E,E,15,[[["self"]],[T]]],[11,R[16],E,E,15,[[["self"]],[R[18]]]],[11,"from",E,E,16,[[[T]],[T]]],[11,R[32],E,E,16,[[["self"]],[T]]],[11,R[33],E,E,16,[[[T],["self"]]]],[11,"into",E,E,16,[[],[U]]],[11,R[12],E,E,16,[[[U]],[R[15]]]],[11,R[13],E,E,16,[[],[R[15]]]],[11,R[14],E,E,16,[[["self"]],[T]]],[11,R[17],E,E,16,[[["self"]],[T]]],[11,R[16],E,E,16,[[["self"]],[R[18]]]],[11,"from",E,E,17,[[[T]],[T]]],[11,R[32],E,E,17,[[["self"]],[T]]],[11,R[33],E,E,17,[[[T],["self"]]]],[11,"into",E,E,17,[[],[U]]],[11,R[12],E,E,17,[[[U]],[R[15]]]],[11,R[13],E,E,17,[[],[R[15]]]],[11,R[14],E,E,17,[[["self"]],[T]]],[11,R[17],E,E,17,[[["self"]],[T]]],[11,R[16],E,E,17,[[["self"]],[R[18]]]],[11,"from",E,E,18,[[[T]],[T]]],[11,R[32],E,E,18,[[["self"]],[T]]],[11,R[33],E,E,18,[[[T],["self"]]]],[11,"into",E,E,18,[[],[U]]],[11,R[12],E,E,18,[[[U]],[R[15]]]],[11,R[13],E,E,18,[[],[R[15]]]],[11,R[14],E,E,18,[[["self"]],[T]]],[11,R[17],E,E,18,[[["self"]],[T]]],[11,R[16],E,E,18,[[["self"]],[R[18]]]],[11,"from",E,E,19,[[[T]],[T]]],[11,R[32],E,E,19,[[["self"]],[T]]],[11,R[33],E,E,19,[[[T],["self"]]]],[11,"into",E,E,19,[[],[U]]],[11,R[12],E,E,19,[[[U]],[R[15]]]],[11,R[13],E,E,19,[[],[R[15]]]],[11,R[14],E,E,19,[[["self"]],[T]]],[11,R[17],E,E,19,[[["self"]],[T]]],[11,R[16],E,E,19,[[["self"]],[R[18]]]],[11,"from",E,E,20,[[[T]],[T]]],[11,R[32],E,E,20,[[["self"]],[T]]],[11,R[33],E,E,20,[[[T],["self"]]]],[11,"into",E,E,20,[[],[U]]],[11,R[12],E,E,20,[[[U]],[R[15]]]],[11,R[13],E,E,20,[[],[R[15]]]],[11,R[14],E,E,20,[[["self"]],[T]]],[11,R[17],E,E,20,[[["self"]],[T]]],[11,R[16],E,E,20,[[["self"]],[R[18]]]],[11,"from",E,E,21,[[[T]],[T]]],[11,R[32],E,E,21,[[["self"]],[T]]],[11,R[33],E,E,21,[[[T],["self"]]]],[11,"into",E,E,21,[[],[U]]],[11,R[12],E,E,21,[[[U]],[R[15]]]],[11,R[13],E,E,21,[[],[R[15]]]],[11,R[14],E,E,21,[[["self"]],[T]]],[11,R[17],E,E,21,[[["self"]],[T]]],[11,R[16],E,E,21,[[["self"]],[R[18]]]],[11,"from",E,E,22,[[[T]],[T]]],[11,R[32],E,E,22,[[["self"]],[T]]],[11,R[33],E,E,22,[[[T],["self"]]]],[11,"into",E,E,22,[[],[U]]],[11,R[12],E,E,22,[[[U]],[R[15]]]],[11,R[13],E,E,22,[[],[R[15]]]],[11,R[14],E,E,22,[[["self"]],[T]]],[11,R[17],E,E,22,[[["self"]],[T]]],[11,R[16],E,E,22,[[["self"]],[R[18]]]],[11,"from",E,E,23,[[[T]],[T]]],[11,R[32],E,E,23,[[["self"]],[T]]],[11,R[33],E,E,23,[[[T],["self"]]]],[11,R[81],E,E,23,[[["self"]],[R[2]]]],[11,"into",E,E,23,[[],[U]]],[11,R[12],E,E,23,[[[U]],[R[15]]]],[11,R[13],E,E,23,[[],[R[15]]]],[11,R[14],E,E,23,[[["self"]],[T]]],[11,R[17],E,E,23,[[["self"]],[T]]],[11,R[16],E,E,23,[[["self"]],[R[18]]]],[11,"from",E,E,24,[[[T]],[T]]],[11,R[32],E,E,24,[[["self"]],[T]]],[11,R[33],E,E,24,[[[T],["self"]]]],[11,R[81],E,E,24,[[["self"]],[R[2]]]],[11,"into",E,E,24,[[],[U]]],[11,R[12],E,E,24,[[[U]],[R[15]]]],[11,R[13],E,E,24,[[],[R[15]]]],[11,R[14],E,E,24,[[["self"]],[T]]],[11,R[17],E,E,24,[[["self"]],[T]]],[11,R[16],E,E,24,[[["self"]],[R[18]]]],[11,"from",E,E,25,[[[T]],[T]]],[11,R[32],E,E,25,[[["self"]],[T]]],[11,R[33],E,E,25,[[[T],["self"]]]],[11,"into",E,E,25,[[],[U]]],[11,R[12],E,E,25,[[[U]],[R[15]]]],[11,R[13],E,E,25,[[],[R[15]]]],[11,R[14],E,E,25,[[["self"]],[T]]],[11,R[17],E,E,25,[[["self"]],[T]]],[11,R[16],E,E,25,[[["self"]],[R[18]]]],[11,"from",E,E,26,[[[T]],[T]]],[11,R[32],E,E,26,[[["self"]],[T]]],[11,R[33],E,E,26,[[[T],["self"]]]],[11,"into",E,E,26,[[],[U]]],[11,R[12],E,E,26,[[[U]],[R[15]]]],[11,R[13],E,E,26,[[],[R[15]]]],[11,R[14],E,E,26,[[["self"]],[T]]],[11,R[17],E,E,26,[[["self"]],[T]]],[11,R[16],E,E,26,[[["self"]],[R[18]]]],[11,"from",E,E,27,[[[T]],[T]]],[11,R[32],E,E,27,[[["self"]],[T]]],[11,R[33],E,E,27,[[[T],["self"]]]],[11,"into",E,E,27,[[],[U]]],[11,R[12],E,E,27,[[[U]],[R[15]]]],[11,R[13],E,E,27,[[],[R[15]]]],[11,R[14],E,E,27,[[["self"]],[T]]],[11,R[17],E,E,27,[[["self"]],[T]]],[11,R[16],E,E,27,[[["self"]],[R[18]]]],[11,"from",E,E,28,[[[T]],[T]]],[11,R[32],E,E,28,[[["self"]],[T]]],[11,R[33],E,E,28,[[[T],["self"]]]],[11,"into",E,E,28,[[],[U]]],[11,R[12],E,E,28,[[[U]],[R[15]]]],[11,R[13],E,E,28,[[],[R[15]]]],[11,R[14],E,E,28,[[["self"]],[T]]],[11,R[17],E,E,28,[[["self"]],[T]]],[11,R[16],E,E,28,[[["self"]],[R[18]]]],[11,"from",E,E,29,[[[T]],[T]]],[11,R[32],E,E,29,[[["self"]],[T]]],[11,R[33],E,E,29,[[[T],["self"]]]],[11,"into",E,E,29,[[],[U]]],[11,R[12],E,E,29,[[[U]],[R[15]]]],[11,R[13],E,E,29,[[],[R[15]]]],[11,R[14],E,E,29,[[["self"]],[T]]],[11,R[17],E,E,29,[[["self"]],[T]]],[11,R[16],E,E,29,[[["self"]],[R[18]]]],[11,"from",E,E,30,[[[T]],[T]]],[11,R[32],E,E,30,[[["self"]],[T]]],[11,R[33],E,E,30,[[[T],["self"]]]],[11,"into",E,E,30,[[],[U]]],[11,R[12],E,E,30,[[[U]],[R[15]]]],[11,R[13],E,E,30,[[],[R[15]]]],[11,R[14],E,E,30,[[["self"]],[T]]],[11,R[17],E,E,30,[[["self"]],[T]]],[11,R[16],E,E,30,[[["self"]],[R[18]]]],[11,"from",E,E,31,[[[T]],[T]]],[11,R[32],E,E,31,[[["self"]],[T]]],[11,R[33],E,E,31,[[[T],["self"]]]],[11,"into",E,E,31,[[],[U]]],[11,R[12],E,E,31,[[[U]],[R[15]]]],[11,R[13],E,E,31,[[],[R[15]]]],[11,R[14],E,E,31,[[["self"]],[T]]],[11,R[17],E,E,31,[[["self"]],[T]]],[11,R[16],E,E,31,[[["self"]],[R[18]]]],[11,"from",E,E,32,[[[T]],[T]]],[11,R[32],E,E,32,[[["self"]],[T]]],[11,R[33],E,E,32,[[[T],["self"]]]],[11,"into",E,E,32,[[],[U]]],[11,R[12],E,E,32,[[[U]],[R[15]]]],[11,R[13],E,E,32,[[],[R[15]]]],[11,R[14],E,E,32,[[["self"]],[T]]],[11,R[17],E,E,32,[[["self"]],[T]]],[11,R[16],E,E,32,[[["self"]],[R[18]]]],[11,"from",E,E,33,[[[T]],[T]]],[11,R[32],E,E,33,[[["self"]],[T]]],[11,R[33],E,E,33,[[[T],["self"]]]],[11,"into",E,E,33,[[],[U]]],[11,R[12],E,E,33,[[[U]],[R[15]]]],[11,R[13],E,E,33,[[],[R[15]]]],[11,R[14],E,E,33,[[["self"]],[T]]],[11,R[17],E,E,33,[[["self"]],[T]]],[11,R[16],E,E,33,[[["self"]],[R[18]]]],[11,"from",E,E,34,[[[T]],[T]]],[11,R[32],E,E,34,[[["self"]],[T]]],[11,R[33],E,E,34,[[[T],["self"]]]],[11,"into",E,E,34,[[],[U]]],[11,R[12],E,E,34,[[[U]],[R[15]]]],[11,R[13],E,E,34,[[],[R[15]]]],[11,R[14],E,E,34,[[["self"]],[T]]],[11,R[17],E,E,34,[[["self"]],[T]]],[11,R[16],E,E,34,[[["self"]],[R[18]]]],[11,"from",E,E,35,[[[T]],[T]]],[11,R[32],E,E,35,[[["self"]],[T]]],[11,R[33],E,E,35,[[[T],["self"]]]],[11,"into",E,E,35,[[],[U]]],[11,R[12],E,E,35,[[[U]],[R[15]]]],[11,R[13],E,E,35,[[],[R[15]]]],[11,R[14],E,E,35,[[["self"]],[T]]],[11,R[17],E,E,35,[[["self"]],[T]]],[11,R[16],E,E,35,[[["self"]],[R[18]]]],[11,"from",E,E,36,[[[T]],[T]]],[11,R[32],E,E,36,[[["self"]],[T]]],[11,R[33],E,E,36,[[[T],["self"]]]],[11,"into",E,E,36,[[],[U]]],[11,R[12],E,E,36,[[[U]],[R[15]]]],[11,R[13],E,E,36,[[],[R[15]]]],[11,R[14],E,E,36,[[["self"]],[T]]],[11,R[17],E,E,36,[[["self"]],[T]]],[11,R[16],E,E,36,[[["self"]],[R[18]]]],[11,"from",E,E,37,[[[T]],[T]]],[11,R[32],E,E,37,[[["self"]],[T]]],[11,R[33],E,E,37,[[[T],["self"]]]],[11,"into",E,E,37,[[],[U]]],[11,R[12],E,E,37,[[[U]],[R[15]]]],[11,R[13],E,E,37,[[],[R[15]]]],[11,R[14],E,E,37,[[["self"]],[T]]],[11,R[17],E,E,37,[[["self"]],[T]]],[11,R[16],E,E,37,[[["self"]],[R[18]]]],[11,"from",E,E,38,[[[T]],[T]]],[11,R[32],E,E,38,[[["self"]],[T]]],[11,R[33],E,E,38,[[[T],["self"]]]],[11,"into",E,E,38,[[],[U]]],[11,R[12],E,E,38,[[[U]],[R[15]]]],[11,R[13],E,E,38,[[],[R[15]]]],[11,R[14],E,E,38,[[["self"]],[T]]],[11,R[17],E,E,38,[[["self"]],[T]]],[11,R[16],E,E,38,[[["self"]],[R[18]]]],[11,"from",E,E,39,[[[T]],[T]]],[11,R[32],E,E,39,[[["self"]],[T]]],[11,R[33],E,E,39,[[[T],["self"]]]],[11,"into",E,E,39,[[],[U]]],[11,R[12],E,E,39,[[[U]],[R[15]]]],[11,R[13],E,E,39,[[],[R[15]]]],[11,R[14],E,E,39,[[["self"]],[T]]],[11,R[17],E,E,39,[[["self"]],[T]]],[11,R[16],E,E,39,[[["self"]],[R[18]]]],[11,"from",E,E,40,[[[T]],[T]]],[11,R[32],E,E,40,[[["self"]],[T]]],[11,R[33],E,E,40,[[[T],["self"]]]],[11,"into",E,E,40,[[],[U]]],[11,R[12],E,E,40,[[[U]],[R[15]]]],[11,R[13],E,E,40,[[],[R[15]]]],[11,R[14],E,E,40,[[["self"]],[T]]],[11,R[17],E,E,40,[[["self"]],[T]]],[11,R[16],E,E,40,[[["self"]],[R[18]]]],[11,"from",E,E,41,[[[T]],[T]]],[11,R[32],E,E,41,[[["self"]],[T]]],[11,R[33],E,E,41,[[[T],["self"]]]],[11,"into",E,E,41,[[],[U]]],[11,R[12],E,E,41,[[[U]],[R[15]]]],[11,R[13],E,E,41,[[],[R[15]]]],[11,R[14],E,E,41,[[["self"]],[T]]],[11,R[17],E,E,41,[[["self"]],[T]]],[11,R[16],E,E,41,[[["self"]],[R[18]]]],[11,"from",R[223],E,42,[[[T]],[T]]],[11,R[32],E,E,42,[[["self"]],[T]]],[11,R[33],E,E,42,[[[T],["self"]]]],[11,"into",E,E,42,[[],[U]]],[11,R[12],E,E,42,[[[U]],[R[15]]]],[11,R[13],E,E,42,[[],[R[15]]]],[11,R[14],E,E,42,[[["self"]],[T]]],[11,R[17],E,E,42,[[["self"]],[T]]],[11,R[16],E,E,42,[[["self"]],[R[18]]]],[11,"from",E,E,43,[[[T]],[T]]],[11,R[32],E,E,43,[[["self"]],[T]]],[11,R[33],E,E,43,[[[T],["self"]]]],[11,"into",E,E,43,[[],[U]]],[11,R[12],E,E,43,[[[U]],[R[15]]]],[11,R[13],E,E,43,[[],[R[15]]]],[11,R[14],E,E,43,[[["self"]],[T]]],[11,R[17],E,E,43,[[["self"]],[T]]],[11,R[16],E,E,43,[[["self"]],[R[18]]]],[11,"from",R[224],E,44,[[[T]],[T]]],[11,"into",E,E,44,[[],[U]]],[11,R[12],E,E,44,[[[U]],[R[15]]]],[11,R[13],E,E,44,[[],[R[15]]]],[11,R[14],E,E,44,[[["self"]],[T]]],[11,R[17],E,E,44,[[["self"]],[T]]],[11,R[16],E,E,44,[[["self"]],[R[18]]]],[11,"from",R[164],E,64,[[[T]],[T]]],[11,R[32],E,E,64,[[["self"]],[T]]],[11,R[33],E,E,64,[[[T],["self"]]]],[11,R[81],E,E,64,[[["self"]],[R[2]]]],[11,"into",E,E,64,[[],[U]]],[11,R[12],E,E,64,[[[U]],[R[15]]]],[11,R[13],E,E,64,[[],[R[15]]]],[11,R[14],E,E,64,[[["self"]],[T]]],[11,R[17],E,E,64,[[["self"]],[T]]],[11,R[16],E,E,64,[[["self"]],[R[18]]]],[11,"from",E,E,65,[[[T]],[T]]],[11,R[32],E,E,65,[[["self"]],[T]]],[11,R[33],E,E,65,[[[T],["self"]]]],[11,R[81],E,E,65,[[["self"]],[R[2]]]],[11,"into",E,E,65,[[],[U]]],[11,R[12],E,E,65,[[[U]],[R[15]]]],[11,R[13],E,E,65,[[],[R[15]]]],[11,R[14],E,E,65,[[["self"]],[T]]],[11,R[17],E,E,65,[[["self"]],[T]]],[11,R[16],E,E,65,[[["self"]],[R[18]]]],[11,"from",E,E,66,[[[T]],[T]]],[11,R[32],E,E,66,[[["self"]],[T]]],[11,R[33],E,E,66,[[[T],["self"]]]],[11,"into",E,E,66,[[],[U]]],[11,R[12],E,E,66,[[[U]],[R[15]]]],[11,R[13],E,E,66,[[],[R[15]]]],[11,R[14],E,E,66,[[["self"]],[T]]],[11,R[17],E,E,66,[[["self"]],[T]]],[11,R[16],E,E,66,[[["self"]],[R[18]]]],[11,"from",E,E,72,[[[T]],[T]]],[11,R[50],E,E,72,[[],["i"]]],[11,"into",E,E,72,[[],[U]]],[11,R[12],E,E,72,[[[U]],[R[15]]]],[11,R[13],E,E,72,[[],[R[15]]]],[11,R[14],E,E,72,[[["self"]],[T]]],[11,R[17],E,E,72,[[["self"]],[T]]],[11,R[16],E,E,72,[[["self"]],[R[18]]]],[11,"from",E,E,67,[[[T]],[T]]],[11,R[32],E,E,67,[[["self"]],[T]]],[11,R[33],E,E,67,[[[T],["self"]]]],[11,"into",E,E,67,[[],[U]]],[11,R[12],E,E,67,[[[U]],[R[15]]]],[11,R[13],E,E,67,[[],[R[15]]]],[11,R[14],E,E,67,[[["self"]],[T]]],[11,R[17],E,E,67,[[["self"]],[T]]],[11,R[16],E,E,67,[[["self"]],[R[18]]]],[11,"from",E,E,68,[[[T]],[T]]],[11,R[32],E,E,68,[[["self"]],[T]]],[11,R[33],E,E,68,[[[T],["self"]]]],[11,"into",E,E,68,[[],[U]]],[11,R[12],E,E,68,[[[U]],[R[15]]]],[11,R[13],E,E,68,[[],[R[15]]]],[11,R[14],E,E,68,[[["self"]],[T]]],[11,R[17],E,E,68,[[["self"]],[T]]],[11,R[16],E,E,68,[[["self"]],[R[18]]]],[11,"from",E,E,73,[[[T]],[T]]],[11,R[50],E,E,73,[[],["i"]]],[11,"into",E,E,73,[[],[U]]],[11,R[12],E,E,73,[[[U]],[R[15]]]],[11,R[13],E,E,73,[[],[R[15]]]],[11,R[14],E,E,73,[[["self"]],[T]]],[11,R[17],E,E,73,[[["self"]],[T]]],[11,R[16],E,E,73,[[["self"]],[R[18]]]],[11,"from",E,E,69,[[[T]],[T]]],[11,R[32],E,E,69,[[["self"]],[T]]],[11,R[33],E,E,69,[[[T],["self"]]]],[11,"into",E,E,69,[[],[U]]],[11,R[12],E,E,69,[[[U]],[R[15]]]],[11,R[13],E,E,69,[[],[R[15]]]],[11,R[14],E,E,69,[[["self"]],[T]]],[11,R[17],E,E,69,[[["self"]],[T]]],[11,R[16],E,E,69,[[["self"]],[R[18]]]],[11,"from",E,E,47,[[[T]],[T]]],[11,R[32],E,E,47,[[["self"]],[T]]],[11,R[33],E,E,47,[[[T],["self"]]]],[11,"into",E,E,47,[[],[U]]],[11,R[12],E,E,47,[[[U]],[R[15]]]],[11,R[13],E,E,47,[[],[R[15]]]],[11,R[14],E,E,47,[[["self"]],[T]]],[11,R[17],E,E,47,[[["self"]],[T]]],[11,R[16],E,E,47,[[["self"]],[R[18]]]],[11,"from",E,E,48,[[[T]],[T]]],[11,R[32],E,E,48,[[["self"]],[T]]],[11,R[33],E,E,48,[[[T],["self"]]]],[11,"into",E,E,48,[[],[U]]],[11,R[12],E,E,48,[[[U]],[R[15]]]],[11,R[13],E,E,48,[[],[R[15]]]],[11,R[14],E,E,48,[[["self"]],[T]]],[11,R[17],E,E,48,[[["self"]],[T]]],[11,R[16],E,E,48,[[["self"]],[R[18]]]],[11,"from",E,E,49,[[[T]],[T]]],[11,R[32],E,E,49,[[["self"]],[T]]],[11,R[33],E,E,49,[[[T],["self"]]]],[11,R[81],E,E,49,[[["self"]],[R[2]]]],[11,"into",E,E,49,[[],[U]]],[11,R[12],E,E,49,[[[U]],[R[15]]]],[11,R[13],E,E,49,[[],[R[15]]]],[11,R[14],E,E,49,[[["self"]],[T]]],[11,R[17],E,E,49,[[["self"]],[T]]],[11,R[16],E,E,49,[[["self"]],[R[18]]]],[11,"from",E,E,50,[[[T]],[T]]],[11,R[32],E,E,50,[[["self"]],[T]]],[11,R[33],E,E,50,[[[T],["self"]]]],[11,"into",E,E,50,[[],[U]]],[11,R[12],E,E,50,[[[U]],[R[15]]]],[11,R[13],E,E,50,[[],[R[15]]]],[11,R[14],E,E,50,[[["self"]],[T]]],[11,R[17],E,E,50,[[["self"]],[T]]],[11,R[16],E,E,50,[[["self"]],[R[18]]]],[11,"from",E,E,51,[[[T]],[T]]],[11,R[32],E,E,51,[[["self"]],[T]]],[11,R[33],E,E,51,[[[T],["self"]]]],[11,"into",E,E,51,[[],[U]]],[11,R[12],E,E,51,[[[U]],[R[15]]]],[11,R[13],E,E,51,[[],[R[15]]]],[11,R[14],E,E,51,[[["self"]],[T]]],[11,R[17],E,E,51,[[["self"]],[T]]],[11,R[16],E,E,51,[[["self"]],[R[18]]]],[11,"from",E,E,52,[[[T]],[T]]],[11,R[32],E,E,52,[[["self"]],[T]]],[11,R[33],E,E,52,[[[T],["self"]]]],[11,"into",E,E,52,[[],[U]]],[11,R[12],E,E,52,[[[U]],[R[15]]]],[11,R[13],E,E,52,[[],[R[15]]]],[11,R[14],E,E,52,[[["self"]],[T]]],[11,R[17],E,E,52,[[["self"]],[T]]],[11,R[16],E,E,52,[[["self"]],[R[18]]]],[11,"from",E,E,53,[[[T]],[T]]],[11,R[32],E,E,53,[[["self"]],[T]]],[11,R[33],E,E,53,[[[T],["self"]]]],[11,"into",E,E,53,[[],[U]]],[11,R[12],E,E,53,[[[U]],[R[15]]]],[11,R[13],E,E,53,[[],[R[15]]]],[11,R[14],E,E,53,[[["self"]],[T]]],[11,R[17],E,E,53,[[["self"]],[T]]],[11,R[16],E,E,53,[[["self"]],[R[18]]]],[11,"from",E,E,54,[[[T]],[T]]],[11,R[32],E,E,54,[[["self"]],[T]]],[11,R[33],E,E,54,[[[T],["self"]]]],[11,"into",E,E,54,[[],[U]]],[11,R[12],E,E,54,[[[U]],[R[15]]]],[11,R[13],E,E,54,[[],[R[15]]]],[11,R[14],E,E,54,[[["self"]],[T]]],[11,R[17],E,E,54,[[["self"]],[T]]],[11,R[16],E,E,54,[[["self"]],[R[18]]]],[11,"from",E,E,55,[[[T]],[T]]],[11,R[32],E,E,55,[[["self"]],[T]]],[11,R[33],E,E,55,[[[T],["self"]]]],[11,"into",E,E,55,[[],[U]]],[11,R[12],E,E,55,[[[U]],[R[15]]]],[11,R[13],E,E,55,[[],[R[15]]]],[11,R[14],E,E,55,[[["self"]],[T]]],[11,R[17],E,E,55,[[["self"]],[T]]],[11,R[16],E,E,55,[[["self"]],[R[18]]]],[11,"from",E,E,56,[[[T]],[T]]],[11,R[32],E,E,56,[[["self"]],[T]]],[11,R[33],E,E,56,[[[T],["self"]]]],[11,"into",E,E,56,[[],[U]]],[11,R[12],E,E,56,[[[U]],[R[15]]]],[11,R[13],E,E,56,[[],[R[15]]]],[11,R[14],E,E,56,[[["self"]],[T]]],[11,R[17],E,E,56,[[["self"]],[T]]],[11,R[16],E,E,56,[[["self"]],[R[18]]]],[11,"from",E,E,57,[[[T]],[T]]],[11,R[32],E,E,57,[[["self"]],[T]]],[11,R[33],E,E,57,[[[T],["self"]]]],[11,"into",E,E,57,[[],[U]]],[11,R[12],E,E,57,[[[U]],[R[15]]]],[11,R[13],E,E,57,[[],[R[15]]]],[11,R[14],E,E,57,[[["self"]],[T]]],[11,R[17],E,E,57,[[["self"]],[T]]],[11,R[16],E,E,57,[[["self"]],[R[18]]]],[11,"from",R[225],E,58,[[[T]],[T]]],[11,R[32],E,E,58,[[["self"]],[T]]],[11,R[33],E,E,58,[[[T],["self"]]]],[11,"into",E,E,58,[[],[U]]],[11,R[12],E,E,58,[[[U]],[R[15]]]],[11,R[13],E,E,58,[[],[R[15]]]],[11,R[14],E,E,58,[[["self"]],[T]]],[11,R[17],E,E,58,[[["self"]],[T]]],[11,R[16],E,E,58,[[["self"]],[R[18]]]],[11,"from",E,E,59,[[[T]],[T]]],[11,R[32],E,E,59,[[["self"]],[T]]],[11,R[33],E,E,59,[[[T],["self"]]]],[11,"into",E,E,59,[[],[U]]],[11,R[12],E,E,59,[[[U]],[R[15]]]],[11,R[13],E,E,59,[[],[R[15]]]],[11,R[14],E,E,59,[[["self"]],[T]]],[11,R[17],E,E,59,[[["self"]],[T]]],[11,R[16],E,E,59,[[["self"]],[R[18]]]],[11,"from",R[226],E,60,[[[T]],[T]]],[11,"into",E,E,60,[[],[U]]],[11,R[12],E,E,60,[[[U]],[R[15]]]],[11,R[13],E,E,60,[[],[R[15]]]],[11,R[14],E,E,60,[[["self"]],[T]]],[11,R[17],E,E,60,[[["self"]],[T]]],[11,R[16],E,E,60,[[["self"]],[R[18]]]],[11,"from",R[227],E,61,[[[T]],[T]]],[11,R[32],E,E,61,[[["self"]],[T]]],[11,R[33],E,E,61,[[[T],["self"]]]],[11,"into",E,E,61,[[],[U]]],[11,R[12],E,E,61,[[[U]],[R[15]]]],[11,R[13],E,E,61,[[],[R[15]]]],[11,R[14],E,E,61,[[["self"]],[T]]],[11,R[17],E,E,61,[[["self"]],[T]]],[11,R[16],E,E,61,[[["self"]],[R[18]]]],[11,"from",E,E,62,[[[T]],[T]]],[11,R[32],E,E,62,[[["self"]],[T]]],[11,R[33],E,E,62,[[[T],["self"]]]],[11,"into",E,E,62,[[],[U]]],[11,R[12],E,E,62,[[[U]],[R[15]]]],[11,R[13],E,E,62,[[],[R[15]]]],[11,R[14],E,E,62,[[["self"]],[T]]],[11,R[17],E,E,62,[[["self"]],[T]]],[11,R[16],E,E,62,[[["self"]],[R[18]]]],[11,"next",R[164],E,72,[[["self"]],[[R[193]],[R[3],[R[193]]]]]],[11,"next",E,E,73,[[["self"]],[[R[3],[R[204]]],[R[204]]]]],[11,"eq",R[130],E,46,[[["error"],["self"]],["bool"]]],[11,"ne",E,E,46,[[["error"],["self"]],["bool"]]],[11,"eq",E,E,23,[[["self"],[R[104]]],["bool"]]],[11,"ne",E,E,23,[[["self"],[R[104]]],["bool"]]],[11,"eq",E,E,1,[[["self"],["span"]],["bool"]]],[11,"ne",E,E,1,[[["self"],["span"]],["bool"]]],[11,"eq",E,E,2,[[["self"],[R[151]]],["bool"]]],[11,"ne",E,E,2,[[["self"],[R[151]]],["bool"]]],[11,"eq",E,E,3,[[["self"],[R[148]]],["bool"]]],[11,"ne",E,E,3,[[["self"],[R[148]]],["bool"]]],[11,"eq",E,E,4,[[["self"],["comment"]],["bool"]]],[11,"ne",E,E,4,[[["self"],["comment"]],["bool"]]],[11,"eq",E,E,24,[[["ast"],["self"]],["bool"]]],[11,"ne",E,E,24,[[["ast"],["self"]],["bool"]]],[11,"eq",E,E,5,[[["self"],[R[228]]],["bool"]]],[11,"ne",E,E,5,[[["self"],[R[228]]],["bool"]]],[11,"eq",E,E,6,[[["self"],["concat"]],["bool"]]],[11,"ne",E,E,6,[[["self"],["concat"]],["bool"]]],[11,"eq",E,E,7,[[["self"],[R[186]]],["bool"]]],[11,"ne",E,E,7,[[["self"],[R[186]]],["bool"]]],[11,"eq",E,E,25,[[["self"],[R[229]]],["bool"]]],[11,"ne",E,E,25,[[["self"],[R[229]]],["bool"]]],[11,"eq",E,E,26,[[["self"],[R[246]]],["bool"]]],[11,"eq",E,E,27,[[[R[247]],["self"]],["bool"]]],[11,"eq",E,E,28,[[["class"],["self"]],["bool"]]],[11,"ne",E,E,28,[[["class"],["self"]],["bool"]]],[11,"eq",E,E,8,[[["self"],[R[230]]],["bool"]]],[11,"ne",E,E,8,[[["self"],[R[230]]],["bool"]]],[11,"eq",E,E,29,[[["self"],[R[248]]],["bool"]]],[11,"eq",E,E,9,[[[R[231]],["self"]],["bool"]]],[11,"ne",E,E,9,[[[R[231]],["self"]],["bool"]]],[11,"eq",E,E,30,[[["self"],[R[153]]],["bool"]]],[11,"eq",E,E,10,[[["self"],[R[191]]],["bool"]]],[11,"ne",E,E,10,[[["self"],[R[191]]],["bool"]]],[11,"eq",E,E,31,[[["self"],[R[232]]],["bool"]]],[11,"ne",E,E,31,[[["self"],[R[232]]],["bool"]]],[11,"eq",E,E,32,[[["self"],[R[249]]],["bool"]]],[11,"eq",E,E,11,[[["self"],[R[233]]],["bool"]]],[11,"ne",E,E,11,[[["self"],[R[233]]],["bool"]]],[11,"eq",E,E,33,[[["self"],[R[234]]],["bool"]]],[11,"ne",E,E,33,[[["self"],[R[234]]],["bool"]]],[11,"eq",E,E,34,[[["self"],[R[149]]],["bool"]]],[11,"ne",E,E,34,[[["self"],[R[149]]],["bool"]]],[11,"eq",E,E,12,[[["self"],[R[235]]],["bool"]]],[11,"ne",E,E,12,[[["self"],[R[235]]],["bool"]]],[11,"eq",E,E,13,[[[R[236]],["self"]],["bool"]]],[11,"ne",E,E,13,[[[R[236]],["self"]],["bool"]]],[11,"eq",E,E,14,[[["self"],[R[150]]],["bool"]]],[11,"ne",E,E,14,[[["self"],[R[150]]],["bool"]]],[11,"eq",E,E,35,[[["self"],[R[250]]],["bool"]]],[11,"eq",E,E,15,[[["self"],[R[237]]],["bool"]]],[11,"ne",E,E,15,[[["self"],[R[237]]],["bool"]]],[11,"eq",E,E,36,[[["self"],[R[251]]],["bool"]]],[11,"eq",E,E,16,[[["self"],[R[187]]],["bool"]]],[11,"ne",E,E,16,[[["self"],[R[187]]],["bool"]]],[11,"eq",E,E,17,[[[R[238]],["self"]],["bool"]]],[11,"ne",E,E,17,[[[R[238]],["self"]],["bool"]]],[11,"eq",E,E,37,[[["self"],[R[239]]],["bool"]]],[11,"ne",E,E,37,[[["self"],[R[239]]],["bool"]]],[11,"eq",E,E,38,[[[R[240]],["self"]],["bool"]]],[11,"ne",E,E,38,[[[R[240]],["self"]],["bool"]]],[11,"eq",E,E,18,[[["group"],["self"]],["bool"]]],[11,"ne",E,E,18,[[["group"],["self"]],["bool"]]],[11,"eq",E,E,39,[[["self"],[R[241]]],["bool"]]],[11,"ne",E,E,39,[[["self"],[R[241]]],["bool"]]],[11,"eq",E,E,19,[[[R[242]],["self"]],["bool"]]],[11,"ne",E,E,19,[[[R[242]],["self"]],["bool"]]],[11,"eq",E,E,20,[[["self"],[R[252]]],["bool"]]],[11,"ne",E,E,20,[[["self"],[R[252]]],["bool"]]],[11,"eq",E,E,21,[[["flags"],["self"]],["bool"]]],[11,"ne",E,E,21,[[["flags"],["self"]],["bool"]]],[11,"eq",E,E,22,[[["self"],[R[243]]],["bool"]]],[11,"ne",E,E,22,[[["self"],[R[243]]],["bool"]]],[11,"eq",E,E,40,[[["self"],[R[244]]],["bool"]]],[11,"ne",E,E,40,[[["self"],[R[244]]],["bool"]]],[11,"eq",E,E,41,[[["self"],["flag"]],["bool"]]],[11,"eq",R[154],E,0,[[["self"],["error"]],["bool"]]],[11,"ne",E,E,0,[[["self"],["error"]],["bool"]]],[11,"eq",R[225],E,58,[[["self"],[R[173]]],["bool"]]],[11,"ne",E,E,58,[[["self"],[R[173]]],["bool"]]],[11,"eq",E,E,59,[[[R[186]],["self"]],["bool"]]],[11,"eq",R[164],E,64,[[["self"],["error"]],["bool"]]],[11,"ne",E,E,64,[[["self"],["error"]],["bool"]]],[11,"eq",E,E,49,[[[R[104]],["self"]],["bool"]]],[11,"eq",E,E,65,[[["self"],["hir"]],["bool"]]],[11,"ne",E,E,65,[[["self"],["hir"]],["bool"]]],[11,"eq",E,E,50,[[["self"],["hirkind"]],["bool"]]],[11,"ne",E,E,50,[[["self"],["hirkind"]],["bool"]]],[11,"eq",E,E,51,[[["self"],[R[186]]],["bool"]]],[11,"ne",E,E,51,[[["self"],[R[186]]],["bool"]]],[11,"eq",E,E,52,[[["class"],["self"]],["bool"]]],[11,"ne",E,E,52,[[["class"],["self"]],["bool"]]],[11,"eq",E,E,66,[[["self"],[R[191]]],["bool"]]],[11,"ne",E,E,66,[[["self"],[R[191]]],["bool"]]],[11,"eq",E,E,67,[[["self"],[R[193]]],["bool"]]],[11,"ne",E,E,67,[[["self"],[R[193]]],["bool"]]],[11,"eq",E,E,68,[[["self"],[R[195]]],["bool"]]],[11,"ne",E,E,68,[[["self"],[R[195]]],["bool"]]],[11,"eq",E,E,69,[[["self"],[R[204]]],["bool"]]],[11,"ne",E,E,69,[[["self"],[R[204]]],["bool"]]],[11,"eq",E,E,53,[[["self"],["anchor"]],["bool"]]],[11,"eq",E,E,54,[[["self"],[R[245]]],["bool"]]],[11,"eq",E,E,47,[[["self"],["group"]],["bool"]]],[11,"ne",E,E,47,[[["self"],["group"]],["bool"]]],[11,"eq",E,E,55,[[["self"],[R[241]]],["bool"]]],[11,"ne",E,E,55,[[["self"],[R[241]]],["bool"]]],[11,"eq",E,E,48,[[[R[187]],["self"]],["bool"]]],[11,"ne",E,E,48,[[[R[187]],["self"]],["bool"]]],[11,"eq",E,E,56,[[[R[239]],["self"]],["bool"]]],[11,"ne",E,E,56,[[[R[239]],["self"]],["bool"]]],[11,"eq",E,E,57,[[[R[240]],["self"]],["bool"]]],[11,"ne",E,E,57,[[[R[240]],["self"]],["bool"]]],[11,"as_ref",R[225],E,59,[[["self"]]]],[11,"from",R[154],E,0,[[["error"]],["error"]]],[11,"from",E,E,0,[[["error"]],["error"]]],[11,"clone",R[223],E,42,[[["self"]],[R[147]]]],[11,"clone",E,E,43,[[["self"]],["parser"]]],[11,"clone",R[130],E,46,[[["self"]],["error"]]],[11,"clone",E,E,23,[[["self"]],[R[104]]]],[11,"clone",E,E,1,[[["self"]],["span"]]],[11,"clone",E,E,2,[[["self"]],[R[151]]]],[11,"clone",E,E,3,[[["self"]],[R[148]]]],[11,"clone",E,E,4,[[["self"]],["comment"]]],[11,"clone",E,E,24,[[["self"]],["ast"]]],[11,"clone",E,E,5,[[["self"]],[R[228]]]],[11,"clone",E,E,6,[[["self"]],["concat"]]],[11,"clone",E,E,7,[[["self"]],[R[186]]]],[11,"clone",E,E,25,[[["self"]],[R[229]]]],[11,"clone",E,E,26,[[["self"]],[R[246]]]],[11,"clone",E,E,27,[[["self"]],[R[247]]]],[11,"clone",E,E,28,[[["self"]],["class"]]],[11,"clone",E,E,8,[[["self"]],[R[230]]]],[11,"clone",E,E,29,[[["self"]],[R[248]]]],[11,"clone",E,E,9,[[["self"]],[R[231]]]],[11,"clone",E,E,30,[[["self"]],[R[153]]]],[11,"clone",E,E,10,[[["self"]],[R[191]]]],[11,"clone",E,E,31,[[["self"]],[R[232]]]],[11,"clone",E,E,32,[[["self"]],[R[249]]]],[11,"clone",E,E,11,[[["self"]],[R[233]]]],[11,"clone",E,E,33,[[["self"]],[R[234]]]],[11,"clone",E,E,34,[[["self"]],[R[149]]]],[11,"clone",E,E,12,[[["self"]],[R[235]]]],[11,"clone",E,E,13,[[["self"]],[R[236]]]],[11,"clone",E,E,14,[[["self"]],[R[150]]]],[11,"clone",E,E,35,[[["self"]],[R[250]]]],[11,"clone",E,E,15,[[["self"]],[R[237]]]],[11,"clone",E,E,36,[[["self"]],[R[251]]]],[11,"clone",E,E,16,[[["self"]],[R[187]]]],[11,"clone",E,E,17,[[["self"]],[R[238]]]],[11,"clone",E,E,37,[[["self"]],[R[239]]]],[11,"clone",E,E,38,[[["self"]],[R[240]]]],[11,"clone",E,E,18,[[["self"]],["group"]]],[11,"clone",E,E,39,[[["self"]],[R[241]]]],[11,"clone",E,E,19,[[["self"]],[R[242]]]],[11,"clone",E,E,20,[[["self"]],[R[252]]]],[11,"clone",E,E,21,[[["self"]],["flags"]]],[11,"clone",E,E,22,[[["self"]],[R[243]]]],[11,"clone",E,E,40,[[["self"]],[R[244]]]],[11,"clone",E,E,41,[[["self"]],["flag"]]],[11,"clone",R[154],E,0,[[["self"]],["error"]]],[11,"clone",R[225],E,58,[[["self"]],[R[173]]]],[11,"clone",E,E,59,[[["self"]],[R[186]]]],[11,"clone",R[227],E,61,[[["self"]],[R[176]]]],[11,"clone",E,E,62,[[["self"]],[R[177]]]],[11,"clone",R[164],E,64,[[["self"]],["error"]]],[11,"clone",E,E,49,[[["self"]],[R[104]]]],[11,"clone",E,E,65,[[["self"]],["hir"]]],[11,"clone",E,E,50,[[["self"]],["hirkind"]]],[11,"clone",E,E,51,[[["self"]],[R[186]]]],[11,"clone",E,E,52,[[["self"]],["class"]]],[11,"clone",E,E,66,[[["self"]],[R[191]]]],[11,"clone",E,E,67,[[["self"]],[R[193]]]],[11,"clone",E,E,68,[[["self"]],[R[195]]]],[11,"clone",E,E,69,[[["self"]],[R[204]]]],[11,"clone",E,E,53,[[["self"]],["anchor"]]],[11,"clone",E,E,54,[[["self"]],[R[245]]]],[11,"clone",E,E,47,[[["self"]],["group"]]],[11,"clone",E,E,55,[[["self"]],[R[241]]]],[11,"clone",E,E,48,[[["self"]],[R[187]]]],[11,"clone",E,E,56,[[["self"]],[R[239]]]],[11,"clone",E,E,57,[[["self"]],[R[240]]]],[11,"clone",R[154],E,70,[[["self"]],[R[147]]]],[11,"clone",E,E,71,[[["self"]],["parser"]]],[11,"cmp",R[130],E,1,[[["self"],["span"]],[R[253]]]],[11,"cmp",E,E,2,[[["self"],[R[151]]],[R[253]]]],[11,"cmp",R[225],E,59,[[[R[186]],["self"]],[R[253]]]],[11,"cmp",R[164],E,67,[[["self"],[R[193]]],[R[253]]]],[11,"cmp",E,E,69,[[["self"],[R[204]]],[R[253]]]],[11,R[23],R[223],E,42,[[],[R[147]]]],[11,R[23],R[227],E,61,[[],[R[176]]]],[11,R[23],R[164],E,67,[[],[R[193]]]],[11,R[23],E,E,69,[[],[R[204]]]],[11,R[23],R[154],E,70,[[],[R[147]]]],[11,"drop",R[130],E,24,[[["self"]]]],[11,"drop",E,E,33,[[["self"]]]],[11,"drop",R[164],E,65,[[["self"]]]],[11,R[254],R[130],E,1,[[["self"],["span"]],[[R[253]],[R[3],[R[253]]]]]],[11,R[254],E,E,2,[[["self"],[R[151]]],[[R[253]],[R[3],[R[253]]]]]],[11,R[254],R[225],E,59,[[[R[186]],["self"]],[[R[3],[R[253]]],[R[253]]]]],[11,R[254],R[164],E,67,[[["self"],[R[193]]],[[R[253]],[R[3],[R[253]]]]]],[11,"lt",E,E,67,[[["self"],[R[193]]],["bool"]]],[11,"le",E,E,67,[[["self"],[R[193]]],["bool"]]],[11,"gt",E,E,67,[[["self"],[R[193]]],["bool"]]],[11,"ge",E,E,67,[[["self"],[R[193]]],["bool"]]],[11,R[254],E,E,69,[[["self"],[R[204]]],[[R[253]],[R[3],[R[253]]]]]],[11,"lt",E,E,69,[[["self"],[R[204]]],["bool"]]],[11,"le",E,E,69,[[["self"],[R[204]]],["bool"]]],[11,"gt",E,E,69,[[["self"],[R[204]]],["bool"]]],[11,"ge",E,E,69,[[["self"],[R[204]]],["bool"]]],[11,"deref",R[225],E,59,[[["self"]],["vec"]]],[11,"deref_mut",E,E,59,[[["self"]],["vec"]]],[11,"fmt",R[130],E,46,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,23,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,24,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[154],E,0,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[164],E,64,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,49,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,65,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[223],E,42,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,43,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[224],E,44,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[130],E,46,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,23,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,1,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,2,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,3,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,4,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,24,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,5,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,6,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,7,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,25,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,26,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,27,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,28,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,8,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,29,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,9,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,30,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,10,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,31,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,32,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,11,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,33,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,34,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,12,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,13,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,14,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,35,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,15,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,36,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,16,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,17,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,37,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,38,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,18,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,39,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,19,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,20,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,21,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,22,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,40,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,41,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[154],E,0,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[225],E,58,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,59,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[226],E,60,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[227],E,61,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,62,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[164],E,64,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,49,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,65,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,50,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,51,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,52,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,66,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,72,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,67,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,68,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,73,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,69,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,53,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,54,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,47,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,55,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,48,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,56,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,57,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",R[154],E,70,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,71,[[["self"],[R[36]]],[R[15]]]],[11,R[255],R[130],E,46,[[["self"]],["str"]]],[11,R[255],R[154],E,0,[[["self"]],["str"]]],[11,R[255],R[164],E,64,[[["self"]],["str"]]],[11,"start",R[130],R[256],45,[[["self"]]]],[11,R[180],E,R[257],45,[[["self"],["ast"]],[R[15]]]],[11,R[181],E,R[258],45,[[["self"],["ast"]],[R[15]]]],[11,R[182],E,R[259],45,[[["self"]],[R[15]]]],[11,R[260],E,R[261],45,[[["self"],[R[149]]],[R[15]]]],[11,R[262],E,R[263],45,[[["self"],[R[149]]],[R[15]]]],[11,R[264],E,R[265],45,[[["self"],[R[150]]],[R[15]]]],[11,R[266],E,R[267],45,[[["self"],[R[150]]],[R[15]]]],[11,R[268],E,R[269],45,[[["self"],[R[150]]],[R[15]]]],[11,"start",R[164],R[270],63,[[["self"]]]],[11,R[180],E,R[271],63,[[["self"],["hir"]],[R[15]]]],[11,R[181],E,R[272],63,[[["self"],["hir"]],[R[15]]]],[11,R[182],E,R[273],63,[[["self"]],[R[15]]]]],"p":[[4,"Error"],[3,"Span"],[3,"Position"],[3,R[274]],[3,"Comment"],[3,R[137]],[3,"Concat"],[3,R[172]],[3,R[275]],[3,R[276]],[3,R[155]],[3,R[277]],[3,R[278]],[3,R[279]],[3,R[280]],[3,R[133]],[3,R[135]],[3,R[281]],[3,"Group"],[3,R[144]],[3,"SetFlags"],[3,"Flags"],[3,R[282]],[4,R[106]],[4,"Ast"],[4,R[283]],[4,R[284]],[4,R[285]],[4,"Class"],[4,R[286]],[4,R[287]],[4,R[288]],[4,R[289]],[4,"ClassSet"],[4,R[290]],[4,R[291]],[4,R[292]],[4,R[165]],[4,R[170]],[4,R[161]],[4,R[293]],[4,"Flag"],[3,R[145]],[3,"Parser"],[3,"Printer"],[8,"Visitor"],[3,"Error"],[3,"Group"],[3,R[135]],[4,R[106]],[4,"HirKind"],[4,R[172]],[4,"Class"],[4,"Anchor"],[4,R[156]],[4,R[161]],[4,R[165]],[4,R[170]],[3,"Literals"],[3,R[172]],[3,"Printer"],[3,R[294]],[3,R[295]],[8,"Visitor"],[3,"Error"],[3,"Hir"],[3,R[155]],[3,R[296]],[3,R[297]],[3,R[298]],[3,R[145]],[3,"Parser"],[3,R[299]],[3,R[300]]]}; +searchIndex["thread_local"]={"doc":"Per-object thread-local storage","i":[[3,R[54],"thread_local","Thread-local variable wrapper",N,N],[3,"IterMut",E,"Mutable iterator over the contents of a `ThreadLocal`.",N,N],[3,R[56],E,"An iterator that moves out of a `ThreadLocal`.",N,N],[3,R[55],E,"Wrapper around `ThreadLocal` which adds a fast path for a…",N,N],[6,"CachedIterMut",E,"Mutable iterator over the contents of a `CachedThreadLocal`.",N,N],[6,"CachedIntoIter",E,"An iterator that moves out of a `CachedThreadLocal`.",N,N],[11,"new",E,"Creates a new empty `ThreadLocal`.",0,[[],[R[52]]]],[11,"get",E,R[43],0,[[["self"]],[[T],[R[3]]]]],[11,"get_or",E,R[42],0,[[["self"],["f"]],[T]]],[11,R[44],E,R[42],0,[[["self"],["f"]],[[T],[R[15]]]]],[11,R[45],E,R[46],0,[[["self"]],["itermut"]]],[11,"clear",E,R[47],0,[[["self"]]]],[11,R[48],E,R[49],0,[[["self"]],[T]]],[11,"new",E,"Creates a new empty `CachedThreadLocal`.",1,[[],[R[53]]]],[11,"get",E,R[43],1,[[["self"]],[[T],[R[3]]]]],[11,"get_or",E,R[42],1,[[["self"],["f"]],[T]]],[11,R[44],E,R[42],1,[[["self"],["f"]],[[T],[R[15]]]]],[11,R[45],E,R[46],1,[[["self"]],["cacheditermut"]]],[11,"clear",E,R[47],1,[[["self"]]]],[11,R[48],E,R[49],1,[[["self"]],[T]]],[11,"from",E,E,0,[[[T]],[T]]],[11,R[50],E,E,0,[[],["i"]]],[11,"into",E,E,0,[[],[U]]],[11,R[12],E,E,0,[[[U]],[R[15]]]],[11,R[13],E,E,0,[[],[R[15]]]],[11,R[14],E,E,0,[[["self"]],[T]]],[11,R[17],E,E,0,[[["self"]],[T]]],[11,R[16],E,E,0,[[["self"]],[R[18]]]],[11,"from",E,E,2,[[[T]],[T]]],[11,R[50],E,E,2,[[],["i"]]],[11,"into",E,E,2,[[],[U]]],[11,R[12],E,E,2,[[[U]],[R[15]]]],[11,R[13],E,E,2,[[],[R[15]]]],[11,R[14],E,E,2,[[["self"]],[T]]],[11,R[17],E,E,2,[[["self"]],[T]]],[11,R[16],E,E,2,[[["self"]],[R[18]]]],[11,"from",E,E,3,[[[T]],[T]]],[11,R[50],E,E,3,[[],["i"]]],[11,"into",E,E,3,[[],[U]]],[11,R[12],E,E,3,[[[U]],[R[15]]]],[11,R[13],E,E,3,[[],[R[15]]]],[11,R[14],E,E,3,[[["self"]],[T]]],[11,R[17],E,E,3,[[["self"]],[T]]],[11,R[16],E,E,3,[[["self"]],[R[18]]]],[11,"from",E,E,1,[[[T]],[T]]],[11,R[50],E,E,1,[[],["i"]]],[11,"into",E,E,1,[[],[U]]],[11,R[12],E,E,1,[[[U]],[R[15]]]],[11,R[13],E,E,1,[[],[R[15]]]],[11,R[14],E,E,1,[[["self"]],[T]]],[11,R[17],E,E,1,[[["self"]],[T]]],[11,R[16],E,E,1,[[["self"]],[R[18]]]],[11,"next",E,E,2,[[["self"]],[[R[3],["box"]],["box"]]]],[11,R[51],E,E,2,[[["self"]]]],[11,"next",E,E,3,[[["self"]],[[R[3],["box"]],["box"]]]],[11,R[51],E,E,3,[[["self"]]]],[11,R[23],E,E,0,[[],[R[52]]]],[11,R[23],E,E,1,[[],[R[53]]]],[11,R[50],E,E,0,[[],["intoiter"]]],[11,R[50],E,E,1,[[],["cachedintoiter"]]],[11,"drop",E,E,0,[[["self"]]]],[11,"fmt",E,E,0,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,1,[[["self"],[R[36]]],[R[15]]]]],"p":[[3,R[54]],[3,R[55]],[3,"IterMut"],[3,R[56]]]}; +searchIndex["ucd_util"]={"doc":"The `ucd-util` crate contains a smattering of utility…","i":[[5,"hangul_name","ucd_util","Return the character name of the given precomposed Hangul…",N,[[["u32"]],[[R[3],[R[2]]],[R[2]]]]],[5,"hangul_full_canonical_decomposition",E,"Return the full canonical decomposition of the given…",N,[[["u32"]],[R[3]]]],[5,"ideograph_name",E,"Return the character name of the given ideograph codepoint.",N,[[["u32"]],[[R[3],[R[2]]],[R[2]]]]],[5,"character_name_normalize",E,"Normalize the given character name in place according to…",N,[[[R[2]]]]],[5,"symbolic_name_normalize",E,"Normalize the given symbolic name in place according to…",N,[[[R[2]]]]],[5,"canonical_property_name",E,"Find the canonical property name for the given normalized…",N,[[["propertytable"],["str"]],[[R[3],["str"]],["str"]]]],[5,"property_values",E,"Find the set of possible property values for a given…",N,[[["propertyvaluetable"],["str"]],[[R[3],[R[4]]],[R[4]]]]],[5,"canonical_property_value",E,"Find the canonical property value for the given normalized…",N,[[["str"],[R[4]]],[[R[3],["str"]],["str"]]]],[6,"PropertyTable",E,"The type of a property name table.",N,N],[6,"PropertyValueTable",E,"Type of a property value table.",N,N],[6,"PropertyValues",E,"A mapping of property values for a specific property.",N,N],[17,"RANGE_HANGUL_SYLLABLE",E,"A set of ranges that corresponds to the set of all Hangul…",N,N],[17,"RANGE_IDEOGRAPH",E,"A set of ranges that corresponds to the set of all…",N,N]],"p":[]}; +searchIndex["utf8_ranges"]={"doc":"Crate `utf8-ranges` converts ranges of Unicode scalar…","i":[[3,R[37],"utf8_ranges","A single inclusive range of UTF-8 bytes.",N,N],[12,"start",E,"Start of byte range (inclusive).",0,N],[12,"end",E,"End of byte range (inclusive).",0,N],[3,R[39],E,"An iterator over ranges of matching UTF-8 byte sequences.",N,N],[4,R[38],E,"Utf8Sequence represents a sequence of byte ranges.",N,N],[13,"One",E,"One byte range.",1,N],[13,"Two",E,"Two successive byte ranges.",1,N],[13,"Three",E,"Three successive byte ranges.",1,N],[13,"Four",E,"Four successive byte ranges.",1,N],[11,"as_slice",E,"Returns the underlying sequence of byte ranges as a slice.",1,[[["self"]]]],[11,"len",E,"Returns the number of byte ranges in this sequence.",1,[[["self"]],["usize"]]],[11,R[501],E,"Returns true if and only if a prefix of `bytes` matches…",1,[[["self"]],["bool"]]],[11,R[501],E,"Returns true if and only if the given byte is in this range.",0,[[["self"],["u8"]],["bool"]]],[11,"new",E,"Create a new iterator over UTF-8 byte ranges for the…",2,[[["char"]],["self"]]],[11,"from",E,E,0,[[[T]],[T]]],[11,R[32],E,E,0,[[["self"]],[T]]],[11,R[33],E,E,0,[[[T],["self"]]]],[11,"into",E,E,0,[[],[U]]],[11,R[12],E,E,0,[[[U]],[R[15]]]],[11,R[13],E,E,0,[[],[R[15]]]],[11,R[14],E,E,0,[[["self"]],[T]]],[11,R[17],E,E,0,[[["self"]],[T]]],[11,R[16],E,E,0,[[["self"]],[R[18]]]],[11,"from",E,E,2,[[[T]],[T]]],[11,R[50],E,E,2,[[],["i"]]],[11,"into",E,E,2,[[],[U]]],[11,R[12],E,E,2,[[[U]],[R[15]]]],[11,R[13],E,E,2,[[],[R[15]]]],[11,R[14],E,E,2,[[["self"]],[T]]],[11,R[17],E,E,2,[[["self"]],[T]]],[11,R[16],E,E,2,[[["self"]],[R[18]]]],[11,"from",E,E,1,[[[T]],[T]]],[11,R[32],E,E,1,[[["self"]],[T]]],[11,R[33],E,E,1,[[[T],["self"]]]],[11,"into",E,E,1,[[],[U]]],[11,R[12],E,E,1,[[[U]],[R[15]]]],[11,R[13],E,E,1,[[],[R[15]]]],[11,R[14],E,E,1,[[["self"]],[T]]],[11,R[17],E,E,1,[[["self"]],[T]]],[11,R[16],E,E,1,[[["self"]],[R[18]]]],[11,"next",E,E,2,[[["self"]],[R[3]]]],[11,"eq",E,E,1,[[["self"],[R[34]]],["bool"]]],[11,"ne",E,E,1,[[["self"],[R[34]]],["bool"]]],[11,"eq",E,E,0,[[[R[35]],["self"]],["bool"]]],[11,"ne",E,E,0,[[[R[35]],["self"]],["bool"]]],[11,"clone",E,E,1,[[["self"]],[R[34]]]],[11,"clone",E,E,0,[[["self"]],[R[35]]]],[11,"fmt",E,E,1,[[["self"],[R[36]]],[R[15]]]],[11,"fmt",E,E,0,[[["self"],[R[36]]],[R[15]]]]],"p":[[3,R[37]],[4,R[38]],[3,R[39]]]}; +initSearch(searchIndex);addSearchOptions(searchIndex); \ No newline at end of file diff --git a/target/doc/settings.css b/target/doc/settings.css new file mode 100644 index 0000000..4201b26 --- /dev/null +++ b/target/doc/settings.css @@ -0,0 +1 @@ +.setting-line{padding:5px;}.setting-line>div{max-width:calc(100% - 74px);display:inline-block;vertical-align:top;font-size:17px;padding-top:2px;}.toggle{position:relative;display:inline-block;width:45px;height:27px;margin-right:20px;}.toggle input{display:none;}.slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;-webkit-transition:.3s;transition:.3s;}.slider:before{position:absolute;content:"";height:19px;width:19px;left:4px;bottom:4px;background-color:white;-webkit-transition:.3s;transition:.3s;}input:checked+.slider{background-color:#2196F3;}input:focus+.slider{box-shadow:0 0 1px #2196F3;}input:checked+.slider:before{-webkit-transform:translateX(19px);-ms-transform:translateX(19px);transform:translateX(19px);} \ No newline at end of file diff --git a/target/doc/settings.html b/target/doc/settings.html new file mode 100644 index 0000000..55bf471 --- /dev/null +++ b/target/doc/settings.html @@ -0,0 +1 @@ +Rustdoc settings

Rustdoc settings

Auto-hide item declarations.
Auto-hide item attributes.
Auto-hide trait implementations documentation
Auto-hide item methods' documentation
Directly go to item in search if there is only one result
Show line numbers on code examples
\ No newline at end of file diff --git a/target/doc/settings.js b/target/doc/settings.js new file mode 100644 index 0000000..cfed84c --- /dev/null +++ b/target/doc/settings.js @@ -0,0 +1 @@ +(function(){function changeSetting(settingName,isEnabled){updateLocalStorage('rustdoc-'+settingName,isEnabled);}function getSettingValue(settingName){return getCurrentValue('rustdoc-'+settingName);}function setEvents(){var elems=document.getElementsByClassName("slider");if(!elems||elems.length===0){return;}for(var i=0;i"){sidebar.style.left="";this.style.left="";child.innerText="<";updateLocalStorage("rustdoc-source-sidebar-show","true");}else{sidebar.style.left="-300px";this.style.left="0";child.innerText=">";updateLocalStorage("rustdoc-source-sidebar-show","false");}}function createSidebarToggle(){var sidebarToggle=document.createElement("div");sidebarToggle.id="sidebar-toggle";sidebarToggle.onclick=toggleSidebar;var inner1=document.createElement("div");inner1.style.position="relative";var inner2=document.createElement("div");inner2.style.paddingTop="3px";if(getCurrentValue("rustdoc-source-sidebar-show")==="true"){inner2.innerText="<";}else{inner2.innerText=">";sidebarToggle.style.left="0";}inner1.appendChild(inner2);sidebarToggle.appendChild(inner1);return sidebarToggle;}function createSourceSidebar(){if(window.rootPath.endsWith("/")===false){window.rootPath+="/";}var main=document.getElementById("main");var sidebarToggle=createSidebarToggle();main.insertBefore(sidebarToggle,main.firstChild);var sidebar=document.createElement("div");sidebar.id="source-sidebar";if(getCurrentValue("rustdoc-source-sidebar-show")!=="true"){sidebar.style.left="-300px";}var currentFile=getCurrentFilePath();var hasFoundFile=false;var title=document.createElement("div");title.className="title";title.innerText="Files";sidebar.appendChild(title);Object.keys(sourcesIndex).forEach(function(key){sourcesIndex[key].name=key;hasFoundFile=createDirEntry(sourcesIndex[key],sidebar,"",currentFile,hasFoundFile);});main.insertBefore(sidebar,main.firstChild);} \ No newline at end of file diff --git a/target/doc/src/aho_corasick/ahocorasick.rs.html b/target/doc/src/aho_corasick/ahocorasick.rs.html new file mode 100644 index 0000000..4205c93 --- /dev/null +++ b/target/doc/src/aho_corasick/ahocorasick.rs.html @@ -0,0 +1,4067 @@ +ahocorasick.rs.html -- source
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+
+use std::io;
+
+use automaton::Automaton;
+use buffer::Buffer;
+use dfa::{self, DFA};
+use error::Result;
+use nfa::{self, NFA};
+use prefilter::PrefilterState;
+use state_id::StateID;
+use Match;
+
+/// An automaton for searching multiple strings in linear time.
+///
+/// The `AhoCorasick` type supports a few basic ways of constructing an
+/// automaton, including
+/// [`AhoCorasick::new`](struct.AhoCorasick.html#method.new)
+/// and
+/// [`AhoCorasick::new_auto_configured`](struct.AhoCorasick.html#method.new_auto_configured).
+/// However, there are a fair number of configurable options that can be set
+/// by using
+/// [`AhoCorasickBuilder`](struct.AhoCorasickBuilder.html)
+/// instead. Such options include, but are not limited to, how matches are
+/// determined, simple case insensitivity, whether to use a DFA or not and
+/// various knobs for controlling the space-vs-time trade offs taken when
+/// building the automaton.
+///
+/// If you aren't sure where to start, try beginning with
+/// [`AhoCorasick::new_auto_configured`](struct.AhoCorasick.html#method.new_auto_configured).
+///
+/// # Resource usage
+///
+/// Aho-Corasick automatons are always constructed in `O(p)` time, where `p`
+/// is the combined length of all patterns being searched. With that said,
+/// building an automaton can be fairly costly because of high constant
+/// factors, particularly when enabling the
+/// [DFA](struct.AhoCorasickBuilder.html#method.dfa)
+/// option (which is disabled by default). For this reason, it's generally a
+/// good idea to build an automaton once and reuse it as much as possible.
+///
+/// Aho-Corasick automatons can also use a fair bit of memory. To get a
+/// concrete idea of how much memory is being used, try using the
+/// [`AhoCorasick::heap_bytes`](struct.AhoCorasick.html#method.heap_bytes)
+/// method.
+///
+/// # Examples
+///
+/// This example shows how to search for occurrences of multiple patterns
+/// simultaneously in a case insensitive fashion. Each match includes the
+/// pattern that matched along with the byte offsets of the match.
+///
+/// ```
+/// use aho_corasick::AhoCorasickBuilder;
+///
+/// let patterns = &["apple", "maple", "snapple"];
+/// let haystack = "Nobody likes maple in their apple flavored Snapple.";
+///
+/// let ac = AhoCorasickBuilder::new()
+///     .ascii_case_insensitive(true)
+///     .build(patterns);
+/// let mut matches = vec![];
+/// for mat in ac.find_iter(haystack) {
+///     matches.push((mat.pattern(), mat.start(), mat.end()));
+/// }
+/// assert_eq!(matches, vec![
+///     (1, 13, 18),
+///     (0, 28, 33),
+///     (2, 43, 50),
+/// ]);
+/// ```
+///
+/// This example shows how to replace matches with some other string:
+///
+/// ```
+/// use aho_corasick::AhoCorasick;
+///
+/// let patterns = &["fox", "brown", "quick"];
+/// let haystack = "The quick brown fox.";
+/// let replace_with = &["sloth", "grey", "slow"];
+///
+/// let ac = AhoCorasick::new(patterns);
+/// let result = ac.replace_all(haystack, replace_with);
+/// assert_eq!(result, "The slow grey sloth.");
+/// ```
+#[derive(Clone, Debug)]
+pub struct AhoCorasick<S: StateID = usize> {
+    imp: Imp<S>,
+    match_kind: MatchKind,
+}
+
+impl AhoCorasick {
+    /// Create a new Aho-Corasick automaton using the default configuration.
+    ///
+    /// The default configuration optimizes for less space usage, but at the
+    /// expense of longer search times. To change the configuration, use
+    /// [`AhoCorasickBuilder`](struct.AhoCorasickBuilder.html)
+    /// for fine-grained control, or
+    /// [`AhoCorasick::new_auto_configured`](struct.AhoCorasick.html#method.new_auto_configured)
+    /// for automatic configuration if you aren't sure which settings to pick.
+    ///
+    /// This uses the default
+    /// [`MatchKind::Standard`](enum.MatchKind.html#variant.Standard)
+    /// match semantics, which reports a match as soon as it is found. This
+    /// corresponds to the standard match semantics supported by textbook
+    /// descriptions of the Aho-Corasick algorithm.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use aho_corasick::AhoCorasick;
+    ///
+    /// let ac = AhoCorasick::new(&[
+    ///     "foo", "bar", "baz",
+    /// ]);
+    /// assert_eq!(Some(1), ac.find("xxx bar xxx").map(|m| m.pattern()));
+    /// ```
+    pub fn new<I, P>(
+        patterns: I,
+    ) -> AhoCorasick
+    where I: IntoIterator<Item=P>,
+          P: AsRef<[u8]>
+    {
+        AhoCorasickBuilder::new().build(patterns)
+    }
+
+    /// Build an Aho-Corasick automaton with an automatically determined
+    /// configuration.
+    ///
+    /// Specifically, this requires a slice of patterns instead of an iterator
+    /// since the configuration is determined by looking at the patterns before
+    /// constructing the automaton. The idea here is to balance space and time
+    /// automatically. That is, when searching a small number of patterns, this
+    /// will attempt to use the fastest possible configuration since the total
+    /// space required will be small anyway. As the number of patterns grows,
+    /// this will fall back to slower configurations that use less space.
+    ///
+    /// If you want auto configuration but with match semantics different from
+    /// the default `MatchKind::Standard`, then use
+    /// [`AhoCorasickBuilder::auto_configure`](struct.AhoCorasickBuilder.html#method.auto_configure).
+    ///
+    /// # Examples
+    ///
+    /// Basic usage is just like `new`, except you must provide a slice:
+    ///
+    /// ```
+    /// use aho_corasick::AhoCorasick;
+    ///
+    /// let ac = AhoCorasick::new_auto_configured(&[
+    ///     "foo", "bar", "baz",
+    /// ]);
+    /// assert_eq!(Some(1), ac.find("xxx bar xxx").map(|m| m.pattern()));
+    /// ```
+    pub fn new_auto_configured<B>(
+        patterns: &[B],
+    ) -> AhoCorasick
+    where B: AsRef<[u8]>
+    {
+        AhoCorasickBuilder::new().auto_configure(patterns).build(patterns)
+    }
+}
+
+impl<S: StateID> AhoCorasick<S> {
+    /// Returns true if and only if this automaton matches the haystack at any
+    /// position.
+    ///
+    /// `haystack` may be any type that is cheaply convertible to a `&[u8]`.
+    /// This includes, but is not limited to, `String`, `&str`, `Vec<u8>`, and
+    /// `&[u8]` itself.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use aho_corasick::AhoCorasick;
+    ///
+    /// let ac = AhoCorasick::new(&[
+    ///     "foo", "bar", "quux", "baz",
+    /// ]);
+    /// assert!(ac.is_match("xxx bar xxx"));
+    /// assert!(!ac.is_match("xxx qux xxx"));
+    /// ```
+    pub fn is_match<B: AsRef<[u8]>>(&self, haystack: B) -> bool {
+        self.earliest_find(haystack).is_some()
+    }
+
+    /// Returns the location of the first detected match in `haystack`.
+    ///
+    /// This method has the same behavior regardless of the
+    /// [`MatchKind`](enum.MatchKind.html)
+    /// of this automaton.
+    ///
+    /// `haystack` may be any type that is cheaply convertible to a `&[u8]`.
+    /// This includes, but is not limited to, `String`, `&str`, `Vec<u8>`, and
+    /// `&[u8]` itself.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use aho_corasick::AhoCorasick;
+    ///
+    /// let ac = AhoCorasick::new(&[
+    ///     "abc", "b",
+    /// ]);
+    /// let mat = ac.earliest_find("abcd").expect("should have match");
+    /// assert_eq!(1, mat.pattern());
+    /// assert_eq!((1, 2), (mat.start(), mat.end()));
+    /// ```
+    pub fn earliest_find<B: AsRef<[u8]>>(&self, haystack: B) -> Option<Match> {
+        let mut prestate = PrefilterState::new(self.max_pattern_len());
+        let mut start = self.imp.start_state();
+        self.imp.earliest_find_at(
+            &mut prestate, haystack.as_ref(), 0, &mut start,
+        )
+    }
+
+    /// Returns the location of the first match according to the match
+    /// semantics that this automaton was constructed with.
+    ///
+    /// When using `MatchKind::Standard`, this corresponds precisely to the
+    /// same behavior as
+    /// [`earliest_find`](struct.AhoCorasick.html#method.earliest_find).
+    /// Otherwise, match semantics correspond to either
+    /// [leftmost-first](enum.MatchKind.html#variant.LeftmostFirst)
+    /// or
+    /// [leftmost-longest](enum.MatchKind.html#variant.LeftmostLongest).
+    ///
+    /// `haystack` may be any type that is cheaply convertible to a `&[u8]`.
+    /// This includes, but is not limited to, `String`, `&str`, `Vec<u8>`, and
+    /// `&[u8]` itself.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage, with standard semantics:
+    ///
+    /// ```
+    /// use aho_corasick::{AhoCorasickBuilder, MatchKind};
+    ///
+    /// let patterns = &["b", "abc", "abcd"];
+    /// let haystack = "abcd";
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .match_kind(MatchKind::Standard) // default, not necessary
+    ///     .build(patterns);
+    /// let mat = ac.find(haystack).expect("should have a match");
+    /// assert_eq!("b", &haystack[mat.start()..mat.end()]);
+    /// ```
+    ///
+    /// Now with leftmost-first semantics:
+    ///
+    /// ```
+    /// use aho_corasick::{AhoCorasickBuilder, MatchKind};
+    ///
+    /// let patterns = &["b", "abc", "abcd"];
+    /// let haystack = "abcd";
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .match_kind(MatchKind::LeftmostFirst)
+    ///     .build(patterns);
+    /// let mat = ac.find(haystack).expect("should have a match");
+    /// assert_eq!("abc", &haystack[mat.start()..mat.end()]);
+    /// ```
+    ///
+    /// And finally, leftmost-longest semantics:
+    ///
+    /// ```
+    /// use aho_corasick::{AhoCorasickBuilder, MatchKind};
+    ///
+    /// let patterns = &["b", "abc", "abcd"];
+    /// let haystack = "abcd";
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .match_kind(MatchKind::LeftmostLongest)
+    ///     .build(patterns);
+    /// let mat = ac.find(haystack).expect("should have a match");
+    /// assert_eq!("abcd", &haystack[mat.start()..mat.end()]);
+    /// ```
+    pub fn find<B: AsRef<[u8]>>(&self, haystack: B) -> Option<Match> {
+        let mut prestate = PrefilterState::new(self.max_pattern_len());
+        let mut start = self.imp.start_state();
+        self.imp.find_at(&mut prestate, haystack.as_ref(), 0, &mut start)
+    }
+
+    /// Returns an iterator of non-overlapping matches, using the match
+    /// semantics that this automaton was constructed with.
+    ///
+    /// `haystack` may be any type that is cheaply convertible to a `&[u8]`.
+    /// This includes, but is not limited to, `String`, `&str`, `Vec<u8>`, and
+    /// `&[u8]` itself.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage, with standard semantics:
+    ///
+    /// ```
+    /// use aho_corasick::{AhoCorasickBuilder, MatchKind};
+    ///
+    /// let patterns = &["append", "appendage", "app"];
+    /// let haystack = "append the app to the appendage";
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .match_kind(MatchKind::Standard) // default, not necessary
+    ///     .build(patterns);
+    /// let matches: Vec<usize> = ac
+    ///     .find_iter(haystack)
+    ///     .map(|mat| mat.pattern())
+    ///     .collect();
+    /// assert_eq!(vec![2, 2, 2], matches);
+    /// ```
+    ///
+    /// Now with leftmost-first semantics:
+    ///
+    /// ```
+    /// use aho_corasick::{AhoCorasickBuilder, MatchKind};
+    ///
+    /// let patterns = &["append", "appendage", "app"];
+    /// let haystack = "append the app to the appendage";
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .match_kind(MatchKind::LeftmostFirst)
+    ///     .build(patterns);
+    /// let matches: Vec<usize> = ac
+    ///     .find_iter(haystack)
+    ///     .map(|mat| mat.pattern())
+    ///     .collect();
+    /// assert_eq!(vec![0, 2, 0], matches);
+    /// ```
+    ///
+    /// And finally, leftmost-longest semantics:
+    ///
+    /// ```
+    /// use aho_corasick::{AhoCorasickBuilder, MatchKind};
+    ///
+    /// let patterns = &["append", "appendage", "app"];
+    /// let haystack = "append the app to the appendage";
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .match_kind(MatchKind::LeftmostLongest)
+    ///     .build(patterns);
+    /// let matches: Vec<usize> = ac
+    ///     .find_iter(haystack)
+    ///     .map(|mat| mat.pattern())
+    ///     .collect();
+    /// assert_eq!(vec![0, 2, 1], matches);
+    /// ```
+    pub fn find_iter<'a, 'b, B: ?Sized + AsRef<[u8]>>(
+        &'a self,
+        haystack: &'b B,
+    ) -> FindIter<'a, 'b, S> {
+        FindIter::new(self, haystack.as_ref())
+    }
+
+    /// Returns an iterator of overlapping matches in the given `haystack`.
+    ///
+    /// Overlapping matches can _only_ be detected using
+    /// `MatchKind::Standard` semantics. If this automaton was constructed with
+    /// leftmost semantics, then this method will panic. To determine whether
+    /// this will panic at runtime, use the
+    /// [`AhoCorasick::supports_overlapping`](struct.AhoCorasick.html#method.supports_overlapping)
+    /// method.
+    ///
+    /// `haystack` may be any type that is cheaply convertible to a `&[u8]`.
+    /// This includes, but is not limited to, `String`, `&str`, `Vec<u8>`, and
+    /// `&[u8]` itself.
+    ///
+    /// # Panics
+    ///
+    /// This panics when `AhoCorasick::supports_overlapping` returns `false`.
+    /// That is, this panics when this automaton's match semantics are not
+    /// `MatchKind::Standard`.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage, with standard semantics:
+    ///
+    /// ```
+    /// use aho_corasick::AhoCorasick;
+    ///
+    /// let patterns = &["append", "appendage", "app"];
+    /// let haystack = "append the app to the appendage";
+    ///
+    /// let ac = AhoCorasick::new(patterns);
+    /// let matches: Vec<usize> = ac
+    ///     .find_overlapping_iter(haystack)
+    ///     .map(|mat| mat.pattern())
+    ///     .collect();
+    /// assert_eq!(vec![2, 0, 2, 2, 0, 1], matches);
+    /// ```
+    pub fn find_overlapping_iter<'a, 'b, B: ?Sized + AsRef<[u8]>>(
+        &'a self,
+        haystack: &'b B,
+    ) -> FindOverlappingIter<'a, 'b, S> {
+        FindOverlappingIter::new(self, haystack.as_ref())
+    }
+
+    /// Replace all matches with a corresponding value in the `replace_with`
+    /// slice given. Matches correspond to the same matches as reported by
+    /// [`find_iter`](struct.AhoCorasick.html#method.find_iter).
+    ///
+    /// Replacements are determined by the index of the matching pattern.
+    /// For example, if the pattern with index `2` is found, then it is
+    /// replaced by `replace_with[2]`.
+    ///
+    /// # Panics
+    ///
+    /// This panics when `replace_with.len()` does not equal the total number
+    /// of patterns that are matched by this automaton.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use aho_corasick::{AhoCorasickBuilder, MatchKind};
+    ///
+    /// let patterns = &["append", "appendage", "app"];
+    /// let haystack = "append the app to the appendage";
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .match_kind(MatchKind::LeftmostFirst)
+    ///     .build(patterns);
+    /// let result = ac.replace_all(haystack, &["x", "y", "z"]);
+    /// assert_eq!("x the z to the xage", result);
+    /// ```
+    pub fn replace_all<B>(
+        &self,
+        haystack: &str,
+        replace_with: &[B],
+    ) -> String
+    where B: AsRef<str>
+    {
+        assert_eq!(
+            replace_with.len(), self.pattern_count(),
+            "replace_all requires a replacement for every pattern \
+             in the automaton"
+        );
+        let mut dst = String::with_capacity(haystack.len());
+        self.replace_all_with(haystack, &mut dst, |mat, _, dst| {
+            dst.push_str(replace_with[mat.pattern()].as_ref());
+            true
+        });
+        dst
+    }
+
+    /// Replace all matches using raw bytes with a corresponding value in the
+    /// `replace_with` slice given. Matches correspond to the same matches as
+    /// reported by [`find_iter`](struct.AhoCorasick.html#method.find_iter).
+    ///
+    /// Replacements are determined by the index of the matching pattern.
+    /// For example, if the pattern with index `2` is found, then it is
+    /// replaced by `replace_with[2]`.
+    ///
+    /// # Panics
+    ///
+    /// This panics when `replace_with.len()` does not equal the total number
+    /// of patterns that are matched by this automaton.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use aho_corasick::{AhoCorasickBuilder, MatchKind};
+    ///
+    /// let patterns = &["append", "appendage", "app"];
+    /// let haystack = b"append the app to the appendage";
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .match_kind(MatchKind::LeftmostFirst)
+    ///     .build(patterns);
+    /// let result = ac.replace_all_bytes(haystack, &["x", "y", "z"]);
+    /// assert_eq!(b"x the z to the xage".to_vec(), result);
+    /// ```
+    pub fn replace_all_bytes<B>(
+        &self,
+        haystack: &[u8],
+        replace_with: &[B],
+    ) -> Vec<u8>
+    where B: AsRef<[u8]>
+    {
+        assert_eq!(
+            replace_with.len(), self.pattern_count(),
+            "replace_all_bytes requires a replacement for every pattern \
+             in the automaton"
+        );
+        let mut dst = Vec::with_capacity(haystack.len());
+        self.replace_all_with_bytes(haystack, &mut dst, |mat, _, dst| {
+            dst.extend(replace_with[mat.pattern()].as_ref());
+            true
+        });
+        dst
+    }
+
+    /// Replace all matches using a closure called on each match.
+    /// Matches correspond to the same matches as reported by
+    /// [`find_iter`](struct.AhoCorasick.html#method.find_iter).
+    ///
+    /// The closure accepts three parameters: the match found, the text of
+    /// the match and a string buffer with which to write the replaced text
+    /// (if any). If the closure returns `true`, then it continues to the next
+    /// match. If the closure returns false, then searching is stopped.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use aho_corasick::{AhoCorasickBuilder, MatchKind};
+    ///
+    /// let patterns = &["append", "appendage", "app"];
+    /// let haystack = "append the app to the appendage";
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .match_kind(MatchKind::LeftmostFirst)
+    ///     .build(patterns);
+    /// let mut result = String::new();
+    /// ac.replace_all_with(haystack, &mut result, |mat, _, dst| {
+    ///     dst.push_str(&mat.pattern().to_string());
+    ///     true
+    /// });
+    /// assert_eq!("0 the 2 to the 0age", result);
+    /// ```
+    pub fn replace_all_with<F>(
+        &self,
+        haystack: &str,
+        dst: &mut String,
+        mut replace_with: F,
+    ) where F: FnMut(&Match, &str, &mut String) -> bool
+    {
+        let mut last_match = 0;
+        for mat in self.find_iter(haystack) {
+            dst.push_str(&haystack[last_match..mat.start()]);
+            last_match = mat.end();
+            replace_with(&mat, &haystack[mat.start()..mat.end()], dst);
+        }
+        dst.push_str(&haystack[last_match..]);
+    }
+
+    /// Replace all matches using raw bytes with a closure called on each
+    /// match. Matches correspond to the same matches as reported by
+    /// [`find_iter`](struct.AhoCorasick.html#method.find_iter).
+    ///
+    /// The closure accepts three parameters: the match found, the text of
+    /// the match and a byte buffer with which to write the replaced text
+    /// (if any). If the closure returns `true`, then it continues to the next
+    /// match. If the closure returns false, then searching is stopped.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use aho_corasick::{AhoCorasickBuilder, MatchKind};
+    ///
+    /// let patterns = &["append", "appendage", "app"];
+    /// let haystack = b"append the app to the appendage";
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .match_kind(MatchKind::LeftmostFirst)
+    ///     .build(patterns);
+    /// let mut result = vec![];
+    /// ac.replace_all_with_bytes(haystack, &mut result, |mat, _, dst| {
+    ///     dst.extend(mat.pattern().to_string().bytes());
+    ///     true
+    /// });
+    /// assert_eq!(b"0 the 2 to the 0age".to_vec(), result);
+    /// ```
+    pub fn replace_all_with_bytes<F>(
+        &self,
+        haystack: &[u8],
+        dst: &mut Vec<u8>,
+        mut replace_with: F,
+    ) where F: FnMut(&Match, &[u8], &mut Vec<u8>) -> bool
+    {
+        let mut last_match = 0;
+        for mat in self.find_iter(haystack) {
+            dst.extend(&haystack[last_match..mat.start()]);
+            last_match = mat.end();
+            replace_with(&mat, &haystack[mat.start()..mat.end()], dst);
+        }
+        dst.extend(&haystack[last_match..]);
+    }
+
+    /// Returns an iterator of non-overlapping matches in the given
+    /// stream. Matches correspond to the same matches as reported by
+    /// [`find_iter`](struct.AhoCorasick.html#method.find_iter).
+    ///
+    /// The matches yielded by this iterator use absolute position offsets in
+    /// the stream given, where the first byte has index `0`. Matches are
+    /// yieled until the stream is exhausted.
+    ///
+    /// Each item yielded by the iterator is an `io::Result<Match>`, where an
+    /// error is yielded if there was a problem reading from the reader given.
+    ///
+    /// When searching a stream, an internal buffer is used. Therefore, callers
+    /// should avoiding providing a buffered reader, if possible.
+    ///
+    /// Searching a stream requires that the automaton was built with
+    /// `MatchKind::Standard` semantics. If this automaton was constructed
+    /// with leftmost semantics, then this method will panic. To determine
+    /// whether this will panic at runtime, use the
+    /// [`AhoCorasick::supports_stream`](struct.AhoCorasick.html#method.supports_stream)
+    /// method.
+    ///
+    /// # Memory usage
+    ///
+    /// In general, searching streams will use a constant amount of memory for
+    /// its internal buffer. The one requirement is that the internal buffer
+    /// must be at least the size of the longest possible match. In most use
+    /// cases, the default buffer size will be much larger than any individual
+    /// match.
+    ///
+    /// # Panics
+    ///
+    /// This panics when `AhoCorasick::supports_stream` returns `false`.
+    /// That is, this panics when this automaton's match semantics are not
+    /// `MatchKind::Standard`. This restriction may be lifted in the future.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use aho_corasick::AhoCorasick;
+    ///
+    /// # fn example() -> Result<(), ::std::io::Error> {
+    /// let patterns = &["append", "appendage", "app"];
+    /// let haystack = "append the app to the appendage";
+    ///
+    /// let ac = AhoCorasick::new(patterns);
+    /// let mut matches = vec![];
+    /// for result in ac.stream_find_iter(haystack.as_bytes()) {
+    ///     let mat = result?;
+    ///     matches.push(mat.pattern());
+    /// }
+    /// assert_eq!(vec![2, 2, 2], matches);
+    /// # Ok(()) }; example().unwrap()
+    /// ```
+    pub fn stream_find_iter<'a, R: io::Read>(
+        &'a self,
+        rdr: R,
+    ) -> StreamFindIter<'a, R, S> {
+        StreamFindIter::new(self, rdr)
+    }
+
+    /// Search for and replace all matches of this automaton in
+    /// the given reader, and write the replacements to the given
+    /// writer. Matches correspond to the same matches as reported by
+    /// [`find_iter`](struct.AhoCorasick.html#method.find_iter).
+    ///
+    /// Replacements are determined by the index of the matching pattern.
+    /// For example, if the pattern with index `2` is found, then it is
+    /// replaced by `replace_with[2]`.
+    ///
+    /// After all matches are replaced, the writer is _not_ flushed.
+    ///
+    /// If there was a problem reading from the given reader or writing to the
+    /// given writer, then the corresponding `io::Error` is returned and all
+    /// replacement is stopped.
+    ///
+    /// When searching a stream, an internal buffer is used. Therefore, callers
+    /// should avoiding providing a buffered reader, if possible. However,
+    /// callers may want to provide a buffered writer.
+    ///
+    /// Searching a stream requires that the automaton was built with
+    /// `MatchKind::Standard` semantics. If this automaton was constructed
+    /// with leftmost semantics, then this method will panic. To determine
+    /// whether this will panic at runtime, use the
+    /// [`AhoCorasick::supports_stream`](struct.AhoCorasick.html#method.supports_stream)
+    /// method.
+    ///
+    /// # Memory usage
+    ///
+    /// In general, searching streams will use a constant amount of memory for
+    /// its internal buffer. The one requirement is that the internal buffer
+    /// must be at least the size of the longest possible match. In most use
+    /// cases, the default buffer size will be much larger than any individual
+    /// match.
+    ///
+    /// # Panics
+    ///
+    /// This panics when `AhoCorasick::supports_stream` returns `false`.
+    /// That is, this panics when this automaton's match semantics are not
+    /// `MatchKind::Standard`. This restriction may be lifted in the future.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use aho_corasick::AhoCorasick;
+    ///
+    /// # fn example() -> Result<(), ::std::io::Error> {
+    /// let patterns = &["fox", "brown", "quick"];
+    /// let haystack = "The quick brown fox.";
+    /// let replace_with = &["sloth", "grey", "slow"];
+    ///
+    /// let ac = AhoCorasick::new(patterns);
+    /// let mut result = vec![];
+    /// ac.stream_replace_all(haystack.as_bytes(), &mut result, replace_with)?;
+    /// assert_eq!(b"The slow grey sloth.".to_vec(), result);
+    /// # Ok(()) }; example().unwrap()
+    /// ```
+    pub fn stream_replace_all<R, W, B>(
+        &self,
+        rdr: R,
+        wtr: W,
+        replace_with: &[B],
+    ) -> io::Result<()>
+    where R: io::Read,
+          W: io::Write,
+          B: AsRef<[u8]>
+    {
+        assert_eq!(
+            replace_with.len(), self.pattern_count(),
+            "stream_replace_all requires a replacement for every pattern \
+             in the automaton"
+        );
+        self.stream_replace_all_with(rdr, wtr, |mat, _, wtr| {
+            wtr.write_all(replace_with[mat.pattern()].as_ref())
+        })
+    }
+
+    /// Search the given reader and replace all matches of this automaton
+    /// using the given closure. The result is written to the given
+    /// writer. Matches correspond to the same matches as reported by
+    /// [`find_iter`](struct.AhoCorasick.html#method.find_iter).
+    ///
+    /// The closure accepts three parameters: the match found, the text of
+    /// the match and the writer with which to write the replaced text
+    /// (if any). If the closure returns `true`, then it continues to the next
+    /// match. If the closure returns false, then searching is stopped.
+    ///
+    /// After all matches are replaced, the writer is _not_ flushed.
+    ///
+    /// If there was a problem reading from the given reader or writing to the
+    /// given writer, then the corresponding `io::Error` is returned and all
+    /// replacement is stopped.
+    ///
+    /// When searching a stream, an internal buffer is used. Therefore, callers
+    /// should avoiding providing a buffered reader, if possible. However,
+    /// callers may want to provide a buffered writer.
+    ///
+    /// Searching a stream requires that the automaton was built with
+    /// `MatchKind::Standard` semantics. If this automaton was constructed
+    /// with leftmost semantics, then this method will panic. To determine
+    /// whether this will panic at runtime, use the
+    /// [`AhoCorasick::supports_stream`](struct.AhoCorasick.html#method.supports_stream)
+    /// method.
+    ///
+    /// # Memory usage
+    ///
+    /// In general, searching streams will use a constant amount of memory for
+    /// its internal buffer. The one requirement is that the internal buffer
+    /// must be at least the size of the longest possible match. In most use
+    /// cases, the default buffer size will be much larger than any individual
+    /// match.
+    ///
+    /// # Panics
+    ///
+    /// This panics when `AhoCorasick::supports_stream` returns `false`.
+    /// That is, this panics when this automaton's match semantics are not
+    /// `MatchKind::Standard`. This restriction may be lifted in the future.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use std::io::Write;
+    /// use aho_corasick::AhoCorasick;
+    ///
+    /// # fn example() -> Result<(), ::std::io::Error> {
+    /// let patterns = &["fox", "brown", "quick"];
+    /// let haystack = "The quick brown fox.";
+    ///
+    /// let ac = AhoCorasick::new(patterns);
+    /// let mut result = vec![];
+    /// ac.stream_replace_all_with(
+    ///     haystack.as_bytes(),
+    ///     &mut result,
+    ///     |mat, _, wtr| {
+    ///         wtr.write_all(mat.pattern().to_string().as_bytes())
+    ///     },
+    /// )?;
+    /// assert_eq!(b"The 2 1 0.".to_vec(), result);
+    /// # Ok(()) }; example().unwrap()
+    /// ```
+    pub fn stream_replace_all_with<R, W, F>(
+        &self,
+        rdr: R,
+        mut wtr: W,
+        mut replace_with: F,
+    ) -> io::Result<()>
+    where R: io::Read,
+          W: io::Write,
+          F: FnMut(&Match, &[u8], &mut W) -> io::Result<()>
+    {
+        let mut it = StreamChunkIter::new(self, rdr);
+        while let Some(result) = it.next() {
+            let chunk = result?;
+            match chunk {
+                StreamChunk::NonMatch { bytes, .. } => {
+                    wtr.write_all(bytes)?;
+                }
+                StreamChunk::Match { bytes, mat } => {
+                    replace_with(&mat, bytes, &mut wtr)?;
+                }
+            }
+        }
+        Ok(())
+    }
+
+    /// Returns the match kind used by this automaton.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use aho_corasick::{AhoCorasick, MatchKind};
+    ///
+    /// let ac = AhoCorasick::new(&[
+    ///     "foo", "bar", "quux", "baz",
+    /// ]);
+    /// assert_eq!(&MatchKind::Standard, ac.match_kind());
+    /// ```
+    pub fn match_kind(&self) -> &MatchKind {
+        self.imp.match_kind()
+    }
+
+    /// Returns the length of the longest pattern matched by this automaton.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use aho_corasick::AhoCorasick;
+    ///
+    /// let ac = AhoCorasick::new(&[
+    ///     "foo", "bar", "quux", "baz",
+    /// ]);
+    /// assert_eq!(4, ac.max_pattern_len());
+    /// ```
+    pub fn max_pattern_len(&self) -> usize {
+        self.imp.max_pattern_len()
+    }
+
+    /// Return the total number of patterns matched by this automaton.
+    ///
+    /// This includes patterns that may never participate in a match. For
+    /// example, if
+    /// [`MatchKind::LeftmostFirst`](enum.MatchKind.html#variant.LeftmostFirst)
+    /// match semantics are used, and the patterns `Sam` and `Samwise` were
+    /// used to build the automaton, then `Samwise` can never participate in a
+    /// match because `Sam` will always take priority.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use aho_corasick::AhoCorasick;
+    ///
+    /// let ac = AhoCorasick::new(&[
+    ///     "foo", "bar", "baz",
+    /// ]);
+    /// assert_eq!(3, ac.pattern_count());
+    /// ```
+    pub fn pattern_count(&self) -> usize {
+        self.imp.pattern_count()
+    }
+
+    /// Returns true if and only if this automaton supports reporting
+    /// overlapping matches.
+    ///
+    /// If this returns false and overlapping matches are requested, then it
+    /// will result in a panic.
+    ///
+    /// Since leftmost matching is inherently incompatible with overlapping
+    /// matches, only
+    /// [`MatchKind::Standard`](enum.MatchKind.html#variant.Standard)
+    /// supports overlapping matches. This is unlikely to change in the future.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use aho_corasick::{AhoCorasickBuilder, MatchKind};
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .match_kind(MatchKind::Standard)
+    ///     .build(&["foo", "bar", "baz"]);
+    /// assert!(ac.supports_overlapping());
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .match_kind(MatchKind::LeftmostFirst)
+    ///     .build(&["foo", "bar", "baz"]);
+    /// assert!(!ac.supports_overlapping());
+    /// ```
+    pub fn supports_overlapping(&self) -> bool {
+        self.match_kind.supports_overlapping()
+    }
+
+    /// Returns true if and only if this automaton supports stream searching.
+    ///
+    /// If this returns false and stream searching (or replacing) is attempted,
+    /// then it will result in a panic.
+    ///
+    /// Currently, only
+    /// [`MatchKind::Standard`](enum.MatchKind.html#variant.Standard)
+    /// supports streaming. This may be expanded in the future.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use aho_corasick::{AhoCorasickBuilder, MatchKind};
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .match_kind(MatchKind::Standard)
+    ///     .build(&["foo", "bar", "baz"]);
+    /// assert!(ac.supports_stream());
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .match_kind(MatchKind::LeftmostFirst)
+    ///     .build(&["foo", "bar", "baz"]);
+    /// assert!(!ac.supports_stream());
+    /// ```
+    pub fn supports_stream(&self) -> bool {
+        self.match_kind.supports_stream()
+    }
+
+    /// Returns the total amount of heap used by this automaton, in units of
+    /// bytes.
+    ///
+    /// # Examples
+    ///
+    /// This example shows the difference in heap usage between a few
+    /// configurations:
+    ///
+    /// ```ignore
+    /// use aho_corasick::{AhoCorasickBuilder, MatchKind};
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .dfa(false) // default
+    ///     .build(&["foo", "bar", "baz"]);
+    /// assert_eq!(10_336, ac.heap_bytes());
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .dfa(false) // default
+    ///     .ascii_case_insensitive(true)
+    ///     .build(&["foo", "bar", "baz"]);
+    /// assert_eq!(10_384, ac.heap_bytes());
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .dfa(true)
+    ///     .byte_classes(false)
+    ///     .build(&["foo", "bar", "baz"]);
+    /// assert_eq!(20_768, ac.heap_bytes());
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .dfa(true)
+    ///     .byte_classes(true) // default
+    ///     .build(&["foo", "bar", "baz"]);
+    /// assert_eq!(1_248, ac.heap_bytes());
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .dfa(true)
+    ///     .ascii_case_insensitive(true)
+    ///     .build(&["foo", "bar", "baz"]);
+    /// assert_eq!(1_248, ac.heap_bytes());
+    /// ```
+    pub fn heap_bytes(&self) -> usize {
+        match self.imp {
+            Imp::NFA(ref nfa) => nfa.heap_bytes(),
+            Imp::DFA(ref dfa) => dfa.heap_bytes(),
+        }
+    }
+}
+
+/// The internal implementation of Aho-Corasick, which is either an NFA or
+/// a DFA. The NFA is slower but uses less memory. The DFA is faster but uses
+/// more memory.
+#[derive(Clone, Debug)]
+enum Imp<S: StateID> {
+    NFA(NFA<S>),
+    DFA(DFA<S>),
+}
+
+impl<S: StateID> Imp<S> {
+    /// Returns the type of match semantics implemented by this automaton.
+    fn match_kind(&self) -> &MatchKind {
+        match *self {
+            Imp::NFA(ref nfa) => nfa.match_kind(),
+            Imp::DFA(ref dfa) => dfa.match_kind(),
+        }
+    }
+
+    /// Returns the identifier of the start state.
+    fn start_state(&self) -> S {
+        match *self {
+            Imp::NFA(ref nfa) => nfa.start_state(),
+            Imp::DFA(ref dfa) => dfa.start_state(),
+        }
+    }
+
+    /// The length, in bytes, of the longest pattern in this automaton. This
+    /// information is useful for maintaining correct buffer sizes when
+    /// searching on streams.
+    fn max_pattern_len(&self) -> usize {
+        match *self {
+            Imp::NFA(ref nfa) => nfa.max_pattern_len(),
+            Imp::DFA(ref dfa) => dfa.max_pattern_len(),
+        }
+    }
+
+    /// The total number of patterns added to this automaton. This includes
+    /// patterns that may never match. The maximum matching pattern that can be
+    /// reported is exactly one less than this number.
+    fn pattern_count(&self) -> usize {
+        match *self {
+            Imp::NFA(ref nfa) => nfa.pattern_count(),
+            Imp::DFA(ref dfa) => dfa.pattern_count(),
+        }
+    }
+
+    #[inline(always)]
+    fn overlapping_find_at(
+        &self,
+        prestate: &mut PrefilterState,
+        haystack: &[u8],
+        at: usize,
+        state_id: &mut S,
+        match_index: &mut usize,
+    ) -> Option<Match> {
+        match *self {
+            Imp::NFA(ref nfa) => {
+                nfa.overlapping_find_at(
+                    prestate, haystack, at, state_id, match_index,
+                )
+            }
+            Imp::DFA(ref dfa) => {
+                dfa.overlapping_find_at(
+                    prestate, haystack, at, state_id, match_index,
+                )
+            }
+        }
+    }
+
+    #[inline(always)]
+    fn earliest_find_at(
+        &self,
+        prestate: &mut PrefilterState,
+        haystack: &[u8],
+        at: usize,
+        state_id: &mut S,
+    ) -> Option<Match> {
+        match *self {
+            Imp::NFA(ref nfa) => {
+                nfa.earliest_find_at(prestate, haystack, at, state_id)
+            }
+            Imp::DFA(ref dfa) => {
+                dfa.earliest_find_at(prestate, haystack, at, state_id)
+            }
+        }
+    }
+
+    #[inline(always)]
+    fn find_at(
+        &self,
+        prestate: &mut PrefilterState,
+        haystack: &[u8],
+        at: usize,
+        state_id: &mut S,
+    ) -> Option<Match> {
+        match *self {
+            Imp::NFA(ref nfa) => {
+                nfa.find_at(prestate, haystack, at, state_id)
+            }
+            Imp::DFA(ref dfa) => {
+                dfa.find_at(prestate, haystack, at, state_id)
+            }
+        }
+    }
+}
+
+/// An iterator of non-overlapping matches in a particular haystack.
+///
+/// This iterator yields matches according to the
+/// [`MatchKind`](enum.MatchKind.html)
+/// used by this automaton.
+///
+/// This iterator is constructed via the
+/// [`AhoCorasick::find_iter`](struct.AhoCorasick.html#method.find_iter)
+/// method.
+///
+/// The type variable `S` refers to the representation used for state
+/// identifiers. (By default, this is `usize`.)
+///
+/// The lifetime `'a` refers to the lifetime of the `AhoCorasick` automaton.
+///
+/// The lifetime `'b` refers to the lifetime of the haystack being searched.
+#[derive(Debug)]
+pub struct FindIter<'a, 'b, S: 'a + StateID> {
+    fsm: &'a Imp<S>,
+    prestate: PrefilterState,
+    haystack: &'b [u8],
+    pos: usize,
+    start: S,
+}
+
+impl<'a, 'b, S: StateID> FindIter<'a, 'b, S> {
+    fn new(ac: &'a AhoCorasick<S>, haystack: &'b [u8]) -> FindIter<'a, 'b, S> {
+        let prestate = PrefilterState::new(ac.max_pattern_len());
+        let start = ac.imp.start_state();
+        FindIter { fsm: &ac.imp, prestate, haystack, pos: 0, start }
+    }
+}
+
+impl<'a, 'b, S: StateID> Iterator for FindIter<'a, 'b, S> {
+    type Item = Match;
+
+    fn next(&mut self) -> Option<Match> {
+        if self.pos > self.haystack.len() {
+            return None;
+        }
+        let mut start = self.start;
+        let result = self.fsm.find_at(
+            &mut self.prestate, self.haystack, self.pos, &mut start,
+        );
+        let mat = match result {
+            None => return None,
+            Some(mat) => mat,
+        };
+        if mat.end() == self.pos {
+            // If the automaton can match the empty string and if we found an
+            // empty match, then we need to forcefully move the position.
+            self.pos += 1;
+        } else {
+            self.pos = mat.end();
+        }
+        Some(mat)
+    }
+}
+
+/// An iterator of overlapping matches in a particular haystack.
+///
+/// This iterator will report all possible matches in a particular haystack,
+/// even when the matches overlap.
+///
+/// This iterator is constructed via the
+/// [`AhoCorasick::find_overlapping_iter`](struct.AhoCorasick.html#method.find_overlapping_iter)
+/// method.
+///
+/// The type variable `S` refers to the representation used for state
+/// identifiers. (By default, this is `usize`.)
+///
+/// The lifetime `'a` refers to the lifetime of the `AhoCorasick` automaton.
+///
+/// The lifetime `'b` refers to the lifetime of the haystack being searched.
+#[derive(Debug)]
+pub struct FindOverlappingIter<'a, 'b, S: 'a + StateID> {
+    fsm: &'a Imp<S>,
+    prestate: PrefilterState,
+    haystack: &'b [u8],
+    pos: usize,
+    last_match_end: usize,
+    state_id: S,
+    match_index: usize,
+}
+
+impl<'a, 'b, S: StateID> FindOverlappingIter<'a, 'b, S> {
+    fn new(
+        ac: &'a AhoCorasick<S>,
+        haystack: &'b [u8],
+    ) -> FindOverlappingIter<'a, 'b, S> {
+        assert!(
+            ac.supports_overlapping(),
+            "automaton does not support overlapping searches"
+        );
+        let prestate = PrefilterState::new(ac.max_pattern_len());
+        FindOverlappingIter {
+            fsm: &ac.imp,
+            prestate,
+            haystack,
+            pos: 0,
+            last_match_end: 0,
+            state_id: ac.imp.start_state(),
+            match_index: 0,
+        }
+    }
+}
+
+impl<'a, 'b, S: StateID> Iterator for FindOverlappingIter<'a, 'b, S> {
+    type Item = Match;
+
+    fn next(&mut self) -> Option<Match> {
+        let result = self.fsm.overlapping_find_at(
+            &mut self.prestate,
+            self.haystack,
+            self.pos,
+            &mut self.state_id,
+            &mut self.match_index,
+        );
+        match result {
+            None => return None,
+            Some(m) => {
+                self.pos = m.end();
+                Some(m)
+            }
+        }
+    }
+}
+
+/// An iterator that reports Aho-Corasick matches in a stream.
+///
+/// This iterator yields elements of type `io::Result<Match>`, where an error
+/// is reported if there was a problem reading from the underlying stream.
+/// The iterator terminates only when the underlying stream reaches `EOF`.
+///
+/// This iterator is constructed via the
+/// [`AhoCorasick::stream_find_iter`](struct.AhoCorasick.html#method.stream_find_iter)
+/// method.
+///
+/// The type variable `R` refers to the `io::Read` stream that is being read
+/// from.
+///
+/// The type variable `S` refers to the representation used for state
+/// identifiers. (By default, this is `usize`.)
+///
+/// The lifetime `'a` refers to the lifetime of the `AhoCorasick` automaton.
+#[derive(Debug)]
+pub struct StreamFindIter<'a, R, S: 'a + StateID> {
+    it: StreamChunkIter<'a, R, S>,
+}
+
+impl<'a, R: io::Read, S: StateID> StreamFindIter<'a, R, S> {
+    fn new(ac: &'a AhoCorasick<S>, rdr: R) -> StreamFindIter<'a, R, S> {
+        StreamFindIter {
+            it: StreamChunkIter::new(ac, rdr),
+        }
+    }
+}
+
+impl<'a, R: io::Read, S: StateID> Iterator for StreamFindIter<'a, R, S> {
+    type Item = io::Result<Match>;
+
+    fn next(&mut self) -> Option<io::Result<Match>> {
+        loop {
+            match self.it.next() {
+                None => return None,
+                Some(Err(err)) => return Some(Err(err)),
+                Some(Ok(StreamChunk::NonMatch { .. })) => {}
+                Some(Ok(StreamChunk::Match { mat, .. })) => {
+                    return Some(Ok(mat));
+                }
+            }
+        }
+    }
+}
+
+/// An iterator over chunks in an underlying reader. Each chunk either
+/// corresponds to non-matching bytes or matching bytes, but all bytes from
+/// the underlying reader are reported in sequence. There may be an arbitrary
+/// number of non-matching chunks before seeing a matching chunk.
+///
+/// N.B. This does not actually implement Iterator because we need to borrow
+/// from the underlying reader. But conceptually, it's still an iterator.
+#[derive(Debug)]
+struct StreamChunkIter<'a, R, S: 'a + StateID> {
+    /// The AC automaton.
+    fsm: &'a Imp<S>,
+    /// State associated with this automaton's prefilter. It is a heuristic
+    /// for stopping the prefilter if it's deemed ineffective.
+    prestate: PrefilterState,
+    /// The source of bytes we read from.
+    rdr: R,
+    /// A fixed size buffer. This is what we actually search. There are some
+    /// invariants around the buffer's size, namely, it must be big enough to
+    /// contain the longest possible match.
+    buf: Buffer,
+    /// The ID of the FSM state we're currently in.
+    state_id: S,
+    /// The current position at which to start the next search in `buf`.
+    search_pos: usize,
+    /// The absolute position of `search_pos`, where `0` corresponds to the
+    /// position of the first byte read from `rdr`.
+    absolute_pos: usize,
+    /// The ending position of the last StreamChunk that was returned to the
+    /// caller. This position is used to determine whether we need to emit
+    /// non-matching bytes before emitting a match.
+    report_pos: usize,
+    /// A match that should be reported on the next call.
+    pending_match: Option<Match>,
+    /// Enabled only when the automaton can match the empty string. When
+    /// enabled, we need to execute one final search after consuming the
+    /// reader to find the trailing empty match.
+    has_empty_match_at_end: bool,
+}
+
+/// A single chunk yielded by the stream chunk iterator.
+///
+/// The `'r` lifetime refers to the lifetime of the stream chunk iterator.
+#[derive(Debug)]
+enum StreamChunk<'r> {
+    /// A chunk that does not contain any matches.
+    NonMatch { bytes: &'r [u8], start: usize },
+    /// A chunk that precisely contains a match.
+    Match { bytes: &'r [u8], mat: Match },
+}
+
+impl<'a, R: io::Read, S: StateID> StreamChunkIter<'a, R, S> {
+    fn new(ac: &'a AhoCorasick<S>, rdr: R) -> StreamChunkIter<'a, R, S> {
+        assert!(
+            ac.supports_stream(),
+            "stream searching is only supported for Standard match semantics"
+        );
+
+        let prestate = PrefilterState::new(ac.max_pattern_len());
+        let buf = Buffer::new(ac.imp.max_pattern_len());
+        let state_id = ac.imp.start_state();
+        StreamChunkIter {
+            fsm: &ac.imp,
+            prestate,
+            rdr,
+            buf,
+            state_id,
+            absolute_pos: 0,
+            report_pos: 0,
+            search_pos: 0,
+            pending_match: None,
+            has_empty_match_at_end: ac.is_match(""),
+        }
+    }
+
+    fn next<'r>(&'r mut self) -> Option<io::Result<StreamChunk<'r>>> {
+        loop {
+            if let Some(mut mat) = self.pending_match.take() {
+                let bytes = &self.buf.buffer()[mat.start()..mat.end()];
+                self.report_pos = mat.end();
+                mat = mat.increment(self.absolute_pos);
+                return Some(Ok(StreamChunk::Match { bytes, mat }));
+            }
+            if self.search_pos >= self.buf.len() {
+                if let Some(end) = self.unreported() {
+                    let bytes = &self.buf.buffer()[self.report_pos..end];
+                    let start = self.absolute_pos + self.report_pos;
+                    self.report_pos = end;
+                    return Some(Ok(StreamChunk::NonMatch { bytes, start }));
+                }
+                if self.buf.len() >= self.buf.min_buffer_len() {
+                    // This is the point at which we roll our buffer, which we
+                    // only do if our buffer has at least the minimum amount of
+                    // bytes in it. Before rolling, we update our various
+                    // positions to be consistent with the buffer after it has
+                    // been rolled.
+
+                    self.report_pos -=
+                        self.buf.len() - self.buf.min_buffer_len();
+                    self.absolute_pos +=
+                        self.search_pos - self.buf.min_buffer_len();
+                    self.search_pos = self.buf.min_buffer_len();
+                    self.buf.roll();
+                }
+                match self.buf.fill(&mut self.rdr) {
+                    Err(err) => return Some(Err(err)),
+                    Ok(false) => {
+                        // We've hit EOF, but if there are still some
+                        // unreported bytes remaining, return them now.
+                        if self.report_pos < self.buf.len() {
+                            let bytes = &self.buf.buffer()[self.report_pos..];
+                            let start = self.absolute_pos + self.report_pos;
+                            self.report_pos = self.buf.len();
+
+                            let chunk = StreamChunk::NonMatch { bytes, start };
+                            return Some(Ok(chunk));
+                        } else {
+                            // We've reported everything, but there might still
+                            // be a match at the very last position.
+                            if !self.has_empty_match_at_end {
+                                return None;
+                            }
+                            // fallthrough for another search to get trailing
+                            // empty matches
+                            self.has_empty_match_at_end = false;
+                        }
+                    }
+                    Ok(true) => {}
+                }
+            }
+            let result = self.fsm.earliest_find_at(
+                &mut self.prestate,
+                self.buf.buffer(),
+                self.search_pos,
+                &mut self.state_id,
+            );
+            match result {
+                None => {
+                    self.search_pos = self.buf.len();
+                }
+                Some(mat) => {
+                    self.state_id = self.fsm.start_state();
+                    if mat.end() == self.search_pos {
+                        // If the automaton can match the empty string and if
+                        // we found an empty match, then we need to forcefully
+                        // move the position.
+                        self.search_pos += 1;
+                    } else {
+                        self.search_pos = mat.end();
+                    }
+                    self.pending_match = Some(mat.clone());
+                    if self.report_pos < mat.start() {
+                        let bytes =
+                            &self.buf.buffer()[self.report_pos..mat.start()];
+                        let start = self.absolute_pos + self.report_pos;
+                        self.report_pos = mat.start();
+
+                        let chunk = StreamChunk::NonMatch { bytes, start };
+                        return Some(Ok(chunk));
+                    }
+                }
+            }
+        }
+    }
+
+    fn unreported(&self) -> Option<usize> {
+        let end = self.search_pos.saturating_sub(self.buf.min_buffer_len());
+        if self.report_pos < end {
+            Some(end)
+        } else {
+            None
+        }
+    }
+}
+
+/// A builder for configuring an Aho-Corasick automaton.
+#[derive(Clone, Debug)]
+pub struct AhoCorasickBuilder {
+    nfa_builder: nfa::Builder,
+    dfa_builder: dfa::Builder,
+    dfa: bool,
+}
+
+impl Default for AhoCorasickBuilder {
+    fn default() -> AhoCorasickBuilder {
+        AhoCorasickBuilder::new()
+    }
+}
+
+impl AhoCorasickBuilder {
+    /// Create a new builder for configuring an Aho-Corasick automaton.
+    ///
+    /// If you don't need fine grained configuration or aren't sure which knobs
+    /// to set, try using
+    /// [`AhoCorasick::new_auto_configured`](struct.AhoCorasick.html#method.new_auto_configured)
+    /// instead.
+    pub fn new() -> AhoCorasickBuilder {
+        AhoCorasickBuilder {
+            nfa_builder: nfa::Builder::new(),
+            dfa_builder: dfa::Builder::new(),
+            dfa: false,
+        }
+    }
+
+    /// Build an Aho-Corasick automaton using the configuration set on this
+    /// builder.
+    ///
+    /// A builder may be reused to create more automatons.
+    ///
+    /// This method will use the default for representing internal state
+    /// identifiers, which is `usize`. This guarantees that building the
+    /// automaton will succeed and is generally a good default, but can make
+    /// the size of the automaton 2-8 times bigger than it needs to be,
+    /// depending on your target platform.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use aho_corasick::AhoCorasickBuilder;
+    ///
+    /// let patterns = &["foo", "bar", "baz"];
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .build(patterns);
+    /// assert_eq!(Some(1), ac.find("xxx bar xxx").map(|m| m.pattern()));
+    /// ```
+    pub fn build<I, P>(
+        &self,
+        patterns: I,
+    ) -> AhoCorasick
+    where I: IntoIterator<Item=P>,
+          P: AsRef<[u8]>
+    {
+        // The builder only returns an error if the chosen state ID
+        // representation is too small to fit all of the given patterns. In
+        // this case, since we fix the representation to usize, it will always
+        // work because it's impossible to overflow usize since the underlying
+        // storage would OOM long before that happens.
+        self.build_with_size::<usize, I, P>(patterns)
+            .expect("usize state ID type should always work")
+    }
+
+    /// Build an Aho-Corasick automaton using the configuration set on this
+    /// builder with a specific state identifier representation. This only has
+    /// an effect when the `dfa` option is enabled.
+    ///
+    /// Generally, the choices for a state identifier representation are
+    /// `u8`, `u16`, `u32`, `u64` or `usize`, with `usize` being the default.
+    /// The advantage of choosing a smaller state identifier representation
+    /// is that the automaton produced will be smaller. This might be
+    /// beneficial for just generally using less space, or might even allow it
+    /// to fit more of the automaton in your CPU's cache, leading to overall
+    /// better search performance.
+    ///
+    /// Unlike the standard `build` method, this can report an error if the
+    /// state identifier representation cannot support the size of the
+    /// automaton.
+    ///
+    /// Note that the state identifier representation is determined by the
+    /// `S` type variable. This requires a type hint of some sort, either
+    /// by specifying the return type or using the turbofish, e.g.,
+    /// `build_with_size::<u16, _, _>(...)`.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use aho_corasick::{AhoCorasick, AhoCorasickBuilder};
+    ///
+    /// # fn example() -> Result<(), ::aho_corasick::Error> {
+    /// let patterns = &["foo", "bar", "baz"];
+    /// let ac: AhoCorasick<u8> = AhoCorasickBuilder::new()
+    ///     .build_with_size(patterns)?;
+    /// assert_eq!(Some(1), ac.find("xxx bar xxx").map(|m| m.pattern()));
+    /// # Ok(()) }; example().unwrap()
+    /// ```
+    ///
+    /// Or alternatively, with turbofish:
+    ///
+    /// ```
+    /// use aho_corasick::AhoCorasickBuilder;
+    ///
+    /// # fn example() -> Result<(), ::aho_corasick::Error> {
+    /// let patterns = &["foo", "bar", "baz"];
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .build_with_size::<u8, _, _>(patterns)?;
+    /// assert_eq!(Some(1), ac.find("xxx bar xxx").map(|m| m.pattern()));
+    /// # Ok(()) }; example().unwrap()
+    /// ```
+    pub fn build_with_size<S, I, P>(
+        &self,
+        patterns: I,
+    ) -> Result<AhoCorasick<S>>
+    where S: StateID,
+          I: IntoIterator<Item=P>,
+          P: AsRef<[u8]>
+    {
+        let nfa = self.nfa_builder.build(patterns)?;
+        let match_kind = nfa.match_kind().clone();
+        let imp =
+            if self.dfa {
+                let dfa = self.dfa_builder.build(&nfa)?;
+                Imp::DFA(dfa)
+            } else {
+                Imp::NFA(nfa)
+            };
+        Ok(AhoCorasick { imp, match_kind })
+    }
+
+    /// Automatically configure the settings on this builder according to the
+    /// patterns that will be used to construct the automaton.
+    ///
+    /// The idea here is to balance space and time automatically. That is, when
+    /// searching a small number of patterns, this will attempt to use the
+    /// fastest possible configuration since the total space required will be
+    /// small anyway. As the number of patterns grows, this will fall back to
+    /// slower configurations that use less space.
+    ///
+    /// This is guaranteed to never set `match_kind`, but any other option may
+    /// be overridden.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use aho_corasick::AhoCorasickBuilder;
+    ///
+    /// let patterns = &["foo", "bar", "baz"];
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .auto_configure(patterns)
+    ///     .build(patterns);
+    /// assert_eq!(Some(1), ac.find("xxx bar xxx").map(|m| m.pattern()));
+    /// ```
+    pub fn auto_configure<B: AsRef<[u8]>>(
+        &mut self,
+        patterns: &[B],
+    ) -> &mut AhoCorasickBuilder {
+        // N.B. Currently we only use the length of `patterns` to make a
+        // decision here, and could therefore ask for an `ExactSizeIterator`
+        // instead. But it's conceivable that we might adapt this to look at
+        // the total number of bytes, which would requires a second pass.
+        //
+        // The logic here is fairly rudimentary at the moment, but probably
+        // OK. The idea here is to use the fastest thing possible for a small
+        // number of patterns. That is, a DFA with no byte classes, since byte
+        // classes require an extra indirection for every byte searched. With a
+        // moderate number of patterns, we still want a DFA, but save on both
+        // space and compilation time by enabling byte classes. Finally, fall
+        // back to the slower but smaller NFA.
+        if patterns.len() <= 100 {
+            // N.B. Using byte classes can actually be faster by improving
+            // locality, but this only really applies for multi-megabyte
+            // automata (i.e., automata that don't fit in your CPU's cache).
+            self.dfa(true).byte_classes(false);
+        } else if patterns.len() <= 5000 {
+            self.dfa(true);
+        }
+        self
+    }
+
+    /// Set the desired match semantics.
+    ///
+    /// The default is `MatchKind::Standard`, which corresponds to the match
+    /// semantics supported by the standard textbook description of the
+    /// Aho-Corasick algorithm. Namely, matches are reported as soon as they
+    /// are found. Moreover, this is the only way to get overlapping matches
+    /// or do stream searching.
+    ///
+    /// The other kinds of match semantics that are supported are
+    /// `MatchKind::LeftmostFirst` and `MatchKind::LeftmostLongest`. The former
+    /// corresponds to the match you would get if you were to try to match
+    /// each pattern at each position in the haystack in the same order that
+    /// you give to the automaton. That is, it returns the leftmost match
+    /// corresponding the earliest pattern given to the automaton. The latter
+    /// corresponds to finding the longest possible match among all leftmost
+    /// matches.
+    ///
+    /// For more details on match semantics, see the
+    /// [documentation for `MatchKind`](enum.MatchKind.html).
+    ///
+    /// # Examples
+    ///
+    /// In these examples, we demonstrate the differences between match
+    /// semantics for a particular set of patterns in a specific order:
+    /// `b`, `abc`, `abcd`.
+    ///
+    /// Standard semantics:
+    ///
+    /// ```
+    /// use aho_corasick::{AhoCorasickBuilder, MatchKind};
+    ///
+    /// let patterns = &["b", "abc", "abcd"];
+    /// let haystack = "abcd";
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .match_kind(MatchKind::Standard) // default, not necessary
+    ///     .build(patterns);
+    /// let mat = ac.find(haystack).expect("should have a match");
+    /// assert_eq!("b", &haystack[mat.start()..mat.end()]);
+    /// ```
+    ///
+    /// Leftmost-first semantics:
+    ///
+    /// ```
+    /// use aho_corasick::{AhoCorasickBuilder, MatchKind};
+    ///
+    /// let patterns = &["b", "abc", "abcd"];
+    /// let haystack = "abcd";
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .match_kind(MatchKind::LeftmostFirst)
+    ///     .build(patterns);
+    /// let mat = ac.find(haystack).expect("should have a match");
+    /// assert_eq!("abc", &haystack[mat.start()..mat.end()]);
+    /// ```
+    ///
+    /// Leftmost-longest semantics:
+    ///
+    /// ```
+    /// use aho_corasick::{AhoCorasickBuilder, MatchKind};
+    ///
+    /// let patterns = &["b", "abc", "abcd"];
+    /// let haystack = "abcd";
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .match_kind(MatchKind::LeftmostLongest)
+    ///     .build(patterns);
+    /// let mat = ac.find(haystack).expect("should have a match");
+    /// assert_eq!("abcd", &haystack[mat.start()..mat.end()]);
+    /// ```
+    pub fn match_kind(&mut self, kind: MatchKind) -> &mut AhoCorasickBuilder {
+        self.nfa_builder.match_kind(kind);
+        self
+    }
+
+    /// Enable ASCII-aware case insensitive matching.
+    ///
+    /// When this option is enabled, searching will be performed without
+    /// respect to case for ASCII letters (`a-z` and `A-Z`) only.
+    ///
+    /// Enabling this option does not change the search algorithm, but it may
+    /// increase the size of the automaton.
+    ///
+    /// **NOTE:** In the future, support for full Unicode case insensitivity
+    /// may be added, but ASCII case insensitivity is comparatively much
+    /// simpler to add.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use aho_corasick::AhoCorasickBuilder;
+    ///
+    /// let patterns = &["FOO", "bAr", "BaZ"];
+    /// let haystack = "foo bar baz";
+    ///
+    /// let ac = AhoCorasickBuilder::new()
+    ///     .ascii_case_insensitive(true)
+    ///     .build(patterns);
+    /// assert_eq!(3, ac.find_iter(haystack).count());
+    /// ```
+    pub fn ascii_case_insensitive(
+        &mut self,
+        yes: bool,
+    ) -> &mut AhoCorasickBuilder {
+        self.nfa_builder.ascii_case_insensitive(yes);
+        self
+    }
+
+    /// Set the limit on how many NFA states use a dense representation for
+    /// their transitions.
+    ///
+    /// A dense representation uses more space, but supports faster access to
+    /// transitions at search time. Thus, this setting permits the control of a
+    /// space vs time trade off when using the NFA variant of Aho-Corasick.
+    ///
+    /// This limit is expressed in terms of the depth of a state, i.e., the
+    /// number of transitions from the starting state of the NFA. The idea is
+    /// that most of the time searching will be spent near the starting state
+    /// of the automaton, so states near the start state should use a dense
+    /// representation. States further away from the start state would then use
+    /// a sparse representation, which uses less space but is slower to access
+    /// transitions at search time.
+    ///
+    /// By default, this is set to a low but non-zero number.
+    ///
+    /// This setting has no effect if the `dfa` option is enabled.
+    pub fn dense_depth(&mut self, depth: usize) -> &mut AhoCorasickBuilder {
+        self.nfa_builder.dense_depth(depth);
+        self
+    }
+
+    /// Compile the standard Aho-Corasick automaton into a deterministic finite
+    /// automaton (DFA).
+    ///
+    /// When this is disabled (which is the default), then a non-deterministic
+    /// finite automaton (NFA) is used instead.
+    ///
+    /// The main benefit to a DFA is that it can execute searches more quickly
+    /// than a DFA (perhaps 2-4 times as fast). The main drawback is that the
+    /// DFA uses more space and can take much longer to build.
+    ///
+    /// Enabling this option does not change the time complexity for
+    /// constructing the Aho-Corasick automaton (which is `O(p)` where
+    /// `p` is the total number of patterns being compiled). Enabling this
+    /// option does however reduce the time complexity of non-overlapping
+    /// searches from `O(n + p)` to `O(n)`, where `n` is the length of the
+    /// haystack.
+    ///
+    /// In general, it's a good idea to enable this if you're searching a
+    /// small number of fairly short patterns (~1000), or if you want the
+    /// fastest possible search without regard to compilation time or space
+    /// usage.
+    pub fn dfa(&mut self, yes: bool) -> &mut AhoCorasickBuilder {
+        self.dfa = yes;
+        self
+    }
+
+    /// Enable heuristic prefilter optimizations.
+    ///
+    /// When enabled, searching will attempt to quickly skip to match
+    /// candidates using specialized literal search routines. A prefilter
+    /// cannot always be used, and is generally treated as a heuristic. It
+    /// can be useful to disable this if the prefilter is observed to be
+    /// sub-optimal for a particular workload.
+    ///
+    /// This is enabled by default.
+    pub fn prefilter(&mut self, yes: bool) -> &mut AhoCorasickBuilder {
+        self.nfa_builder.prefilter(yes);
+        self
+    }
+
+    /// Shrink the size of the transition alphabet by mapping bytes to their
+    /// equivalence classes. This only has an effect when the `dfa` option is
+    /// enabled.
+    ///
+    /// When enabled, each a DFA will use a map from all possible bytes
+    /// to their corresponding equivalence class. Each equivalence class
+    /// represents a set of bytes that does not discriminate between a match
+    /// and a non-match in the DFA. For example, the patterns `bar` and `baz`
+    /// have at least five equivalence classes: singleton sets of `b`, `a`, `r`
+    /// and `z`, and a final set that contains every other byte.
+    ///
+    /// The advantage of this map is that the size of the transition table can
+    /// be reduced drastically from `#states * 256 * sizeof(id)` to
+    /// `#states * k * sizeof(id)` where `k` is the number of equivalence
+    /// classes. As a result, total space usage can decrease substantially.
+    /// Moreover, since a smaller alphabet is used, compilation becomes faster
+    /// as well.
+    ///
+    /// The disadvantage of this map is that every byte searched must be
+    /// passed through this map before it can be used to determine the next
+    /// transition. This has a small match time performance cost. However, if
+    /// the DFA is otherwise very large without byte classes, then using byte
+    /// classes can greatly improve memory locality and thus lead to better
+    /// overall performance.
+    ///
+    /// This option is enabled by default.
+    pub fn byte_classes(&mut self, yes: bool) -> &mut AhoCorasickBuilder {
+        self.dfa_builder.byte_classes(yes);
+        self
+    }
+
+    /// Premultiply state identifiers in the transition table. This only has
+    /// an effect when the `dfa` option is enabled.
+    ///
+    /// When enabled, state identifiers are premultiplied to point to their
+    /// corresponding row in the transition table. That is, given the `i`th
+    /// state, its corresponding premultiplied identifier is `i * k` where `k`
+    /// is the alphabet size of the automaton. (The alphabet size is at most
+    /// 256, but is in practice smaller if byte classes is enabled.)
+    ///
+    /// When state identifiers are not premultiplied, then the identifier of
+    /// the `i`th state is `i`.
+    ///
+    /// The advantage of premultiplying state identifiers is that is saves a
+    /// multiplication instruction per byte when searching with a DFA. This has
+    /// been observed to lead to a 20% performance benefit in micro-benchmarks.
+    ///
+    /// The primary disadvantage of premultiplying state identifiers is
+    /// that they require a larger integer size to represent. For example,
+    /// if the DFA has 200 states, then its premultiplied form requires 16
+    /// bits to represent every possible state identifier, where as its
+    /// non-premultiplied form only requires 8 bits.
+    ///
+    /// This option is enabled by default.
+    pub fn premultiply(&mut self, yes: bool) -> &mut AhoCorasickBuilder {
+        self.dfa_builder.premultiply(yes);
+        self
+    }
+}
+
+/// A knob for controlling the match semantics of an Aho-Corasick automaton.
+///
+/// There are two generally different ways that Aho-Corasick automatons can
+/// report matches. The first way is the "standard" approach that results from
+/// implementing most textbook explanations of Aho-Corasick. The second way is
+/// to report only the leftmost non-overlapping matches. The leftmost approach
+/// is in turn split into two different ways of resolving ambiguous matches:
+/// leftmost-first and leftmost-longest.
+///
+/// The `Standard` match kind is the default and is the only one that supports
+/// overlapping matches and stream searching. (Trying to find overlapping
+/// or streaming matches using leftmost match semantics will result in a
+/// panic.) The `Standard` match kind will report matches as they are seen.
+/// When searching for overlapping matches, then all possible matches are
+/// reported. When searching for non-overlapping matches, the first match seen
+/// is reported. For example, for non-overlapping matches, given the patterns
+/// `abcd` and `b` and the subject string `abcdef`, only a match for `b` is
+/// reported since it is detected first. The `abcd` match is never reported
+/// since it overlaps with the `b` match.
+///
+/// In contrast, the leftmost match kind always prefers the leftmost match
+/// among all possible matches. Given the same example as above with `abcd` and
+/// `b` as patterns and `abcdef` as the subject string, the leftmost match is
+/// `abcd` since it begins before the `b` match, even though the `b` match is
+/// detected before the `abcd` match. In this case, the `b` match is not
+/// reported at all since it overlaps with the `abcd` match.
+///
+/// The difference between leftmost-first and leftmost-longest is in how they
+/// resolve ambiguous matches when there are multiple leftmost matches to
+/// choose from. Leftmost-first always chooses the pattern that was provided
+/// earliest, where as leftmost-longest always chooses the longest matching
+/// pattern. For example, given the patterns `a` and `ab` and the subject
+/// string `ab`, the leftmost-first match is `a` but the leftmost-longest match
+/// is `ab`. Conversely, if the patterns were given in reverse order, i.e.,
+/// `ab` and `a`, then both the leftmost-first and leftmost-longest matches
+/// would be `ab`. Stated differently, the leftmost-first match depends on the
+/// order in which the patterns were given to the Aho-Corasick automaton.
+/// Because of that, when leftmost-first matching is used, if a pattern `A`
+/// that appears before a pattern `B` is a prefix of `B`, then it is impossible
+/// to ever observe a match of `B`.
+///
+/// If you're not sure which match kind to pick, then stick with the standard
+/// kind, which is the default. In particular, if you need overlapping or
+/// streaming matches, then you _must_ use the standard kind. The leftmost
+/// kinds are useful in specific circumstances. For example, leftmost-first can
+/// be very useful as a way to implement match priority based on the order of
+/// patterns given and leftmost-longest can be useful for dictionary searching
+/// such that only the longest matching words are reported.
+///
+/// # Relationship with regular expression alternations
+///
+/// Understanding match semantics can be a little tricky, and one easy way
+/// to conceptualize non-overlapping matches from an Aho-Corasick automaton
+/// is to think about them as a simple alternation of literals in a regular
+/// expression. For example, let's say we wanted to match the strings
+/// `Sam` and `Samwise`, which would turn into the regex `Sam|Samwise`. It
+/// turns out that regular expression engines have two different ways of
+/// matching this alternation. The first way, leftmost-longest, is commonly
+/// found in POSIX compatible implementations of regular expressions (such as
+/// `grep`). The second way, leftmost-first, is commonly found in backtracking
+/// implementations such as Perl. (Some regex engines, such as RE2 and Rust's
+/// regex engine do not use backtracking, but still implement leftmost-first
+/// semantics in an effort to match the behavior of dominant backtracking
+/// regex engines such as those found in Perl, Ruby, Python, Javascript and
+/// PHP.)
+///
+/// That is, when matching `Sam|Samwise` against `Samwise`, a POSIX regex
+/// will match `Samwise` because it is the longest possible match, but a
+/// Perl-like regex will match `Sam` since it appears earlier in the
+/// alternation. Indeed, the regex `Sam|Samwise` in a Perl-like regex engine
+/// will never match `Samwise` since `Sam` will always have higher priority.
+/// Conversely, matching the regex `Samwise|Sam` against `Samwise` will lead to
+/// a match of `Samwise` in both POSIX and Perl-like regexes since `Samwise` is
+/// still longest match, but it also appears earlier than `Sam`.
+///
+/// The "standard" match semantics of Aho-Corasick generally don't correspond
+/// to the match semantics of any large group of regex implementations, so
+/// there's no direct analogy that can be made here. Standard match semantics
+/// are generally useful for overlapping matches, or if you just want to see
+/// matches as they are detected.
+///
+/// The main conclusion to draw from this section is that the match semantics
+/// can be tweaked to precisely match either Perl-like regex alternations or
+/// POSIX regex alternations.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum MatchKind {
+    /// Use standard match semantics, which support overlapping matches. When
+    /// used with non-overlapping matches, matches are reported as they are
+    /// seen.
+    Standard,
+    /// Use leftmost-first match semantics, which reports leftmost matches.
+    /// When there are multiple possible leftmost matches, the match
+    /// corresponding to the pattern that appeared earlier when constructing
+    /// the automaton is reported.
+    ///
+    /// This does **not** support overlapping matches or stream searching. If
+    /// this match kind is used, attempting to find overlapping matches or
+    /// stream matches will panic.
+    LeftmostFirst,
+    /// Use leftmost-longest match semantics, which reports leftmost matches.
+    /// When there are multiple possible leftmost matches, the longest match
+    /// is chosen.
+    ///
+    /// This does **not** support overlapping matches or stream searching. If
+    /// this match kind is used, attempting to find overlapping matches or
+    /// stream matches will panic.
+    LeftmostLongest,
+    /// Hints that destructuring should not be exhaustive.
+    ///
+    /// This enum may grow additional variants, so this makes sure clients
+    /// don't count on exhaustive matching. (Otherwise, adding a new variant
+    /// could break existing code.)
+    #[doc(hidden)]
+    __Nonexhaustive,
+}
+
+/// The default match kind is `MatchKind::Standard`.
+impl Default for MatchKind {
+    fn default() -> MatchKind {
+        MatchKind::Standard
+    }
+}
+
+impl MatchKind {
+    fn supports_overlapping(&self) -> bool {
+        self.is_standard()
+    }
+
+    fn supports_stream(&self) -> bool {
+        // TODO: It may be possible to support this. It's hard.
+        //
+        // See: https://github.com/rust-lang/regex/issues/425#issuecomment-471367838
+        self.is_standard()
+    }
+
+    pub(crate) fn is_standard(&self) -> bool {
+        *self == MatchKind::Standard
+    }
+
+    pub(crate) fn is_leftmost(&self) -> bool {
+        *self == MatchKind::LeftmostFirst
+        || *self == MatchKind::LeftmostLongest
+    }
+
+    pub(crate) fn is_leftmost_first(&self) -> bool {
+        *self == MatchKind::LeftmostFirst
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn oibits() {
+        use std::panic::{RefUnwindSafe, UnwindSafe};
+
+        fn assert_send<T: Send>() {}
+        fn assert_sync<T: Sync>() {}
+        fn assert_unwind_safe<T: RefUnwindSafe + UnwindSafe>() {}
+
+        assert_send::<AhoCorasick>();
+        assert_sync::<AhoCorasick>();
+        assert_unwind_safe::<AhoCorasick>();
+        assert_send::<AhoCorasickBuilder>();
+        assert_sync::<AhoCorasickBuilder>();
+        assert_unwind_safe::<AhoCorasickBuilder>();
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/aho_corasick/automaton.rs.html b/target/doc/src/aho_corasick/automaton.rs.html new file mode 100644 index 0000000..342f8f6 --- /dev/null +++ b/target/doc/src/aho_corasick/automaton.rs.html @@ -0,0 +1,805 @@ +automaton.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+
+use ahocorasick::MatchKind;
+use prefilter::{Prefilter, PrefilterState};
+use state_id::{StateID, dead_id, fail_id};
+use Match;
+
+// NOTE: This trait was essentially copied from regex-automata, with some
+// wording changed since we use this trait for NFAs in addition to DFAs in this
+// crate. Additionally, we do not export this trait. It's only used internally
+// to reduce code duplication. The regex-automata crate needs to expose it
+// because its Regex type is generic over implementations of this trait. In
+// this crate, we can encapsulate everything behind the AhoCorasick type.
+
+/// A trait describing the interface of an Aho-Corasick finite state machine.
+///
+/// Every automaton has exactly one fail state, one dead state and exactly one
+/// start state. Generally, these correspond to the first, second and third
+/// states, respectively. The failure state is always treated as a sentinel.
+/// That is, no correct Aho-Corasick automaton will ever transition into the
+/// fail state. The dead state, however, can be transitioned into, but only
+/// when leftmost-first or leftmost-longest match semantics are enabled and
+/// only when at least one match has been observed.
+///
+/// Every automaton also has one or more match states, such that
+/// `Automaton::is_match_state_unchecked(id)` returns `true` if and only if
+/// `id` corresponds to a match state.
+pub trait Automaton {
+    /// The representation used for state identifiers in this automaton.
+    ///
+    /// Typically, this is one of `u8`, `u16`, `u32`, `u64` or `usize`.
+    type ID: StateID;
+
+    /// The type of matching that should be done.
+    fn match_kind(&self) -> &MatchKind;
+
+    /// An optional prefilter for quickly skipping to the next candidate match.
+    /// A prefilter must report at least every match, although it may report
+    /// positions that do not correspond to a match. That is, it must not allow
+    /// false negatives, but can allow false positives.
+    ///
+    /// Currently, a prefilter only runs when the automaton is in the start
+    /// state. That is, the position reported by a prefilter should always
+    /// correspond to the start of a potential match.
+    fn prefilter(&self) -> Option<&Prefilter>;
+
+    /// Return the identifier of this automaton's start state.
+    fn start_state(&self) -> Self::ID;
+
+    /// Returns true if and only if the given state identifier refers to a
+    /// valid state.
+    fn is_valid(&self, id: Self::ID) -> bool;
+
+    /// Returns true if and only if the given identifier corresponds to a match
+    /// state.
+    ///
+    /// The state ID given must be valid, or else implementors may panic.
+    fn is_match_state(&self, id: Self::ID) -> bool;
+
+    /// Returns true if and only if the given identifier corresponds to a state
+    /// that is either the dead state or a match state.
+    ///
+    /// Depending on the implementation of the automaton, this routine can
+    /// be used to save a branch in the core matching loop. Nevertheless,
+    /// `is_match_state(id) || id == dead_id()` is always a valid
+    /// implementation. Indeed, this is the default implementation.
+    ///
+    /// The state ID given must be valid, or else implementors may panic.
+    fn is_match_or_dead_state(&self, id: Self::ID) -> bool {
+        id == dead_id() || self.is_match_state(id)
+    }
+
+    /// If the given state is a match state, return the match corresponding
+    /// to the given match index. `end` must be the ending position of the
+    /// detected match. If no match exists or if `match_index` exceeds the
+    /// number of matches in this state, then `None` is returned.
+    ///
+    /// The state ID given must be valid, or else implementors may panic.
+    ///
+    /// If the given state ID is correct and if the `match_index` is less than
+    /// the number of matches for that state, then this is guaranteed to return
+    /// a match.
+    fn get_match(
+        &self,
+        id: Self::ID,
+        match_index: usize,
+        end: usize,
+    ) -> Option<Match>;
+
+    /// Returns the number of matches for the given state. If the given state
+    /// is not a match state, then this returns 0.
+    ///
+    /// The state ID given must be valid, or else implementors must panic.
+    fn match_count(&self, id: Self::ID) -> usize;
+
+    /// Given the current state that this automaton is in and the next input
+    /// byte, this method returns the identifier of the next state. The
+    /// identifier returned must always be valid and may never correspond to
+    /// the fail state. The returned identifier may, however, point to the
+    /// dead state.
+    ///
+    /// This is not safe so that implementors may look up the next state
+    /// without memory safety checks such as bounds checks. As such, callers
+    /// must ensure that the given identifier corresponds to a valid automaton
+    /// state. Implementors must, in turn, ensure that this routine is safe for
+    /// all valid state identifiers and for all possible `u8` values.
+    unsafe fn next_state_unchecked(
+        &self,
+        current: Self::ID,
+        input: u8,
+    ) -> Self::ID;
+
+    /// Like next_state_unchecked, but debug_asserts that the underlying
+    /// implementation never returns a `fail_id()` for the next state.
+    unsafe fn next_state_unchecked_no_fail(
+        &self,
+        current: Self::ID,
+        input: u8,
+    ) -> Self::ID {
+        let next = self.next_state_unchecked(current, input);
+        // We should never see a transition to the failure state.
+        debug_assert!(
+            next != fail_id(),
+            "automaton should never return fail_id for next state"
+        );
+        next
+    }
+
+    /// Execute a search using standard match semantics.
+    ///
+    /// This can be used even when the automaton was constructed with leftmost
+    /// match semantics when you want to find the earliest possible match. This
+    /// can also be used as part of an overlapping search implementation.
+    ///
+    /// N.B. This does not report a match if `state_id` is given as a matching
+    /// state. As such, this should not be used directly.
+    #[inline(always)]
+    fn standard_find_at(
+        &self,
+        prestate: &mut PrefilterState,
+        haystack: &[u8],
+        at: usize,
+        state_id: &mut Self::ID,
+    ) -> Option<Match> {
+        if let Some(pre) = self.prefilter() {
+            self.standard_find_at_imp(
+                prestate, Some(pre), haystack, at, state_id,
+            )
+        } else {
+            self.standard_find_at_imp(
+                prestate, None, haystack, at, state_id,
+            )
+        }
+    }
+
+    // It's important for this to always be inlined. Namely, it's only caller
+    // is standard_find_at, and the inlining should remove the case analysis
+    // for prefilter scanning when there is no prefilter available.
+    #[inline(always)]
+    fn standard_find_at_imp(
+        &self,
+        prestate: &mut PrefilterState,
+        prefilter: Option<&Prefilter>,
+        haystack: &[u8],
+        at: usize,
+        state_id: &mut Self::ID,
+    ) -> Option<Match> {
+        // This is necessary for guaranteeing a safe API, since we use the
+        // state ID below in a function that exhibits UB if called with an
+        // invalid state ID.
+        assert!(
+            self.is_valid(*state_id),
+            "{} is not a valid state ID",
+            state_id.to_usize()
+        );
+        unsafe {
+            let start = haystack.as_ptr();
+            let end = haystack[haystack.len()..].as_ptr();
+            let mut ptr = haystack[at..].as_ptr();
+            while ptr < end {
+                if let Some(pre) = prefilter {
+                    if prestate.is_effective()
+                        && *state_id == self.start_state()
+                    {
+                        let at = ptr as usize - start as usize;
+                        match pre.next_candidate(haystack, at) {
+                            None => return None,
+                            Some(i) => {
+                                prestate.update(i - at);
+                                ptr = start.offset(i as isize);
+                            }
+                        }
+                    }
+                }
+                // SAFETY: next_state is safe for all possible u8 values,
+                // so the only thing we're concerned about is the validity
+                // of `state_id`. `state_id` either comes from the caller
+                // (in which case, we assert above that it is valid), or it
+                // comes from the return value of next_state, which is also
+                // guaranteed to be valid.
+                *state_id = self.next_state_unchecked_no_fail(*state_id, *ptr);
+                ptr = ptr.offset(1);
+                // This routine always quits immediately after seeing a
+                // match, and since dead states can only come after seeing
+                // a match, seeing a dead state here is impossible.
+                debug_assert!(
+                    *state_id != dead_id(),
+                    "standard find should never see a dead state"
+                );
+
+                let end = ptr as usize - start as usize;
+                if let Some(m) = self.get_match(*state_id, 0, end) {
+                    return Some(m);
+                }
+            }
+            None
+        }
+    }
+
+    /// Execute a search using leftmost (either first or longest) match
+    /// semantics.
+    ///
+    /// The principle difference between searching with standard semantics and
+    /// searching with leftmost semantics is that leftmost searching will
+    /// continue searching even after a match has been found. Once a match
+    /// is found, the search does not stop until either the haystack has been
+    /// exhausted or a dead state is observed in the automaton. (Dead states
+    /// only exist in automatons constructed with leftmost semantics.) That is,
+    /// we rely on the construction of the automaton to tell us when to quit.
+    #[inline(never)]
+    fn leftmost_find_at(
+        &self,
+        prestate: &mut PrefilterState,
+        haystack: &[u8],
+        at: usize,
+        state_id: &mut Self::ID,
+    ) -> Option<Match> {
+        if let Some(pre) = self.prefilter() {
+            self.leftmost_find_at_imp(
+                prestate, Some(pre), haystack, at, state_id,
+            )
+        } else {
+            self.leftmost_find_at_imp(
+                prestate, None, haystack, at, state_id,
+            )
+        }
+    }
+
+    // It's important for this to always be inlined. Namely, it's only caller
+    // is leftmost_find_at, and the inlining should remove the case analysis
+    // for prefilter scanning when there is no prefilter available.
+    #[inline(always)]
+    fn leftmost_find_at_imp(
+        &self,
+        prestate: &mut PrefilterState,
+        prefilter: Option<&Prefilter>,
+        haystack: &[u8],
+        at: usize,
+        state_id: &mut Self::ID,
+    ) -> Option<Match> {
+        debug_assert!(self.match_kind().is_leftmost());
+        // This is necessary for guaranteeing a safe API, since we use the
+        // state ID below in a function that exhibits UB if called with an
+        // invalid state ID.
+        assert!(
+            self.is_valid(*state_id),
+            "{} is not a valid state ID",
+            state_id.to_usize()
+        );
+        unsafe {
+            let start = haystack.as_ptr();
+            let end = haystack[haystack.len()..].as_ptr();
+            let mut ptr = haystack[at..].as_ptr();
+
+            let mut last_match = self.get_match(*state_id, 0, at);
+            while ptr < end {
+                if let Some(pre) = prefilter {
+                    if prestate.is_effective()
+                        && *state_id == self.start_state()
+                    {
+                        let at = ptr as usize - start as usize;
+                        match pre.next_candidate(haystack, at) {
+                            None => return None,
+                            Some(i) => {
+                                prestate.update(i - at);
+                                ptr = start.offset(i as isize);
+                            }
+                        }
+                    }
+                }
+                // SAFETY: next_state is safe for all possible u8 values,
+                // so the only thing we're concerned about is the validity
+                // of `state_id`. `state_id` either comes from the caller
+                // (in which case, we assert above that it is valid), or it
+                // comes from the return value of next_state, which is also
+                // guaranteed to be valid.
+                *state_id = self.next_state_unchecked_no_fail(*state_id, *ptr);
+                ptr = ptr.offset(1);
+                if self.is_match_or_dead_state(*state_id) {
+                    if *state_id == dead_id() {
+                        // The only way to enter into a dead state is if a
+                        // match has been found, so we assert as much. This
+                        // is different from normal automata, where you might
+                        // enter a dead state if you know a subsequent match
+                        // will never be found (regardless of whether a match
+                        // has already been found). For Aho-Corasick, it is
+                        // built so that we can match at any position, so the
+                        // possibility of a match always exists.
+                        debug_assert!(
+                            last_match.is_some(),
+                            "failure state should only be seen after match"
+                        );
+                        return last_match;
+                    }
+                    let end = ptr as usize - start as usize;
+                    last_match = self.get_match(*state_id, 0, end);
+                }
+            }
+            last_match
+        }
+    }
+
+    /// Execute an overlapping search.
+    ///
+    /// When executing an overlapping match, the previous state ID in addition
+    /// to the previous match index should be given. If there are more matches
+    /// at the given state, then the match is reported and the given index is
+    /// incremented.
+    #[inline(always)]
+    fn overlapping_find_at(
+        &self,
+        prestate: &mut PrefilterState,
+        haystack: &[u8],
+        at: usize,
+        state_id: &mut Self::ID,
+        match_index: &mut usize,
+    ) -> Option<Match> {
+        let match_count = self.match_count(*state_id);
+        if *match_index < match_count {
+            // This is guaranteed to return a match since
+            // match_index < match_count.
+            let result = self.get_match(
+                *state_id,
+                *match_index,
+                at,
+            );
+            debug_assert!(result.is_some(), "must be a match");
+            *match_index += 1;
+            return result;
+        }
+
+        *match_index = 0;
+        match self.standard_find_at(prestate, haystack, at, state_id) {
+            None => None,
+            Some(m) => {
+                *match_index = 1;
+                Some(m)
+            }
+        }
+    }
+
+    /// Return the earliest match found. This returns as soon as we know that
+    /// we have a match. As such, this does not necessarily correspond to the
+    /// leftmost starting match, but rather, the leftmost position at which a
+    /// match ends.
+    #[inline(always)]
+    fn earliest_find_at(
+        &self,
+        prestate: &mut PrefilterState,
+        haystack: &[u8],
+        at: usize,
+        state_id: &mut Self::ID,
+    ) -> Option<Match> {
+        if *state_id == self.start_state() {
+            if let Some(m) = self.get_match(*state_id, 0, at) {
+                return Some(m);
+            }
+        }
+        self.standard_find_at(prestate, haystack, at, state_id)
+    }
+
+    /// A convenience function for finding the next match according to the
+    /// match semantics of this automaton. For standard match semantics, this
+    /// finds the earliest match. Otherwise, the leftmost match is found.
+    #[inline(always)]
+    fn find_at(
+        &self,
+        prestate: &mut PrefilterState,
+        haystack: &[u8],
+        at: usize,
+        state_id: &mut Self::ID,
+    ) -> Option<Match> {
+        match *self.match_kind() {
+            MatchKind::Standard => {
+                self.earliest_find_at(prestate, haystack, at, state_id)
+            }
+            MatchKind::LeftmostFirst | MatchKind::LeftmostLongest => {
+                self.leftmost_find_at(prestate, haystack, at, state_id)
+            }
+            MatchKind::__Nonexhaustive => unreachable!(),
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/aho_corasick/buffer.rs.html b/target/doc/src/aho_corasick/buffer.rs.html new file mode 100644 index 0000000..614fb6a --- /dev/null +++ b/target/doc/src/aho_corasick/buffer.rs.html @@ -0,0 +1,265 @@ +buffer.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+
+use std::cmp;
+use std::io;
+use std::ptr;
+
+/// The default buffer capacity that we use for the stream buffer.
+const DEFAULT_BUFFER_CAPACITY: usize = 8 * (1<<10); // 8 KB
+
+/// A fairly simple roll buffer for supporting stream searches.
+///
+/// This buffer acts as a temporary place to store a fixed amount of data when
+/// reading from a stream. Its central purpose is to allow "rolling" some
+/// suffix of the data to the beginning of the buffer before refilling it with
+/// more data from the stream. For example, let's say we are trying to match
+/// "foobar" on a stream. When we report the match, we'd like to not only
+/// report the correct offsets at which the match occurs, but also the matching
+/// bytes themselves. So let's say our stream is a file with the following
+/// contents: `test test foobar test test`. Now assume that we happen to read
+/// the aforementioned file in two chunks: `test test foo` and `bar test test`.
+/// Naively, it would not be possible to report a single contiguous `foobar`
+/// match, but this roll buffer allows us to do that. Namely, after the second
+/// read, the contents of the buffer should be `st foobar test test`, where the
+/// search should ultimately resume immediately after `foo`. (The prefix `st `
+/// is included because the roll buffer saves N bytes at the end of the buffer,
+/// where N is the maximum possible length of a match.)
+///
+/// A lot of the logic for dealing with this is unfortunately split out between
+/// this roll buffer and the `StreamChunkIter`.
+#[derive(Debug)]
+pub struct Buffer {
+    /// The raw buffer contents. This has a fixed size and never increases.
+    buf: Vec<u8>,
+    /// The minimum size of the buffer, which is equivalent to the maximum
+    /// possible length of a match. This corresponds to the amount that we
+    /// roll
+    min: usize,
+    /// The end of the contents of this buffer.
+    end: usize,
+}
+
+impl Buffer {
+    /// Create a new buffer for stream searching. The minimum buffer length
+    /// given should be the size of the maximum possible match length.
+    pub fn new(min_buffer_len: usize) -> Buffer {
+        let min = cmp::max(1, min_buffer_len);
+        // The minimum buffer amount is also the amount that we roll our
+        // buffer in order to support incremental searching. To this end,
+        // our actual capacity needs to be at least 1 byte bigger than our
+        // minimum amount, otherwise we won't have any overlap. In actuality,
+        // we want our buffer to be a bit bigger than that for performance
+        // reasons, so we set a lower bound of `8 * min`.
+        //
+        // TODO: It would be good to find a way to test the streaming
+        // implementation with the minimal buffer size.
+        let capacity = cmp::max(min * 8, DEFAULT_BUFFER_CAPACITY);
+        Buffer {
+            buf: vec![0; capacity],
+            min,
+            end: 0,
+        }
+    }
+
+    /// Return the contents of this buffer.
+    #[inline]
+    pub fn buffer(&self) -> &[u8] {
+        &self.buf[..self.end]
+    }
+
+    /// Return the minimum size of the buffer. The only way a buffer may be
+    /// smaller than this is if the stream itself contains less than the
+    /// minimum buffer amount.
+    #[inline]
+    pub fn min_buffer_len(&self) -> usize {
+        self.min
+    }
+
+    /// Return the total length of the contents in the buffer.
+    #[inline]
+    pub fn len(&self) -> usize {
+        self.end
+    }
+
+    /// Return all free capacity in this buffer.
+    fn free_buffer(&mut self) -> &mut [u8] {
+        &mut self.buf[self.end..]
+    }
+
+    /// Refill the contents of this buffer by reading as much as possible into
+    /// this buffer's free capacity. If no more bytes could be read, then this
+    /// returns false. Otherwise, this reads until it has filled the buffer
+    /// past the minimum amount.
+    pub fn fill<R: io::Read>(&mut self, mut rdr: R) -> io::Result<bool> {
+        let mut readany = false;
+        loop {
+            let readlen = rdr.read(self.free_buffer())?;
+            if readlen == 0 {
+                return Ok(readany);
+            }
+            readany = true;
+            self.end += readlen;
+            if self.len() >= self.min {
+                return Ok(true);
+            }
+        }
+    }
+
+    /// Roll the contents of the buffer so that the suffix of this buffer is
+    /// moved to the front and all other contents are dropped. The size of the
+    /// suffix corresponds precisely to the minimum buffer length.
+    ///
+    /// This should only be called when the entire contents of this buffer have
+    /// been searched.
+    pub fn roll(&mut self) {
+        let roll_start = self.end
+            .checked_sub(self.min)
+            .expect("buffer capacity should be bigger than minimum amount");
+        let roll_len = self.min;
+
+        assert!(roll_start + roll_len <= self.end);
+        unsafe {
+            // SAFETY: A buffer contains Copy data, so there's no problem
+            // moving it around. Safety also depends on our indices being in
+            // bounds, which they always should be, given the assert above.
+            ptr::copy(
+                self.buf[roll_start..].as_ptr(),
+                self.buf.as_mut_ptr(),
+                roll_len,
+            );
+        }
+        self.end = roll_len;
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/aho_corasick/classes.rs.html b/target/doc/src/aho_corasick/classes.rs.html new file mode 100644 index 0000000..6f16b92 --- /dev/null +++ b/target/doc/src/aho_corasick/classes.rs.html @@ -0,0 +1,489 @@ +classes.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+
+use std::fmt;
+
+/// A representation of byte oriented equivalence classes.
+///
+/// This is used in an FSM to reduce the size of the transition table. This can
+/// have a particularly large impact not only on the total size of an FSM, but
+/// also on compile times.
+#[derive(Clone, Copy)]
+pub struct ByteClasses([u8; 256]);
+
+impl ByteClasses {
+    /// Creates a new set of equivalence classes where all bytes are mapped to
+    /// the same class.
+    pub fn empty() -> ByteClasses {
+        ByteClasses([0; 256])
+    }
+
+    /// Creates a new set of equivalence classes where each byte belongs to
+    /// its own equivalence class.
+    pub fn singletons() -> ByteClasses {
+        let mut classes = ByteClasses::empty();
+        for i in 0..256 {
+            classes.set(i as u8, i as u8);
+        }
+        classes
+    }
+
+    /// Set the equivalence class for the given byte.
+    #[inline]
+    pub fn set(&mut self, byte: u8, class: u8) {
+        self.0[byte as usize] = class;
+    }
+
+    /// Get the equivalence class for the given byte.
+    #[inline]
+    pub fn get(&self, byte: u8) -> u8 {
+        self.0[byte as usize]
+    }
+
+    /// Get the equivalence class for the given byte while forcefully
+    /// eliding bounds checks.
+    #[inline]
+    pub unsafe fn get_unchecked(&self, byte: u8) -> u8 {
+        *self.0.get_unchecked(byte as usize)
+    }
+
+    /// Return the total number of elements in the alphabet represented by
+    /// these equivalence classes. Equivalently, this returns the total number
+    /// of equivalence classes.
+    #[inline]
+    pub fn alphabet_len(&self) -> usize {
+        self.0[255] as usize + 1
+    }
+
+    /// Returns true if and only if every byte in this class maps to its own
+    /// equivalence class. Equivalently, there are 256 equivalence classes
+    /// and each class contains exactly one byte.
+    #[inline]
+    pub fn is_singleton(&self) -> bool {
+        self.alphabet_len() == 256
+    }
+
+    /// Returns an iterator over a sequence of representative bytes from each
+    /// equivalence class. Namely, this yields exactly N items, where N is
+    /// equivalent to the number of equivalence classes. Each item is an
+    /// arbitrary byte drawn from each equivalence class.
+    ///
+    /// This is useful when one is determinizing an NFA and the NFA's alphabet
+    /// hasn't been converted to equivalence classes yet. Picking an arbitrary
+    /// byte from each equivalence class then permits a full exploration of
+    /// the NFA instead of using every possible byte value.
+    pub fn representatives(&self) -> ByteClassRepresentatives {
+        ByteClassRepresentatives { classes: self, byte: 0, last_class: None }
+    }
+
+    /// Returns all of the bytes in the given equivalence class.
+    ///
+    /// The second element in the tuple indicates the number of elements in
+    /// the array.
+    fn elements(&self, equiv: u8) -> ([u8; 256], usize) {
+        let (mut array, mut len) = ([0; 256], 0);
+        for b in 0..256 {
+            if self.get(b as u8) == equiv {
+                array[len] = b as u8;
+                len += 1;
+            }
+        }
+        (array, len)
+    }
+}
+
+impl fmt::Debug for ByteClasses {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        if self.is_singleton() {
+            write!(f, "ByteClasses({{singletons}})")
+        } else {
+            write!(f, "ByteClasses(")?;
+            for equiv in 0..self.alphabet_len() {
+                let (members, len) = self.elements(equiv as u8);
+                write!(f, " {} => {:?}", equiv, &members[..len])?;
+            }
+            write!(f, ")")
+        }
+    }
+}
+
+/// An iterator over representative bytes from each equivalence class.
+#[derive(Debug)]
+pub struct ByteClassRepresentatives<'a> {
+    classes: &'a ByteClasses,
+    byte: usize,
+    last_class: Option<u8>,
+}
+
+impl<'a> Iterator for ByteClassRepresentatives<'a> {
+    type Item = u8;
+
+    fn next(&mut self) -> Option<u8> {
+        while self.byte < 256 {
+            let byte = self.byte as u8;
+            let class = self.classes.get(byte);
+            self.byte += 1;
+
+            if self.last_class != Some(class) {
+                self.last_class = Some(class);
+                return Some(byte);
+            }
+        }
+        None
+    }
+}
+
+/// A byte class builder keeps track of an *approximation* of equivalence
+/// classes of bytes during NFA construction. That is, every byte in an
+/// equivalence class cannot discriminate between a match and a non-match.
+///
+/// For example, in the literals `abc` and `xyz`, the bytes [\x00-`], [d-w]
+/// and [{-\xFF] never discriminate between a match and a non-match, precisely
+/// because they never occur in the literals anywhere.
+///
+/// Note though that this does not necessarily compute the minimal set of
+/// equivalence classes. For example, in the literals above, the byte ranges
+/// [\x00-`], [d-w] and [{-\xFF] are all treated as distinct equivalence
+/// classes even though they could be treated a single class. The reason for
+/// this is implementation complexity. In the future, we should endeavor to
+/// compute the minimal equivalence classes since they can have a rather large
+/// impact on the size of the DFA.
+///
+/// The representation here is 256 booleans, all initially set to false. Each
+/// boolean maps to its corresponding byte based on position. A `true` value
+/// indicates the end of an equivalence class, where its corresponding byte
+/// and all of the bytes corresponding to all previous contiguous `false`
+/// values are in the same equivalence class.
+///
+/// This particular representation only permits contiguous ranges of bytes to
+/// be in the same equivalence class, which means that we can never discover
+/// the true minimal set of equivalence classes.
+#[derive(Debug)]
+pub struct ByteClassBuilder(Vec<bool>);
+
+impl ByteClassBuilder {
+    /// Create a new builder of byte classes where all bytes are part of the
+    /// same equivalence class.
+    pub fn new() -> ByteClassBuilder {
+        ByteClassBuilder(vec![false; 256])
+    }
+
+    /// Indicate the the range of byte given (inclusive) can discriminate a
+    /// match between it and all other bytes outside of the range.
+    pub fn set_range(&mut self, start: u8, end: u8) {
+        debug_assert!(start <= end);
+        if start > 0 {
+            self.0[start as usize - 1] = true;
+        }
+        self.0[end as usize] = true;
+    }
+
+    /// Build byte classes that map all byte values to their corresponding
+    /// equivalence class. The last mapping indicates the largest equivalence
+    /// class identifier (which is never bigger than 255).
+    pub fn build(&self) -> ByteClasses {
+        let mut classes = ByteClasses::empty();
+        let mut class = 0u8;
+        let mut i = 0;
+        loop {
+            classes.set(i as u8, class as u8);
+            if i >= 255 {
+                break;
+            }
+            if self.0[i] {
+                class = class.checked_add(1).unwrap();
+            }
+            i += 1;
+        }
+        classes
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn byte_classes() {
+        let mut set = ByteClassBuilder::new();
+        set.set_range(b'a', b'z');
+
+        let classes = set.build();
+        assert_eq!(classes.get(0), 0);
+        assert_eq!(classes.get(1), 0);
+        assert_eq!(classes.get(2), 0);
+        assert_eq!(classes.get(b'a' - 1), 0);
+        assert_eq!(classes.get(b'a'), 1);
+        assert_eq!(classes.get(b'm'), 1);
+        assert_eq!(classes.get(b'z'), 1);
+        assert_eq!(classes.get(b'z' + 1), 2);
+        assert_eq!(classes.get(254), 2);
+        assert_eq!(classes.get(255), 2);
+
+        let mut set = ByteClassBuilder::new();
+        set.set_range(0, 2);
+        set.set_range(4, 6);
+        let classes = set.build();
+        assert_eq!(classes.get(0), 0);
+        assert_eq!(classes.get(1), 0);
+        assert_eq!(classes.get(2), 0);
+        assert_eq!(classes.get(3), 1);
+        assert_eq!(classes.get(4), 2);
+        assert_eq!(classes.get(5), 2);
+        assert_eq!(classes.get(6), 2);
+        assert_eq!(classes.get(7), 3);
+        assert_eq!(classes.get(255), 3);
+    }
+
+    #[test]
+    fn full_byte_classes() {
+        let mut set = ByteClassBuilder::new();
+        for i in 0..256u16 {
+            set.set_range(i as u8, i as u8);
+        }
+        assert_eq!(set.build().alphabet_len(), 256);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/aho_corasick/dfa.rs.html b/target/doc/src/aho_corasick/dfa.rs.html new file mode 100644 index 0000000..490370b --- /dev/null +++ b/target/doc/src/aho_corasick/dfa.rs.html @@ -0,0 +1,1379 @@ +dfa.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+
+use std::mem::size_of;
+
+use ahocorasick::MatchKind;
+use automaton::Automaton;
+use classes::ByteClasses;
+use error::Result;
+use nfa::{NFA, PatternID, PatternLength};
+use prefilter::{Prefilter, PrefilterObj, PrefilterState};
+use state_id::{StateID, dead_id, fail_id, premultiply_overflow_error};
+use Match;
+
+#[derive(Clone, Debug)]
+pub enum DFA<S> {
+    Standard(Standard<S>),
+    ByteClass(ByteClass<S>),
+    Premultiplied(Premultiplied<S>),
+    PremultipliedByteClass(PremultipliedByteClass<S>),
+}
+
+impl<S: StateID> DFA<S> {
+    fn repr(&self) -> &Repr<S> {
+        match *self {
+            DFA::Standard(ref dfa) => dfa.repr(),
+            DFA::ByteClass(ref dfa) => dfa.repr(),
+            DFA::Premultiplied(ref dfa) => dfa.repr(),
+            DFA::PremultipliedByteClass(ref dfa) => dfa.repr(),
+        }
+    }
+
+    pub fn match_kind(&self) -> &MatchKind {
+        &self.repr().match_kind
+    }
+
+    pub fn heap_bytes(&self) -> usize {
+        self.repr().heap_bytes
+    }
+
+    pub fn max_pattern_len(&self) -> usize {
+        self.repr().max_pattern_len
+    }
+
+    pub fn pattern_count(&self) -> usize {
+        self.repr().pattern_count
+    }
+
+    pub fn start_state(&self) -> S {
+        self.repr().start_id
+    }
+
+    #[inline(always)]
+    pub fn overlapping_find_at(
+        &self,
+        prestate: &mut PrefilterState,
+        haystack: &[u8],
+        at: usize,
+        state_id: &mut S,
+        match_index: &mut usize,
+    ) -> Option<Match> {
+        match *self {
+            DFA::Standard(ref dfa) => {
+                dfa.overlapping_find_at(
+                    prestate, haystack, at, state_id, match_index,
+                )
+            }
+            DFA::ByteClass(ref dfa) => {
+                dfa.overlapping_find_at(
+                    prestate, haystack, at, state_id, match_index,
+                )
+            }
+            DFA::Premultiplied(ref dfa) => {
+                dfa.overlapping_find_at(
+                    prestate, haystack, at, state_id, match_index,
+                )
+            }
+            DFA::PremultipliedByteClass(ref dfa) => {
+                dfa.overlapping_find_at(
+                    prestate, haystack, at, state_id, match_index,
+                )
+            }
+        }
+    }
+
+    #[inline(always)]
+    pub fn earliest_find_at(
+        &self,
+        prestate: &mut PrefilterState,
+        haystack: &[u8],
+        at: usize,
+        state_id: &mut S,
+    ) -> Option<Match> {
+        match *self {
+            DFA::Standard(ref dfa) => {
+                dfa.earliest_find_at(prestate, haystack, at, state_id)
+            }
+            DFA::ByteClass(ref dfa) => {
+                dfa.earliest_find_at(prestate, haystack, at, state_id)
+            }
+            DFA::Premultiplied(ref dfa) => {
+                dfa.earliest_find_at(prestate, haystack, at, state_id)
+            }
+            DFA::PremultipliedByteClass(ref dfa) => {
+                dfa.earliest_find_at(prestate, haystack, at, state_id)
+            }
+        }
+    }
+
+    #[inline(always)]
+    pub fn find_at(
+        &self,
+        prestate: &mut PrefilterState,
+        haystack: &[u8],
+        at: usize,
+        state_id: &mut S,
+    ) -> Option<Match> {
+        match *self {
+            DFA::Standard(ref dfa) => {
+                dfa.find_at(prestate, haystack, at, state_id)
+            }
+            DFA::ByteClass(ref dfa) => {
+                dfa.find_at(prestate, haystack, at, state_id)
+            }
+            DFA::Premultiplied(ref dfa) => {
+                dfa.find_at(prestate, haystack, at, state_id)
+            }
+            DFA::PremultipliedByteClass(ref dfa) => {
+                dfa.find_at(prestate, haystack, at, state_id)
+            }
+        }
+    }
+}
+
+#[derive(Clone, Debug)]
+pub struct Standard<S>(Repr<S>);
+
+impl<S: StateID> Standard<S> {
+    fn repr(&self) -> &Repr<S> {
+        &self.0
+    }
+}
+
+impl<S: StateID> Automaton for Standard<S> {
+    type ID = S;
+
+    fn match_kind(&self) -> &MatchKind {
+        &self.repr().match_kind
+    }
+
+    fn prefilter(&self) -> Option<&Prefilter> {
+        self.repr().prefilter.as_ref().map(|p| p.as_ref())
+    }
+
+    fn start_state(&self) -> S {
+        self.repr().start_id
+    }
+
+    fn is_valid(&self, id: S) -> bool {
+        id.to_usize() < self.repr().state_count
+    }
+
+    fn is_match_state(&self, id: S) -> bool {
+        self.repr().is_match_state(id)
+    }
+
+    fn is_match_or_dead_state(&self, id: S) -> bool {
+        self.repr().is_match_or_dead_state(id)
+    }
+
+    fn get_match(
+        &self,
+        id: S,
+        match_index: usize,
+        end: usize,
+    ) -> Option<Match> {
+        self.repr().get_match(id, match_index, end)
+    }
+
+    fn match_count(&self, id: S) -> usize {
+        self.repr().match_count(id)
+    }
+
+    unsafe fn next_state_unchecked(&self, current: S, input: u8) -> S {
+        let o = current.to_usize() * 256 + input as usize;
+        *self.repr().trans.get_unchecked(o)
+    }
+}
+
+#[derive(Clone, Debug)]
+pub struct ByteClass<S>(Repr<S>);
+
+impl<S: StateID> ByteClass<S> {
+    fn repr(&self) -> &Repr<S> {
+        &self.0
+    }
+}
+
+impl<S: StateID> Automaton for ByteClass<S> {
+    type ID = S;
+
+    fn match_kind(&self) -> &MatchKind {
+        &self.repr().match_kind
+    }
+
+    fn prefilter(&self) -> Option<&Prefilter> {
+        self.repr().prefilter.as_ref().map(|p| p.as_ref())
+    }
+
+    fn start_state(&self) -> S {
+        self.repr().start_id
+    }
+
+    fn is_valid(&self, id: S) -> bool {
+        id.to_usize() < self.repr().state_count
+    }
+
+    fn is_match_state(&self, id: S) -> bool {
+        self.repr().is_match_state(id)
+    }
+
+    fn is_match_or_dead_state(&self, id: S) -> bool {
+        self.repr().is_match_or_dead_state(id)
+    }
+
+    fn get_match(
+        &self,
+        id: S,
+        match_index: usize,
+        end: usize,
+    ) -> Option<Match> {
+        self.repr().get_match(id, match_index, end)
+    }
+
+    fn match_count(&self, id: S) -> usize {
+        self.repr().match_count(id)
+    }
+
+    unsafe fn next_state_unchecked(&self, current: S, input: u8) -> S {
+        let alphabet_len = self.repr().byte_classes.alphabet_len();
+        let input = self.repr().byte_classes.get_unchecked(input);
+        let o = current.to_usize() * alphabet_len + input as usize;
+        *self.repr().trans.get_unchecked(o)
+    }
+}
+
+#[derive(Clone, Debug)]
+pub struct Premultiplied<S>(Repr<S>);
+
+impl<S: StateID> Premultiplied<S> {
+    fn repr(&self) -> &Repr<S> {
+        &self.0
+    }
+}
+
+impl<S: StateID> Automaton for Premultiplied<S> {
+    type ID = S;
+
+    fn match_kind(&self) -> &MatchKind {
+        &self.repr().match_kind
+    }
+
+    fn prefilter(&self) -> Option<&Prefilter> {
+        self.repr().prefilter.as_ref().map(|p| p.as_ref())
+    }
+
+    fn start_state(&self) -> S {
+        self.repr().start_id
+    }
+
+    fn is_valid(&self, id: S) -> bool {
+        (id.to_usize() / 256) < self.repr().state_count
+    }
+
+    fn is_match_state(&self, id: S) -> bool {
+        self.repr().is_match_state(id)
+    }
+
+    fn is_match_or_dead_state(&self, id: S) -> bool {
+        self.repr().is_match_or_dead_state(id)
+    }
+
+    fn get_match(
+        &self,
+        id: S,
+        match_index: usize,
+        end: usize,
+    ) -> Option<Match> {
+        if id > self.repr().max_match {
+            return None;
+        }
+        self.repr()
+            .matches
+            .get(id.to_usize() / 256)
+            .and_then(|m| m.get(match_index))
+            .map(|&(id, len)| Match { pattern: id, len, end })
+    }
+
+    fn match_count(&self, id: S) -> usize {
+        let o = id.to_usize() / 256;
+        self.repr().matches[o].len()
+    }
+
+    unsafe fn next_state_unchecked(&self, current: S, input: u8) -> S {
+        let o = current.to_usize() + input as usize;
+        *self.repr().trans.get_unchecked(o)
+    }
+}
+
+#[derive(Clone, Debug)]
+pub struct PremultipliedByteClass<S>(Repr<S>);
+
+impl<S: StateID> PremultipliedByteClass<S> {
+    fn repr(&self) -> &Repr<S> {
+        &self.0
+    }
+}
+
+impl<S: StateID> Automaton for PremultipliedByteClass<S> {
+    type ID = S;
+
+    fn match_kind(&self) -> &MatchKind {
+        &self.repr().match_kind
+    }
+
+    fn prefilter(&self) -> Option<&Prefilter> {
+        self.repr().prefilter.as_ref().map(|p| p.as_ref())
+    }
+
+    fn start_state(&self) -> S {
+        self.repr().start_id
+    }
+
+    fn is_valid(&self, id: S) -> bool {
+        (id.to_usize() / self.repr().alphabet_len()) < self.repr().state_count
+    }
+
+    fn is_match_state(&self, id: S) -> bool {
+        self.repr().is_match_state(id)
+    }
+
+    fn is_match_or_dead_state(&self, id: S) -> bool {
+        self.repr().is_match_or_dead_state(id)
+    }
+
+    fn get_match(
+        &self,
+        id: S,
+        match_index: usize,
+        end: usize,
+    ) -> Option<Match> {
+        if id > self.repr().max_match {
+            return None;
+        }
+        self.repr()
+            .matches
+            .get(id.to_usize() / self.repr().alphabet_len())
+            .and_then(|m| m.get(match_index))
+            .map(|&(id, len)| Match { pattern: id, len, end })
+    }
+
+    fn match_count(&self, id: S) -> usize {
+        let o = id.to_usize() / self.repr().alphabet_len();
+        self.repr().matches[o].len()
+    }
+
+    unsafe fn next_state_unchecked(&self, current: S, input: u8) -> S {
+        let input = self.repr().byte_classes.get_unchecked(input);
+        let o = current.to_usize() + input as usize;
+        *self.repr().trans.get_unchecked(o)
+    }
+}
+
+#[derive(Clone, Debug)]
+pub struct Repr<S> {
+    match_kind: MatchKind,
+    premultiplied: bool,
+    start_id: S,
+    /// The length, in bytes, of the longest pattern in this automaton. This
+    /// information is useful for keeping correct buffer sizes when searching
+    /// on streams.
+    max_pattern_len: usize,
+    /// The total number of patterns added to this automaton. This includes
+    /// patterns that may never match.
+    pattern_count: usize,
+    state_count: usize,
+    max_match: S,
+    /// The number of bytes of heap used by this NFA's transition table.
+    heap_bytes: usize,
+    /// A prefilter for quickly detecting candidate matchs, if pertinent.
+    prefilter: Option<PrefilterObj>,
+    byte_classes: ByteClasses,
+    trans: Vec<S>,
+    matches: Vec<Vec<(PatternID, PatternLength)>>,
+}
+
+impl<S: StateID> Repr<S> {
+    /// Returns the total alphabet size for this DFA.
+    ///
+    /// If byte classes are enabled, then this corresponds to the number of
+    /// equivalence classes. If they are disabled, then this is always 256.
+    fn alphabet_len(&self) -> usize {
+        self.byte_classes.alphabet_len()
+    }
+
+    /// Returns true only if the given state is a match state.
+    fn is_match_state(&self, id: S) -> bool {
+        id <= self.max_match && id > dead_id()
+    }
+
+    /// Returns true only if the given state is either a dead state or a match
+    /// state.
+    fn is_match_or_dead_state(&self, id: S) -> bool {
+        id <= self.max_match
+    }
+
+    /// Get the ith match for the given state, where the end position of a
+    /// match was found at `end`.
+    ///
+    /// # Panics
+    ///
+    /// The caller must ensure that the given state identifier is valid,
+    /// otherwise this may panic. The `match_index` need not be valid. That is,
+    /// if the given state has no matches then this returns `None`.
+    fn get_match(
+        &self,
+        id: S,
+        match_index: usize,
+        end: usize,
+    ) -> Option<Match> {
+        if id > self.max_match {
+            return None;
+        }
+        self.matches
+            .get(id.to_usize())
+            .and_then(|m| m.get(match_index))
+            .map(|&(id, len)| Match { pattern: id, len, end })
+    }
+
+    /// Return the total number of matches for the given state.
+    ///
+    /// # Panics
+    ///
+    /// The caller must ensure that the given identifier is valid, or else
+    /// this panics.
+    fn match_count(&self, id: S) -> usize {
+        self.matches[id.to_usize()].len()
+    }
+
+    /// Get the next state given `from` as the current state and `byte` as the
+    /// current input byte.
+    fn next_state(&self, from: S, byte: u8) -> S {
+        let alphabet_len = self.alphabet_len();
+        let byte = self.byte_classes.get(byte);
+        self.trans[from.to_usize() * alphabet_len + byte as usize]
+    }
+
+    /// Set the `byte` transition for the `from` state to point to `to`.
+    fn set_next_state(&mut self, from: S, byte: u8, to: S) {
+        let alphabet_len = self.alphabet_len();
+        let byte = self.byte_classes.get(byte);
+        self.trans[from.to_usize() * alphabet_len + byte as usize] = to;
+    }
+
+    /// Swap the given states in place.
+    fn swap_states(&mut self, id1: S, id2: S) {
+        assert!(!self.premultiplied, "can't swap states in premultiplied DFA");
+
+        let o1 = id1.to_usize() * self.alphabet_len();
+        let o2 = id2.to_usize() * self.alphabet_len();
+        for b in 0..self.alphabet_len() {
+            self.trans.swap(o1 + b, o2 + b);
+        }
+        self.matches.swap(id1.to_usize(), id2.to_usize());
+    }
+
+    /// This routine shuffles all match states in this DFA to the beginning
+    /// of the DFA such that every non-match state appears after every match
+    /// state. (With one exception: the special fail and dead states remain as
+    /// the first two states.)
+    ///
+    /// The purpose of doing this shuffling is to avoid an extra conditional
+    /// in the search loop, and in particular, detecting whether a state is a
+    /// match or not does not need to access any memory.
+    ///
+    /// This updates `self.max_match` to point to the last matching state as
+    /// well as `self.start` if the starting state was moved.
+    fn shuffle_match_states(&mut self) {
+        assert!(
+            !self.premultiplied,
+            "cannot shuffle match states of premultiplied DFA"
+        );
+
+        if self.state_count <= 1 {
+            return;
+        }
+
+        let mut first_non_match = self.start_id.to_usize();
+        while first_non_match < self.state_count
+            && self.matches[first_non_match].len() > 0
+        {
+            first_non_match += 1;
+        }
+
+        let mut swaps: Vec<S> = vec![fail_id(); self.state_count];
+        let mut cur = self.state_count - 1;
+        while cur > first_non_match {
+            if self.matches[cur].len() > 0 {
+                self.swap_states(
+                    S::from_usize(cur),
+                    S::from_usize(first_non_match),
+                );
+                swaps[cur] = S::from_usize(first_non_match);
+                swaps[first_non_match] = S::from_usize(cur);
+
+                first_non_match += 1;
+                while first_non_match < cur
+                    && self.matches[first_non_match].len() > 0
+                {
+                    first_non_match += 1;
+                }
+            }
+            cur -= 1;
+        }
+        for id in (0..self.state_count).map(S::from_usize) {
+            let alphabet_len = self.alphabet_len();
+            let offset = id.to_usize() * alphabet_len;
+            for next in &mut self.trans[offset..offset + alphabet_len] {
+                if swaps[next.to_usize()] != fail_id() {
+                    *next = swaps[next.to_usize()];
+                }
+            }
+        }
+        if swaps[self.start_id.to_usize()] != fail_id() {
+            self.start_id = swaps[self.start_id.to_usize()];
+        }
+        self.max_match = S::from_usize(first_non_match - 1);
+    }
+
+    fn premultiply(&mut self) -> Result<()> {
+        if self.premultiplied || self.state_count <= 1 {
+            return Ok(());
+        }
+
+        let alpha_len = self.alphabet_len();
+        premultiply_overflow_error(
+            S::from_usize(self.state_count - 1),
+            alpha_len,
+        )?;
+
+        for id in (2..self.state_count).map(S::from_usize) {
+            let offset = id.to_usize() * alpha_len;
+            for next in &mut self.trans[offset..offset + alpha_len] {
+                if *next == dead_id() {
+                    continue;
+                }
+                *next = S::from_usize(next.to_usize() * alpha_len);
+            }
+        }
+        self.premultiplied = true;
+        self.start_id = S::from_usize(self.start_id.to_usize() * alpha_len);
+        self.max_match = S::from_usize(self.max_match.to_usize() * alpha_len);
+        Ok(())
+    }
+
+    /// Computes the total amount of heap used by this NFA in bytes.
+    fn calculate_size(&mut self) {
+        let mut size =
+            (self.trans.len() * size_of::<S>())
+            + (self.matches.len() *
+               size_of::<Vec<(PatternID, PatternLength)>>());
+        for state_matches in &self.matches {
+            size +=
+                state_matches.len() * size_of::<(PatternID, PatternLength)>();
+        }
+        self.heap_bytes = size;
+    }
+}
+
+/// A builder for configuring the determinization of an NFA into a DFA.
+#[derive(Clone, Debug)]
+pub struct Builder {
+    premultiply: bool,
+    byte_classes: bool,
+}
+
+impl Builder {
+    /// Create a new builder for a DFA.
+    pub fn new() -> Builder {
+        Builder {
+            premultiply: true,
+            byte_classes: true,
+        }
+    }
+
+    /// Build a DFA from the given NFA.
+    ///
+    /// This returns an error if the state identifiers exceed their
+    /// representation size. This can only happen when state ids are
+    /// premultiplied (which is enabled by default).
+    pub fn build<S: StateID>(&self, nfa: &NFA<S>) -> Result<DFA<S>> {
+        let byte_classes =
+            if self.byte_classes {
+                nfa.byte_classes().clone()
+            } else {
+                ByteClasses::singletons()
+            };
+        let alphabet_len = byte_classes.alphabet_len();
+        let trans = vec![fail_id(); alphabet_len * nfa.state_len()];
+        let matches = vec![vec![]; nfa.state_len()];
+        let mut repr = Repr {
+            match_kind: nfa.match_kind().clone(),
+            premultiplied: false,
+            start_id: nfa.start_state(),
+            max_pattern_len: nfa.max_pattern_len(),
+            pattern_count: nfa.pattern_count(),
+            state_count: nfa.state_len(),
+            max_match: fail_id(),
+            heap_bytes: 0,
+            prefilter: nfa.prefilter_obj().map(|p| p.clone()),
+            byte_classes: byte_classes.clone(),
+            trans: trans,
+            matches: matches,
+        };
+        for id in (0..nfa.state_len()).map(S::from_usize) {
+            repr.matches[id.to_usize()].extend_from_slice(nfa.matches(id));
+
+            let fail = nfa.failure_transition(id);
+            nfa.iter_all_transitions(&byte_classes, id, |b, mut next| {
+                if next == fail_id() {
+                    next = nfa_next_state_memoized(nfa, &repr, id, fail, b);
+                }
+                repr.set_next_state(id, b, next);
+            });
+        }
+        repr.shuffle_match_states();
+        repr.calculate_size();
+        if self.premultiply {
+            repr.premultiply()?;
+            if byte_classes.is_singleton() {
+                Ok(DFA::Premultiplied(Premultiplied(repr)))
+            } else {
+                Ok(DFA::PremultipliedByteClass(PremultipliedByteClass(repr)))
+            }
+        } else {
+            if byte_classes.is_singleton() {
+                Ok(DFA::Standard(Standard(repr)))
+            } else {
+                Ok(DFA::ByteClass(ByteClass(repr)))
+            }
+        }
+    }
+
+    /// Whether to use byte classes or in the DFA.
+    pub fn byte_classes(&mut self, yes: bool) -> &mut Builder {
+        self.byte_classes = yes;
+        self
+    }
+
+    /// Whether to premultiply state identifier in the DFA.
+    pub fn premultiply(&mut self, yes: bool) -> &mut Builder {
+        self.premultiply = yes;
+        self
+    }
+}
+
+/// This returns the next NFA transition (including resolving failure
+/// transitions), except once it sees a state id less than the id of the DFA
+/// state that is currently being populated, then we no longer need to follow
+/// failure transitions and can instead query the pre-computed state id from
+/// the DFA itself.
+///
+/// In general, this should only be called when a failure transition is seen.
+fn nfa_next_state_memoized<S: StateID>(
+    nfa: &NFA<S>,
+    dfa: &Repr<S>,
+    populating: S,
+    mut current: S,
+    input: u8,
+) -> S {
+    loop {
+        if current < populating {
+            return dfa.next_state(current, input);
+        }
+        let next = nfa.next_state(current, input);
+        if next != fail_id() {
+            return next;
+        }
+        current = nfa.failure_transition(current);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/aho_corasick/error.rs.html b/target/doc/src/aho_corasick/error.rs.html new file mode 100644 index 0000000..15a7b83 --- /dev/null +++ b/target/doc/src/aho_corasick/error.rs.html @@ -0,0 +1,209 @@ +error.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+
+use std::error;
+use std::fmt;
+use std::result;
+
+pub type Result<T> = result::Result<T, Error>;
+
+/// An error that occurred during the construction of an Aho-Corasick
+/// automaton.
+#[derive(Clone, Debug)]
+pub struct Error {
+    kind: ErrorKind,
+}
+
+/// The kind of error that occurred.
+#[derive(Clone, Debug)]
+pub enum ErrorKind {
+    /// An error that occurs when constructing an automaton would require the
+    /// use of a state ID that overflows the chosen state ID representation.
+    /// For example, if one is using `u8` for state IDs and builds a DFA with
+    /// 257 states, then the last state's ID will be `256` which cannot be
+    /// represented with `u8`.
+    StateIDOverflow {
+        /// The maximum possible state ID.
+        max: usize,
+    },
+    /// An error that occurs when premultiplication of state IDs is requested
+    /// when constructing an Aho-Corasick DFA, but doing so would overflow the
+    /// chosen state ID representation.
+    ///
+    /// When `max == requested_max`, then the state ID would overflow `usize`.
+    PremultiplyOverflow {
+        /// The maximum possible state id.
+        max: usize,
+        /// The maximum ID required by premultiplication.
+        requested_max: usize,
+    }
+}
+
+impl Error {
+    /// Return the kind of this error.
+    pub fn kind(&self) -> &ErrorKind {
+        &self.kind
+    }
+
+    pub(crate) fn state_id_overflow(max: usize) -> Error {
+        Error { kind: ErrorKind::StateIDOverflow { max } }
+    }
+
+    pub(crate) fn premultiply_overflow(
+        max: usize,
+        requested_max: usize,
+    ) -> Error {
+        Error { kind: ErrorKind::PremultiplyOverflow { max, requested_max } }
+    }
+}
+
+impl error::Error for Error {
+    fn description(&self) -> &str {
+        match self.kind {
+            ErrorKind::StateIDOverflow { .. } => {
+                "state id representation too small"
+            }
+            ErrorKind::PremultiplyOverflow { .. } => {
+                "state id representation too small for premultiplication"
+            }
+        }
+    }
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self.kind {
+            ErrorKind::StateIDOverflow { max } => {
+                write!(
+                    f,
+                    "building the automaton failed because it required \
+                     building more states that can be identified, where the \
+                     maximum ID for the chosen representation is {}",
+                    max,
+                )
+            }
+            ErrorKind::PremultiplyOverflow { max, requested_max } => {
+                if max == requested_max {
+                    write!(
+                        f,
+                        "premultiplication of states requires the ability to \
+                         represent a state ID greater than what can fit on \
+                         this platform's usize, which is {}",
+                        ::std::usize::MAX,
+                    )
+                } else {
+                    write!(
+                        f,
+                        "premultiplication of states requires the ability to \
+                         represent at least a state ID of {}, but the chosen \
+                         representation only permits a maximum state ID of {}",
+                        requested_max, max,
+                    )
+                }
+            }
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/aho_corasick/lib.rs.html b/target/doc/src/aho_corasick/lib.rs.html new file mode 100644 index 0000000..ec05f93 --- /dev/null +++ b/target/doc/src/aho_corasick/lib.rs.html @@ -0,0 +1,595 @@ +lib.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+
+/*!
+A library for finding occurrences of many patterns at once. This library
+provides multiple pattern search principally through an implementation of the
+[Aho-Corasick algorithm](https://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_algorithm),
+which builds a fast finite state machine for executing searches in linear time.
+
+Additionally, this library provides a number of configuration options for
+building the automaton that permit controlling the space versus time trade
+off. Other features include simple ASCII case insensitive matching, finding
+overlapping matches, replacements, searching streams and even searching and
+replacing text in streams.
+
+Finally, unlike all other (known) Aho-Corasick implementations, this one
+supports enabling
+[leftmost-first](enum.MatchKind.html#variant.LeftmostFirst)
+or
+[leftmost-longest](enum.MatchKind.html#variant.LeftmostFirst)
+match semantics, using a (seemingly) novel alternative construction algorithm.
+For more details on what match semantics means, see the
+[`MatchKind`](enum.MatchKind.html)
+type.
+
+# Overview
+
+This section gives a brief overview of the primary types in this crate:
+
+* [`AhoCorasick`](struct.AhoCorasick.html) is the primary type and represents
+  an Aho-Corasick automaton. This is the type you use to execute searches.
+* [`AhoCorasickBuilder`](struct.AhoCorasickBuilder.html) can be used to build
+  an Aho-Corasick automaton, and supports configuring a number of options.
+* [`Match`](struct.Match.html) represents a single match reported by an
+  Aho-Corasick automaton. Each match has two pieces of information: the pattern
+  that matched and the start and end byte offsets corresponding to the position
+  in the haystack at which it matched.
+
+# Example: basic searching
+
+This example shows how to search for occurrences of multiple patterns
+simultaneously. Each match includes the pattern that matched along with the
+byte offsets of the match.
+
+```
+use aho_corasick::AhoCorasick;
+
+let patterns = &["apple", "maple", "Snapple"];
+let haystack = "Nobody likes maple in their apple flavored Snapple.";
+
+let ac = AhoCorasick::new(patterns);
+let mut matches = vec![];
+for mat in ac.find_iter(haystack) {
+    matches.push((mat.pattern(), mat.start(), mat.end()));
+}
+assert_eq!(matches, vec![
+    (1, 13, 18),
+    (0, 28, 33),
+    (2, 43, 50),
+]);
+```
+
+# Example: case insensitivity
+
+This is like the previous example, but matches `Snapple` case insensitively
+using `AhoCorasickBuilder`:
+
+```
+use aho_corasick::AhoCorasickBuilder;
+
+let patterns = &["apple", "maple", "snapple"];
+let haystack = "Nobody likes maple in their apple flavored Snapple.";
+
+let ac = AhoCorasickBuilder::new()
+    .ascii_case_insensitive(true)
+    .build(patterns);
+let mut matches = vec![];
+for mat in ac.find_iter(haystack) {
+    matches.push((mat.pattern(), mat.start(), mat.end()));
+}
+assert_eq!(matches, vec![
+    (1, 13, 18),
+    (0, 28, 33),
+    (2, 43, 50),
+]);
+```
+
+# Example: replacing matches in a stream
+
+This example shows how to execute a search and replace on a stream without
+loading the entire stream into memory first.
+
+```
+use aho_corasick::AhoCorasick;
+
+# fn example() -> Result<(), ::std::io::Error> {
+let patterns = &["fox", "brown", "quick"];
+let replace_with = &["sloth", "grey", "slow"];
+
+// In a real example, these might be `std::fs::File`s instead. All you need to
+// do is supply a pair of `std::io::Read` and `std::io::Write` implementations.
+let rdr = "The quick brown fox.";
+let mut wtr = vec![];
+
+let ac = AhoCorasick::new(patterns);
+ac.stream_replace_all(rdr.as_bytes(), &mut wtr, replace_with)?;
+assert_eq!(b"The slow grey sloth.".to_vec(), wtr);
+# Ok(()) }; example().unwrap()
+```
+
+# Example: finding the leftmost first match
+
+In the textbook description of Aho-Corasick, its formulation is typically
+structured such that it reports all possible matches, even when they overlap
+with another. In many cases, overlapping matches may not be desired, such as
+the case of finding all successive non-overlapping matches like you might with
+a standard regular expression.
+
+Unfortunately the "obvious" way to modify the Aho-Corasick algorithm to do
+this doesn't always work in the expected way, since it will report matches as
+soon as they are seen. For example, consider matching the regex `Samwise|Sam`
+against the text `Samwise`. Most regex engines (that are Perl-like, or
+non-POSIX) will report `Samwise` as a match, but the standard Aho-Corasick
+algorithm modified for reporting non-overlapping matches will report `Sam`.
+
+A novel contribution of this library is the ability to change the match
+semantics of Aho-Corasick (without additional search time overhead) such that
+`Samwise` is reported instead. For example, here's the standard approach:
+
+```
+use aho_corasick::AhoCorasick;
+
+let patterns = &["Samwise", "Sam"];
+let haystack = "Samwise";
+
+let ac = AhoCorasick::new(patterns);
+let mat = ac.find(haystack).expect("should have a match");
+assert_eq!("Sam", &haystack[mat.start()..mat.end()]);
+```
+
+And now here's the leftmost-first version, which matches how a Perl-like
+regex will work:
+
+```
+use aho_corasick::{AhoCorasickBuilder, MatchKind};
+
+let patterns = &["Samwise", "Sam"];
+let haystack = "Samwise";
+
+let ac = AhoCorasickBuilder::new()
+    .match_kind(MatchKind::LeftmostFirst)
+    .build(patterns);
+let mat = ac.find(haystack).expect("should have a match");
+assert_eq!("Samwise", &haystack[mat.start()..mat.end()]);
+```
+
+In addition to leftmost-first semantics, this library also supports
+leftmost-longest semantics, which match the POSIX behavior of a regular
+expression alternation. See
+[`MatchKind`](enum.MatchKind.html)
+for more details.
+
+# Prefilters
+
+While an Aho-Corasick automaton can perform admirably when compared to more
+naive solutions, it is generally slower than more specialized algorithms that
+are accelerated using vector instructions such as SIMD.
+
+For that reason, this library will internally use a "prefilter" to attempt
+to accelerate searches when possible. Currently, this library has fairly
+limited implementation that only applies when there are 3 or fewer unique
+starting bytes among all patterns in an automaton.
+
+In the future, it is intended for this prefilter to grow more sophisticated
+by pushing applicable optimizations from the
+[`regex`](http://docs.rs/regex)
+crate (and other places) down into this library.
+
+While a prefilter is generally good to have on by default since it works well
+in the common case, it can lead to less predictable or even sub-optimal
+performance in some cases. For that reason, prefilters can be disabled via
+[`AhoCorasickBuilder::prefilter`](struct.AhoCorasickBuilder.html#method.prefilter).
+*/
+
+#![deny(missing_docs)]
+#![allow(bare_trait_objects)]
+
+// We can never be truly no_std, but we could be alloc-only some day, so
+// require the std feature for now.
+#[cfg(not(feature = "std"))]
+compile_error!("`std` feature is currently required to build this crate");
+
+extern crate memchr;
+#[cfg(test)]
+#[macro_use]
+extern crate doc_comment;
+
+#[cfg(test)]
+doctest!("../README.md");
+
+pub use ahocorasick::{
+    AhoCorasick, AhoCorasickBuilder, MatchKind,
+    FindIter, FindOverlappingIter, StreamFindIter,
+};
+pub use error::{Error, ErrorKind};
+pub use state_id::StateID;
+
+mod ahocorasick;
+mod automaton;
+mod buffer;
+mod dfa;
+mod error;
+mod classes;
+mod prefilter;
+mod nfa;
+mod state_id;
+#[cfg(test)]
+mod tests;
+
+/// A representation of a match reported by an Aho-Corasick automaton.
+///
+/// A match has two essential pieces of information: the identifier of the
+/// pattern that matched, along with the start and end offsets of the match
+/// in the haystack.
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use aho_corasick::AhoCorasick;
+///
+/// let ac = AhoCorasick::new(&[
+///     "foo", "bar", "baz",
+/// ]);
+/// let mat = ac.find("xxx bar xxx").expect("should have a match");
+/// assert_eq!(1, mat.pattern());
+/// assert_eq!(4, mat.start());
+/// assert_eq!(7, mat.end());
+/// ```
+#[derive(Clone, Debug, Eq, Hash, PartialEq)]
+pub struct Match {
+    /// The pattern id.
+    pattern: usize,
+    /// The length of this match, such that the starting position of the match
+    /// is `end - len`.
+    ///
+    /// We use length here because, other than the pattern id, the only
+    /// information about each pattern that the automaton stores is its length.
+    /// So using the length here is just a bit more natural. But it isn't
+    /// technically required.
+    len: usize,
+    /// The end offset of the match, exclusive.
+    end: usize,
+}
+
+impl Match {
+    /// Returns the identifier of the pattern that matched.
+    ///
+    /// The identifier of a pattern is derived from the position in which it
+    /// was originally inserted into the corresponding automaton. The first
+    /// pattern has identifier `0`, and each subsequent pattern is `1`, `2`
+    /// and so on.
+    #[inline]
+    pub fn pattern(&self) -> usize {
+        self.pattern
+    }
+
+    /// The starting position of the match.
+    #[inline]
+    pub fn start(&self) -> usize {
+        self.end - self.len
+    }
+
+    /// The ending position of the match.
+    #[inline]
+    pub fn end(&self) -> usize {
+        self.end
+    }
+
+    /// Returns true if and only if this match is empty. That is, when
+    /// `start() == end()`.
+    ///
+    /// An empty match can only be returned when the empty string was among
+    /// the patterns used to build the Aho-Corasick automaton.
+    #[inline]
+    pub fn is_empty(&self) -> bool {
+        self.len == 0
+    }
+
+    #[inline]
+    fn increment(&self, by: usize) -> Match {
+        Match {
+            pattern: self.pattern,
+            len: self.len,
+            end: self.end + by,
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/aho_corasick/nfa.rs.html b/target/doc/src/aho_corasick/nfa.rs.html new file mode 100644 index 0000000..7b625e5 --- /dev/null +++ b/target/doc/src/aho_corasick/nfa.rs.html @@ -0,0 +1,2503 @@ +nfa.rs.html -- source
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+
+use std::collections::VecDeque;
+use std::cmp;
+use std::fmt;
+use std::mem::size_of;
+
+use ahocorasick::MatchKind;
+use automaton::Automaton;
+use classes::{ByteClasses, ByteClassBuilder};
+use error::Result;
+use prefilter::{self, Prefilter, PrefilterObj};
+use state_id::{StateID, dead_id, fail_id, usize_to_state_id};
+use Match;
+
+/// The identifier for a pattern, which is simply the position of the pattern
+/// in the sequence of patterns given by the caller.
+pub type PatternID = usize;
+
+/// The length of a pattern, in bytes.
+pub type PatternLength = usize;
+
+/// An Aho-Corasick automaton, represented as an NFA.
+///
+/// This is the classical formulation of Aho-Corasick, which involves building
+/// up a prefix trie of a given set of patterns, and then wiring up failure
+/// transitions between states in order to guarantee linear time matching. The
+/// standard formulation is, technically, an NFA because of these failure
+/// transitions. That is, one can see them as enabling the automaton to be in
+/// multiple states at once. Indeed, during search, it is possible to check
+/// the transitions on multiple states for a single input byte.
+///
+/// This particular implementation not only supports the standard style of
+/// matching, but also provides a mode for choosing leftmost-first or
+/// leftmost-longest match semantics. When a leftmost mode is chosen, some
+/// failure transitions that would otherwise be added are elided. See
+/// the documentation of `MatchKind` for more details and examples on how the
+/// match semantics may differ.
+///
+/// If one wants a DFA, then it is necessary to first build an NFA and convert
+/// it into a DFA. Note, however, that because we've constrained ourselves to
+/// matching literal patterns, this does not need to use subset construction
+/// for determinization. Instead, the DFA has at most a number of states
+/// equivalent to the number of NFA states. The only real difference between
+/// them is that all failure transitions are followed and pre-computed. This
+/// uses much more memory, but also executes searches more quickly.
+#[derive(Clone)]
+pub struct NFA<S> {
+    /// The match semantics built into this NFA.
+    match_kind: MatchKind,
+    /// The start state id as an index into `states`.
+    start_id: S,
+    /// The length, in bytes, of the longest pattern in this automaton. This
+    /// information is useful for keeping correct buffer sizes when searching
+    /// on streams.
+    max_pattern_len: usize,
+    /// The total number of patterns added to this automaton, including
+    /// patterns that may never be matched.
+    pattern_count: usize,
+    /// The number of bytes of heap used by this NFA's transition table.
+    heap_bytes: usize,
+    /// A prefilter for quickly skipping to candidate matches, if pertinent.
+    prefilter: Option<PrefilterObj>,
+    /// A set of equivalence classes in terms of bytes. We compute this while
+    /// building the NFA, but don't use it in the NFA's states. Instead, we
+    /// use this for building the DFA. We store it on the NFA since it's easy
+    /// to compute while visiting the the patterns.
+    byte_classes: ByteClasses,
+    /// A set of states. Each state defines its own transitions, a fail
+    /// transition and a set of indices corresponding to matches.
+    ///
+    /// The first state is always the fail state, which is used only as a
+    /// sentinel. Namely, in the final NFA, no transition into the fail state
+    /// exists. (Well, they do, but they aren't followed. Instead, the state's
+    /// failure transition is followed.)
+    ///
+    /// The second state (index 1) is always the dead state. Dead states are
+    /// in every automaton, but only used when leftmost-{first,longest} match
+    /// semantics are enabled. Specifically, they instruct search to stop
+    /// at specific points in order to report the correct match location. In
+    /// the standard Aho-Corasick construction, there are no transitions to
+    /// the dead state.
+    ///
+    /// The third state (index 2) is generally intended to be the starting or
+    /// "root" state.
+    states: Vec<State<S>>,
+}
+
+impl<S: StateID> NFA<S> {
+    /// Returns the equivalence classes of bytes found while constructing
+    /// this NFA.
+    ///
+    /// Note that the NFA doesn't actually make use of these equivalence
+    /// classes. Instead, these are useful for building the DFA when desired.
+    pub fn byte_classes(&self) -> &ByteClasses {
+        &self.byte_classes
+    }
+
+    /// Returns a start byte prefilter, if one exists.
+    pub fn prefilter_obj(&self) -> Option<&PrefilterObj> {
+        self.prefilter.as_ref()
+    }
+
+    /// Returns the total number of heap bytes used by this NFA's transition
+    /// table.
+    pub fn heap_bytes(&self) -> usize {
+        self.heap_bytes
+    }
+
+    /// Return the length of the longest pattern in this automaton.
+    pub fn max_pattern_len(&self) -> usize {
+        self.max_pattern_len
+    }
+
+    /// Return the total number of patterns added to this automaton.
+    pub fn pattern_count(&self) -> usize {
+        self.pattern_count
+    }
+
+    /// Returns the total number of states in this NFA.
+    pub fn state_len(&self) -> usize {
+        self.states.len()
+    }
+
+    /// Returns the matches for the given state.
+    pub fn matches(&self, id: S) -> &[(PatternID, PatternLength)] {
+        &self.states[id.to_usize()].matches
+    }
+
+    /// Returns an iterator over all transitions in the given state according
+    /// to the given equivalence classes, including transitions to `fail_id()`.
+    /// The number of transitions returned is always equivalent to the number
+    /// of equivalence classes.
+    pub fn iter_all_transitions<F: FnMut(u8, S)>(
+        &self,
+        byte_classes: &ByteClasses,
+        id: S,
+        f: F,
+    ) {
+        self.states[id.to_usize()].trans.iter_all(byte_classes, f);
+    }
+
+    /// Returns the failure transition for the given state.
+    pub fn failure_transition(&self, id: S) -> S {
+        self.states[id.to_usize()].fail
+    }
+
+    /// Returns the next state for the given state and input byte.
+    ///
+    /// Note that this does not follow failure transitions. As such, the id
+    /// returned may be `fail_id`.
+    pub fn next_state(&self, current: S, input: u8) -> S {
+        self.states[current.to_usize()].next_state(input)
+    }
+
+    fn state(&self, id: S) -> &State<S> {
+        &self.states[id.to_usize()]
+    }
+
+    fn state_mut(&mut self, id: S) -> &mut State<S> {
+        &mut self.states[id.to_usize()]
+    }
+
+    fn start(&self) -> &State<S> {
+        self.state(self.start_id)
+    }
+
+    fn start_mut(&mut self) -> &mut State<S> {
+        let id = self.start_id;
+        self.state_mut(id)
+    }
+
+    fn iter_transitions_mut(&mut self, id: S) -> IterTransitionsMut<S> {
+        IterTransitionsMut::new(self, id)
+    }
+
+    fn copy_matches(&mut self, src: S, dst: S) {
+        let (src, dst) = get_two_mut(
+            &mut self.states, src.to_usize(), dst.to_usize(),
+        );
+        dst.matches.extend_from_slice(&src.matches);
+    }
+
+    fn copy_empty_matches(&mut self, dst: S) {
+        let start_id = self.start_id;
+        self.copy_matches(start_id, dst);
+    }
+
+    fn add_dense_state(&mut self, depth: usize) -> Result<S> {
+        let trans = Transitions::Dense(vec![fail_id(); 256]);
+        let id = usize_to_state_id(self.states.len())?;
+        self.states.push(State {
+            trans,
+            fail: self.start_id,
+            depth: depth,
+            matches: vec![],
+        });
+        Ok(id)
+    }
+
+    fn add_sparse_state(&mut self, depth: usize) -> Result<S> {
+        let trans = Transitions::Sparse(vec![]);
+        let id = usize_to_state_id(self.states.len())?;
+        self.states.push(State {
+            trans,
+            fail: self.start_id,
+            depth: depth,
+            matches: vec![],
+        });
+        Ok(id)
+    }
+}
+
+impl<S: StateID> Automaton for NFA<S> {
+    type ID = S;
+
+    fn match_kind(&self) -> &MatchKind {
+        &self.match_kind
+    }
+
+    fn prefilter(&self) -> Option<&Prefilter> {
+        self.prefilter.as_ref().map(|p| p.as_ref())
+    }
+
+    fn start_state(&self) -> S {
+        self.start_id
+    }
+
+    fn is_valid(&self, id: S) -> bool {
+        id.to_usize() < self.states.len()
+    }
+
+    fn is_match_state(&self, id: S) -> bool {
+        self.states[id.to_usize()].is_match()
+    }
+
+    fn get_match(
+        &self,
+        id: S,
+        match_index: usize,
+        end: usize,
+    ) -> Option<Match> {
+        let state = match self.states.get(id.to_usize()) {
+            None => return None,
+            Some(state) => state,
+        };
+        state.matches
+            .get(match_index)
+            .map(|&(id, len)| Match { pattern: id, len, end })
+    }
+
+    fn match_count(&self, id: S) -> usize {
+        self.states[id.to_usize()].matches.len()
+    }
+
+    unsafe fn next_state_unchecked(&self, mut current: S, input: u8) -> S {
+        // This terminates since:
+        //
+        // 1. `State.fail` never points to fail_id().
+        // 2. All `State.fail` values point to a state closer to `start`.
+        // 3. The start state has no transitions to fail_id().
+        loop {
+            let state = self.states.get_unchecked(current.to_usize());
+            let next = state.next_state(input);
+            if next != fail_id() {
+                return next;
+            }
+            current = state.fail;
+        }
+    }
+}
+
+/// A representation of an NFA state for an Aho-Corasick automaton.
+///
+/// It contains the transitions to the next state, a failure transition for
+/// cases where there exists no other transition for the current input byte,
+/// the matches implied by visiting this state (if any) and the depth of this
+/// state. The depth of a state is simply the distance from it to the start
+/// state in the automaton, where the depth of the start state is 0.
+#[derive(Clone, Debug)]
+pub struct State<S> {
+    trans: Transitions<S>,
+    fail: S,
+    matches: Vec<(PatternID, PatternLength)>,
+    // TODO: Strictly speaking, this isn't needed for searching. It's only
+    // used when building an NFA that supports leftmost match semantics. We
+    // could drop this from the state and dynamically build a map only when
+    // computing failure transitions, but it's not clear which is better.
+    // Benchmark this.
+    depth: usize,
+}
+
+impl<S: StateID> State<S> {
+    fn heap_bytes(&self) -> usize {
+        self.trans.heap_bytes()
+        + (self.matches.len() * size_of::<(PatternID, PatternLength)>())
+    }
+
+    fn add_match(&mut self, i: PatternID, len: PatternLength) {
+        self.matches.push((i, len));
+    }
+
+    fn is_match(&self) -> bool {
+        !self.matches.is_empty()
+    }
+
+    fn get_longest_match_len(&self) -> Option<usize> {
+        // Why is this true? Because the first match in any matching state
+        // will always correspond to the match added to it during trie
+        // construction (since when we copy matches due to failure transitions,
+        // we always append them). Therefore, it follows that the first match
+        // must always be longest since any subsequent match must be from a
+        // failure transition, and a failure transition by construction points
+        // to a proper suffix. A proper suffix is, by definition, smaller.
+        self.matches.get(0).map(|&(_, len)| len)
+    }
+
+    fn next_state(&self, input: u8) -> S {
+        self.trans.next_state(input)
+    }
+
+    fn set_next_state(&mut self, input: u8, next: S) {
+        self.trans.set_next_state(input, next);
+    }
+}
+
+/// A representation of transitions in an NFA.
+///
+/// Transitions have either a sparse representation, which is slower for
+/// lookups but uses less memory, or a dense representation, which is faster
+/// for lookups but uses more memory. In the sparse representation, the absence
+/// of a state implies a transition to `fail_id()`. Transitions to `dead_id()`
+/// are still explicitly represented.
+///
+/// For the NFA, by default, we use a dense representation for transitions for
+/// states close to the start state because it's likely these are the states
+/// that will be most frequently visited.
+#[derive(Clone, Debug)]
+enum Transitions<S> {
+    Sparse(Vec<(u8, S)>),
+    Dense(Vec<S>),
+}
+
+impl<S: StateID> Transitions<S> {
+    fn heap_bytes(&self) -> usize {
+        match *self {
+            Transitions::Sparse(ref sparse) => {
+                sparse.len() * size_of::<(u8, S)>()
+            }
+            Transitions::Dense(ref dense) => {
+                dense.len() * size_of::<S>()
+            }
+        }
+    }
+
+    fn next_state(&self, input: u8) -> S {
+        match *self {
+            Transitions::Sparse(ref sparse) => {
+                for &(b, id) in sparse {
+                    if b == input {
+                        return id;
+                    }
+                }
+                fail_id()
+            }
+            Transitions::Dense(ref dense) => {
+                // SAFETY: This is safe because all dense transitions have
+                // exactly 256 elements, so all u8 values are valid indices.
+                unsafe { *dense.get_unchecked(input as usize) }
+            }
+        }
+    }
+
+    fn set_next_state(&mut self, input: u8, next: S) {
+        match *self {
+            Transitions::Sparse(ref mut sparse) => {
+                match sparse.binary_search_by_key(&input, |&(b, _)| b) {
+                    Ok(i) => sparse[i] = (input, next),
+                    Err(i) => sparse.insert(i, (input, next)),
+                }
+            }
+            Transitions::Dense(ref mut dense) => {
+                dense[input as usize] = next;
+            }
+        }
+    }
+
+    /// Iterate over transitions in this state while skipping over transitions
+    /// to `fail_id()`.
+    fn iter<F: FnMut(u8, S)>(&self, mut f: F) {
+        match *self {
+            Transitions::Sparse(ref sparse) => {
+                for &(b, id) in sparse {
+                    f(b, id);
+                }
+            }
+            Transitions::Dense(ref dense) => {
+                for b in AllBytesIter::new() {
+                    let id = dense[b as usize];
+                    if id != fail_id() {
+                        f(b, id);
+                    }
+                }
+            }
+        }
+    }
+
+    /// Iterate over all transitions in this state according to the given
+    /// equivalence classes, including transitions to `fail_id()`.
+    fn iter_all<F: FnMut(u8, S)>(&self, classes: &ByteClasses, mut f: F) {
+        if classes.is_singleton() {
+            match *self {
+                Transitions::Sparse(ref sparse) => {
+                    sparse_iter(sparse, f);
+                }
+                Transitions::Dense(ref dense) => {
+                    for b in AllBytesIter::new() {
+                        f(b, dense[b as usize]);
+                    }
+                }
+            }
+        } else {
+            // In this case, we only want to yield a single byte for each
+            // equivalence class.
+            match *self {
+                Transitions::Sparse(ref sparse) => {
+                    let mut last_class = None;
+                    sparse_iter(sparse, |b, next| {
+                        let class = classes.get(b);
+                        if last_class != Some(class) {
+                            last_class = Some(class);
+                            f(b, next);
+                        }
+                    })
+                }
+                Transitions::Dense(ref dense) => {
+                    for b in classes.representatives() {
+                        f(b, dense[b as usize]);
+                    }
+                }
+            }
+        }
+    }
+}
+
+/// Iterator over transitions in a state, skipping transitions to `fail_id()`.
+///
+/// This abstracts over the representation of NFA transitions, which may be
+/// either in a sparse or dense representation.
+///
+/// This somewhat idiosyncratically borrows the NFA mutably, so that when one
+/// is iterating over transitions, the caller can still mutate the NFA. This
+/// is useful when creating failure transitions.
+#[derive(Debug)]
+struct IterTransitionsMut<'a, S: StateID + 'a> {
+    nfa: &'a mut NFA<S>,
+    state_id: S,
+    cur: usize,
+}
+
+impl<'a, S: StateID> IterTransitionsMut<'a, S> {
+    fn new(nfa: &'a mut NFA<S>, state_id: S) -> IterTransitionsMut<'a, S> {
+        IterTransitionsMut { nfa, state_id, cur: 0 }
+    }
+
+    fn nfa(&mut self) -> &mut NFA<S> {
+        self.nfa
+    }
+}
+
+impl<'a, S: StateID> Iterator for IterTransitionsMut<'a, S> {
+    type Item = (u8, S);
+
+    fn next(&mut self) -> Option<(u8, S)> {
+        match self.nfa.states[self.state_id.to_usize()].trans {
+            Transitions::Sparse(ref sparse) => {
+                if self.cur >= sparse.len() {
+                    return None;
+                }
+                let i = self.cur;
+                self.cur += 1;
+                Some(sparse[i])
+            }
+            Transitions::Dense(ref dense) => {
+                while self.cur < dense.len() {
+                    // There are always exactly 255 transitions in dense repr.
+                    debug_assert!(self.cur < 256);
+
+                    let b = self.cur as u8;
+                    let id = dense[self.cur];
+                    self.cur += 1;
+                    if id != fail_id() {
+                        return Some((b, id));
+                    }
+                }
+                None
+            }
+        }
+    }
+}
+
+/// A simple builder for configuring the NFA construction of Aho-Corasick.
+#[derive(Clone, Debug)]
+pub struct Builder {
+    dense_depth: usize,
+    match_kind: MatchKind,
+    prefilter: bool,
+    ascii_case_insensitive: bool,
+}
+
+impl Default for Builder {
+    fn default() -> Builder {
+        Builder {
+            dense_depth: 2,
+            match_kind: MatchKind::default(),
+            prefilter: true,
+            ascii_case_insensitive: false,
+        }
+    }
+}
+
+impl Builder {
+    pub fn new() -> Builder {
+        Builder::default()
+    }
+
+    pub fn build<I, P, S: StateID>(
+        &self,
+        patterns: I,
+    ) -> Result<NFA<S>>
+    where I: IntoIterator<Item=P>,
+          P: AsRef<[u8]>
+    {
+        Compiler::new(self)?.compile(patterns)
+    }
+
+    pub fn match_kind(&mut self, kind: MatchKind) -> &mut Builder {
+        self.match_kind = kind;
+        self
+    }
+
+    pub fn dense_depth(&mut self, depth: usize) -> &mut Builder {
+        self.dense_depth = depth;
+        self
+    }
+
+    pub fn prefilter(&mut self, yes: bool) -> &mut Builder {
+        self.prefilter = yes;
+        self
+    }
+
+    pub fn ascii_case_insensitive(&mut self, yes: bool) -> &mut Builder {
+        self.ascii_case_insensitive = yes;
+        self
+    }
+}
+
+/// A compiler uses a builder configuration and builds up the NFA formulation
+/// of an Aho-Corasick automaton. This roughly corresponds to the standard
+/// formulation described in textbooks.
+#[derive(Debug)]
+struct Compiler<'a, S: StateID> {
+    builder: &'a Builder,
+    nfa: NFA<S>,
+    byte_classes: ByteClassBuilder,
+}
+
+impl<'a, S: StateID> Compiler<'a, S> {
+    fn new(builder: &'a Builder) -> Result<Compiler<'a, S>> {
+        Ok(Compiler {
+            builder: builder,
+            nfa: NFA {
+                match_kind: builder.match_kind,
+                start_id: usize_to_state_id(2)?,
+                max_pattern_len: 0,
+                pattern_count: 0,
+                heap_bytes: 0,
+                prefilter: None,
+                byte_classes: ByteClasses::singletons(),
+                states: vec![],
+            },
+            byte_classes: ByteClassBuilder::new(),
+        })
+    }
+
+    fn compile<I, P>(
+        mut self,
+        patterns: I,
+    ) -> Result<NFA<S>>
+    where I: IntoIterator<Item=P>,
+          P: AsRef<[u8]>
+    {
+        self.add_state(0)?; // the fail state, which is never entered
+        self.add_state(0)?; // the dead state, only used for leftmost
+        self.add_state(0)?; // the start state
+        self.build_trie(patterns)?;
+        self.add_start_state_loop();
+        self.add_dead_state_loop();
+        if self.match_kind().is_leftmost() {
+            self.fill_failure_transitions_leftmost();
+        } else {
+            self.fill_failure_transitions_standard();
+        }
+        self.close_start_state_loop();
+        self.nfa.byte_classes = self.byte_classes.build();
+        self.build_prefilters();
+        self.calculate_size();
+        Ok(self.nfa)
+    }
+
+    /// This sets up the initial prefix trie that makes up the Aho-Corasick
+    /// automaton. Effectively, it creates the basic structure of the
+    /// automaton, where every pattern given has a path from the start state to
+    /// the end of the pattern.
+    fn build_trie<I, P>(
+        &mut self,
+        patterns: I,
+    ) -> Result<()>
+    where I: IntoIterator<Item=P>,
+          P: AsRef<[u8]>
+    {
+    'PATTERNS:
+        for (pati, pat) in patterns.into_iter().enumerate() {
+            let pat = pat.as_ref();
+            self.nfa.max_pattern_len = cmp::max(
+                self.nfa.max_pattern_len, pat.len(),
+            );
+            self.nfa.pattern_count += 1;
+
+            let mut prev = self.nfa.start_id;
+            let mut saw_match = false;
+            for (depth, &b) in pat.iter().enumerate() {
+                // When leftmost-first match semantics are requested, we
+                // specifically stop adding patterns when a previously added
+                // pattern is a prefix of it. We avoid adding it because
+                // leftmost-first semantics imply that the pattern can never
+                // match. This is not just an optimization to save space! It
+                // is necessary for correctness. In fact, this is the only
+                // difference in the automaton between the implementations for
+                // leftmost-first and leftmost-longest.
+                saw_match = saw_match || self.nfa.state(prev).is_match();
+                if self.builder.match_kind.is_leftmost_first() && saw_match {
+                    // Skip to the next pattern immediately. This avoids
+                    // incorrectly adding a match after this loop terminates.
+                    continue 'PATTERNS;
+                }
+
+                // Add this byte to our equivalence classes. We don't use these
+                // for NFA construction. These are instead used only if we're
+                // building a DFA. They would technically be useful for the
+                // NFA, but it would require a second pass over the patterns.
+                self.byte_classes.set_range(b, b);
+
+                // If the transition from prev using the current byte already
+                // exists, then just move through it. Otherwise, add a new
+                // state. We track the depth here so that we can determine
+                // how to represent transitions. States near the start state
+                // use a dense representation that uses more memory but is
+                // faster. Other states use a sparse representation that uses
+                // less memory but is slower.
+                let next = self.nfa.state(prev).next_state(b);
+                if next != fail_id() {
+                    prev = next;
+                } else {
+                    let next = self.add_state(depth + 1)?;
+                    self.nfa.state_mut(prev).set_next_state(b, next);
+                    if self.builder.ascii_case_insensitive {
+                        if b'A' <= b && b <= b'Z' {
+                            let b = b.to_ascii_lowercase();
+                            self.nfa.state_mut(prev).set_next_state(b, next);
+                        } else if b'a' <= b && b <= b'z' {
+                            let b = b.to_ascii_uppercase();
+                            self.nfa.state_mut(prev).set_next_state(b, next);
+                        }
+                    }
+                    prev = next;
+                }
+            }
+            // Once the pattern has been added, log the match in the final
+            // state that it reached.
+            self.nfa.state_mut(prev).add_match(pati, pat.len());
+        }
+        Ok(())
+    }
+
+    /// This routine creates failure transitions according to the standard
+    /// textbook formulation of the Aho-Corasick algorithm.
+    ///
+    /// Building failure transitions is the most interesting part of building
+    /// the Aho-Corasick automaton, because they are what allow searches to
+    /// be performed in linear time. Specifically, a failure transition is
+    /// a single transition associated with each state that points back to
+    /// the longest proper suffix of the pattern being searched. The failure
+    /// transition is followed whenever there exists no transition on the
+    /// current state for the current input byte. If there is no other proper
+    /// suffix, then the failure transition points back to the starting state.
+    ///
+    /// For example, let's say we built an Aho-Corasick automaton with the
+    /// following patterns: 'abcd' and 'cef'. The trie looks like this:
+    ///
+    /// ```ignore
+    ///          a - S1 - b - S2 - c - S3 - d - S4*
+    ///         /
+    ///     S0 - c - S5 - e - S6 - f - S7*
+    /// ```
+    ///
+    /// At this point, it should be fairly straight-forward to see how this
+    /// trie can be used in a simplistic way. At any given position in the
+    /// text we're searching (called the "subject" string), all we need to do
+    /// is follow the transitions in the trie by consuming one transition for
+    /// each byte in the subject string. If we reach a match state, then we can
+    /// report that location as a match.
+    ///
+    /// The trick comes when searching a subject string like 'abcef'. We'll
+    /// initially follow the transition from S0 to S1 and wind up in S3 after
+    /// observng the 'c' byte. At this point, the next byte is 'e' but state
+    /// S3 has no transition for 'e', so the search fails. We then would need
+    /// to restart the search at the next position in 'abcef', which
+    /// corresponds to 'b'. The match would fail, but the next search starting
+    /// at 'c' would finally succeed. The problem with this approach is that
+    /// we wind up searching the subject string potentially many times. In
+    /// effect, this makes the algorithm have worst case `O(n * m)` complexity,
+    /// where `n ~ len(subject)` and `m ~ len(all patterns)`. We would instead
+    /// like to achieve a `O(n + m)` worst case complexity.
+    ///
+    /// This is where failure transitions come in. Instead of dying at S3 in
+    /// the first search, the automaton can instruct the search to move to
+    /// another part of the automaton that corresponds to a suffix of what
+    /// we've seen so far. Recall that we've seen 'abc' in the subject string,
+    /// and the automaton does indeed have a non-empty suffix, 'c', that could
+    /// potentially lead to another match. Thus, the actual Aho-Corasick
+    /// automaton for our patterns in this case looks like this:
+    ///
+    /// ```ignore
+    ///          a - S1 - b - S2 - c - S3 - d - S4*
+    ///         /                      /
+    ///        /       ----------------
+    ///       /       /
+    ///     S0 - c - S5 - e - S6 - f - S7*
+    /// ```
+    ///
+    /// That is, we have a failure transition from S3 to S5, which is followed
+    /// exactly in cases when we are in state S3 but see any byte other than
+    /// 'd' (that is, we've "failed" to find a match in this portion of our
+    /// trie). We know we can transition back to S5 because we've already seen
+    /// a 'c' byte, so we don't need to re-scan it. We can then pick back up
+    /// with the search starting at S5 and complete our match.
+    ///
+    /// Adding failure transitions to a trie is fairly simple, but subtle. The
+    /// key issue is that you might have multiple failure transition that you
+    /// need to follow. For example, look at the trie for the patterns
+    /// 'abcd', 'b', 'bcd' and 'cd':
+    ///
+    /// ```ignore
+    ///        - a - S1 - b - S2 - c - S3 - d - S4*
+    ///       /
+    ///     S0 - b - S5* - c - S6 - d - S7*
+    ///       \
+    ///        - c - S8 - d - S9*
+    /// ```
+    ///
+    /// The failure transitions for this trie are defined from S2 to S5,
+    /// S3 to S6 and S6 to S8. Moreover, state S2 needs to track that it
+    /// corresponds to a match, since its failure transition to S5 is itself
+    /// a match state.
+    ///
+    /// Perhaps simplest way to think about adding these failure transitions
+    /// is recursively. That is, if you know the failure transitions for every
+    /// possible previous state that could be visited (e.g., when computing the
+    /// failure transition for S3, you already know the failure transitions
+    /// for S0, S1 and S2), then you can simply follow the failure transition
+    /// of the previous state and check whether the incoming transition is
+    /// defined after following the failure transition.
+    ///
+    /// For example, when determining the failure state for S3, by our
+    /// assumptions, we already know that there is a failure transition from
+    /// S2 (the previous state) to S5. So we follow that transition and check
+    /// whether the transition connecting S2 to S3 is defined. Indeed, it is,
+    /// as there is a transition from S5 to S6 for the byte 'c'. If no such
+    /// transition existed, we could keep following the failure transitions
+    /// until we reach the start state, which is the failure transition for
+    /// every state that has no corresponding proper suffix.
+    ///
+    /// We don't actually use recursion to implement this, but instead, use a
+    /// breadth first search of the automaton. Our base case is the start
+    /// state, whose failure transition is just a transition to itself.
+    fn fill_failure_transitions_standard(&mut self) {
+        // Initialize the queue for breadth first search with all transitions
+        // out of the start state. We handle the start state specially because
+        // we only want to follow non-self transitions. If we followed self
+        // transitions, then this would never terminate.
+        let mut queue = VecDeque::new();
+        for b in AllBytesIter::new() {
+            let next = self.nfa.start().next_state(b);
+            if next != self.nfa.start_id {
+                queue.push_back(next);
+            }
+        }
+        while let Some(id) = queue.pop_front() {
+            let mut it = self.nfa.iter_transitions_mut(id);
+            while let Some((b, next)) = it.next() {
+                queue.push_back(next);
+
+                let mut fail = it.nfa().state(id).fail;
+                while it.nfa().state(fail).next_state(b) == fail_id() {
+                    fail = it.nfa().state(fail).fail;
+                }
+                fail = it.nfa().state(fail).next_state(b);
+                it.nfa().state_mut(next).fail = fail;
+                it.nfa().copy_matches(fail, next);
+            }
+            // If the start state is a match state, then this automaton can
+            // match the empty string. This implies all states are match states
+            // since every position matches the empty string, so copy the
+            // matches from the start state to every state. Strictly speaking,
+            // this is only necessary for overlapping matches since each
+            // non-empty non-start match state needs to report empty matches
+            // in addition to its own. For the non-overlapping case, such
+            // states only report the first match, which is never empty since
+            // it isn't a start state.
+            it.nfa().copy_empty_matches(id);
+        }
+    }
+
+    /// This routine is just like fill_failure_transitions_standard, except
+    /// it adds failure transitions in a way that preserves leftmost match
+    /// semantics (for both leftmost-first and leftmost-longest).
+    ///
+    /// The algorithms are so similar that it would be possible to write it
+    /// generically. But doing so without overhead would require a bit of
+    /// ceremony, so we just copy it and add in the extra leftmost logic.
+    /// Moreover, the standard algorithm above is so simple that it feels like
+    /// a crime to disturb it.
+    ///
+    /// In effect, this proceeds just like the standard approach, but we
+    /// specifically add only a subset of all failure transitions. Namely, we
+    /// only add failure transitions that either do not occur after a match
+    /// or failure transitions that do occur after a match but preserve the
+    /// match. The comments in the implementation below should help.
+    ///
+    /// N.B. The only differences in the automaton between leftmost-first and
+    /// leftmost-longest are in trie construction. Otherwise, both have exactly
+    /// the same set of failure transitions. leftmost-longest adds everything
+    /// to the trie, where as leftmost-first skips any patterns for which there
+    /// exists a prefix of it that was added earlier.
+    ///
+    /// N.B. I came up with this algorithm on my own, and after scouring all of
+    /// the other AC implementations I know of (Perl, Snort, many on GitHub).
+    /// I couldn't find any that implement leftmost semantics like this.
+    /// Perl of course needs leftmost-first semantics, but they implement it
+    /// with a seeming hack at *search* time instead of encoding it into the
+    /// automaton. There are also a couple Java libraries that support leftmost
+    /// longest semantics, but they do it by building a queue of matches at
+    /// search time, which is even worse than what Perl is doing. ---AG
+    fn fill_failure_transitions_leftmost(&mut self) {
+        /// Represents an item in our queue of states to process.
+        ///
+        /// Fundamentally, this queue serves the same purpose as the queue
+        /// for filling failure transitions using the standard formulation.
+        /// In the leftmost case, though, we need to track a bit more
+        /// information. See comments below.
+        #[derive(Clone, Copy, Debug)]
+        struct QueuedState<S> {
+            /// The id of the state to visit.
+            id: S,
+            /// The depth at which the first match was observed in the path
+            /// to this state. Note that this corresponds to the depth at
+            /// which the beginning of the match was detected. If no match
+            /// has been seen, then this is None.
+            match_at_depth: Option<usize>,
+        }
+
+        impl<S: StateID> QueuedState<S> {
+            /// Create a queued state corresponding to the given NFA's start
+            /// state.
+            fn start(nfa: &NFA<S>) -> QueuedState<S> {
+                let match_at_depth =
+                    if nfa.start().is_match() {
+                        Some(0)
+                    } else {
+                        None
+                    };
+                QueuedState { id: nfa.start_id, match_at_depth }
+            }
+
+            /// Return the next state to queue up. The given id must be a state
+            /// corresponding to a single transition from this queued state.
+            fn next_queued_state(
+                &self,
+                nfa: &NFA<S>,
+                id: S,
+            ) -> QueuedState<S> {
+                let match_at_depth = self.next_match_at_depth(nfa, id);
+                QueuedState { id, match_at_depth }
+            }
+
+            /// Return the earliest depth at which a match has occurred for
+            /// the given state. The given state must correspond to a single
+            /// transition from this queued state.
+            fn next_match_at_depth(
+                &self,
+                nfa: &NFA<S>,
+                next: S,
+            ) -> Option<usize> {
+                // This is a little tricky. If the previous state has already
+                // seen a match or if `next` isn't a match state, then nothing
+                // needs to change since a later state cannot find an earlier
+                // match.
+                match self.match_at_depth {
+                    Some(x) => return Some(x),
+                    None if nfa.state(next).is_match() => {}
+                    None => return None,
+                }
+                let depth =
+                    nfa.state(next).depth
+                    - nfa.state(next).get_longest_match_len().unwrap()
+                    + 1;
+                Some(depth)
+            }
+        }
+
+        // Initialize the queue for breadth first search with all transitions
+        // out of the start state. We handle the start state specially because
+        // we only want to follow non-self transitions. If we followed self
+        // transitions, then this would never terminate.
+        let mut queue: VecDeque<QueuedState<S>> = VecDeque::new();
+        let start = QueuedState::start(&self.nfa);
+        for b in AllBytesIter::new() {
+            let next_id = self.nfa.start().next_state(b);
+            if next_id != start.id {
+                let next = start.next_queued_state(&self.nfa, next_id);
+                queue.push_back(next);
+                // If a state immediately following the start state is a match
+                // state, then we never want to follow its failure transition
+                // since the failure transition necessarily leads back to the
+                // start state, which we never want to do for leftmost matching
+                // after a match has been found.
+                //
+                // N.B. This is a special case of the more general handling
+                // found below.
+                if self.nfa.state(next_id).is_match() {
+                    self.nfa.state_mut(next_id).fail = dead_id();
+                }
+            }
+        }
+        while let Some(item) = queue.pop_front() {
+            let mut any_trans = false;
+            let mut it = self.nfa.iter_transitions_mut(item.id);
+            while let Some((b, next_id)) = it.next() {
+                any_trans = true;
+
+                // Queue up the next state.
+                let next = item.next_queued_state(it.nfa(), next_id);
+                queue.push_back(next);
+
+                // Find the failure state for next. Same as standard.
+                let mut fail = it.nfa().state(item.id).fail;
+                while it.nfa().state(fail).next_state(b) == fail_id() {
+                    fail = it.nfa().state(fail).fail;
+                }
+                fail = it.nfa().state(fail).next_state(b);
+
+                // This is the key difference from the standard formulation.
+                // Namely, if we've seen a match, then we only want a failure
+                // transition if the failure transition preserves the match
+                // we've seen. In general, this is not true of all failure
+                // transitions since they can point back to any suffix of what
+                // we've seen so far. Instead, we only want to point back to
+                // suffixes that contain any match we've seen.
+                //
+                // We achieve this by comparing the depth of the failure
+                // transition with the number of states between this state
+                // and the beginning of the earliest match detected. If the
+                // depth of the failure state is smaller than this difference,
+                // then it cannot contain the match. If it's bigger or equal
+                // to the difference, then it necessarily includes the match
+                // we've seen since all failure transitions correspond to a
+                // suffix.
+                //
+                // If we've determined that we don't want the failure
+                // transition, then we set this state's failure transition to
+                // the dead state. In other words, when a search hits this
+                // state, it will not continue and correctly stop. (N.B. A
+                // dead state is different than a fail state. A dead state
+                // MUST be preceded by a match and acts as a sentinel to search
+                // routines to terminate.)
+                //
+                // Understanding this is tricky, and it took me several days
+                // to think through this and get it right. If you want to grok
+                // it, then I'd recommend: 1) switch the implementation to
+                // always use the standard algorithm for filling in failure
+                // transitions, 2) run the test suite and 3) examine the test
+                // failures. Write out the automatons for them and try to work
+                // backwards by figuring out which failure transitions should
+                // be removed. You should arrive at the same rule used below.
+                if let Some(match_depth) = next.match_at_depth {
+                    let fail_depth = it.nfa().state(fail).depth;
+                    let next_depth = it.nfa().state(next.id).depth;
+                    if next_depth - match_depth + 1 > fail_depth {
+                        it.nfa().state_mut(next.id).fail = dead_id();
+                        continue;
+                    }
+                    assert_ne!(
+                        start.id,
+                        it.nfa().state(next.id).fail,
+                        "states that are match states or follow match \
+                         states should never have a failure transition \
+                         back to the start state in leftmost searching",
+                    );
+                }
+                it.nfa().state_mut(next.id).fail = fail;
+                it.nfa().copy_matches(fail, next.id);
+            }
+            // If there are no transitions for this state and if it's a match
+            // state, then we must set its failure transition to the dead
+            // state since we never want it to restart the search.
+            if !any_trans && it.nfa().state(item.id).is_match() {
+                it.nfa().state_mut(item.id).fail = dead_id();
+            }
+            // We don't need to copy empty matches from the start state here
+            // because that's only necessary for overlapping matches and
+            // leftmost match kinds don't support overlapping matches.
+        }
+    }
+
+    /// Construct prefilters from the automaton, if applicable.
+    fn build_prefilters(&mut self) {
+        if !self.builder.prefilter {
+            return;
+        }
+
+        let mut builder = prefilter::StartBytesBuilder::new();
+        for b in AllBytesIter::new() {
+            if self.nfa.start().next_state(b) != self.nfa.start_id {
+                builder.add(b);
+            }
+        }
+        self.nfa.prefilter = builder.build();
+    }
+
+    /// Set the failure transitions on the start state to loop back to the
+    /// start state. This effectively permits the Aho-Corasick automaton to
+    /// match at any position. This is also required for finding the next
+    /// state to terminate, namely, finding the next state should never return
+    /// a fail_id.
+    ///
+    /// This must be done after building the initial trie, since trie
+    /// construction depends on transitions to `fail_id` to determine whether a
+    /// state already exists or not.
+    fn add_start_state_loop(&mut self) {
+        let start_id = self.nfa.start_id;
+        let start = self.nfa.start_mut();
+        for b in AllBytesIter::new() {
+            if start.next_state(b) == fail_id() {
+                start.set_next_state(b, start_id);
+            }
+        }
+    }
+
+    /// Remove the start state loop by rewriting any transitions on the start
+    /// state back to the start state with transitions to the dead state.
+    ///
+    /// The loop is only closed when two conditions are met: the start state
+    /// is a match state and the match kind is leftmost-first or
+    /// leftmost-longest.
+    ///
+    /// The reason for this is that under leftmost semantics, a start state
+    /// that is also a match implies that we should never restart the search
+    /// process. We allow normal transitions out of the start state, but if
+    /// none exist, we transition to the dead state, which signals that
+    /// searching should stop.
+    fn close_start_state_loop(&mut self) {
+        if self.match_kind().is_leftmost() && self.nfa.start().is_match() {
+            let start_id = self.nfa.start_id;
+            let start = self.nfa.start_mut();
+            for b in AllBytesIter::new() {
+                if start.next_state(b) == start_id {
+                    start.set_next_state(b, dead_id());
+                }
+            }
+        }
+    }
+
+    /// Sets all transitions on the dead state to point back to the dead state.
+    /// Normally, missing transitions map back to the failure state, but the
+    /// point of the dead state is to act as a sink that can never be escaped.
+    fn add_dead_state_loop(&mut self) {
+        let dead = self.nfa.state_mut(dead_id());
+        for b in AllBytesIter::new() {
+            dead.set_next_state(b, dead_id());
+        }
+    }
+
+    /// Computes the total amount of heap used by this NFA in bytes.
+    fn calculate_size(&mut self) {
+        let mut size = 0;
+        for state in &self.nfa.states {
+            size += state.heap_bytes();
+        }
+        self.nfa.heap_bytes = size;
+    }
+
+    /// Add a new state to the underlying NFA with the given depth. The depth
+    /// is used to determine how to represent the transitions.
+    ///
+    /// If adding the new state would overflow the chosen state ID
+    /// representation, then this returns an error.
+    fn add_state(&mut self, depth: usize) -> Result<S> {
+        if depth < self.builder.dense_depth {
+            self.nfa.add_dense_state(depth)
+        } else {
+            self.nfa.add_sparse_state(depth)
+        }
+    }
+
+    /// Returns the match kind configured on the underlying builder.
+    fn match_kind(&self) -> MatchKind {
+        self.builder.match_kind
+    }
+}
+
+/// An iterator over every byte value.
+///
+/// We use this instead of (0..256).map(|b| b as u8) because this optimizes
+/// better in debug builds.
+///
+/// We also use this instead of 0..=255 because we're targeting Rust 1.24 and
+/// inclusive range syntax was stabilized in Rust 1.26. We can get rid of this
+/// once our MSRV is Rust 1.26 or newer.
+#[derive(Debug)]
+struct AllBytesIter(u16);
+
+impl AllBytesIter {
+    fn new() -> AllBytesIter {
+        AllBytesIter(0)
+    }
+}
+
+impl Iterator for AllBytesIter {
+    type Item = u8;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.0 >= 256 {
+            None
+        } else {
+            let b = self.0 as u8;
+            self.0 += 1;
+            Some(b)
+        }
+    }
+}
+
+impl<S: StateID> fmt::Debug for NFA<S> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        writeln!(f, "NFA(")?;
+        writeln!(f, "match_kind: {:?}", self.match_kind)?;
+        writeln!(f, "{}", "-".repeat(79))?;
+        for (id, s) in self.states.iter().enumerate() {
+            let mut trans = vec![];
+            s.trans.iter(|byte, next| {
+                // The start state has a bunch of uninteresting transitions
+                // back into itself. It's questionable to hide them since they
+                // are critical to understanding the automaton, but they are
+                // very noisy without better formatting for contiugous ranges
+                // to the same state.
+                if id == self.start_id.to_usize() && next == self.start_id {
+                    return;
+                }
+                // Similarly, the dead state has a bunch of uninteresting
+                // transitions too.
+                if id == dead_id() {
+                    return;
+                }
+                trans.push(format!("{} => {}", escape(byte), next.to_usize()));
+            });
+            writeln!(f, "{:04}: {}", id, trans.join(", "))?;
+
+            let matches: Vec<String> = s.matches
+                .iter()
+                .map(|&(pattern_id, _)| pattern_id.to_string())
+                .collect();
+            writeln!(f, "  matches: {}", matches.join(", "))?;
+            writeln!(f, "     fail: {}", s.fail.to_usize())?;
+            writeln!(f, "    depth: {}", s.depth)?;
+        }
+        writeln!(f, "{}", "-".repeat(79))?;
+        writeln!(f, ")")?;
+        Ok(())
+    }
+}
+
+/// Iterate over all possible byte transitions given a sparse set.
+fn sparse_iter<S: StateID, F: FnMut(u8, S)>(trans: &[(u8, S)], mut f: F) {
+    let mut byte = 0u16;
+    for &(b, id) in trans {
+        while byte < (b as u16) {
+            f(byte as u8, fail_id());
+            byte += 1;
+        }
+        f(b, id);
+        byte += 1;
+    }
+    for b in byte..256 {
+        f(b as u8, fail_id());
+    }
+}
+
+/// Safely return two mutable borrows to two different locations in the given
+/// slice.
+///
+/// This panics if i == j.
+fn get_two_mut<T>(xs: &mut [T], i: usize, j: usize) -> (&mut T, &mut T) {
+    assert!(i != j, "{} must not be equal to {}", i, j);
+    if i < j {
+        let (before, after) = xs.split_at_mut(j);
+        (&mut before[i], &mut after[0])
+    } else {
+        let (before, after) = xs.split_at_mut(i);
+        (&mut after[0], &mut before[j])
+    }
+}
+
+/// Return the given byte as its escaped string form.
+fn escape(b: u8) -> String {
+    use std::ascii;
+
+    String::from_utf8(ascii::escape_default(b).collect::<Vec<_>>()).unwrap()
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn scratch() {
+        let nfa: NFA<usize> = Builder::new()
+            .dense_depth(0)
+            // .match_kind(MatchKind::LeftmostShortest)
+            // .match_kind(MatchKind::LeftmostLongest)
+            .match_kind(MatchKind::LeftmostFirst)
+            // .build(&["abcd", "ce", "b"])
+            // .build(&["ab", "bc"])
+            // .build(&["b", "bcd", "ce"])
+            // .build(&["abc", "bx"])
+            // .build(&["abc", "bd", "ab"])
+            // .build(&["abcdefghi", "hz", "abcdefgh"])
+            // .build(&["abcd", "bce", "b"])
+            .build(&["abcdefg", "bcde", "bcdef"])
+            .unwrap();
+        println!("{:?}", nfa);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/aho_corasick/prefilter.rs.html b/target/doc/src/aho_corasick/prefilter.rs.html new file mode 100644 index 0000000..914a817 --- /dev/null +++ b/target/doc/src/aho_corasick/prefilter.rs.html @@ -0,0 +1,505 @@ +prefilter.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+
+use std::fmt;
+use std::panic::{RefUnwindSafe, UnwindSafe};
+
+use memchr::{memchr, memchr2, memchr3};
+
+/// A prefilter describes the behavior of fast literal scanners for quickly
+/// skipping past bytes in the haystack that we know cannot possibly
+/// participate in a match.
+pub trait Prefilter: Send + Sync + RefUnwindSafe + UnwindSafe + fmt::Debug {
+    /// Returns the next possible match candidate. This may yield false
+    /// positives, so callers must "confirm" a match starting at the position
+    /// returned. This, however, must never produce false negatives. That is,
+    /// this must, at minimum, return the starting position of the next match
+    /// in the given haystack after or at the given position.
+    fn next_candidate(&self, haystack: &[u8], at: usize) -> Option<usize>;
+
+    /// A method for cloning a prefilter, to work-around the fact that Clone
+    /// is not object-safe.
+    fn clone_prefilter(&self) -> Box<Prefilter>;
+}
+
+/// A convenience object for representing any type that implements Prefilter
+/// and is cloneable.
+#[derive(Debug)]
+pub struct PrefilterObj(Box<Prefilter>);
+
+impl Clone for PrefilterObj {
+    fn clone(&self) -> Self {
+        PrefilterObj(self.0.clone_prefilter())
+    }
+}
+
+impl PrefilterObj {
+    /// Create a new prefilter object.
+    pub fn new<T: Prefilter + 'static>(t: T) -> PrefilterObj {
+        PrefilterObj(Box::new(t))
+    }
+
+    /// Return the underlying prefilter trait object.
+    pub fn as_ref(&self) -> &Prefilter {
+        &*self.0
+    }
+}
+
+/// PrefilterState tracks state associated with the effectiveness of a
+/// prefilter. It is used to track how many bytes, on average, are skipped by
+/// the prefilter. If this average dips below a certain threshold over time,
+/// then the state renders the prefilter inert and stops using it.
+///
+/// A prefilter state should be created for each search. (Where creating an
+/// iterator via, e.g., `find_iter`, is treated as a single search.)
+#[derive(Clone, Debug)]
+pub struct PrefilterState {
+    /// The number of skips that has been executed.
+    skips: usize,
+    /// The total number of bytes that have been skipped.
+    skipped: usize,
+    /// The maximum length of a match. This is used to help determine how many
+    /// bytes on average should be skipped in order for a prefilter to be
+    /// effective.
+    max_match_len: usize,
+    /// Once this heuristic has been deemed ineffective, it will be inert
+    /// throughout the rest of its lifetime. This serves as a cheap way to
+    /// check inertness.
+    inert: bool,
+}
+
+impl PrefilterState {
+    /// The minimum number of skip attempts to try before considering whether
+    /// a prefilter is effective or not.
+    const MIN_SKIPS: usize = 40;
+
+    /// The minimum amount of bytes that skipping must average, expressed as
+    /// a factor of the multiple of the length of a possible match.
+    ///
+    /// That is, after MIN_SKIPS have occurred, if the average number of bytes
+    /// skipped ever falls below MIN_AVG_FACTOR, then this searcher is rendered
+    /// inert.
+    const MIN_AVG_FACTOR: usize = 2;
+
+    /// Create a fresh prefilter state.
+    pub fn new(max_match_len: usize) -> PrefilterState {
+        PrefilterState { skips: 0, skipped: 0, max_match_len, inert: false }
+    }
+
+    /// Update this state with the number of bytes skipped on the last
+    /// invocation of the prefilter.
+    #[inline]
+    pub fn update(&mut self, skipped: usize) {
+        self.skips += 1;
+        self.skipped += skipped;
+    }
+
+    /// Return true if and only if this state indicates that a prefilter is
+    /// still effective.
+    #[inline]
+    pub fn is_effective(&mut self) -> bool {
+        if self.inert {
+            return false;
+        }
+        if self.skips < PrefilterState::MIN_SKIPS {
+            return true;
+        }
+
+        let min_avg = PrefilterState::MIN_AVG_FACTOR * self.max_match_len;
+        if self.skipped >= min_avg * self.skips {
+            return true;
+        }
+
+        // We're inert.
+        self.inert = true;
+        false
+    }
+}
+
+/// A builder for construction a starting byte prefilter.
+///
+/// A starting byte prefilter is a simplistic prefilter that looks for possible
+/// matches by reporting all positions corresponding to a particular byte. This
+/// generally only takes affect when there are at most 3 distinct possible
+/// starting bytes. e.g., the patterns `foo`, `bar`, and `baz` have two
+/// distinct starting bytes (`f` and `b`), and this prefiler returns all
+/// occurrences of either `f` or `b`.
+///
+/// In some cases, a heuristic frequency analysis may determine that it would
+/// be better not to use this prefilter even when there are 3 or fewer distinct
+/// starting bytes.
+#[derive(Clone, Debug)]
+pub struct StartBytesBuilder {
+    byteset: Vec<bool>,
+}
+
+impl StartBytesBuilder {
+    /// Create a new builder for constructing a start byte prefilter.
+    pub fn new() -> StartBytesBuilder {
+        StartBytesBuilder { byteset: vec![false; 256] }
+    }
+
+    /// Build the starting bytes prefilter.
+    ///
+    /// If there are more than 3 distinct starting bytes, or if heuristics
+    /// otherwise determine that this prefilter should not be used, then `None`
+    /// is returned.
+    pub fn build(&self) -> Option<PrefilterObj> {
+        let (mut bytes, mut len) = ([0; 3], 0);
+        for b in 0..256 {
+            if !self.byteset[b] {
+                continue;
+            }
+            // We've exceeded our limit, so bail.
+            if len == 3 {
+                return None;
+            }
+            // We don't handle non-ASCII bytes for now. Getting non-ASCII
+            // bytes right is trickier, since we generally don't want to put
+            // a leading UTF-8 code unit into a prefilter that isn't ASCII,
+            // since they can frequently. Instead, it would be better to use a
+            // continuation byte, but this requires more sophisticated analysis
+            // of the automaton and a richer prefilter API.
+            if b > 0x7F {
+                return None;
+            }
+            bytes[len] = b as u8;
+            len += 1;
+        }
+        match len {
+            0 => None,
+            1 => {
+                Some(PrefilterObj::new(StartBytesOne {
+                    byte1: bytes[0],
+                }))
+            }
+            2 => {
+                Some(PrefilterObj::new(StartBytesTwo {
+                    byte1: bytes[0],
+                    byte2: bytes[1],
+                }))
+            }
+            3 => {
+                Some(PrefilterObj::new(StartBytesThree {
+                    byte1: bytes[0],
+                    byte2: bytes[1],
+                    byte3: bytes[2],
+                }))
+            }
+            _ => unreachable!(),
+        }
+    }
+
+    /// Add a starting byte to this builder.
+    ///
+    /// In general, all possible starting bytes for an automaton should be
+    /// added to this builder before attempting to construct the prefilter.
+    pub fn add(&mut self, byte: u8) {
+        self.byteset[byte as usize] = true;
+    }
+}
+
+/// A prefilter for scanning for a single starting byte.
+#[derive(Clone, Debug)]
+pub struct StartBytesOne {
+    byte1: u8,
+}
+
+impl Prefilter for StartBytesOne {
+    fn next_candidate(&self, haystack: &[u8], at: usize) -> Option<usize> {
+        memchr(self.byte1, &haystack[at..])
+            .map(|i| at + i)
+    }
+
+    fn clone_prefilter(&self) -> Box<Prefilter> {
+        Box::new(self.clone())
+    }
+}
+
+/// A prefilter for scanning for two starting bytes.
+#[derive(Clone, Debug)]
+pub struct StartBytesTwo {
+    byte1: u8,
+    byte2: u8,
+}
+
+impl Prefilter for StartBytesTwo {
+    fn next_candidate(&self, haystack: &[u8], at: usize) -> Option<usize> {
+        memchr2(self.byte1, self.byte2, &haystack[at..])
+            .map(|i| at + i)
+    }
+
+    fn clone_prefilter(&self) -> Box<Prefilter> {
+        Box::new(self.clone())
+    }
+}
+
+/// A prefilter for scanning for three starting bytes.
+#[derive(Clone, Debug)]
+pub struct StartBytesThree {
+    byte1: u8,
+    byte2: u8,
+    byte3: u8,
+}
+
+impl Prefilter for StartBytesThree {
+    fn next_candidate(&self, haystack: &[u8], at: usize) -> Option<usize> {
+        memchr3(self.byte1, self.byte2, self.byte3, &haystack[at..])
+            .map(|i| at + i)
+    }
+
+    fn clone_prefilter(&self) -> Box<Prefilter> {
+        Box::new(self.clone())
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/aho_corasick/state_id.rs.html b/target/doc/src/aho_corasick/state_id.rs.html new file mode 100644 index 0000000..a8d861e --- /dev/null +++ b/target/doc/src/aho_corasick/state_id.rs.html @@ -0,0 +1,335 @@ +state_id.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+
+use std::fmt::Debug;
+use std::hash::Hash;
+
+use error::{Error, Result};
+
+// NOTE: Most of this code was copied from regex-automata, but without the
+// (de)serialization specific stuff.
+
+/// Check that the premultiplication of the given state identifier can
+/// fit into the representation indicated by `S`. If it cannot, or if it
+/// overflows `usize` itself, then an error is returned.
+pub fn premultiply_overflow_error<S: StateID>(
+    last_state: S,
+    alphabet_len: usize,
+) -> Result<()> {
+    let requested = match last_state.to_usize().checked_mul(alphabet_len) {
+        Some(requested) => requested,
+        None => return Err(Error::premultiply_overflow(0, 0)),
+    };
+    if requested > S::max_id() {
+        return Err(Error::premultiply_overflow(S::max_id(), requested));
+    }
+    Ok(())
+}
+
+/// Convert the given `usize` to the chosen state identifier
+/// representation. If the given value cannot fit in the chosen
+/// representation, then an error is returned.
+pub fn usize_to_state_id<S: StateID>(value: usize) -> Result<S> {
+    if value > S::max_id() {
+        Err(Error::state_id_overflow(S::max_id()))
+    } else {
+        Ok(S::from_usize(value))
+    }
+}
+
+/// Return the unique identifier for an automaton's fail state in the chosen
+/// representation indicated by `S`.
+pub fn fail_id<S: StateID>() -> S {
+    S::from_usize(0)
+}
+
+/// Return the unique identifier for an automaton's fail state in the chosen
+/// representation indicated by `S`.
+pub fn dead_id<S: StateID>() -> S {
+    S::from_usize(1)
+}
+
+mod private {
+    /// Sealed stops crates other than aho-corasick from implementing any
+    /// traits that use it.
+    pub trait Sealed{}
+    impl Sealed for u8 {}
+    impl Sealed for u16 {}
+    impl Sealed for u32 {}
+    impl Sealed for u64 {}
+    impl Sealed for usize {}
+}
+
+/// A trait describing the representation of an automaton's state identifier.
+///
+/// The purpose of this trait is to safely express both the possible state
+/// identifier representations that can be used in an automaton and to convert
+/// between state identifier representations and types that can be used to
+/// efficiently index memory (such as `usize`).
+///
+/// In general, one should not need to implement this trait explicitly. Indeed,
+/// for now, this trait is sealed such that it cannot be implemented by any
+/// other type. In particular, this crate provides implementations for `u8`,
+/// `u16`, `u32`, `u64` and `usize`. (`u32` and `u64` are only provided for
+/// targets that can represent all corresponding values in a `usize`.)
+///
+/// # Safety
+///
+/// This trait is unsafe because the correctness of its implementations may be
+/// relied upon by other unsafe code. For example, one possible way to
+/// implement this trait incorrectly would be to return a maximum identifier
+/// in `max_id` that is greater than the real maximum identifier. This will
+/// likely result in wrap-on-overflow semantics in release mode, which can in
+/// turn produce incorrect state identifiers. Those state identifiers may then
+/// in turn access out-of-bounds memory in an automaton's search routine, where
+/// bounds checks are explicitly elided for performance reasons.
+pub unsafe trait StateID:
+    private::Sealed
+    + Clone + Copy + Debug + Eq + Hash + PartialEq + PartialOrd + Ord
+{
+    /// Convert from a `usize` to this implementation's representation.
+    ///
+    /// Implementors may assume that `n <= Self::max_id`. That is, implementors
+    /// do not need to check whether `n` can fit inside this implementation's
+    /// representation.
+    fn from_usize(n: usize) -> Self;
+
+    /// Convert this implementation's representation to a `usize`.
+    ///
+    /// Implementors must not return a `usize` value greater than
+    /// `Self::max_id` and must not permit overflow when converting between the
+    /// implementor's representation and `usize`. In general, the preferred
+    /// way for implementors to achieve this is to simply not provide
+    /// implementations of `StateID` that cannot fit into the target platform's
+    /// `usize`.
+    fn to_usize(self) -> usize;
+
+    /// Return the maximum state identifier supported by this representation.
+    ///
+    /// Implementors must return a correct bound. Doing otherwise may result
+    /// in memory unsafety.
+    fn max_id() -> usize;
+}
+
+unsafe impl StateID for usize {
+    #[inline]
+    fn from_usize(n: usize) -> usize { n }
+
+    #[inline]
+    fn to_usize(self) -> usize { self }
+
+    #[inline]
+    fn max_id() -> usize { ::std::usize::MAX }
+}
+
+unsafe impl StateID for u8 {
+    #[inline]
+    fn from_usize(n: usize) -> u8 { n as u8 }
+
+    #[inline]
+    fn to_usize(self) -> usize { self as usize }
+
+    #[inline]
+    fn max_id() -> usize { ::std::u8::MAX as usize }
+}
+
+unsafe impl StateID for u16 {
+    #[inline]
+    fn from_usize(n: usize) -> u16 { n as u16 }
+
+    #[inline]
+    fn to_usize(self) -> usize { self as usize }
+
+    #[inline]
+    fn max_id() -> usize { ::std::u16::MAX as usize }
+}
+
+#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
+unsafe impl StateID for u32 {
+    #[inline]
+    fn from_usize(n: usize) -> u32 { n as u32 }
+
+    #[inline]
+    fn to_usize(self) -> usize { self as usize }
+
+    #[inline]
+    fn max_id() -> usize { ::std::u32::MAX as usize }
+}
+
+#[cfg(target_pointer_width = "64")]
+unsafe impl StateID for u64 {
+    #[inline]
+    fn from_usize(n: usize) -> u64 { n as u64 }
+
+    #[inline]
+    fn to_usize(self) -> usize { self as usize }
+
+    #[inline]
+    fn max_id() -> usize { ::std::u64::MAX as usize }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/c2_chacha/guts.rs.html b/target/doc/src/c2_chacha/guts.rs.html new file mode 100644 index 0000000..2fb2ccb --- /dev/null +++ b/target/doc/src/c2_chacha/guts.rs.html @@ -0,0 +1,601 @@ +guts.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+
+#[cfg(feature = "rustcrypto_api")]
+pub use stream_cipher::generic_array;
+
+pub use ppv_lite86::Machine;
+use ppv_lite86::{vec128_storage, ArithOps, BitOps32, LaneWords4, MultiLane, StoreBytes, Vec4};
+
+pub(crate) const BLOCK: usize = 64;
+pub(crate) const BLOCK64: u64 = BLOCK as u64;
+const LOG2_BUFBLOCKS: u64 = 2;
+const BUFBLOCKS: u64 = 1 << LOG2_BUFBLOCKS;
+pub(crate) const BUFSZ64: u64 = BLOCK64 * BUFBLOCKS;
+pub(crate) const BUFSZ: usize = BUFSZ64 as usize;
+
+#[derive(Clone)]
+pub struct ChaCha {
+    pub(crate) b: vec128_storage,
+    pub(crate) c: vec128_storage,
+    pub(crate) d: vec128_storage,
+}
+
+#[derive(Clone)]
+pub struct State<V> {
+    pub(crate) a: V,
+    pub(crate) b: V,
+    pub(crate) c: V,
+    pub(crate) d: V,
+}
+
+#[inline(always)]
+pub(crate) fn round<V: ArithOps + BitOps32>(mut x: State<V>) -> State<V> {
+    x.a += x.b;
+    x.d = (x.d ^ x.a).rotate_each_word_right16();
+    x.c += x.d;
+    x.b = (x.b ^ x.c).rotate_each_word_right20();
+    x.a += x.b;
+    x.d = (x.d ^ x.a).rotate_each_word_right24();
+    x.c += x.d;
+    x.b = (x.b ^ x.c).rotate_each_word_right25();
+    x
+}
+
+#[inline(always)]
+pub(crate) fn diagonalize<V: LaneWords4>(mut x: State<V>) -> State<V> {
+    x.b = x.b.shuffle_lane_words3012();
+    x.c = x.c.shuffle_lane_words2301();
+    x.d = x.d.shuffle_lane_words1230();
+    x
+}
+#[inline(always)]
+pub(crate) fn undiagonalize<V: LaneWords4>(mut x: State<V>) -> State<V> {
+    x.b = x.b.shuffle_lane_words1230();
+    x.c = x.c.shuffle_lane_words2301();
+    x.d = x.d.shuffle_lane_words3012();
+    x
+}
+
+impl ChaCha {
+    #[inline(always)]
+    pub fn new(key: &[u8; 32], nonce: &[u8]) -> Self {
+        init_chacha(key, nonce)
+    }
+
+    #[inline(always)]
+    fn pos64<M: Machine>(&self, m: M) -> u64 {
+        let d: M::u32x4 = m.unpack(self.d);
+        ((d.extract(1) as u64) << 32) | d.extract(0) as u64
+    }
+
+    /// Set 64-bit block count, affecting next refill.
+    #[inline(always)]
+    pub(crate) fn seek64<M: Machine>(&mut self, m: M, blockct: u64) {
+        let d: M::u32x4 = m.unpack(self.d);
+        self.d = d
+            .insert((blockct >> 32) as u32, 1)
+            .insert(blockct as u32, 0)
+            .into();
+    }
+
+    /// Set 32-bit block count, affecting next refill.
+    #[inline(always)]
+    pub(crate) fn seek32<M: Machine>(&mut self, m: M, blockct: u32) {
+        let d: M::u32x4 = m.unpack(self.d);
+        self.d = d.insert(blockct, 0).into();
+    }
+
+    /// Produce output from the current state.
+    #[inline(always)]
+    fn output_narrow<M: Machine>(&mut self, m: M, x: State<M::u32x4>, out: &mut [u8; BLOCK]) {
+        let k = m.vec([0x6170_7865, 0x3320_646e, 0x7962_2d32, 0x6b20_6574]);
+        (x.a + k).write_le(&mut out[0..16]);
+        (x.b + m.unpack(self.b)).write_le(&mut out[16..32]);
+        (x.c + m.unpack(self.c)).write_le(&mut out[32..48]);
+        (x.d + m.unpack(self.d)).write_le(&mut out[48..64]);
+    }
+
+    /// Add one to the block counter (no overflow check).
+    #[inline(always)]
+    fn inc_block_ct<M: Machine>(&mut self, m: M) {
+        let mut pos = self.pos64(m);
+        let d0: M::u32x4 = m.unpack(self.d);
+        pos += 1;
+        let d1 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
+        self.d = d1.into();
+    }
+
+    /// Produce 4 blocks of output, advancing the state
+    #[inline(always)]
+    pub fn refill4(&mut self, drounds: u32, out: &mut [u8; BUFSZ]) {
+        refill_wide(self, drounds, out)
+    }
+
+    /// Produce a block of output, advancing the state
+    #[inline(always)]
+    pub fn refill(&mut self, drounds: u32, out: &mut [u8; BLOCK]) {
+        refill_narrow(self, drounds, out)
+    }
+
+    #[inline(always)]
+    pub(crate) fn refill_rounds(&mut self, drounds: u32) -> State<vec128_storage> {
+        refill_narrow_rounds(self, drounds)
+    }
+
+    #[inline(always)]
+    pub fn set_stream_param(&mut self, param: u32, value: u64) {
+        set_stream_param(self, param, value)
+    }
+
+    #[inline(always)]
+    pub fn get_stream_param(&self, param: u32) -> u64 {
+        get_stream_param(self, param)
+    }
+}
+
+#[inline(always)]
+fn refill_wide_impl<Mach: Machine>(
+    m: Mach,
+    state: &mut ChaCha,
+    drounds: u32,
+    out: &mut [u8; BUFSZ],
+) {
+    let k = m.vec([0x6170_7865, 0x3320_646e, 0x7962_2d32, 0x6b20_6574]);
+    let mut pos = state.pos64(m);
+    let d0: Mach::u32x4 = m.unpack(state.d);
+    pos += 1;
+    let d1 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
+    pos += 1;
+    let d2 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
+    pos += 1;
+    let d3 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
+
+    let b = m.unpack(state.b);
+    let c = m.unpack(state.c);
+    let mut x = State {
+        a: Mach::u32x4x4::from_lanes([k, k, k, k]),
+        b: Mach::u32x4x4::from_lanes([b, b, b, b]),
+        c: Mach::u32x4x4::from_lanes([c, c, c, c]),
+        d: m.unpack(Mach::u32x4x4::from_lanes([d0, d1, d2, d3]).into()),
+    };
+    for _ in 0..drounds {
+        x = round(x);
+        x = undiagonalize(round(diagonalize(x)));
+    }
+    let mut pos = state.pos64(m);
+    let d0: Mach::u32x4 = m.unpack(state.d);
+    pos += 1;
+    let d1 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
+    pos += 1;
+    let d2 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
+    pos += 1;
+    let d3 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
+    pos += 1;
+    let d4 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
+
+    let (a, b, c, d) = (
+        x.a.to_lanes(),
+        x.b.to_lanes(),
+        x.c.to_lanes(),
+        x.d.to_lanes(),
+    );
+    let sb = m.unpack(state.b);
+    let sc = m.unpack(state.c);
+    let sd = [m.unpack(state.d), d1, d2, d3];
+    state.d = d4.into();
+    let mut words = out.chunks_exact_mut(16);
+    for ((((&a, &b), &c), &d), &sd) in a.iter().zip(&b).zip(&c).zip(&d).zip(&sd) {
+        (a + k).write_le(words.next().unwrap());
+        (b + sb).write_le(words.next().unwrap());
+        (c + sc).write_le(words.next().unwrap());
+        (d + sd).write_le(words.next().unwrap());
+    }
+}
+
+dispatch!(m, Mach, {
+    fn refill_wide(state: &mut ChaCha, drounds: u32, out: &mut [u8; BUFSZ]) {
+        refill_wide_impl(m, state, drounds, out);
+    }
+});
+
+/// Refill the buffer from a single-block round, updating the block count.
+dispatch_light128!(m, Mach, {
+    fn refill_narrow(state: &mut ChaCha, drounds: u32, out: &mut [u8; BLOCK]) {
+        let x = refill_narrow_rounds(state, drounds);
+        let x = State {
+            a: m.unpack(x.a),
+            b: m.unpack(x.b),
+            c: m.unpack(x.c),
+            d: m.unpack(x.d),
+        };
+        state.output_narrow(m, x, out);
+        state.inc_block_ct(m);
+    }
+});
+
+/// Single-block, rounds-only; shared by try_apply_keystream for tails shorter than BUFSZ
+/// and XChaCha's setup step.
+dispatch!(m, Mach, {
+    fn refill_narrow_rounds(state: &mut ChaCha, drounds: u32) -> State<vec128_storage> {
+        let k: Mach::u32x4 = m.vec([0x6170_7865, 0x3320_646e, 0x7962_2d32, 0x6b20_6574]);
+        let mut x = State {
+            a: k,
+            b: m.unpack(state.b),
+            c: m.unpack(state.c),
+            d: m.unpack(state.d),
+        };
+        for _ in 0..drounds {
+            x = round(x);
+            x = undiagonalize(round(diagonalize(x)));
+        }
+        State {
+            a: x.a.into(),
+            b: x.b.into(),
+            c: x.c.into(),
+            d: x.d.into(),
+        }
+    }
+});
+
+dispatch_light128!(m, Mach, {
+    fn set_stream_param(state: &mut ChaCha, param: u32, value: u64) {
+        let d: Mach::u32x4 = m.unpack(state.d);
+        state.d = d
+            .insert((value >> 32) as u32, (param << 1) | 1)
+            .insert(value as u32, param << 1)
+            .into();
+    }
+});
+
+dispatch_light128!(m, Mach, {
+    fn get_stream_param(state: &ChaCha, param: u32) -> u64 {
+        let d: Mach::u32x4 = m.unpack(state.d);
+        ((d.extract((param << 1) | 1) as u64) << 32) | d.extract(param << 1) as u64
+    }
+});
+
+fn read_u32le(xs: &[u8]) -> u32 {
+    assert_eq!(xs.len(), 4);
+    u32::from(xs[0]) | (u32::from(xs[1]) << 8) | (u32::from(xs[2]) << 16) | (u32::from(xs[3]) << 24)
+}
+
+dispatch_light128!(m, Mach, {
+    fn init_chacha(key: &[u8; 32], nonce: &[u8]) -> ChaCha {
+        let ctr_nonce = [
+            0,
+            if nonce.len() == 12 {
+                read_u32le(&nonce[0..4])
+            } else {
+                0
+            },
+            read_u32le(&nonce[nonce.len() - 8..nonce.len() - 4]),
+            read_u32le(&nonce[nonce.len() - 4..]),
+        ];
+        let key0: Mach::u32x4 = m.read_le(&key[..16]);
+        let key1: Mach::u32x4 = m.read_le(&key[16..]);
+        ChaCha {
+            b: key0.into(),
+            c: key1.into(),
+            d: ctr_nonce.into(),
+        }
+    }
+});
+
+dispatch_light128!(m, Mach, {
+    fn init_chacha_x(key: &[u8; 32], nonce: &[u8; 24], rounds: u32) -> ChaCha {
+        let key0: Mach::u32x4 = m.read_le(&key[..16]);
+        let key1: Mach::u32x4 = m.read_le(&key[16..]);
+        let nonce0: Mach::u32x4 = m.read_le(&nonce[..16]);
+        let mut state = ChaCha {
+            b: key0.into(),
+            c: key1.into(),
+            d: nonce0.into(),
+        };
+        let x = refill_narrow_rounds(&mut state, rounds);
+        let ctr_nonce1 = [0, 0, read_u32le(&nonce[16..20]), read_u32le(&nonce[20..24])];
+        state.b = x.a;
+        state.c = x.d;
+        state.d = ctr_nonce1.into();
+        state
+    }
+});
+
+
\ No newline at end of file diff --git a/target/doc/src/c2_chacha/lib.rs.html b/target/doc/src/c2_chacha/lib.rs.html new file mode 100644 index 0000000..b39346d --- /dev/null +++ b/target/doc/src/c2_chacha/lib.rs.html @@ -0,0 +1,101 @@ +lib.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+
+// copyright 2019 Kaz Wesley
+
+//! Pure Rust ChaCha with SIMD optimizations.
+//!
+//! Stream-cipher usage:
+//! ```
+//! extern crate c2_chacha;
+//!
+//! use c2_chacha::stream_cipher::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek};
+//! use c2_chacha::{ChaCha20, ChaCha12};
+//!
+//! let key = b"very secret key-the most secret.";
+//! let iv = b"my nonce";
+//! let plaintext = b"The quick brown fox jumps over the lazy dog.";
+//!
+//! let mut buffer = plaintext.to_vec();
+//! // create cipher instance
+//! let mut cipher = ChaCha20::new_var(key, iv).unwrap();
+//! // apply keystream (encrypt)
+//! cipher.apply_keystream(&mut buffer);
+//! // and decrypt it back
+//! cipher.seek(0);
+//! cipher.apply_keystream(&mut buffer);
+//! // stream ciphers can be used with streaming messages
+//! let mut cipher = ChaCha12::new_var(key, iv).unwrap();
+//! for chunk in buffer.chunks_mut(3) {
+//!     cipher.apply_keystream(chunk);
+//! }
+//! ```
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+#[cfg(test)]
+#[macro_use]
+extern crate hex_literal;
+
+#[cfg(feature = "std")]
+#[macro_use]
+extern crate lazy_static;
+
+#[macro_use]
+extern crate ppv_lite86;
+
+pub mod guts;
+
+#[cfg(feature = "rustcrypto_api")]
+mod rustcrypto_impl;
+#[cfg(feature = "rustcrypto_api")]
+pub use self::rustcrypto_impl::{stream_cipher, ChaCha12, ChaCha20, ChaCha8, Ietf, XChaCha20};
+
+
\ No newline at end of file diff --git a/target/doc/src/cfg_if/lib.rs.html b/target/doc/src/cfg_if/lib.rs.html new file mode 100644 index 0000000..7a24deb --- /dev/null +++ b/target/doc/src/cfg_if/lib.rs.html @@ -0,0 +1,291 @@ +lib.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+
+//! A macro for defining `#[cfg]` if-else statements.
+//!
+//! The macro provided by this crate, `cfg_if`, is similar to the `if/elif` C
+//! preprocessor macro by allowing definition of a cascade of `#[cfg]` cases,
+//! emitting the implementation which matches first.
+//!
+//! This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
+//! without having to rewrite each clause multiple times.
+//!
+//! # Example
+//!
+//! ```
+//! #[macro_use]
+//! extern crate cfg_if;
+//!
+//! cfg_if! {
+//!     if #[cfg(unix)] {
+//!         fn foo() { /* unix specific functionality */ }
+//!     } else if #[cfg(target_pointer_width = "32")] {
+//!         fn foo() { /* non-unix, 32-bit functionality */ }
+//!     } else {
+//!         fn foo() { /* fallback implementation */ }
+//!     }
+//! }
+//!
+//! # fn main() {}
+//! ```
+
+#![no_std]
+
+#![doc(html_root_url = "https://docs.rs/cfg-if")]
+#![deny(missing_docs)]
+#![cfg_attr(test, deny(warnings))]
+
+/// The main macro provided by this crate. See crate documentation for more
+/// information.
+#[macro_export(local_inner_macros)]
+macro_rules! cfg_if {
+    // match if/else chains with a final `else`
+    ($(
+        if #[cfg($($meta:meta),*)] { $($it:item)* }
+    ) else * else {
+        $($it2:item)*
+    }) => {
+        cfg_if! {
+            @__items
+            () ;
+            $( ( ($($meta),*) ($($it)*) ), )*
+            ( () ($($it2)*) ),
+        }
+    };
+
+    // match if/else chains lacking a final `else`
+    (
+        if #[cfg($($i_met:meta),*)] { $($i_it:item)* }
+        $(
+            else if #[cfg($($e_met:meta),*)] { $($e_it:item)* }
+        )*
+    ) => {
+        cfg_if! {
+            @__items
+            () ;
+            ( ($($i_met),*) ($($i_it)*) ),
+            $( ( ($($e_met),*) ($($e_it)*) ), )*
+            ( () () ),
+        }
+    };
+
+    // Internal and recursive macro to emit all the items
+    //
+    // Collects all the negated cfgs in a list at the beginning and after the
+    // semicolon is all the remaining items
+    (@__items ($($not:meta,)*) ; ) => {};
+    (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => {
+        // Emit all items within one block, applying an approprate #[cfg]. The
+        // #[cfg] will require all `$m` matchers specified and must also negate
+        // all previous matchers.
+        cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* }
+
+        // Recurse to emit all other items in `$rest`, and when we do so add all
+        // our `$m` matchers to the list of `$not` matchers as future emissions
+        // will have to negate everything we just matched as well.
+        cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
+    };
+
+    // Internal macro to Apply a cfg attribute to a list of items
+    (@__apply $m:meta, $($it:item)*) => {
+        $(#[$m] $it)*
+    };
+}
+
+#[cfg(test)]
+mod tests {
+    cfg_if! {
+        if #[cfg(test)] {
+            use core::option::Option as Option2;
+            fn works1() -> Option2<u32> { Some(1) }
+        } else {
+            fn works1() -> Option<u32> { None }
+        }
+    }
+
+    cfg_if! {
+        if #[cfg(foo)] {
+            fn works2() -> bool { false }
+        } else if #[cfg(test)] {
+            fn works2() -> bool { true }
+        } else {
+            fn works2() -> bool { false }
+        }
+    }
+
+    cfg_if! {
+        if #[cfg(foo)] {
+            fn works3() -> bool { false }
+        } else {
+            fn works3() -> bool { true }
+        }
+    }
+
+    cfg_if! {
+        if #[cfg(test)] {
+            use core::option::Option as Option3;
+            fn works4() -> Option3<u32> { Some(1) }
+        }
+    }
+
+    cfg_if! {
+        if #[cfg(foo)] {
+            fn works5() -> bool { false }
+        } else if #[cfg(test)] {
+            fn works5() -> bool { true }
+        }
+    }
+
+    #[test]
+    fn it_works() {
+        assert!(works1().is_some());
+        assert!(works2());
+        assert!(works3());
+        assert!(works4().is_some());
+        assert!(works5());
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/getrandom/error.rs.html b/target/doc/src/getrandom/error.rs.html new file mode 100644 index 0000000..10b5abc --- /dev/null +++ b/target/doc/src/getrandom/error.rs.html @@ -0,0 +1,335 @@ +error.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+use core::fmt;
+use core::num::NonZeroU32;
+
+/// A small and `no_std` compatible error type.
+///
+/// The [`Error::raw_os_error()`] will indicate if the error is from the OS, and
+/// if so, which error code the OS gave the application. If such an error is
+/// encountered, please consult with your system documentation.
+///
+/// Internally this type is a NonZeroU32, with certain values reserved for
+/// certain purposes, see [`Error::INTERNAL_START`] and [`Error::CUSTOM_START`].
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub struct Error(NonZeroU32);
+
+impl Error {
+    #[deprecated(since = "0.1.7")]
+    pub const UNKNOWN: Error = UNSUPPORTED;
+    #[deprecated(since = "0.1.7")]
+    pub const UNAVAILABLE: Error = UNSUPPORTED;
+
+    /// Codes below this point represent OS Errors (i.e. positive i32 values).
+    /// Codes at or above this point, but below [`Error::CUSTOM_START`] are
+    /// reserved for use by the `rand` and `getrandom` crates.
+    pub const INTERNAL_START: u32 = 1 << 31;
+
+    /// Codes at or above this point can be used by users to define their own
+    /// custom errors.
+    pub const CUSTOM_START: u32 = (1 << 31) + (1 << 30);
+
+    /// Extract the raw OS error code (if this error came from the OS)
+    ///
+    /// This method is identical to `std::io::Error::raw_os_error()`, except
+    /// that it works in `no_std` contexts. If this method returns `None`, the
+    /// error value can still be formatted via the `Diplay` implementation.
+    #[inline]
+    pub fn raw_os_error(&self) -> Option<i32> {
+        if self.0.get() < Self::INTERNAL_START {
+            Some(self.0.get() as i32)
+        } else {
+            None
+        }
+    }
+
+    /// Extract the bare error code.
+    ///
+    /// This code can either come from the underlying OS, or be a custom error.
+    /// Use [`Error::raw_os_error()`] to disambiguate.
+    #[inline]
+    pub fn code(&self) -> NonZeroU32 {
+        self.0
+    }
+}
+
+#[cfg(any(unix, target_os = "redox"))]
+fn os_err_desc(errno: i32, buf: &mut [u8]) -> Option<&str> {
+    let buf_ptr = buf.as_mut_ptr() as *mut libc::c_char;
+    if unsafe { libc::strerror_r(errno, buf_ptr, buf.len()) } != 0 {
+        return None;
+    }
+
+    // Take up to trailing null byte
+    let idx = buf.iter().position(|&b| b == 0).unwrap_or(buf.len());
+    core::str::from_utf8(&buf[..idx]).ok()
+}
+
+#[cfg(not(any(unix, target_os = "redox")))]
+fn os_err_desc(_errno: i32, _buf: &mut [u8]) -> Option<&str> {
+    None
+}
+
+impl fmt::Debug for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let mut dbg = f.debug_struct("Error");
+        if let Some(errno) = self.raw_os_error() {
+            dbg.field("os_error", &errno);
+            let mut buf = [0u8; 128];
+            if let Some(desc) = os_err_desc(errno, &mut buf) {
+                dbg.field("description", &desc);
+            }
+        } else if let Some(desc) = internal_desc(*self) {
+            dbg.field("internal_code", &self.0.get());
+            dbg.field("description", &desc);
+        } else {
+            dbg.field("unknown_code", &self.0.get());
+        }
+        dbg.finish()
+    }
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        if let Some(errno) = self.raw_os_error() {
+            let mut buf = [0u8; 128];
+            match os_err_desc(errno, &mut buf) {
+                Some(desc) => f.write_str(desc),
+                None => write!(f, "OS Error: {}", errno),
+            }
+        } else if let Some(desc) = internal_desc(*self) {
+            f.write_str(desc)
+        } else {
+            write!(f, "Unknown Error: {}", self.0.get())
+        }
+    }
+}
+
+impl From<NonZeroU32> for Error {
+    fn from(code: NonZeroU32) -> Self {
+        Self(code)
+    }
+}
+
+// TODO: Convert to a function when min_version >= 1.33
+macro_rules! internal_error {
+    ($n:expr) => {
+        Error(unsafe { NonZeroU32::new_unchecked(Error::INTERNAL_START + $n as u16 as u32) })
+    };
+}
+
+/// Internal Error constants
+pub(crate) const UNSUPPORTED: Error = internal_error!(0);
+pub(crate) const ERRNO_NOT_POSITIVE: Error = internal_error!(1);
+pub(crate) const UNKNOWN_IO_ERROR: Error = internal_error!(2);
+pub(crate) const SEC_RANDOM_FAILED: Error = internal_error!(3);
+pub(crate) const RTL_GEN_RANDOM_FAILED: Error = internal_error!(4);
+pub(crate) const FAILED_RDRAND: Error = internal_error!(5);
+pub(crate) const NO_RDRAND: Error = internal_error!(6);
+pub(crate) const BINDGEN_CRYPTO_UNDEF: Error = internal_error!(7);
+pub(crate) const BINDGEN_GRV_UNDEF: Error = internal_error!(8);
+pub(crate) const STDWEB_NO_RNG: Error = internal_error!(9);
+pub(crate) const STDWEB_RNG_FAILED: Error = internal_error!(10);
+
+fn internal_desc(error: Error) -> Option<&'static str> {
+    match error {
+        UNSUPPORTED => Some("getrandom: this target is not supported"),
+        ERRNO_NOT_POSITIVE => Some("errno: did not return a positive value"),
+        UNKNOWN_IO_ERROR => Some("Unknown std::io::Error"),
+        SEC_RANDOM_FAILED => Some("SecRandomCopyBytes: call failed"),
+        RTL_GEN_RANDOM_FAILED => Some("RtlGenRandom: call failed"),
+        FAILED_RDRAND => Some("RDRAND: failed multiple times: CPU issue likely"),
+        NO_RDRAND => Some("RDRAND: instruction not supported"),
+        BINDGEN_CRYPTO_UNDEF => Some("wasm-bindgen: self.crypto is undefined"),
+        BINDGEN_GRV_UNDEF => Some("wasm-bindgen: crypto.getRandomValues is undefined"),
+        STDWEB_NO_RNG => Some("stdweb: no randomness source available"),
+        STDWEB_RNG_FAILED => Some("stdweb: failed to get randomness"),
+        _ => None,
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::Error;
+    use core::mem::size_of;
+
+    #[test]
+    fn test_size() {
+        assert_eq!(size_of::<Error>(), 4);
+        assert_eq!(size_of::<Result<(), Error>>(), 4);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/getrandom/error_impls.rs.html b/target/doc/src/getrandom/error_impls.rs.html new file mode 100644 index 0000000..4453564 --- /dev/null +++ b/target/doc/src/getrandom/error_impls.rs.html @@ -0,0 +1,73 @@ +error_impls.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+extern crate std;
+
+use crate::{error::UNKNOWN_IO_ERROR, Error};
+use core::convert::From;
+use core::num::NonZeroU32;
+use std::io;
+
+impl From<io::Error> for Error {
+    fn from(err: io::Error) -> Self {
+        if let Some(errno) = err.raw_os_error() {
+            if let Some(code) = NonZeroU32::new(errno as u32) {
+                return Error::from(code);
+            }
+        }
+        UNKNOWN_IO_ERROR
+    }
+}
+
+impl From<Error> for io::Error {
+    fn from(err: Error) -> Self {
+        match err.raw_os_error() {
+            Some(errno) => io::Error::from_raw_os_error(errno),
+            None => io::Error::new(io::ErrorKind::Other, err),
+        }
+    }
+}
+
+impl std::error::Error for Error {}
+
+
\ No newline at end of file diff --git a/target/doc/src/getrandom/lib.rs.html b/target/doc/src/getrandom/lib.rs.html new file mode 100644 index 0000000..5102433 --- /dev/null +++ b/target/doc/src/getrandom/lib.rs.html @@ -0,0 +1,515 @@ +lib.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+
+// Copyright 2019 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Interface to the random number generator of the operating system.
+//!
+//! # Platform sources
+//!
+//! | OS               | interface
+//! |------------------|---------------------------------------------------------
+//! | Linux, Android   | [`getrandom`][1] system call if available, otherwise [`/dev/urandom`][2] after reading from `/dev/random` once
+//! | Windows          | [`RtlGenRandom`][3]
+//! | macOS            | [`getentropy()`][19] if available, otherwise [`/dev/random`][20] (identical to `/dev/urandom`)
+//! | iOS              | [`SecRandomCopyBytes`][4]
+//! | FreeBSD          | [`getrandom()`][21] if available, otherwise [`kern.arandom`][5]
+//! | OpenBSD          | [`getentropy`][6]
+//! | NetBSD           | [`/dev/urandom`][7] after reading from `/dev/random` once
+//! | Dragonfly BSD    | [`/dev/random`][8]
+//! | Solaris, illumos | [`getrandom`][9] system call if available, otherwise [`/dev/random`][10]
+//! | Fuchsia OS       | [`cprng_draw`][11]
+//! | Redox            | [`rand:`][12]
+//! | CloudABI         | [`cloudabi_sys_random_get`][13]
+//! | Haiku            | `/dev/random` (identical to `/dev/urandom`)
+//! | L4RE, SGX, UEFI  | [RDRAND][18]
+//! | Hermit           | [RDRAND][18] as [`sys_rand`][22] is currently broken.
+//! | Web browsers     | [`Crypto.getRandomValues`][14] (see [Support for WebAssembly and ams.js][14])
+//! | Node.js          | [`crypto.randomBytes`][15] (see [Support for WebAssembly and ams.js][16])
+//! | WASI             | [`__wasi_random_get`][17]
+//!
+//! Getrandom doesn't have a blanket implementation for all Unix-like operating
+//! systems that reads from `/dev/urandom`. This ensures all supported operating
+//! systems are using the recommended interface and respect maximum buffer
+//! sizes.
+//!
+//! ## Support for WebAssembly and ams.js
+//!
+//! The three Emscripten targets `asmjs-unknown-emscripten`,
+//! `wasm32-unknown-emscripten` and `wasm32-experimental-emscripten` use
+//! Emscripten's emulation of `/dev/random` on web browsers and Node.js.
+//!
+//! The bare WASM target `wasm32-unknown-unknown` tries to call the javascript
+//! methods directly, using either `stdweb` or `wasm-bindgen` depending on what
+//! features are activated for this crate. Note that if both features are
+//! enabled `wasm-bindgen` will be used. If neither feature is enabled,
+//! `getrandom` will always fail.
+//!
+//! The WASI target `wasm32-wasi` uses the `__wasi_random_get` function defined
+//! by the WASI standard.
+//!
+//!
+//! ## Early boot
+//!
+//! It is possible that early in the boot process the OS hasn't had enough time
+//! yet to collect entropy to securely seed its RNG, especially on virtual
+//! machines.
+//!
+//! Some operating systems always block the thread until the RNG is securely
+//! seeded. This can take anywhere from a few seconds to more than a minute.
+//! Others make a best effort to use a seed from before the shutdown and don't
+//! document much.
+//!
+//! A few, Linux, NetBSD and Solaris, offer a choice between blocking and
+//! getting an error; in these cases we always choose to block.
+//!
+//! On Linux (when the `genrandom` system call is not available) and on NetBSD
+//! reading from `/dev/urandom` never blocks, even when the OS hasn't collected
+//! enough entropy yet. To avoid returning low-entropy bytes, we first read from
+//! `/dev/random` and only switch to `/dev/urandom` once this has succeeded.
+//!
+//! # Error handling
+//!
+//! We always choose failure over returning insecure "random" bytes. In general,
+//! on supported platforms, failure is highly unlikely, though not impossible.
+//! If an error does occur, then it is likely that it will occur on every call to
+//! `getrandom`, hence after the first successful call one can be reasonably
+//! confident that no errors will occur.
+//!
+//! On unsupported platforms, `getrandom` always fails. See the [`Error`] type
+//! for more information on what data is returned on failure.
+//!
+//! [1]: http://man7.org/linux/man-pages/man2/getrandom.2.html
+//! [2]: http://man7.org/linux/man-pages/man4/urandom.4.html
+//! [3]: https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-rtlgenrandom
+//! [4]: https://developer.apple.com/documentation/security/1399291-secrandomcopybytes?language=objc
+//! [5]: https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4
+//! [6]: https://man.openbsd.org/getentropy.2
+//! [7]: http://netbsd.gw.com/cgi-bin/man-cgi?random+4+NetBSD-current
+//! [8]: https://leaf.dragonflybsd.org/cgi/web-man?command=random&section=4
+//! [9]: https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html
+//! [10]: https://docs.oracle.com/cd/E86824_01/html/E54777/random-7d.html
+//! [11]: https://fuchsia.googlesource.com/fuchsia/+/master/zircon/docs/syscalls/cprng_draw.md
+//! [12]: https://github.com/redox-os/randd/blob/master/src/main.rs
+//! [13]: https://github.com/nuxinl/cloudabi#random_get
+//! [14]: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
+//! [15]: https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback
+//! [16]: #support-for-webassembly-and-amsjs
+//! [17]: https://github.com/WebAssembly/WASI/blob/master/design/WASI-core.md#__wasi_random_get
+//! [18]: https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
+//! [19]: https://www.unix.com/man-page/mojave/2/getentropy/
+//! [20]: https://www.unix.com/man-page/mojave/4/random/
+//! [21]: https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable
+//! [22]: https://github.com/hermitcore/libhermit-rs/blob/09c38b0371cee6f56a541400ba453e319e43db53/src/syscalls/random.rs#L21
+
+#![doc(
+    html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
+    html_favicon_url = "https://www.rust-lang.org/favicon.ico",
+    html_root_url = "https://rust-random.github.io/rand/"
+)]
+#![no_std]
+#![cfg_attr(feature = "stdweb", recursion_limit = "128")]
+
+#[macro_use]
+extern crate cfg_if;
+
+cfg_if! {
+    if #[cfg(feature = "log")] {
+        #[allow(unused)]
+        #[macro_use]
+        extern crate log;
+    } else {
+        #[allow(unused)]
+        macro_rules! error {
+            ($($x:tt)*) => {};
+        }
+    }
+}
+
+mod error;
+pub use crate::error::Error;
+
+#[allow(dead_code)]
+mod util;
+// Unlike the other Unix, Fuchsia and iOS don't use the libc to make any calls.
+#[cfg(any(
+    target_os = "android",
+    target_os = "dragonfly",
+    target_os = "emscripten",
+    target_os = "freebsd",
+    target_os = "haiku",
+    target_os = "illumos",
+    target_os = "linux",
+    target_os = "macos",
+    target_os = "netbsd",
+    target_os = "openbsd",
+    target_os = "redox",
+    target_os = "solaris",
+))]
+#[allow(dead_code)]
+mod util_libc;
+
+// std-only trait definitions (also need for use_file)
+#[cfg(any(
+    feature = "std",
+    target_os = "android",
+    target_os = "dragonfly",
+    target_os = "emscripten",
+    target_os = "freebsd",
+    target_os = "haiku",
+    target_os = "illumos",
+    target_os = "linux",
+    target_os = "macos",
+    target_os = "netbsd",
+    target_os = "openbsd",
+    target_os = "redox",
+    target_os = "solaris",
+))]
+mod error_impls;
+
+// These targets read from a file as a fallback method.
+#[cfg(any(
+    target_os = "android",
+    target_os = "linux",
+    target_os = "macos",
+    target_os = "solaris",
+    target_os = "illumos",
+))]
+mod use_file;
+
+// System-specific implementations.
+//
+// These should all provide getrandom_inner with the same signature as getrandom.
+cfg_if! {
+    if #[cfg(target_os = "android")] {
+        #[path = "linux_android.rs"] mod imp;
+    } else if #[cfg(target_os = "cloudabi")] {
+        #[path = "cloudabi.rs"] mod imp;
+    } else if #[cfg(target_os = "dragonfly")] {
+        #[path = "use_file.rs"] mod imp;
+    } else if #[cfg(target_os = "emscripten")] {
+        #[path = "use_file.rs"] mod imp;
+    } else if #[cfg(target_os = "freebsd")] {
+        #[path = "freebsd.rs"] mod imp;
+    } else if #[cfg(target_os = "fuchsia")] {
+        #[path = "fuchsia.rs"] mod imp;
+    } else if #[cfg(target_os = "haiku")] {
+        #[path = "use_file.rs"] mod imp;
+    } else if #[cfg(target_os = "illumos")] {
+        #[path = "solaris_illumos.rs"] mod imp;
+    } else if #[cfg(target_os = "ios")] {
+        #[path = "ios.rs"] mod imp;
+    } else if #[cfg(target_os = "linux")] {
+        #[path = "linux_android.rs"] mod imp;
+    } else if #[cfg(target_os = "macos")] {
+        #[path = "macos.rs"] mod imp;
+    } else if #[cfg(target_os = "netbsd")] {
+        #[path = "use_file.rs"] mod imp;
+    } else if #[cfg(target_os = "openbsd")] {
+        #[path = "openbsd.rs"] mod imp;
+    } else if #[cfg(target_os = "redox")] {
+        #[path = "use_file.rs"] mod imp;
+    } else if #[cfg(target_os = "solaris")] {
+        #[path = "solaris_illumos.rs"] mod imp;
+    } else if #[cfg(target_os = "wasi")] {
+        #[path = "wasi.rs"] mod imp;
+    } else if #[cfg(windows)] {
+        #[path = "windows.rs"] mod imp;
+    } else if #[cfg(all(target_arch = "x86_64", any(
+                  target_os = "hermit",
+                  target_os = "l4re",
+                  target_os = "uefi",
+                  target_env = "sgx",
+              )))] {
+        #[path = "rdrand.rs"] mod imp;
+    } else if #[cfg(target_arch = "wasm32")] {
+        cfg_if! {
+            if #[cfg(feature = "wasm-bindgen")] {
+                #[path = "wasm32_bindgen.rs"] mod imp;
+            } else if #[cfg(feature = "stdweb")] {
+                #[path = "wasm32_stdweb.rs"] mod imp;
+            } else {
+                #[path = "dummy.rs"] mod imp;
+            }
+        }
+    } else {
+        #[path = "dummy.rs"] mod imp;
+    }
+}
+
+/// Fill `dest` with random bytes from the system's preferred random number
+/// source.
+///
+/// This function returns an error on any failure, including partial reads. We
+/// make no guarantees regarding the contents of `dest` on error.
+///
+/// Blocking is possible, at least during early boot; see module documentation.
+///
+/// In general, `getrandom` will be fast enough for interactive usage, though
+/// significantly slower than a user-space CSPRNG; for the latter consider
+/// [`rand::thread_rng`](https://docs.rs/rand/*/rand/fn.thread_rng.html).
+pub fn getrandom(dest: &mut [u8]) -> Result<(), error::Error> {
+    imp::getrandom_inner(dest)
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/getrandom/util.rs.html b/target/doc/src/getrandom/util.rs.html new file mode 100644 index 0000000..35e425d --- /dev/null +++ b/target/doc/src/getrandom/util.rs.html @@ -0,0 +1,195 @@ +util.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+
+// Copyright 2019 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use core::sync::atomic::{AtomicUsize, Ordering::Relaxed};
+
+// This structure represents a laziliy initialized static usize value. Useful
+// when it is perferable to just rerun initialization instead of locking.
+// Both unsync_init and sync_init will invoke an init() function until it
+// succeeds, then return the cached value for future calls.
+//
+// Both methods support init() "failing". If the init() method returns UNINIT,
+// that value will be returned as normal, but will not be cached.
+//
+// Users should only depend on the _value_ returned by init() functions.
+// Specifically, for the following init() function:
+//      fn init() -> usize {
+//          a();
+//          let v = b();
+//          c();
+//          v
+//      }
+// the effects of c() or writes to shared memory will not necessarily be
+// observed and additional syncronization methods with be needed.
+pub struct LazyUsize(AtomicUsize);
+
+impl LazyUsize {
+    pub const fn new() -> Self {
+        Self(AtomicUsize::new(Self::UNINIT))
+    }
+
+    // The initialization is not completed.
+    pub const UNINIT: usize = usize::max_value();
+    // The initialization is currently running.
+    pub const ACTIVE: usize = usize::max_value() - 1;
+
+    // Runs the init() function at least once, returning the value of some run
+    // of init(). Multiple callers can run their init() functions in parallel.
+    // init() should always return the same value, if it succeeds.
+    pub fn unsync_init(&self, init: impl FnOnce() -> usize) -> usize {
+        // Relaxed ordering is fine, as we only have a single atomic variable.
+        let mut val = self.0.load(Relaxed);
+        if val == Self::UNINIT {
+            val = init();
+            self.0.store(val, Relaxed);
+        }
+        val
+    }
+
+    // Synchronously runs the init() function. Only one caller will have their
+    // init() function running at a time, and exactly one successful call will
+    // be run. init() returning UNINIT or ACTIVE will be considered a failure,
+    // and future calls to sync_init will rerun their init() function.
+    pub fn sync_init(&self, init: impl FnOnce() -> usize, mut wait: impl FnMut()) -> usize {
+        // Common and fast path with no contention. Don't wast time on CAS.
+        match self.0.load(Relaxed) {
+            Self::UNINIT | Self::ACTIVE => {}
+            val => return val,
+        }
+        // Relaxed ordering is fine, as we only have a single atomic variable.
+        loop {
+            match self.0.compare_and_swap(Self::UNINIT, Self::ACTIVE, Relaxed) {
+                Self::UNINIT => {
+                    let val = init();
+                    self.0.store(
+                        match val {
+                            Self::UNINIT | Self::ACTIVE => Self::UNINIT,
+                            val => val,
+                        },
+                        Relaxed,
+                    );
+                    return val;
+                }
+                Self::ACTIVE => wait(),
+                val => return val,
+            }
+        }
+    }
+}
+
+// Identical to LazyUsize except with bool instead of usize.
+pub struct LazyBool(LazyUsize);
+
+impl LazyBool {
+    pub const fn new() -> Self {
+        Self(LazyUsize::new())
+    }
+
+    pub fn unsync_init(&self, init: impl FnOnce() -> bool) -> bool {
+        self.0.unsync_init(|| init() as usize) != 0
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/getrandom/windows.rs.html b/target/doc/src/getrandom/windows.rs.html new file mode 100644 index 0000000..7c5f107 --- /dev/null +++ b/target/doc/src/getrandom/windows.rs.html @@ -0,0 +1,55 @@ +windows.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Implementation for Windows
+use crate::{error::RTL_GEN_RANDOM_FAILED, Error};
+
+extern "system" {
+    #[link_name = "SystemFunction036"]
+    fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: u32) -> u8;
+}
+
+pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
+    // Prevent overflow of u32
+    for chunk in dest.chunks_mut(u32::max_value() as usize) {
+        let ret = unsafe { RtlGenRandom(chunk.as_mut_ptr(), chunk.len() as u32) };
+        if ret == 0 {
+            return Err(RTL_GEN_RANDOM_FAILED);
+        }
+    }
+    Ok(())
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/lazy_static/inline_lazy.rs.html b/target/doc/src/lazy_static/inline_lazy.rs.html new file mode 100644 index 0000000..55d13b9 --- /dev/null +++ b/target/doc/src/lazy_static/inline_lazy.rs.html @@ -0,0 +1,133 @@ +inline_lazy.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+
+// Copyright 2016 lazy-static.rs Developers
+//
+// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
+// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
+// http://opensource.org/licenses/MIT>, at your option. This file may not be
+// copied, modified, or distributed except according to those terms.
+
+extern crate core;
+extern crate std;
+
+use self::std::prelude::v1::*;
+use self::std::cell::Cell;
+use self::std::sync::Once;
+pub use self::std::sync::ONCE_INIT;
+
+// FIXME: Replace Option<T> with MaybeInitialized<T>
+pub struct Lazy<T: Sync>(Cell<Option<T>>, Once);
+
+impl<T: Sync> Lazy<T> {
+    pub const INIT: Self = Lazy(Cell::new(None), ONCE_INIT);
+
+    #[inline(always)]
+    pub fn get<F>(&'static self, f: F) -> &T
+    where
+        F: FnOnce() -> T,
+    {
+        self.1.call_once(|| {
+            self.0.set(Some(f()));
+        });
+
+        // `self.0` is guaranteed to be `Some` by this point
+        // The `Once` will catch and propegate panics
+        unsafe {
+            match *self.0.as_ptr() {
+                Some(ref x) => x,
+                None => {
+                    debug_assert!(false, "attempted to derefence an uninitialized lazy static. This is a bug");
+
+                    unreachable_unchecked()
+                },
+            }
+        }
+    }
+}
+
+unsafe impl<T: Sync> Sync for Lazy<T> {}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! __lazy_static_create {
+    ($NAME:ident, $T:ty) => {
+        static $NAME: $crate::lazy::Lazy<$T> = $crate::lazy::Lazy::INIT;
+    };
+}
+
+/// Polyfill for std::hint::unreachable_unchecked. There currently exists a
+/// [crate](https://docs.rs/unreachable) for an equivalent to std::hint::unreachable_unchecked, but
+/// lazy_static currently doesn't include any runtime dependencies and we've chosen to include this
+/// short polyfill rather than include a new crate in every consumer's build.
+///
+/// This should be replaced by std's version when lazy_static starts to require at least Rust 1.27.
+unsafe fn unreachable_unchecked() -> ! {
+    enum Void {}
+    match std::mem::uninitialized::<Void>() {}
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/lazy_static/lib.rs.html b/target/doc/src/lazy_static/lib.rs.html new file mode 100644 index 0000000..efe067f --- /dev/null +++ b/target/doc/src/lazy_static/lib.rs.html @@ -0,0 +1,425 @@ +lib.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+
+// Copyright 2016 lazy-static.rs Developers
+//
+// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
+// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
+// http://opensource.org/licenses/MIT>, at your option. This file may not be
+// copied, modified, or distributed except according to those terms.
+
+/*!
+A macro for declaring lazily evaluated statics.
+
+Using this macro, it is possible to have `static`s that require code to be
+executed at runtime in order to be initialized.
+This includes anything requiring heap allocations, like vectors or hash maps,
+as well as anything that requires function calls to be computed.
+
+# Syntax
+
+```ignore
+lazy_static! {
+    [pub] static ref NAME_1: TYPE_1 = EXPR_1;
+    [pub] static ref NAME_2: TYPE_2 = EXPR_2;
+    ...
+    [pub] static ref NAME_N: TYPE_N = EXPR_N;
+}
+```
+
+Attributes (including doc comments) are supported as well:
+
+```rust
+# #[macro_use]
+# extern crate lazy_static;
+# fn main() {
+lazy_static! {
+    /// This is an example for using doc comment attributes
+    static ref EXAMPLE: u8 = 42;
+}
+# }
+```
+
+# Semantics
+
+For a given `static ref NAME: TYPE = EXPR;`, the macro generates a unique type that
+implements `Deref<TYPE>` and stores it in a static with name `NAME`. (Attributes end up
+attaching to this type.)
+
+On first deref, `EXPR` gets evaluated and stored internally, such that all further derefs
+can return a reference to the same object. Note that this can lead to deadlocks
+if you have multiple lazy statics that depend on each other in their initialization.
+
+Apart from the lazy initialization, the resulting "static ref" variables
+have generally the same properties as regular "static" variables:
+
+- Any type in them needs to fulfill the `Sync` trait.
+- If the type has a destructor, then it will not run when the process exits.
+
+# Example
+
+Using the macro:
+
+```rust
+#[macro_use]
+extern crate lazy_static;
+
+use std::collections::HashMap;
+
+lazy_static! {
+    static ref HASHMAP: HashMap<u32, &'static str> = {
+        let mut m = HashMap::new();
+        m.insert(0, "foo");
+        m.insert(1, "bar");
+        m.insert(2, "baz");
+        m
+    };
+    static ref COUNT: usize = HASHMAP.len();
+    static ref NUMBER: u32 = times_two(21);
+}
+
+fn times_two(n: u32) -> u32 { n * 2 }
+
+fn main() {
+    println!("The map has {} entries.", *COUNT);
+    println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());
+    println!("A expensive calculation on a static results in: {}.", *NUMBER);
+}
+```
+
+# Implementation details
+
+The `Deref` implementation uses a hidden static variable that is guarded by an atomic check on each access.
+
+# Cargo features
+
+This crate provides two cargo features:
+
+- `spin_no_std`: This allows using this crate in a no-std environment, by depending on the standalone `spin` crate.
+
+Both features depend on unstable language features, which means
+no guarantees can be made about them in regard to SemVer stability.
+
+*/
+
+#![doc(html_root_url = "https://docs.rs/lazy_static/1.3.0")]
+#![no_std]
+
+#[cfg(not(feature = "spin_no_std"))]
+#[path="inline_lazy.rs"]
+#[doc(hidden)]
+pub mod lazy;
+
+#[cfg(feature = "spin_no_std")]
+#[path="core_lazy.rs"]
+#[doc(hidden)]
+pub mod lazy;
+
+#[doc(hidden)]
+pub use core::ops::Deref as __Deref;
+
+#[macro_export(local_inner_macros)]
+#[doc(hidden)]
+macro_rules! __lazy_static_internal {
+    // optional visibility restrictions are wrapped in `()` to allow for
+    // explicitly passing otherwise implicit information about private items
+    ($(#[$attr:meta])* ($($vis:tt)*) static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
+        __lazy_static_internal!(@MAKE TY, $(#[$attr])*, ($($vis)*), $N);
+        __lazy_static_internal!(@TAIL, $N : $T = $e);
+        lazy_static!($($t)*);
+    };
+    (@TAIL, $N:ident : $T:ty = $e:expr) => {
+        impl $crate::__Deref for $N {
+            type Target = $T;
+            fn deref(&self) -> &$T {
+                #[inline(always)]
+                fn __static_ref_initialize() -> $T { $e }
+
+                #[inline(always)]
+                fn __stability() -> &'static $T {
+                    __lazy_static_create!(LAZY, $T);
+                    LAZY.get(__static_ref_initialize)
+                }
+                __stability()
+            }
+        }
+        impl $crate::LazyStatic for $N {
+            fn initialize(lazy: &Self) {
+                let _ = &**lazy;
+            }
+        }
+    };
+    // `vis` is wrapped in `()` to prevent parsing ambiguity
+    (@MAKE TY, $(#[$attr:meta])*, ($($vis:tt)*), $N:ident) => {
+        #[allow(missing_copy_implementations)]
+        #[allow(non_camel_case_types)]
+        #[allow(dead_code)]
+        $(#[$attr])*
+        $($vis)* struct $N {__private_field: ()}
+        #[doc(hidden)]
+        $($vis)* static $N: $N = $N {__private_field: ()};
+    };
+    () => ()
+}
+
+#[macro_export(local_inner_macros)]
+macro_rules! lazy_static {
+    ($(#[$attr:meta])* static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
+        // use `()` to explicitly forward the information about private items
+        __lazy_static_internal!($(#[$attr])* () static ref $N : $T = $e; $($t)*);
+    };
+    ($(#[$attr:meta])* pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
+        __lazy_static_internal!($(#[$attr])* (pub) static ref $N : $T = $e; $($t)*);
+    };
+    ($(#[$attr:meta])* pub ($($vis:tt)+) static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
+        __lazy_static_internal!($(#[$attr])* (pub ($($vis)+)) static ref $N : $T = $e; $($t)*);
+    };
+    () => ()
+}
+
+/// Support trait for enabling a few common operation on lazy static values.
+///
+/// This is implemented by each defined lazy static, and
+/// used by the free functions in this crate.
+pub trait LazyStatic {
+    #[doc(hidden)]
+    fn initialize(lazy: &Self);
+}
+
+/// Takes a shared reference to a lazy static and initializes
+/// it if it has not been already.
+///
+/// This can be used to control the initialization point of a lazy static.
+///
+/// Example:
+///
+/// ```rust
+/// #[macro_use]
+/// extern crate lazy_static;
+///
+/// lazy_static! {
+///     static ref BUFFER: Vec<u8> = (0..255).collect();
+/// }
+///
+/// fn main() {
+///     lazy_static::initialize(&BUFFER);
+///
+///     // ...
+///     work_with_initialized_data(&BUFFER);
+/// }
+/// # fn work_with_initialized_data(_: &[u8]) {}
+/// ```
+pub fn initialize<T: LazyStatic>(lazy: &T) {
+    LazyStatic::initialize(lazy);
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/memchr/fallback.rs.html b/target/doc/src/memchr/fallback.rs.html new file mode 100644 index 0000000..58a3d35 --- /dev/null +++ b/target/doc/src/memchr/fallback.rs.html @@ -0,0 +1,695 @@ +fallback.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+
+// This module defines pure Rust platform independent implementations of all
+// the memchr routines. We do our best to make them fast. Some of them may even
+// get auto-vectorized.
+
+use core::cmp;
+use core::ptr;
+use core::usize;
+
+#[cfg(target_pointer_width = "32")]
+const USIZE_BYTES: usize = 4;
+
+#[cfg(target_pointer_width = "64")]
+const USIZE_BYTES: usize = 8;
+
+// The number of bytes to loop at in one iteration of memchr/memrchr.
+const LOOP_SIZE: usize = 2 * USIZE_BYTES;
+
+/// Return `true` if `x` contains any zero byte.
+///
+/// From *Matters Computational*, J. Arndt
+///
+/// "The idea is to subtract one from each of the bytes and then look for
+/// bytes where the borrow propagated all the way to the most significant
+/// bit."
+#[inline(always)]
+fn contains_zero_byte(x: usize) -> bool {
+    const LO_U64: u64 = 0x0101010101010101;
+    const HI_U64: u64 = 0x8080808080808080;
+
+    const LO_USIZE: usize = LO_U64 as usize;
+    const HI_USIZE: usize = HI_U64 as usize;
+
+    x.wrapping_sub(LO_USIZE) & !x & HI_USIZE != 0
+}
+
+/// Repeat the given byte into a word size number. That is, every 8 bits
+/// is equivalent to the given byte. For example, if `b` is `\x4E` or
+/// `01001110` in binary, then the returned value on a 32-bit system would be:
+/// `01001110_01001110_01001110_01001110`.
+#[inline(always)]
+fn repeat_byte(b: u8) -> usize {
+    (b as usize) * (usize::MAX / 255)
+}
+
+pub fn memchr(n1: u8, haystack: &[u8]) -> Option<usize> {
+    let vn1 = repeat_byte(n1);
+    let confirm = |byte| byte == n1;
+    let loop_size = cmp::min(LOOP_SIZE, haystack.len());
+    let align = USIZE_BYTES - 1;
+    let start_ptr = haystack.as_ptr();
+    let end_ptr = haystack[haystack.len()..].as_ptr();
+    let mut ptr = start_ptr;
+
+    unsafe {
+        if haystack.len() < USIZE_BYTES {
+            return forward_search(start_ptr, end_ptr, ptr, confirm);
+        }
+
+        let chunk = read_unaligned_usize(ptr);
+        if contains_zero_byte(chunk ^ vn1) {
+            return forward_search(start_ptr, end_ptr, ptr, confirm);
+        }
+
+        ptr = ptr_add(ptr, USIZE_BYTES - (start_ptr as usize & align));
+        debug_assert!(ptr > start_ptr);
+        debug_assert!(ptr_sub(end_ptr, USIZE_BYTES) >= start_ptr);
+        while loop_size == LOOP_SIZE && ptr <= ptr_sub(end_ptr, loop_size) {
+            debug_assert_eq!(0, (ptr as usize) % USIZE_BYTES);
+
+            let a = *(ptr as *const usize);
+            let b = *(ptr_add(ptr, USIZE_BYTES) as *const usize);
+            let eqa = contains_zero_byte(a ^ vn1);
+            let eqb = contains_zero_byte(b ^ vn1);
+            if eqa || eqb {
+                break;
+            }
+            ptr = ptr_add(ptr, LOOP_SIZE);
+        }
+        forward_search(start_ptr, end_ptr, ptr, confirm)
+    }
+}
+
+/// Like `memchr`, but searches for two bytes instead of one.
+pub fn memchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
+    let vn1 = repeat_byte(n1);
+    let vn2 = repeat_byte(n2);
+    let confirm = |byte| byte == n1 || byte == n2;
+    let align = USIZE_BYTES - 1;
+    let start_ptr = haystack.as_ptr();
+    let end_ptr = haystack[haystack.len()..].as_ptr();
+    let mut ptr = start_ptr;
+
+    unsafe {
+        if haystack.len() < USIZE_BYTES {
+            return forward_search(start_ptr, end_ptr, ptr, confirm);
+        }
+
+        let chunk = read_unaligned_usize(ptr);
+        let eq1 = contains_zero_byte(chunk ^ vn1);
+        let eq2 = contains_zero_byte(chunk ^ vn2);
+        if eq1 || eq2 {
+            return forward_search(start_ptr, end_ptr, ptr, confirm);
+        }
+
+        ptr = ptr_add(ptr, USIZE_BYTES - (start_ptr as usize & align));
+        debug_assert!(ptr > start_ptr);
+        debug_assert!(ptr_sub(end_ptr, USIZE_BYTES) >= start_ptr);
+        while ptr <= ptr_sub(end_ptr, USIZE_BYTES) {
+            debug_assert_eq!(0, (ptr as usize) % USIZE_BYTES);
+
+            let chunk = *(ptr as *const usize);
+            let eq1 = contains_zero_byte(chunk ^ vn1);
+            let eq2 = contains_zero_byte(chunk ^ vn2);
+            if eq1 || eq2 {
+                break;
+            }
+            ptr = ptr_add(ptr, USIZE_BYTES);
+        }
+        forward_search(start_ptr, end_ptr, ptr, confirm)
+    }
+}
+
+/// Like `memchr`, but searches for three bytes instead of one.
+pub fn memchr3(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
+    let vn1 = repeat_byte(n1);
+    let vn2 = repeat_byte(n2);
+    let vn3 = repeat_byte(n3);
+    let confirm = |byte| byte == n1 || byte == n2 || byte == n3;
+    let align = USIZE_BYTES - 1;
+    let start_ptr = haystack.as_ptr();
+    let end_ptr = haystack[haystack.len()..].as_ptr();
+    let mut ptr = start_ptr;
+
+    unsafe {
+        if haystack.len() < USIZE_BYTES {
+            return forward_search(start_ptr, end_ptr, ptr, confirm);
+        }
+
+        let chunk = read_unaligned_usize(ptr);
+        let eq1 = contains_zero_byte(chunk ^ vn1);
+        let eq2 = contains_zero_byte(chunk ^ vn2);
+        let eq3 = contains_zero_byte(chunk ^ vn3);
+        if eq1 || eq2 || eq3 {
+            return forward_search(start_ptr, end_ptr, ptr, confirm);
+        }
+
+        ptr = ptr_add(ptr, USIZE_BYTES - (start_ptr as usize & align));
+        debug_assert!(ptr > start_ptr);
+        debug_assert!(ptr_sub(end_ptr, USIZE_BYTES) >= start_ptr);
+        while ptr <= ptr_sub(end_ptr, USIZE_BYTES) {
+            debug_assert_eq!(0, (ptr as usize) % USIZE_BYTES);
+
+            let chunk = *(ptr as *const usize);
+            let eq1 = contains_zero_byte(chunk ^ vn1);
+            let eq2 = contains_zero_byte(chunk ^ vn2);
+            let eq3 = contains_zero_byte(chunk ^ vn3);
+            if eq1 || eq2 || eq3 {
+                break;
+            }
+            ptr = ptr_add(ptr, USIZE_BYTES);
+        }
+        forward_search(start_ptr, end_ptr, ptr, confirm)
+    }
+}
+
+/// Return the last index matching the byte `x` in `text`.
+pub fn memrchr(n1: u8, haystack: &[u8]) -> Option<usize> {
+    let vn1 = repeat_byte(n1);
+    let confirm = |byte| byte == n1;
+    let loop_size = cmp::min(LOOP_SIZE, haystack.len());
+    let align = USIZE_BYTES - 1;
+    let start_ptr = haystack.as_ptr();
+    let end_ptr = haystack[haystack.len()..].as_ptr();
+    let mut ptr = end_ptr;
+
+    unsafe {
+        if haystack.len() < USIZE_BYTES {
+            return reverse_search(start_ptr, end_ptr, ptr, confirm);
+        }
+
+        let chunk = read_unaligned_usize(ptr_sub(ptr, USIZE_BYTES));
+        if contains_zero_byte(chunk ^ vn1) {
+            return reverse_search(start_ptr, end_ptr, ptr, confirm);
+        }
+
+        ptr = (end_ptr as usize & !align) as *const u8;
+        debug_assert!(start_ptr <= ptr && ptr <= end_ptr);
+        while loop_size == LOOP_SIZE && ptr >= ptr_add(start_ptr, loop_size) {
+            debug_assert_eq!(0, (ptr as usize) % USIZE_BYTES);
+
+            let a = *(ptr_sub(ptr, 2 * USIZE_BYTES) as *const usize);
+            let b = *(ptr_sub(ptr, 1 * USIZE_BYTES) as *const usize);
+            let eqa = contains_zero_byte(a ^ vn1);
+            let eqb = contains_zero_byte(b ^ vn1);
+            if eqa || eqb {
+                break;
+            }
+            ptr = ptr_sub(ptr, loop_size);
+        }
+        reverse_search(start_ptr, end_ptr, ptr, confirm)
+    }
+}
+
+/// Like `memrchr`, but searches for two bytes instead of one.
+pub fn memrchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
+    let vn1 = repeat_byte(n1);
+    let vn2 = repeat_byte(n2);
+    let confirm = |byte| byte == n1 || byte == n2;
+    let align = USIZE_BYTES - 1;
+    let start_ptr = haystack.as_ptr();
+    let end_ptr = haystack[haystack.len()..].as_ptr();
+    let mut ptr = end_ptr;
+
+    unsafe {
+        if haystack.len() < USIZE_BYTES {
+            return reverse_search(start_ptr, end_ptr, ptr, confirm);
+        }
+
+        let chunk = read_unaligned_usize(ptr_sub(ptr, USIZE_BYTES));
+        let eq1 = contains_zero_byte(chunk ^ vn1);
+        let eq2 = contains_zero_byte(chunk ^ vn2);
+        if eq1 || eq2 {
+            return reverse_search(start_ptr, end_ptr, ptr, confirm);
+        }
+
+        ptr = (end_ptr as usize & !align) as *const u8;
+        debug_assert!(start_ptr <= ptr && ptr <= end_ptr);
+        while ptr >= ptr_add(start_ptr, USIZE_BYTES) {
+            debug_assert_eq!(0, (ptr as usize) % USIZE_BYTES);
+
+            let chunk = *(ptr_sub(ptr, USIZE_BYTES) as *const usize);
+            let eq1 = contains_zero_byte(chunk ^ vn1);
+            let eq2 = contains_zero_byte(chunk ^ vn2);
+            if eq1 || eq2 {
+                break;
+            }
+            ptr = ptr_sub(ptr, USIZE_BYTES);
+        }
+        reverse_search(start_ptr, end_ptr, ptr, confirm)
+    }
+}
+
+/// Like `memrchr`, but searches for three bytes instead of one.
+pub fn memrchr3(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
+    let vn1 = repeat_byte(n1);
+    let vn2 = repeat_byte(n2);
+    let vn3 = repeat_byte(n3);
+    let confirm = |byte| byte == n1 || byte == n2 || byte == n3;
+    let align = USIZE_BYTES - 1;
+    let start_ptr = haystack.as_ptr();
+    let end_ptr = haystack[haystack.len()..].as_ptr();
+    let mut ptr = end_ptr;
+
+    unsafe {
+        if haystack.len() < USIZE_BYTES {
+            return reverse_search(start_ptr, end_ptr, ptr, confirm);
+        }
+
+        let chunk = read_unaligned_usize(ptr_sub(ptr, USIZE_BYTES));
+        let eq1 = contains_zero_byte(chunk ^ vn1);
+        let eq2 = contains_zero_byte(chunk ^ vn2);
+        let eq3 = contains_zero_byte(chunk ^ vn3);
+        if eq1 || eq2 || eq3 {
+            return reverse_search(start_ptr, end_ptr, ptr, confirm);
+        }
+
+        ptr = (end_ptr as usize & !align) as *const u8;
+        debug_assert!(start_ptr <= ptr && ptr <= end_ptr);
+        while ptr >= ptr_add(start_ptr, USIZE_BYTES) {
+            debug_assert_eq!(0, (ptr as usize) % USIZE_BYTES);
+
+            let chunk = *(ptr_sub(ptr, USIZE_BYTES) as *const usize);
+            let eq1 = contains_zero_byte(chunk ^ vn1);
+            let eq2 = contains_zero_byte(chunk ^ vn2);
+            let eq3 = contains_zero_byte(chunk ^ vn3);
+            if eq1 || eq2 || eq3 {
+                break;
+            }
+            ptr = ptr_sub(ptr, USIZE_BYTES);
+        }
+        reverse_search(start_ptr, end_ptr, ptr, confirm)
+    }
+}
+
+#[inline(always)]
+unsafe fn forward_search<F: Fn(u8) -> bool>(
+    start_ptr: *const u8,
+    end_ptr: *const u8,
+    mut ptr: *const u8,
+    confirm: F,
+) -> Option<usize> {
+    debug_assert!(start_ptr <= ptr);
+    debug_assert!(ptr <= end_ptr);
+
+    while ptr < end_ptr {
+        if confirm(*ptr) {
+            return Some(sub(ptr, start_ptr));
+        }
+        ptr = ptr.offset(1);
+    }
+    None
+}
+
+#[inline(always)]
+unsafe fn reverse_search<F: Fn(u8) -> bool>(
+    start_ptr: *const u8,
+    end_ptr: *const u8,
+    mut ptr: *const u8,
+    confirm: F,
+) -> Option<usize> {
+    debug_assert!(start_ptr <= ptr);
+    debug_assert!(ptr <= end_ptr);
+
+    while ptr > start_ptr {
+        ptr = ptr.offset(-1);
+        if confirm(*ptr) {
+            return Some(sub(ptr, start_ptr));
+        }
+    }
+    None
+}
+
+/// Increment the given pointer by the given amount.
+unsafe fn ptr_add(ptr: *const u8, amt: usize) -> *const u8 {
+    debug_assert!(amt < ::core::isize::MAX as usize);
+    ptr.offset(amt as isize)
+}
+
+/// Decrement the given pointer by the given amount.
+unsafe fn ptr_sub(ptr: *const u8, amt: usize) -> *const u8 {
+    debug_assert!(amt < ::core::isize::MAX as usize);
+    ptr.offset((amt as isize).wrapping_neg())
+}
+
+unsafe fn read_unaligned_usize(ptr: *const u8) -> usize {
+    let mut n: usize = 0;
+    ptr::copy_nonoverlapping(ptr, &mut n as *mut _ as *mut u8, USIZE_BYTES);
+    n
+}
+
+/// Subtract `b` from `a` and return the difference. `a` should be greater than
+/// or equal to `b`.
+fn sub(a: *const u8, b: *const u8) -> usize {
+    debug_assert!(a >= b);
+    (a as usize) - (b as usize)
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/memchr/iter.rs.html b/target/doc/src/memchr/iter.rs.html new file mode 100644 index 0000000..7cf7d41 --- /dev/null +++ b/target/doc/src/memchr/iter.rs.html @@ -0,0 +1,357 @@ +iter.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+
+use {memchr, memchr2, memchr3, memrchr, memrchr2, memrchr3};
+
+macro_rules! iter_next {
+    // Common code for the memchr iterators:
+    // update haystack and position and produce the index
+    //
+    // self: &mut Self where Self is the iterator
+    // search_result: Option<usize> which is the result of the corresponding
+    // memchr function.
+    //
+    // Returns Option<usize> (the next iterator element)
+    ($self_:expr, $search_result:expr) => {
+        $search_result.map(move |index| {
+            // split and take the remaining back half
+            $self_.haystack = $self_.haystack.split_at(index + 1).1;
+            let found_position = $self_.position + index;
+            $self_.position = found_position + 1;
+            found_position
+        })
+    }
+}
+
+macro_rules! iter_next_back {
+    ($self_:expr, $search_result:expr) => {
+        $search_result.map(move |index| {
+            // split and take the remaining front half
+            $self_.haystack = $self_.haystack.split_at(index).0;
+            $self_.position + index
+        })
+    }
+}
+
+/// An iterator for `memchr`.
+pub struct Memchr<'a> {
+    needle: u8,
+    // The haystack to iterate over
+    haystack: &'a [u8],
+    // The index
+    position: usize,
+}
+
+impl<'a> Memchr<'a> {
+    /// Creates a new iterator that yields all positions of needle in haystack.
+    #[inline]
+    pub fn new(needle: u8, haystack: &[u8]) -> Memchr {
+        Memchr {
+            needle: needle,
+            haystack: haystack,
+            position: 0,
+        }
+    }
+}
+
+impl<'a> Iterator for Memchr<'a> {
+    type Item = usize;
+
+    #[inline]
+    fn next(&mut self) -> Option<usize> {
+        iter_next!(self, memchr(self.needle, self.haystack))
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (0, Some(self.haystack.len()))
+    }
+}
+
+impl<'a> DoubleEndedIterator for Memchr<'a> {
+    #[inline]
+    fn next_back(&mut self) -> Option<Self::Item> {
+        iter_next_back!(self, memrchr(self.needle, self.haystack))
+    }
+}
+
+/// An iterator for `memchr2`.
+pub struct Memchr2<'a> {
+    needle1: u8,
+    needle2: u8,
+    // The haystack to iterate over
+    haystack: &'a [u8],
+    // The index
+    position: usize,
+}
+
+impl<'a> Memchr2<'a> {
+    /// Creates a new iterator that yields all positions of needle in haystack.
+    #[inline]
+    pub fn new(needle1: u8, needle2: u8, haystack: &[u8]) -> Memchr2 {
+        Memchr2 {
+            needle1: needle1,
+            needle2: needle2,
+            haystack: haystack,
+            position: 0,
+        }
+    }
+}
+
+impl<'a> Iterator for Memchr2<'a> {
+    type Item = usize;
+
+    #[inline]
+    fn next(&mut self) -> Option<usize> {
+        iter_next!(self, memchr2(self.needle1, self.needle2, self.haystack))
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (0, Some(self.haystack.len()))
+    }
+}
+
+impl<'a> DoubleEndedIterator for Memchr2<'a> {
+    #[inline]
+    fn next_back(&mut self) -> Option<Self::Item> {
+        iter_next_back!(
+            self,
+            memrchr2(self.needle1, self.needle2, self.haystack)
+        )
+    }
+}
+
+/// An iterator for `memchr3`.
+pub struct Memchr3<'a> {
+    needle1: u8,
+    needle2: u8,
+    needle3: u8,
+    // The haystack to iterate over
+    haystack: &'a [u8],
+    // The index
+    position: usize,
+}
+
+impl<'a> Memchr3<'a> {
+    /// Create a new `Memchr3` that's initialized to zero with a haystack
+    #[inline]
+    pub fn new(
+        needle1: u8,
+        needle2: u8,
+        needle3: u8,
+        haystack: &[u8],
+    ) -> Memchr3 {
+        Memchr3 {
+            needle1: needle1,
+            needle2: needle2,
+            needle3: needle3,
+            haystack: haystack,
+            position: 0,
+        }
+    }
+}
+
+impl<'a> Iterator for Memchr3<'a> {
+    type Item = usize;
+
+    #[inline]
+    fn next(&mut self) -> Option<usize> {
+        iter_next!(
+            self,
+            memchr3(self.needle1, self.needle2, self.needle3, self.haystack)
+        )
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (0, Some(self.haystack.len()))
+    }
+}
+
+impl<'a> DoubleEndedIterator for Memchr3<'a> {
+    #[inline]
+    fn next_back(&mut self) -> Option<Self::Item> {
+        iter_next_back!(
+            self,
+            memrchr3(self.needle1, self.needle2, self.needle3, self.haystack)
+        )
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/memchr/lib.rs.html b/target/doc/src/memchr/lib.rs.html new file mode 100644 index 0000000..8d236c0 --- /dev/null +++ b/target/doc/src/memchr/lib.rs.html @@ -0,0 +1,627 @@ +lib.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+
+/*!
+The `memchr` crate provides heavily optimized routines for searching bytes.
+
+The `memchr` function is traditionally provided by libc, however, the
+performance of `memchr` can vary significantly depending on the specific
+implementation of libc that is used. They can range from manually tuned
+Assembly implementations (like that found in GNU's libc) all the way to
+non-vectorized C implementations (like that found in MUSL).
+
+To smooth out the differences between implementations of libc, at least
+on `x86_64` for Rust 1.27+, this crate provides its own implementation of
+`memchr` that should perform competitively with the one found in GNU's libc.
+The implementation is in pure Rust and has no dependency on a C compiler or an
+Assembler.
+
+Additionally, GNU libc also provides an extension, `memrchr`. This crate
+provides its own implementation of `memrchr` as well, on top of `memchr2`,
+`memchr3`, `memrchr2` and `memrchr3`. The difference between `memchr` and
+`memchr2` is that that `memchr2` permits finding all occurrences of two bytes
+instead of one. Similarly for `memchr3`.
+*/
+
+#![cfg_attr(not(feature = "use_std"), no_std)]
+
+#![deny(missing_docs)]
+#![doc(html_root_url = "https://docs.rs/memchr/2.0.0")]
+
+// Supporting 16-bit would be fine. If you need it, please submit a bug report
+// at https://github.com/BurntSushi/rust-memchr
+#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
+compile_error!("memchr currently not supported on non-32 or non-64 bit");
+
+#[cfg(feature = "use_std")]
+extern crate core;
+
+#[cfg(test)]
+#[macro_use]
+extern crate quickcheck;
+
+use core::iter::Rev;
+
+pub use iter::{Memchr, Memchr2, Memchr3};
+
+// N.B. If you're looking for the cfg knobs for libc, see build.rs.
+#[cfg(memchr_libc)]
+mod c;
+#[allow(dead_code)]
+mod fallback;
+mod iter;
+mod naive;
+#[cfg(all(target_arch = "x86_64", memchr_runtime_simd))]
+mod x86;
+#[cfg(test)]
+mod tests;
+
+/// An iterator over all occurrences of the needle in a haystack.
+#[inline]
+pub fn memchr_iter(needle: u8, haystack: &[u8]) -> Memchr {
+    Memchr::new(needle, haystack)
+}
+
+/// An iterator over all occurrences of the needles in a haystack.
+#[inline]
+pub fn memchr2_iter(
+    needle1: u8,
+    needle2: u8,
+    haystack: &[u8],
+) -> Memchr2 {
+    Memchr2::new(needle1, needle2, haystack)
+}
+
+/// An iterator over all occurrences of the needles in a haystack.
+#[inline]
+pub fn memchr3_iter(
+    needle1: u8,
+    needle2: u8,
+    needle3: u8,
+    haystack: &[u8],
+) -> Memchr3 {
+    Memchr3::new(needle1, needle2, needle3, haystack)
+}
+
+/// An iterator over all occurrences of the needle in a haystack, in reverse.
+#[inline]
+pub fn memrchr_iter(needle: u8, haystack: &[u8]) -> Rev<Memchr> {
+    Memchr::new(needle, haystack).rev()
+}
+
+/// An iterator over all occurrences of the needles in a haystack, in reverse.
+#[inline]
+pub fn memrchr2_iter(
+    needle1: u8,
+    needle2: u8,
+    haystack: &[u8],
+) -> Rev<Memchr2> {
+    Memchr2::new(needle1, needle2, haystack).rev()
+}
+
+/// An iterator over all occurrences of the needles in a haystack, in reverse.
+#[inline]
+pub fn memrchr3_iter(
+    needle1: u8,
+    needle2: u8,
+    needle3: u8,
+    haystack: &[u8],
+) -> Rev<Memchr3> {
+    Memchr3::new(needle1, needle2, needle3, haystack).rev()
+}
+
+/// Search for the first occurrence of a byte in a slice.
+///
+/// This returns the index corresponding to the first occurrence of `needle` in
+/// `haystack`, or `None` if one is not found.
+///
+/// While this is operationally the same as something like
+/// `haystack.iter().position(|&b| b == needle)`, `memchr` will use a highly
+/// optimized routine that can be up to an order of magnitude faster in some
+/// cases.
+///
+/// # Example
+///
+/// This shows how to find the first position of a byte in a byte string.
+///
+/// ```
+/// use memchr::memchr;
+///
+/// let haystack = b"the quick brown fox";
+/// assert_eq!(memchr(b'k', haystack), Some(8));
+/// ```
+#[inline]
+pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
+    #[cfg(all(target_arch = "x86_64", memchr_runtime_simd))]
+    #[inline(always)]
+    fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
+        x86::memchr(n1, haystack)
+    }
+
+    #[cfg(all(
+        memchr_libc,
+        not(all(target_arch = "x86_64", memchr_runtime_simd))
+    ))]
+    #[inline(always)]
+    fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
+        c::memchr(n1, haystack)
+    }
+
+    #[cfg(all(
+        not(memchr_libc),
+        not(all(target_arch = "x86_64", memchr_runtime_simd))
+    ))]
+    #[inline(always)]
+    fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
+        fallback::memchr(n1, haystack)
+    }
+
+    if haystack.is_empty() {
+        None
+    } else {
+        imp(needle, haystack)
+    }
+}
+
+/// Like `memchr`, but searches for two bytes instead of one.
+#[inline]
+pub fn memchr2(needle1: u8, needle2: u8, haystack: &[u8]) -> Option<usize> {
+    #[cfg(all(target_arch = "x86_64", memchr_runtime_simd))]
+    #[inline(always)]
+    fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
+        x86::memchr2(n1, n2, haystack)
+    }
+
+    #[cfg(not(all(target_arch = "x86_64", memchr_runtime_simd)))]
+    #[inline(always)]
+    fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
+        fallback::memchr2(n1, n2, haystack)
+    }
+
+    if haystack.is_empty() {
+        None
+    } else {
+        imp(needle1, needle2, haystack)
+    }
+}
+
+/// Like `memchr`, but searches for three bytes instead of one.
+#[inline]
+pub fn memchr3(
+    needle1: u8,
+    needle2: u8,
+    needle3: u8,
+    haystack: &[u8],
+) -> Option<usize> {
+    #[cfg(all(target_arch = "x86_64", memchr_runtime_simd))]
+    #[inline(always)]
+    fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
+        x86::memchr3(n1, n2, n3, haystack)
+    }
+
+    #[cfg(not(all(target_arch = "x86_64", memchr_runtime_simd)))]
+    #[inline(always)]
+    fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
+        fallback::memchr3(n1, n2, n3, haystack)
+    }
+
+    if haystack.is_empty() {
+        None
+    } else {
+        imp(needle1, needle2, needle3, haystack)
+    }
+}
+
+/// Search for the last occurrence of a byte in a slice.
+///
+/// This returns the index corresponding to the last occurrence of `needle` in
+/// `haystack`, or `None` if one is not found.
+///
+/// While this is operationally the same as something like
+/// `haystack.iter().rposition(|&b| b == needle)`, `memrchr` will use a highly
+/// optimized routine that can be up to an order of magnitude faster in some
+/// cases.
+///
+/// # Example
+///
+/// This shows how to find the last position of a byte in a byte string.
+///
+/// ```
+/// use memchr::memrchr;
+///
+/// let haystack = b"the quick brown fox";
+/// assert_eq!(memrchr(b'o', haystack), Some(17));
+/// ```
+#[inline]
+pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
+    #[cfg(all(target_arch = "x86_64", memchr_runtime_simd))]
+    #[inline(always)]
+    fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
+        x86::memrchr(n1, haystack)
+    }
+
+    #[cfg(all(
+        all(memchr_libc, target_os = "linux"),
+        not(all(target_arch = "x86_64", memchr_runtime_simd))
+    ))]
+    #[inline(always)]
+    fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
+        c::memrchr(n1, haystack)
+    }
+
+    #[cfg(all(
+        not(all(memchr_libc, target_os = "linux")),
+        not(all(target_arch = "x86_64", memchr_runtime_simd))
+    ))]
+    #[inline(always)]
+    fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
+        fallback::memrchr(n1, haystack)
+    }
+
+    if haystack.is_empty() {
+        None
+    } else {
+        imp(needle, haystack)
+    }
+}
+
+/// Like `memrchr`, but searches for two bytes instead of one.
+#[inline]
+pub fn memrchr2(needle1: u8, needle2: u8, haystack: &[u8]) -> Option<usize> {
+    #[cfg(all(target_arch = "x86_64", memchr_runtime_simd))]
+    #[inline(always)]
+    fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
+        x86::memrchr2(n1, n2, haystack)
+    }
+
+    #[cfg(not(all(target_arch = "x86_64", memchr_runtime_simd)))]
+    #[inline(always)]
+    fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
+        fallback::memrchr2(n1, n2, haystack)
+    }
+
+    if haystack.is_empty() {
+        None
+    } else {
+        imp(needle1, needle2, haystack)
+    }
+}
+
+/// Like `memrchr`, but searches for three bytes instead of one.
+#[inline]
+pub fn memrchr3(
+    needle1: u8,
+    needle2: u8,
+    needle3: u8,
+    haystack: &[u8],
+) -> Option<usize> {
+    #[cfg(all(target_arch = "x86_64", memchr_runtime_simd))]
+    #[inline(always)]
+    fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
+        x86::memrchr3(n1, n2, n3, haystack)
+    }
+
+    #[cfg(not(all(target_arch = "x86_64", memchr_runtime_simd)))]
+    #[inline(always)]
+    fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
+        fallback::memrchr3(n1, n2, n3, haystack)
+    }
+
+    if haystack.is_empty() {
+        None
+    } else {
+        imp(needle1, needle2, needle3, haystack)
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/memchr/naive.rs.html b/target/doc/src/memchr/naive.rs.html new file mode 100644 index 0000000..46d6ece --- /dev/null +++ b/target/doc/src/memchr/naive.rs.html @@ -0,0 +1,77 @@ +naive.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+
+#![allow(dead_code)]
+
+pub fn memchr(n1: u8, haystack: &[u8]) -> Option<usize> {
+    haystack
+        .iter()
+        .position(|&b| b == n1)
+}
+
+pub fn memchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
+    haystack
+        .iter()
+        .position(|&b| b == n1 || b == n2)
+}
+
+pub fn memchr3(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
+    haystack
+        .iter()
+        .position(|&b| b == n1 || b == n2 || b == n3)
+}
+
+pub fn memrchr(n1: u8, haystack: &[u8]) -> Option<usize> {
+    haystack
+        .iter()
+        .rposition(|&b| b == n1)
+}
+
+pub fn memrchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
+    haystack
+        .iter()
+        .rposition(|&b| b == n1 || b == n2)
+}
+
+pub fn memrchr3(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
+    haystack
+        .iter()
+        .rposition(|&b| b == n1 || b == n2 || b == n3)
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/memchr/x86/avx.rs.html b/target/doc/src/memchr/x86/avx.rs.html new file mode 100644 index 0000000..7ea1223 --- /dev/null +++ b/target/doc/src/memchr/x86/avx.rs.html @@ -0,0 +1,1409 @@ +avx.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+
+use core::arch::x86_64::*;
+use core::cmp;
+use core::mem::size_of;
+
+use x86::sse2;
+
+const VECTOR_SIZE: usize = size_of::<__m256i>();
+const VECTOR_ALIGN: usize = VECTOR_SIZE - 1;
+
+// The number of bytes to loop at in one iteration of memchr/memrchr.
+const LOOP_SIZE: usize = 4 * VECTOR_SIZE;
+
+// The number of bytes to loop at in one iteration of memchr2/memrchr2 and
+// memchr3/memrchr3. There was no observable difference between 128 and 64
+// bytes in benchmarks. memchr3 in particular only gets a very slight speed up
+// from the loop unrolling.
+const LOOP_SIZE2: usize = 2 * VECTOR_SIZE;
+
+#[target_feature(enable = "avx2")]
+pub unsafe fn memchr(n1: u8, haystack: &[u8]) -> Option<usize> {
+    // For a high level explanation for how this algorithm works, see the
+    // sse2 implementation. The avx implementation here is the same, but with
+    // 256-bit vectors instead of 128-bit vectors.
+
+    let start_ptr = haystack.as_ptr();
+    let end_ptr = haystack[haystack.len()..].as_ptr();
+    let mut ptr = start_ptr;
+
+    if haystack.len() < VECTOR_SIZE {
+        // For small haystacks, defer to the SSE2 implementation. Codegen
+        // suggests this completely avoids touching the AVX vectors.
+        return sse2::memchr(n1, haystack);
+    }
+
+    let vn1 = _mm256_set1_epi8(n1 as i8);
+    let loop_size = cmp::min(LOOP_SIZE, haystack.len());
+    if let Some(i) = forward_search1(start_ptr, end_ptr, ptr, vn1) {
+        return Some(i);
+    }
+
+    ptr = ptr.add(VECTOR_SIZE - (start_ptr as usize & VECTOR_ALIGN));
+    debug_assert!(ptr > start_ptr && end_ptr.sub(VECTOR_SIZE) >= start_ptr);
+    while loop_size == LOOP_SIZE && ptr <= end_ptr.sub(loop_size) {
+        debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE);
+
+        let a = _mm256_load_si256(ptr as *const __m256i);
+        let b = _mm256_load_si256(ptr.add(VECTOR_SIZE) as *const __m256i);
+        let c = _mm256_load_si256(ptr.add(2 * VECTOR_SIZE) as *const __m256i);
+        let d = _mm256_load_si256(ptr.add(3 * VECTOR_SIZE) as *const __m256i);
+        let eqa = _mm256_cmpeq_epi8(vn1, a);
+        let eqb = _mm256_cmpeq_epi8(vn1, b);
+        let eqc = _mm256_cmpeq_epi8(vn1, c);
+        let eqd = _mm256_cmpeq_epi8(vn1, d);
+        let or1 = _mm256_or_si256(eqa, eqb);
+        let or2 = _mm256_or_si256(eqc, eqd);
+        let or3 = _mm256_or_si256(or1, or2);
+        if _mm256_movemask_epi8(or3) != 0 {
+            let mut at = sub(ptr, start_ptr);
+            let mask = _mm256_movemask_epi8(eqa);
+            if mask != 0 {
+                return Some(at + forward_pos(mask));
+            }
+
+            at += VECTOR_SIZE;
+            let mask = _mm256_movemask_epi8(eqb);
+            if mask != 0 {
+                return Some(at + forward_pos(mask));
+            }
+
+            at += VECTOR_SIZE;
+            let mask = _mm256_movemask_epi8(eqc);
+            if mask != 0 {
+                return Some(at + forward_pos(mask));
+            }
+
+            at += VECTOR_SIZE;
+            let mask = _mm256_movemask_epi8(eqd);
+            debug_assert!(mask != 0);
+            return Some(at + forward_pos(mask));
+        }
+        ptr = ptr.add(loop_size);
+    }
+    while ptr <= end_ptr.sub(VECTOR_SIZE) {
+        debug_assert!(sub(end_ptr, ptr) >= VECTOR_SIZE);
+
+        if let Some(i) = forward_search1(start_ptr, end_ptr, ptr, vn1) {
+            return Some(i);
+        }
+        ptr = ptr.add(VECTOR_SIZE);
+    }
+    if ptr < end_ptr {
+        debug_assert!(sub(end_ptr, ptr) < VECTOR_SIZE);
+        ptr = ptr.sub(VECTOR_SIZE - sub(end_ptr, ptr));
+        debug_assert_eq!(sub(end_ptr, ptr), VECTOR_SIZE);
+
+        return forward_search1(start_ptr, end_ptr, ptr, vn1);
+    }
+    None
+}
+
+#[target_feature(enable = "avx2")]
+pub unsafe fn memchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
+    let vn1 = _mm256_set1_epi8(n1 as i8);
+    let vn2 = _mm256_set1_epi8(n2 as i8);
+    let len = haystack.len();
+    let loop_size = cmp::min(LOOP_SIZE2, len);
+    let start_ptr = haystack.as_ptr();
+    let end_ptr = haystack[haystack.len()..].as_ptr();
+    let mut ptr = start_ptr;
+
+    if haystack.len() < VECTOR_SIZE {
+        while ptr < end_ptr {
+            if *ptr == n1 || *ptr == n2 {
+                return Some(sub(ptr, start_ptr));
+            }
+            ptr = ptr.offset(1);
+        }
+        return None;
+    }
+
+    if let Some(i) = forward_search2(start_ptr, end_ptr, ptr, vn1, vn2) {
+        return Some(i);
+    }
+
+    ptr = ptr.add(VECTOR_SIZE - (start_ptr as usize & VECTOR_ALIGN));
+    debug_assert!(ptr > start_ptr && end_ptr.sub(VECTOR_SIZE) >= start_ptr);
+    while loop_size == LOOP_SIZE2 && ptr <= end_ptr.sub(loop_size) {
+        debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE);
+
+        let a = _mm256_load_si256(ptr as *const __m256i);
+        let b = _mm256_load_si256(ptr.add(VECTOR_SIZE) as *const __m256i);
+        let eqa1 = _mm256_cmpeq_epi8(vn1, a);
+        let eqb1 = _mm256_cmpeq_epi8(vn1, b);
+        let eqa2 = _mm256_cmpeq_epi8(vn2, a);
+        let eqb2 = _mm256_cmpeq_epi8(vn2, b);
+        let or1 = _mm256_or_si256(eqa1, eqb1);
+        let or2 = _mm256_or_si256(eqa2, eqb2);
+        let or3 = _mm256_or_si256(or1, or2);
+        if _mm256_movemask_epi8(or3) != 0 {
+            let mut at = sub(ptr, start_ptr);
+            let mask1 = _mm256_movemask_epi8(eqa1);
+            let mask2 = _mm256_movemask_epi8(eqa2);
+            if mask1 != 0 || mask2 != 0 {
+                return Some(at + forward_pos2(mask1, mask2));
+            }
+
+            at += VECTOR_SIZE;
+            let mask1 = _mm256_movemask_epi8(eqb1);
+            let mask2 = _mm256_movemask_epi8(eqb2);
+            return Some(at + forward_pos2(mask1, mask2));
+        }
+        ptr = ptr.add(loop_size);
+    }
+    while ptr <= end_ptr.sub(VECTOR_SIZE) {
+        if let Some(i) = forward_search2(start_ptr, end_ptr, ptr, vn1, vn2) {
+            return Some(i);
+        }
+        ptr = ptr.add(VECTOR_SIZE);
+    }
+    if ptr < end_ptr {
+        debug_assert!(sub(end_ptr, ptr) < VECTOR_SIZE);
+        ptr = ptr.sub(VECTOR_SIZE - sub(end_ptr, ptr));
+        debug_assert_eq!(sub(end_ptr, ptr), VECTOR_SIZE);
+
+        return forward_search2(start_ptr, end_ptr, ptr, vn1, vn2);
+    }
+    None
+}
+
+#[target_feature(enable = "avx2")]
+pub unsafe fn memchr3(
+    n1: u8, n2: u8, n3: u8,
+    haystack: &[u8]
+) -> Option<usize> {
+    let vn1 = _mm256_set1_epi8(n1 as i8);
+    let vn2 = _mm256_set1_epi8(n2 as i8);
+    let vn3 = _mm256_set1_epi8(n3 as i8);
+    let len = haystack.len();
+    let loop_size = cmp::min(LOOP_SIZE2, len);
+    let start_ptr = haystack.as_ptr();
+    let end_ptr = haystack[haystack.len()..].as_ptr();
+    let mut ptr = start_ptr;
+
+    if haystack.len() < VECTOR_SIZE {
+        while ptr < end_ptr {
+            if *ptr == n1 || *ptr == n2 || *ptr == n3 {
+                return Some(sub(ptr, start_ptr));
+            }
+            ptr = ptr.offset(1);
+        }
+        return None;
+    }
+
+    if let Some(i) = forward_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3) {
+        return Some(i);
+    }
+
+    ptr = ptr.add(VECTOR_SIZE - (start_ptr as usize & VECTOR_ALIGN));
+    debug_assert!(ptr > start_ptr && end_ptr.sub(VECTOR_SIZE) >= start_ptr);
+    while loop_size == LOOP_SIZE2 && ptr <= end_ptr.sub(loop_size) {
+        debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE);
+
+        let a = _mm256_load_si256(ptr as *const __m256i);
+        let b = _mm256_load_si256(ptr.add(VECTOR_SIZE) as *const __m256i);
+        let eqa1 = _mm256_cmpeq_epi8(vn1, a);
+        let eqb1 = _mm256_cmpeq_epi8(vn1, b);
+        let eqa2 = _mm256_cmpeq_epi8(vn2, a);
+        let eqb2 = _mm256_cmpeq_epi8(vn2, b);
+        let eqa3 = _mm256_cmpeq_epi8(vn3, a);
+        let eqb3 = _mm256_cmpeq_epi8(vn3, b);
+        let or1 = _mm256_or_si256(eqa1, eqb1);
+        let or2 = _mm256_or_si256(eqa2, eqb2);
+        let or3 = _mm256_or_si256(eqa3, eqb3);
+        let or4 = _mm256_or_si256(or1, or2);
+        let or5 = _mm256_or_si256(or3, or4);
+        if _mm256_movemask_epi8(or5) != 0 {
+            let mut at = sub(ptr, start_ptr);
+            let mask1 = _mm256_movemask_epi8(eqa1);
+            let mask2 = _mm256_movemask_epi8(eqa2);
+            let mask3 = _mm256_movemask_epi8(eqa3);
+            if mask1 != 0 || mask2 != 0 || mask3 != 0 {
+                return Some(at + forward_pos3(mask1, mask2, mask3));
+            }
+
+            at += VECTOR_SIZE;
+            let mask1 = _mm256_movemask_epi8(eqb1);
+            let mask2 = _mm256_movemask_epi8(eqb2);
+            let mask3 = _mm256_movemask_epi8(eqb3);
+            if mask1 != 0 || mask2 != 0 || mask3 != 0 {
+                return Some(at + forward_pos3(mask1, mask2, mask3));
+            }
+
+            at += VECTOR_SIZE;
+            let mask1 = _mm256_movemask_epi8(eqb1);
+            let mask2 = _mm256_movemask_epi8(eqb2);
+            let mask3 = _mm256_movemask_epi8(eqb3);
+            return Some(at + forward_pos3(mask1, mask2, mask3));
+        }
+        ptr = ptr.add(loop_size);
+    }
+    while ptr <= end_ptr.sub(VECTOR_SIZE) {
+        if let Some(i) = forward_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3) {
+            return Some(i);
+        }
+        ptr = ptr.add(VECTOR_SIZE);
+    }
+    if ptr < end_ptr {
+        debug_assert!(sub(end_ptr, ptr) < VECTOR_SIZE);
+        ptr = ptr.sub(VECTOR_SIZE - sub(end_ptr, ptr));
+        debug_assert_eq!(sub(end_ptr, ptr), VECTOR_SIZE);
+
+        return forward_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3);
+    }
+    None
+}
+
+#[target_feature(enable = "avx2")]
+pub unsafe fn memrchr(n1: u8, haystack: &[u8]) -> Option<usize> {
+    let vn1 = _mm256_set1_epi8(n1 as i8);
+    let len = haystack.len();
+    let loop_size = cmp::min(LOOP_SIZE, len);
+    let start_ptr = haystack.as_ptr();
+    let end_ptr = haystack[haystack.len()..].as_ptr();
+    let mut ptr = end_ptr;
+
+    if haystack.len() < VECTOR_SIZE {
+        while ptr > start_ptr {
+            ptr = ptr.offset(-1);
+            if *ptr == n1 {
+                return Some(sub(ptr, start_ptr));
+            }
+        }
+        return None;
+    }
+
+    ptr = ptr.sub(VECTOR_SIZE);
+    if let Some(i) = reverse_search1(start_ptr, end_ptr, ptr, vn1) {
+        return Some(i);
+    }
+
+    ptr = (end_ptr as usize & !VECTOR_ALIGN) as *const u8;
+    debug_assert!(start_ptr <= ptr && ptr <= end_ptr);
+    while loop_size == LOOP_SIZE && ptr >= start_ptr.add(loop_size) {
+        debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE);
+
+        ptr = ptr.sub(loop_size);
+        let a = _mm256_load_si256(ptr as *const __m256i);
+        let b = _mm256_load_si256(ptr.add(VECTOR_SIZE) as *const __m256i);
+        let c = _mm256_load_si256(ptr.add(2 * VECTOR_SIZE) as *const __m256i);
+        let d = _mm256_load_si256(ptr.add(3 * VECTOR_SIZE) as *const __m256i);
+        let eqa = _mm256_cmpeq_epi8(vn1, a);
+        let eqb = _mm256_cmpeq_epi8(vn1, b);
+        let eqc = _mm256_cmpeq_epi8(vn1, c);
+        let eqd = _mm256_cmpeq_epi8(vn1, d);
+        let or1 = _mm256_or_si256(eqa, eqb);
+        let or2 = _mm256_or_si256(eqc, eqd);
+        let or3 = _mm256_or_si256(or1, or2);
+        if _mm256_movemask_epi8(or3) != 0 {
+            let mut at = sub(ptr.add(3 * VECTOR_SIZE), start_ptr);
+            let mask = _mm256_movemask_epi8(eqd);
+            if mask != 0 {
+                return Some(at + reverse_pos(mask));
+            }
+
+            at -= VECTOR_SIZE;
+            let mask = _mm256_movemask_epi8(eqc);
+            if mask != 0 {
+                return Some(at + reverse_pos(mask));
+            }
+
+            at -= VECTOR_SIZE;
+            let mask = _mm256_movemask_epi8(eqb);
+            if mask != 0 {
+                return Some(at + reverse_pos(mask));
+            }
+
+            at -= VECTOR_SIZE;
+            let mask = _mm256_movemask_epi8(eqa);
+            debug_assert!(mask != 0);
+            return Some(at + reverse_pos(mask));
+        }
+    }
+    while ptr >= start_ptr.add(VECTOR_SIZE) {
+        ptr = ptr.sub(VECTOR_SIZE);
+        if let Some(i) = reverse_search1(start_ptr, end_ptr, ptr, vn1) {
+            return Some(i);
+        }
+    }
+    if ptr > start_ptr {
+        debug_assert!(sub(ptr, start_ptr) < VECTOR_SIZE);
+        return reverse_search1(start_ptr, end_ptr, start_ptr, vn1);
+    }
+    None
+}
+
+#[target_feature(enable = "avx2")]
+pub unsafe fn memrchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
+    let vn1 = _mm256_set1_epi8(n1 as i8);
+    let vn2 = _mm256_set1_epi8(n2 as i8);
+    let len = haystack.len();
+    let loop_size = cmp::min(LOOP_SIZE2, len);
+    let start_ptr = haystack.as_ptr();
+    let end_ptr = haystack[haystack.len()..].as_ptr();
+    let mut ptr = end_ptr;
+
+    if haystack.len() < VECTOR_SIZE {
+        while ptr > start_ptr {
+            ptr = ptr.offset(-1);
+            if *ptr == n1 || *ptr == n2 {
+                return Some(sub(ptr, start_ptr));
+            }
+        }
+        return None;
+    }
+
+    ptr = ptr.sub(VECTOR_SIZE);
+    if let Some(i) = reverse_search2(start_ptr, end_ptr, ptr, vn1, vn2) {
+        return Some(i);
+    }
+
+    ptr = (end_ptr as usize & !VECTOR_ALIGN) as *const u8;
+    debug_assert!(start_ptr <= ptr && ptr <= end_ptr);
+    while loop_size == LOOP_SIZE2 && ptr >= start_ptr.add(loop_size) {
+        debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE);
+
+        ptr = ptr.sub(loop_size);
+        let a = _mm256_load_si256(ptr as *const __m256i);
+        let b = _mm256_load_si256(ptr.add(VECTOR_SIZE) as *const __m256i);
+        let eqa1 = _mm256_cmpeq_epi8(vn1, a);
+        let eqb1 = _mm256_cmpeq_epi8(vn1, b);
+        let eqa2 = _mm256_cmpeq_epi8(vn2, a);
+        let eqb2 = _mm256_cmpeq_epi8(vn2, b);
+        let or1 = _mm256_or_si256(eqa1, eqb1);
+        let or2 = _mm256_or_si256(eqa2, eqb2);
+        let or3 = _mm256_or_si256(or1, or2);
+        if _mm256_movemask_epi8(or3) != 0 {
+            let mut at = sub(ptr.add(VECTOR_SIZE), start_ptr);
+            let mask1 = _mm256_movemask_epi8(eqb1);
+            let mask2 = _mm256_movemask_epi8(eqb2);
+            if mask1 != 0 || mask2 != 0 {
+                return Some(at + reverse_pos2(mask1, mask2));
+            }
+
+            at -= VECTOR_SIZE;
+            let mask1 = _mm256_movemask_epi8(eqa1);
+            let mask2 = _mm256_movemask_epi8(eqa2);
+            return Some(at + reverse_pos2(mask1, mask2));
+        }
+    }
+    while ptr >= start_ptr.add(VECTOR_SIZE) {
+        ptr = ptr.sub(VECTOR_SIZE);
+        if let Some(i) = reverse_search2(start_ptr, end_ptr, ptr, vn1, vn2) {
+            return Some(i);
+        }
+    }
+    if ptr > start_ptr {
+        debug_assert!(sub(ptr, start_ptr) < VECTOR_SIZE);
+        return reverse_search2(start_ptr, end_ptr, start_ptr, vn1, vn2);
+    }
+    None
+}
+
+#[target_feature(enable = "avx2")]
+pub unsafe fn memrchr3(
+    n1: u8, n2: u8, n3: u8,
+    haystack: &[u8],
+) -> Option<usize> {
+    let vn1 = _mm256_set1_epi8(n1 as i8);
+    let vn2 = _mm256_set1_epi8(n2 as i8);
+    let vn3 = _mm256_set1_epi8(n3 as i8);
+    let len = haystack.len();
+    let loop_size = cmp::min(LOOP_SIZE2, len);
+    let start_ptr = haystack.as_ptr();
+    let end_ptr = haystack[haystack.len()..].as_ptr();
+    let mut ptr = end_ptr;
+
+    if haystack.len() < VECTOR_SIZE {
+        while ptr > start_ptr {
+            ptr = ptr.offset(-1);
+            if *ptr == n1 || *ptr == n2 || *ptr == n3 {
+                return Some(sub(ptr, start_ptr));
+            }
+        }
+        return None;
+    }
+
+    ptr = ptr.sub(VECTOR_SIZE);
+    if let Some(i) = reverse_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3) {
+        return Some(i);
+    }
+
+    ptr = (end_ptr as usize & !VECTOR_ALIGN) as *const u8;
+    debug_assert!(start_ptr <= ptr && ptr <= end_ptr);
+    while loop_size == LOOP_SIZE2 && ptr >= start_ptr.add(loop_size) {
+        debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE);
+
+        ptr = ptr.sub(loop_size);
+        let a = _mm256_load_si256(ptr as *const __m256i);
+        let b = _mm256_load_si256(ptr.add(VECTOR_SIZE) as *const __m256i);
+        let eqa1 = _mm256_cmpeq_epi8(vn1, a);
+        let eqb1 = _mm256_cmpeq_epi8(vn1, b);
+        let eqa2 = _mm256_cmpeq_epi8(vn2, a);
+        let eqb2 = _mm256_cmpeq_epi8(vn2, b);
+        let eqa3 = _mm256_cmpeq_epi8(vn3, a);
+        let eqb3 = _mm256_cmpeq_epi8(vn3, b);
+        let or1 = _mm256_or_si256(eqa1, eqb1);
+        let or2 = _mm256_or_si256(eqa2, eqb2);
+        let or3 = _mm256_or_si256(eqa3, eqb3);
+        let or4 = _mm256_or_si256(or1, or2);
+        let or5 = _mm256_or_si256(or3, or4);
+        if _mm256_movemask_epi8(or5) != 0 {
+            let mut at = sub(ptr.add(VECTOR_SIZE), start_ptr);
+            let mask1 = _mm256_movemask_epi8(eqb1);
+            let mask2 = _mm256_movemask_epi8(eqb2);
+            let mask3 = _mm256_movemask_epi8(eqb3);
+            if mask1 != 0 || mask2 != 0 || mask3 != 0 {
+                return Some(at + reverse_pos3(mask1, mask2, mask3));
+            }
+
+            at -= VECTOR_SIZE;
+            let mask1 = _mm256_movemask_epi8(eqa1);
+            let mask2 = _mm256_movemask_epi8(eqa2);
+            let mask3 = _mm256_movemask_epi8(eqa3);
+            return Some(at + reverse_pos3(mask1, mask2, mask3));
+        }
+    }
+    while ptr >= start_ptr.add(VECTOR_SIZE) {
+        ptr = ptr.sub(VECTOR_SIZE);
+        if let Some(i) = reverse_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3) {
+            return Some(i);
+        }
+    }
+    if ptr > start_ptr {
+        debug_assert!(sub(ptr, start_ptr) < VECTOR_SIZE);
+        return reverse_search3(start_ptr, end_ptr, start_ptr, vn1, vn2, vn3);
+    }
+    None
+}
+
+#[target_feature(enable = "avx2")]
+unsafe fn forward_search1(
+    start_ptr: *const u8,
+    end_ptr: *const u8,
+    ptr: *const u8,
+    vn1: __m256i,
+) -> Option<usize> {
+    debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE);
+    debug_assert!(start_ptr <= ptr);
+    debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE));
+
+    let chunk = _mm256_loadu_si256(ptr as *const __m256i);
+    let mask = _mm256_movemask_epi8(_mm256_cmpeq_epi8(chunk, vn1));
+    if mask != 0 {
+        Some(sub(ptr, start_ptr) + forward_pos(mask))
+    } else {
+        None
+    }
+}
+
+#[target_feature(enable = "avx2")]
+unsafe fn forward_search2(
+    start_ptr: *const u8,
+    end_ptr: *const u8,
+    ptr: *const u8,
+    vn1: __m256i,
+    vn2: __m256i,
+) -> Option<usize> {
+    debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE);
+    debug_assert!(start_ptr <= ptr);
+    debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE));
+
+    let chunk = _mm256_loadu_si256(ptr as *const __m256i);
+    let eq1 = _mm256_cmpeq_epi8(chunk, vn1);
+    let eq2 = _mm256_cmpeq_epi8(chunk, vn2);
+    if _mm256_movemask_epi8(_mm256_or_si256(eq1, eq2)) != 0 {
+        let mask1 = _mm256_movemask_epi8(eq1);
+        let mask2 = _mm256_movemask_epi8(eq2);
+        Some(sub(ptr, start_ptr) + forward_pos2(mask1, mask2))
+    } else {
+        None
+    }
+}
+
+#[target_feature(enable = "avx2")]
+unsafe fn forward_search3(
+    start_ptr: *const u8,
+    end_ptr: *const u8,
+    ptr: *const u8,
+    vn1: __m256i,
+    vn2: __m256i,
+    vn3: __m256i,
+) -> Option<usize> {
+    debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE);
+    debug_assert!(start_ptr <= ptr);
+    debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE));
+
+    let chunk = _mm256_loadu_si256(ptr as *const __m256i);
+    let eq1 = _mm256_cmpeq_epi8(chunk, vn1);
+    let eq2 = _mm256_cmpeq_epi8(chunk, vn2);
+    let eq3 = _mm256_cmpeq_epi8(chunk, vn3);
+    let or = _mm256_or_si256(eq1, eq2);
+    if _mm256_movemask_epi8(_mm256_or_si256(or, eq3)) != 0 {
+        let mask1 = _mm256_movemask_epi8(eq1);
+        let mask2 = _mm256_movemask_epi8(eq2);
+        let mask3 = _mm256_movemask_epi8(eq3);
+        Some(sub(ptr, start_ptr) + forward_pos3(mask1, mask2, mask3))
+    } else {
+        None
+    }
+}
+
+#[target_feature(enable = "avx2")]
+unsafe fn reverse_search1(
+    start_ptr: *const u8,
+    end_ptr: *const u8,
+    ptr: *const u8,
+    vn1: __m256i,
+) -> Option<usize> {
+    debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE);
+    debug_assert!(start_ptr <= ptr);
+    debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE));
+
+    let chunk = _mm256_loadu_si256(ptr as *const __m256i);
+    let mask = _mm256_movemask_epi8(_mm256_cmpeq_epi8(vn1, chunk));
+    if mask != 0 {
+        Some(sub(ptr, start_ptr) + reverse_pos(mask))
+    } else {
+        None
+    }
+}
+
+#[target_feature(enable = "avx2")]
+unsafe fn reverse_search2(
+    start_ptr: *const u8,
+    end_ptr: *const u8,
+    ptr: *const u8,
+    vn1: __m256i,
+    vn2: __m256i,
+) -> Option<usize> {
+    debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE);
+    debug_assert!(start_ptr <= ptr);
+    debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE));
+
+    let chunk = _mm256_loadu_si256(ptr as *const __m256i);
+    let eq1 = _mm256_cmpeq_epi8(chunk, vn1);
+    let eq2 = _mm256_cmpeq_epi8(chunk, vn2);
+    if _mm256_movemask_epi8(_mm256_or_si256(eq1, eq2)) != 0 {
+        let mask1 = _mm256_movemask_epi8(eq1);
+        let mask2 = _mm256_movemask_epi8(eq2);
+        Some(sub(ptr, start_ptr) + reverse_pos2(mask1, mask2))
+    } else {
+        None
+    }
+}
+
+#[target_feature(enable = "avx2")]
+unsafe fn reverse_search3(
+    start_ptr: *const u8,
+    end_ptr: *const u8,
+    ptr: *const u8,
+    vn1: __m256i,
+    vn2: __m256i,
+    vn3: __m256i,
+) -> Option<usize> {
+    debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE);
+    debug_assert!(start_ptr <= ptr);
+    debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE));
+
+    let chunk = _mm256_loadu_si256(ptr as *const __m256i);
+    let eq1 = _mm256_cmpeq_epi8(chunk, vn1);
+    let eq2 = _mm256_cmpeq_epi8(chunk, vn2);
+    let eq3 = _mm256_cmpeq_epi8(chunk, vn3);
+    let or = _mm256_or_si256(eq1, eq2);
+    if _mm256_movemask_epi8(_mm256_or_si256(or, eq3)) != 0 {
+        let mask1 = _mm256_movemask_epi8(eq1);
+        let mask2 = _mm256_movemask_epi8(eq2);
+        let mask3 = _mm256_movemask_epi8(eq3);
+        Some(sub(ptr, start_ptr) + reverse_pos3(mask1, mask2, mask3))
+    } else {
+        None
+    }
+}
+
+/// Compute the position of the first matching byte from the given mask. The
+/// position returned is always in the range [0, 31].
+///
+/// The mask given is expected to be the result of _mm256_movemask_epi8.
+fn forward_pos(mask: i32) -> usize {
+    // We are dealing with little endian here, where the most significant byte
+    // is at a higher address. That means the least significant bit that is set
+    // corresponds to the position of our first matching byte. That position
+    // corresponds to the number of zeros after the least significant bit.
+    mask.trailing_zeros() as usize
+}
+
+/// Compute the position of the first matching byte from the given masks. The
+/// position returned is always in the range [0, 31]. Each mask corresponds to
+/// the equality comparison of a single byte.
+///
+/// The masks given are expected to be the result of _mm256_movemask_epi8,
+/// where at least one of the masks is non-zero (i.e., indicates a match).
+fn forward_pos2(mask1: i32, mask2: i32) -> usize {
+    debug_assert!(mask1 != 0 || mask2 != 0);
+
+    forward_pos(mask1 | mask2)
+}
+
+/// Compute the position of the first matching byte from the given masks. The
+/// position returned is always in the range [0, 31]. Each mask corresponds to
+/// the equality comparison of a single byte.
+///
+/// The masks given are expected to be the result of _mm256_movemask_epi8,
+/// where at least one of the masks is non-zero (i.e., indicates a match).
+fn forward_pos3(mask1: i32, mask2: i32, mask3: i32) -> usize {
+    debug_assert!(mask1 != 0 || mask2 != 0 || mask3 != 0);
+
+    forward_pos(mask1 | mask2 | mask3)
+}
+
+/// Compute the position of the last matching byte from the given mask. The
+/// position returned is always in the range [0, 31].
+///
+/// The mask given is expected to be the result of _mm256_movemask_epi8.
+fn reverse_pos(mask: i32) -> usize {
+    // We are dealing with little endian here, where the most significant byte
+    // is at a higher address. That means the most significant bit that is set
+    // corresponds to the position of our last matching byte. The position from
+    // the end of the mask is therefore the number of leading zeros in a 32
+    // bit integer, and the position from the start of the mask is therefore
+    // 32 - (leading zeros) - 1.
+    VECTOR_SIZE - (mask as u32).leading_zeros() as usize - 1
+}
+
+/// Compute the position of the last matching byte from the given masks. The
+/// position returned is always in the range [0, 31]. Each mask corresponds to
+/// the equality comparison of a single byte.
+///
+/// The masks given are expected to be the result of _mm256_movemask_epi8,
+/// where at least one of the masks is non-zero (i.e., indicates a match).
+fn reverse_pos2(mask1: i32, mask2: i32) -> usize {
+    debug_assert!(mask1 != 0 || mask2 != 0);
+
+    reverse_pos(mask1 | mask2)
+}
+
+/// Compute the position of the last matching byte from the given masks. The
+/// position returned is always in the range [0, 31]. Each mask corresponds to
+/// the equality comparison of a single byte.
+///
+/// The masks given are expected to be the result of _mm256_movemask_epi8,
+/// where at least one of the masks is non-zero (i.e., indicates a match).
+fn reverse_pos3(mask1: i32, mask2: i32, mask3: i32) -> usize {
+    debug_assert!(mask1 != 0 || mask2 != 0 || mask3 != 0);
+
+    reverse_pos(mask1 | mask2 | mask3)
+}
+
+/// Subtract `b` from `a` and return the difference. `a` should be greater than
+/// or equal to `b`.
+fn sub(a: *const u8, b: *const u8) -> usize {
+    debug_assert!(a >= b);
+    (a as usize) - (b as usize)
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/memchr/x86/mod.rs.html b/target/doc/src/memchr/x86/mod.rs.html new file mode 100644 index 0000000..8c6de1d --- /dev/null +++ b/target/doc/src/memchr/x86/mod.rs.html @@ -0,0 +1,213 @@ +mod.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+
+use fallback;
+
+// We only use AVX when we can detect at runtime whether it's available, which
+// requires std.
+#[cfg(feature = "use_std")]
+mod avx;
+mod sse2;
+
+// This macro employs a gcc-like "ifunc" trick where by upon first calling
+// `memchr` (for example), CPU feature detection will be performed at runtime
+// to determine the best implementation to use. After CPU feature detection
+// is done, we replace `memchr`'s function pointer with the selection. Upon
+// subsequent invocations, the CPU-specific routine is invoked directly, which
+// skips the CPU feature detection and subsequent branch that's required.
+//
+// While this typically doesn't matter for rare occurrences or when used on
+// larger haystacks, `memchr` can be called in tight loops where the overhead
+// of this branch can actually add up *and is measurable*. This trick was
+// necessary to bring this implementation up to glibc's speeds for the 'tiny'
+// benchmarks, for example.
+//
+// At some point, I expect the Rust ecosystem will get a nice macro for doing
+// exactly this, at which point, we can replace our hand-jammed version of it.
+//
+// N.B. The ifunc strategy does prevent function inlining of course, but on
+// modern CPUs, you'll probably end up with the AVX2 implementation, which
+// probably can't be inlined anyway---unless you've compiled your entire
+// program with AVX2 enabled. However, even then, the various memchr
+// implementations aren't exactly small, so inlining might not help anyway!
+#[cfg(feature = "use_std")]
+macro_rules! ifunc {
+    ($fnty:ty, $name:ident, $haystack:ident, $($needle:ident),+) => {{
+        use std::mem;
+        use std::sync::atomic::{AtomicPtr, Ordering};
+
+        type FnRaw = *mut ();
+
+        static FN: AtomicPtr<()> = AtomicPtr::new(detect as FnRaw);
+
+        fn detect($($needle: u8),+, haystack: &[u8]) -> Option<usize> {
+            let fun =
+                if cfg!(memchr_runtime_avx) && is_x86_feature_detected!("avx2") {
+                    avx::$name as FnRaw
+                } else if cfg!(memchr_runtime_sse2) {
+                    sse2::$name as FnRaw
+                } else {
+                    fallback::$name as FnRaw
+                };
+            FN.store(fun as FnRaw, Ordering::Relaxed);
+            unsafe {
+                mem::transmute::<FnRaw, $fnty>(fun)($($needle),+, haystack)
+            }
+        }
+
+        unsafe {
+            let fun = FN.load(Ordering::Relaxed);
+            mem::transmute::<FnRaw, $fnty>(fun)($($needle),+, $haystack)
+        }
+    }}
+}
+
+// When std isn't available to provide runtime CPU feature detection, or if
+// runtime CPU feature detection has been explicitly disabled, then just call
+// our optimized SSE2 routine directly. SSE2 is avalbale on all x86_64 targets,
+// so no CPU feature detection is necessary.
+#[cfg(not(feature = "use_std"))]
+macro_rules! ifunc {
+    ($fnty:ty, $name:ident, $haystack:ident, $($needle:ident),+) => {{
+        if cfg!(memchr_runtime_sse2) {
+            unsafe { sse2::$name($($needle),+, $haystack) }
+        } else {
+            fallback::$name($($needle),+, $haystack)
+        }
+    }}
+}
+
+#[inline(always)]
+pub fn memchr(n1: u8, haystack: &[u8]) -> Option<usize> {
+    ifunc!(fn(u8, &[u8]) -> Option<usize>, memchr, haystack, n1)
+}
+
+#[inline(always)]
+pub fn memchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
+    ifunc!(fn(u8, u8, &[u8]) -> Option<usize>, memchr2, haystack, n1, n2)
+}
+
+#[inline(always)]
+pub fn memchr3(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
+    ifunc!(fn(u8, u8, u8, &[u8]) -> Option<usize>, memchr3, haystack, n1, n2, n3)
+}
+
+#[inline(always)]
+pub fn memrchr(n1: u8, haystack: &[u8]) -> Option<usize> {
+    ifunc!(fn(u8, &[u8]) -> Option<usize>, memrchr, haystack, n1)
+}
+
+#[inline(always)]
+pub fn memrchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
+    ifunc!(fn(u8, u8, &[u8]) -> Option<usize>, memrchr2, haystack, n1, n2)
+}
+
+#[inline(always)]
+pub fn memrchr3(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
+    ifunc!(fn(u8, u8, u8, &[u8]) -> Option<usize>, memrchr3, haystack, n1, n2, n3)
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/memchr/x86/sse2.rs.html b/target/doc/src/memchr/x86/sse2.rs.html new file mode 100644 index 0000000..aeecab6 --- /dev/null +++ b/target/doc/src/memchr/x86/sse2.rs.html @@ -0,0 +1,1585 @@ +sse2.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+
+use core::arch::x86_64::*;
+use core::cmp;
+use core::mem::size_of;
+
+const VECTOR_SIZE: usize = size_of::<__m128i>();
+const VECTOR_ALIGN: usize = VECTOR_SIZE - 1;
+
+// The number of bytes to loop at in one iteration of memchr/memrchr.
+const LOOP_SIZE: usize = 4 * VECTOR_SIZE;
+
+// The number of bytes to loop at in one iteration of memchr2/memrchr2 and
+// memchr3/memrchr3. There was no observable difference between 64 and 32 bytes
+// in benchmarks. memchr3 in particular only gets a very slight speed up from
+// the loop unrolling.
+const LOOP_SIZE2: usize = 2 * VECTOR_SIZE;
+
+#[target_feature(enable = "sse2")]
+pub unsafe fn memchr(n1: u8, haystack: &[u8]) -> Option<usize> {
+    // What follows is a fast SSE2-only algorithm to detect the position of
+    // `n1` in `haystack` if it exists. From what I know, this is the "classic"
+    // algorithm. I believe it can be found in places like glibc and Go's
+    // standard library. It appears to be well known and is elaborated on in
+    // more detail here: https://gms.tf/stdfind-and-memchr-optimizations.html
+    //
+    // While this routine is very long, the basic idea is actually very simple
+    // and can be expressed straight-forwardly in pseudo code:
+    //
+    //     needle = (n1 << 15) | (n1 << 14) | ... | (n1 << 1) | n1
+    //     while i <= haystack.len() - 16:
+    //       // A 16 byte vector. Each byte in chunk corresponds to a byte in
+    //       // the haystack.
+    //       chunk = haystack[i:i+16]
+    //       // Compare bytes in needle with bytes in chunk. The result is a 16
+    //       // byte chunk where each byte is 0xFF if the corresponding bytes
+    //       // in needle and chunk were equal, or 0x00 otherwise.
+    //       eqs = cmpeq(needle, chunk)
+    //       // Return a 32 bit integer where the most significant 16 bits
+    //       // are always 0 and the lower 16 bits correspond to whether the
+    //       // most significant bit in the correspond byte in `eqs` is set.
+    //       // In other words, `mask as u16` has bit i set if and only if
+    //       // needle[i] == chunk[i].
+    //       mask = movemask(eqs)
+    //
+    //       // Mask is 0 if there is no match, and non-zero otherwise.
+    //       if mask != 0:
+    //         // trailing_zeros tells us the position of the least significant
+    //         // bit that is set.
+    //         return i + trailing_zeros(mask)
+    //
+    //     // haystack length may not be a multiple of 16, so search the rest.
+    //     while i < haystack.len():
+    //       if haystack[i] == n1:
+    //         return i
+    //
+    //     // No match found.
+    //     return NULL
+    //
+    // In fact, we could loosely translate the above code to Rust line-for-line
+    // and it would be a pretty fast algorithm. But, we pull out all the stops
+    // to go as fast as possible:
+    //
+    // 1. We use aligned loads. That is, we do some finagling to make sure our
+    //    primary loop not only proceeds in increments of 16 bytes, but that
+    //    the address of haystack's pointer that we dereference is aligned to
+    //    16 bytes. 16 is a magic number here because it is the size of SSE2
+    //    128-bit vector. (For the AVX2 algorithm, 32 is the magic number.)
+    //    Therefore, to get aligned loads, our pointer's address must be evenly
+    //    divisible by 16.
+    // 2. Our primary loop proceeds 64 bytes at a time instead of 16. It's
+    //    kind of like loop unrolling, but we combine the equality comparisons
+    //    using a vector OR such that we only need to extract a single mask to
+    //    determine whether a match exists or not. If so, then we do some
+    //    book-keeping to determine the precise location but otherwise mush on.
+    // 3. We use our "chunk" comparison routine in as many places as possible,
+    //    even if it means using unaligned loads. In particular, if haystack
+    //    starts with an unaligned address, then we do an unaligned load to
+    //    search the first 16 bytes. We then start our primary loop at the
+    //    smallest subsequent aligned address, which will actually overlap with
+    //    previously searched bytes. But we're OK with that. We do a similar
+    //    dance at the end of our primary loop. Finally, to avoid a
+    //    byte-at-a-time loop at the end, we do a final 16 byte unaligned load
+    //    that may overlap with a previous load. This is OK because it converts
+    //    a loop into a small number of very fast vector instructions.
+    //
+    // The primary downside of this algorithm is that it's effectively
+    // completely unsafe. Therefore, we have to be super careful to avoid
+    // undefined behavior:
+    //
+    // 1. We use raw pointers everywhere. Not only does dereferencing a pointer
+    //    require the pointer to be valid, but we actually can't even store the
+    //    address of an invalid pointer (unless it's 1 past the end of
+    //    haystack) without sacrificing performance.
+    // 2. _mm_loadu_si128 is used when you don't care about alignment, and
+    //    _mm_load_si128 is used when you do care. You cannot use the latter
+    //    on unaligned pointers.
+    // 3. We make liberal use of debug_assert! to check assumptions.
+    // 4. We make a concerted effort to stick with pointers instead of indices.
+    //    Indices are nicer because there's less to worry about with them (see
+    //    above about pointer offsets), but I could not get the compiler to
+    //    produce as good of code as what the below produces. In any case,
+    //    pointers are what we really care about here, and alignment is
+    //    expressed a bit more naturally with them.
+    //
+    // In general, most of the algorithms in this crate have a similar
+    // structure to what you see below, so this comment applies fairly well to
+    // all of them.
+
+    let vn1 = _mm_set1_epi8(n1 as i8);
+    let len = haystack.len();
+    let loop_size = cmp::min(LOOP_SIZE, len);
+    let start_ptr = haystack.as_ptr();
+    let end_ptr = haystack[haystack.len()..].as_ptr();
+    let mut ptr = start_ptr;
+
+    if haystack.len() < VECTOR_SIZE {
+        while ptr < end_ptr {
+            if *ptr == n1 {
+                return Some(sub(ptr, start_ptr));
+            }
+            ptr = ptr.offset(1);
+        }
+        return None;
+    }
+
+    if let Some(i) = forward_search1(start_ptr, end_ptr, ptr, vn1) {
+        return Some(i);
+    }
+
+    ptr = ptr.add(VECTOR_SIZE - (start_ptr as usize & VECTOR_ALIGN));
+    debug_assert!(ptr > start_ptr && end_ptr.sub(VECTOR_SIZE) >= start_ptr);
+    while loop_size == LOOP_SIZE && ptr <= end_ptr.sub(loop_size) {
+        debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE);
+
+        let a = _mm_load_si128(ptr as *const __m128i);
+        let b = _mm_load_si128(ptr.add(VECTOR_SIZE) as *const __m128i);
+        let c = _mm_load_si128(ptr.add(2 * VECTOR_SIZE) as *const __m128i);
+        let d = _mm_load_si128(ptr.add(3 * VECTOR_SIZE) as *const __m128i);
+        let eqa = _mm_cmpeq_epi8(vn1, a);
+        let eqb = _mm_cmpeq_epi8(vn1, b);
+        let eqc = _mm_cmpeq_epi8(vn1, c);
+        let eqd = _mm_cmpeq_epi8(vn1, d);
+        let or1 = _mm_or_si128(eqa, eqb);
+        let or2 = _mm_or_si128(eqc, eqd);
+        let or3 = _mm_or_si128(or1, or2);
+        if _mm_movemask_epi8(or3) != 0 {
+            let mut at = sub(ptr, start_ptr);
+            let mask = _mm_movemask_epi8(eqa);
+            if mask != 0 {
+                return Some(at + forward_pos(mask));
+            }
+
+            at += VECTOR_SIZE;
+            let mask = _mm_movemask_epi8(eqb);
+            if mask != 0 {
+                return Some(at + forward_pos(mask));
+            }
+
+            at += VECTOR_SIZE;
+            let mask = _mm_movemask_epi8(eqc);
+            if mask != 0 {
+                return Some(at + forward_pos(mask));
+            }
+
+            at += VECTOR_SIZE;
+            let mask = _mm_movemask_epi8(eqd);
+            debug_assert!(mask != 0);
+            return Some(at + forward_pos(mask));
+        }
+        ptr = ptr.add(loop_size);
+    }
+    while ptr <= end_ptr.sub(VECTOR_SIZE) {
+        debug_assert!(sub(end_ptr, ptr) >= VECTOR_SIZE);
+
+        if let Some(i) = forward_search1(start_ptr, end_ptr, ptr, vn1) {
+            return Some(i);
+        }
+        ptr = ptr.add(VECTOR_SIZE);
+    }
+    if ptr < end_ptr {
+        debug_assert!(sub(end_ptr, ptr) < VECTOR_SIZE);
+        ptr = ptr.sub(VECTOR_SIZE - sub(end_ptr, ptr));
+        debug_assert_eq!(sub(end_ptr, ptr), VECTOR_SIZE);
+
+        return forward_search1(start_ptr, end_ptr, ptr, vn1);
+    }
+    None
+}
+
+#[target_feature(enable = "sse2")]
+pub unsafe fn memchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
+    let vn1 = _mm_set1_epi8(n1 as i8);
+    let vn2 = _mm_set1_epi8(n2 as i8);
+    let len = haystack.len();
+    let loop_size = cmp::min(LOOP_SIZE2, len);
+    let start_ptr = haystack.as_ptr();
+    let end_ptr = haystack[haystack.len()..].as_ptr();
+    let mut ptr = start_ptr;
+
+    if haystack.len() < VECTOR_SIZE {
+        while ptr < end_ptr {
+            if *ptr == n1 || *ptr == n2 {
+                return Some(sub(ptr, start_ptr));
+            }
+            ptr = ptr.offset(1);
+        }
+        return None;
+    }
+
+    if let Some(i) = forward_search2(start_ptr, end_ptr, ptr, vn1, vn2) {
+        return Some(i);
+    }
+
+    ptr = ptr.add(VECTOR_SIZE - (start_ptr as usize & VECTOR_ALIGN));
+    debug_assert!(ptr > start_ptr && end_ptr.sub(VECTOR_SIZE) >= start_ptr);
+    while loop_size == LOOP_SIZE2 && ptr <= end_ptr.sub(loop_size) {
+        debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE);
+
+        let a = _mm_load_si128(ptr as *const __m128i);
+        let b = _mm_load_si128(ptr.add(VECTOR_SIZE) as *const __m128i);
+        let eqa1 = _mm_cmpeq_epi8(vn1, a);
+        let eqb1 = _mm_cmpeq_epi8(vn1, b);
+        let eqa2 = _mm_cmpeq_epi8(vn2, a);
+        let eqb2 = _mm_cmpeq_epi8(vn2, b);
+        let or1 = _mm_or_si128(eqa1, eqb1);
+        let or2 = _mm_or_si128(eqa2, eqb2);
+        let or3 = _mm_or_si128(or1, or2);
+        if _mm_movemask_epi8(or3) != 0 {
+            let mut at = sub(ptr, start_ptr);
+            let mask1 = _mm_movemask_epi8(eqa1);
+            let mask2 = _mm_movemask_epi8(eqa2);
+            if mask1 != 0 || mask2 != 0 {
+                return Some(at + forward_pos2(mask1, mask2));
+            }
+
+            at += VECTOR_SIZE;
+            let mask1 = _mm_movemask_epi8(eqb1);
+            let mask2 = _mm_movemask_epi8(eqb2);
+            return Some(at + forward_pos2(mask1, mask2));
+        }
+        ptr = ptr.add(loop_size);
+    }
+    while ptr <= end_ptr.sub(VECTOR_SIZE) {
+        if let Some(i) = forward_search2(start_ptr, end_ptr, ptr, vn1, vn2) {
+            return Some(i);
+        }
+        ptr = ptr.add(VECTOR_SIZE);
+    }
+    if ptr < end_ptr {
+        debug_assert!(sub(end_ptr, ptr) < VECTOR_SIZE);
+        ptr = ptr.sub(VECTOR_SIZE - sub(end_ptr, ptr));
+        debug_assert_eq!(sub(end_ptr, ptr), VECTOR_SIZE);
+
+        return forward_search2(start_ptr, end_ptr, ptr, vn1, vn2);
+    }
+    None
+}
+
+#[target_feature(enable = "sse2")]
+pub unsafe fn memchr3(
+    n1: u8, n2: u8, n3: u8,
+    haystack: &[u8]
+) -> Option<usize> {
+    let vn1 = _mm_set1_epi8(n1 as i8);
+    let vn2 = _mm_set1_epi8(n2 as i8);
+    let vn3 = _mm_set1_epi8(n3 as i8);
+    let len = haystack.len();
+    let loop_size = cmp::min(LOOP_SIZE2, len);
+    let start_ptr = haystack.as_ptr();
+    let end_ptr = haystack[haystack.len()..].as_ptr();
+    let mut ptr = start_ptr;
+
+    if haystack.len() < VECTOR_SIZE {
+        while ptr < end_ptr {
+            if *ptr == n1 || *ptr == n2 || *ptr == n3 {
+                return Some(sub(ptr, start_ptr));
+            }
+            ptr = ptr.offset(1);
+        }
+        return None;
+    }
+
+    if let Some(i) = forward_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3) {
+        return Some(i);
+    }
+
+    ptr = ptr.add(VECTOR_SIZE - (start_ptr as usize & VECTOR_ALIGN));
+    debug_assert!(ptr > start_ptr && end_ptr.sub(VECTOR_SIZE) >= start_ptr);
+    while loop_size == LOOP_SIZE2 && ptr <= end_ptr.sub(loop_size) {
+        debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE);
+
+        let a = _mm_load_si128(ptr as *const __m128i);
+        let b = _mm_load_si128(ptr.add(VECTOR_SIZE) as *const __m128i);
+        let eqa1 = _mm_cmpeq_epi8(vn1, a);
+        let eqb1 = _mm_cmpeq_epi8(vn1, b);
+        let eqa2 = _mm_cmpeq_epi8(vn2, a);
+        let eqb2 = _mm_cmpeq_epi8(vn2, b);
+        let eqa3 = _mm_cmpeq_epi8(vn3, a);
+        let eqb3 = _mm_cmpeq_epi8(vn3, b);
+        let or1 = _mm_or_si128(eqa1, eqb1);
+        let or2 = _mm_or_si128(eqa2, eqb2);
+        let or3 = _mm_or_si128(eqa3, eqb3);
+        let or4 = _mm_or_si128(or1, or2);
+        let or5 = _mm_or_si128(or3, or4);
+        if _mm_movemask_epi8(or5) != 0 {
+            let mut at = sub(ptr, start_ptr);
+            let mask1 = _mm_movemask_epi8(eqa1);
+            let mask2 = _mm_movemask_epi8(eqa2);
+            let mask3 = _mm_movemask_epi8(eqa3);
+            if mask1 != 0 || mask2 != 0 || mask3 != 0 {
+                return Some(at + forward_pos3(mask1, mask2, mask3));
+            }
+
+            at += VECTOR_SIZE;
+            let mask1 = _mm_movemask_epi8(eqb1);
+            let mask2 = _mm_movemask_epi8(eqb2);
+            let mask3 = _mm_movemask_epi8(eqb3);
+            if mask1 != 0 || mask2 != 0 || mask3 != 0 {
+                return Some(at + forward_pos3(mask1, mask2, mask3));
+            }
+
+            at += VECTOR_SIZE;
+            let mask1 = _mm_movemask_epi8(eqb1);
+            let mask2 = _mm_movemask_epi8(eqb2);
+            let mask3 = _mm_movemask_epi8(eqb3);
+            return Some(at + forward_pos3(mask1, mask2, mask3));
+        }
+        ptr = ptr.add(loop_size);
+    }
+    while ptr <= end_ptr.sub(VECTOR_SIZE) {
+        if let Some(i) = forward_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3) {
+            return Some(i);
+        }
+        ptr = ptr.add(VECTOR_SIZE);
+    }
+    if ptr < end_ptr {
+        debug_assert!(sub(end_ptr, ptr) < VECTOR_SIZE);
+        ptr = ptr.sub(VECTOR_SIZE - sub(end_ptr, ptr));
+        debug_assert_eq!(sub(end_ptr, ptr), VECTOR_SIZE);
+
+        return forward_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3);
+    }
+    None
+}
+
+#[target_feature(enable = "sse2")]
+pub unsafe fn memrchr(n1: u8, haystack: &[u8]) -> Option<usize> {
+    let vn1 = _mm_set1_epi8(n1 as i8);
+    let len = haystack.len();
+    let loop_size = cmp::min(LOOP_SIZE, len);
+    let start_ptr = haystack.as_ptr();
+    let end_ptr = haystack[haystack.len()..].as_ptr();
+    let mut ptr = end_ptr;
+
+    if haystack.len() < VECTOR_SIZE {
+        while ptr > start_ptr {
+            ptr = ptr.offset(-1);
+            if *ptr == n1 {
+                return Some(sub(ptr, start_ptr));
+            }
+        }
+        return None;
+    }
+
+    ptr = ptr.sub(VECTOR_SIZE);
+    if let Some(i) = reverse_search1(start_ptr, end_ptr, ptr, vn1) {
+        return Some(i);
+    }
+
+    ptr = (end_ptr as usize & !VECTOR_ALIGN) as *const u8;
+    debug_assert!(start_ptr <= ptr && ptr <= end_ptr);
+    while loop_size == LOOP_SIZE && ptr >= start_ptr.add(loop_size) {
+        debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE);
+
+        ptr = ptr.sub(loop_size);
+        let a = _mm_load_si128(ptr as *const __m128i);
+        let b = _mm_load_si128(ptr.add(VECTOR_SIZE) as *const __m128i);
+        let c = _mm_load_si128(ptr.add(2 * VECTOR_SIZE) as *const __m128i);
+        let d = _mm_load_si128(ptr.add(3 * VECTOR_SIZE) as *const __m128i);
+        let eqa = _mm_cmpeq_epi8(vn1, a);
+        let eqb = _mm_cmpeq_epi8(vn1, b);
+        let eqc = _mm_cmpeq_epi8(vn1, c);
+        let eqd = _mm_cmpeq_epi8(vn1, d);
+        let or1 = _mm_or_si128(eqa, eqb);
+        let or2 = _mm_or_si128(eqc, eqd);
+        let or3 = _mm_or_si128(or1, or2);
+        if _mm_movemask_epi8(or3) != 0 {
+            let mut at = sub(ptr.add(3 * VECTOR_SIZE), start_ptr);
+            let mask = _mm_movemask_epi8(eqd);
+            if mask != 0 {
+                return Some(at + reverse_pos(mask));
+            }
+
+            at -= VECTOR_SIZE;
+            let mask = _mm_movemask_epi8(eqc);
+            if mask != 0 {
+                return Some(at + reverse_pos(mask));
+            }
+
+            at -= VECTOR_SIZE;
+            let mask = _mm_movemask_epi8(eqb);
+            if mask != 0 {
+                return Some(at + reverse_pos(mask));
+            }
+
+            at -= VECTOR_SIZE;
+            let mask = _mm_movemask_epi8(eqa);
+            debug_assert!(mask != 0);
+            return Some(at + reverse_pos(mask));
+        }
+    }
+    while ptr >= start_ptr.add(VECTOR_SIZE) {
+        ptr = ptr.sub(VECTOR_SIZE);
+        if let Some(i) = reverse_search1(start_ptr, end_ptr, ptr, vn1) {
+            return Some(i);
+        }
+    }
+    if ptr > start_ptr {
+        debug_assert!(sub(ptr, start_ptr) < VECTOR_SIZE);
+        return reverse_search1(start_ptr, end_ptr, start_ptr, vn1);
+    }
+    None
+}
+
+#[target_feature(enable = "sse2")]
+pub unsafe fn memrchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
+    let vn1 = _mm_set1_epi8(n1 as i8);
+    let vn2 = _mm_set1_epi8(n2 as i8);
+    let len = haystack.len();
+    let loop_size = cmp::min(LOOP_SIZE2, len);
+    let start_ptr = haystack.as_ptr();
+    let end_ptr = haystack[haystack.len()..].as_ptr();
+    let mut ptr = end_ptr;
+
+    if haystack.len() < VECTOR_SIZE {
+        while ptr > start_ptr {
+            ptr = ptr.offset(-1);
+            if *ptr == n1 || *ptr == n2 {
+                return Some(sub(ptr, start_ptr));
+            }
+        }
+        return None;
+    }
+
+    ptr = ptr.sub(VECTOR_SIZE);
+    if let Some(i) = reverse_search2(start_ptr, end_ptr, ptr, vn1, vn2) {
+        return Some(i);
+    }
+
+    ptr = (end_ptr as usize & !VECTOR_ALIGN) as *const u8;
+    debug_assert!(start_ptr <= ptr && ptr <= end_ptr);
+    while loop_size == LOOP_SIZE2 && ptr >= start_ptr.add(loop_size) {
+        debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE);
+
+        ptr = ptr.sub(loop_size);
+        let a = _mm_load_si128(ptr as *const __m128i);
+        let b = _mm_load_si128(ptr.add(VECTOR_SIZE) as *const __m128i);
+        let eqa1 = _mm_cmpeq_epi8(vn1, a);
+        let eqb1 = _mm_cmpeq_epi8(vn1, b);
+        let eqa2 = _mm_cmpeq_epi8(vn2, a);
+        let eqb2 = _mm_cmpeq_epi8(vn2, b);
+        let or1 = _mm_or_si128(eqa1, eqb1);
+        let or2 = _mm_or_si128(eqa2, eqb2);
+        let or3 = _mm_or_si128(or1, or2);
+        if _mm_movemask_epi8(or3) != 0 {
+            let mut at = sub(ptr.add(VECTOR_SIZE), start_ptr);
+            let mask1 = _mm_movemask_epi8(eqb1);
+            let mask2 = _mm_movemask_epi8(eqb2);
+            if mask1 != 0 || mask2 != 0 {
+                return Some(at + reverse_pos2(mask1, mask2));
+            }
+
+            at -= VECTOR_SIZE;
+            let mask1 = _mm_movemask_epi8(eqa1);
+            let mask2 = _mm_movemask_epi8(eqa2);
+            return Some(at + reverse_pos2(mask1, mask2));
+        }
+    }
+    while ptr >= start_ptr.add(VECTOR_SIZE) {
+        ptr = ptr.sub(VECTOR_SIZE);
+        if let Some(i) = reverse_search2(start_ptr, end_ptr, ptr, vn1, vn2) {
+            return Some(i);
+        }
+    }
+    if ptr > start_ptr {
+        debug_assert!(sub(ptr, start_ptr) < VECTOR_SIZE);
+        return reverse_search2(start_ptr, end_ptr, start_ptr, vn1, vn2);
+    }
+    None
+}
+
+#[target_feature(enable = "sse2")]
+pub unsafe fn memrchr3(
+    n1: u8, n2: u8, n3: u8,
+    haystack: &[u8],
+) -> Option<usize> {
+    let vn1 = _mm_set1_epi8(n1 as i8);
+    let vn2 = _mm_set1_epi8(n2 as i8);
+    let vn3 = _mm_set1_epi8(n3 as i8);
+    let len = haystack.len();
+    let loop_size = cmp::min(LOOP_SIZE2, len);
+    let start_ptr = haystack.as_ptr();
+    let end_ptr = haystack[haystack.len()..].as_ptr();
+    let mut ptr = end_ptr;
+
+    if haystack.len() < VECTOR_SIZE {
+        while ptr > start_ptr {
+            ptr = ptr.offset(-1);
+            if *ptr == n1 || *ptr == n2 || *ptr == n3 {
+                return Some(sub(ptr, start_ptr));
+            }
+        }
+        return None;
+    }
+
+    ptr = ptr.sub(VECTOR_SIZE);
+    if let Some(i) = reverse_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3) {
+        return Some(i);
+    }
+
+    ptr = (end_ptr as usize & !VECTOR_ALIGN) as *const u8;
+    debug_assert!(start_ptr <= ptr && ptr <= end_ptr);
+    while loop_size == LOOP_SIZE2 && ptr >= start_ptr.add(loop_size) {
+        debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE);
+
+        ptr = ptr.sub(loop_size);
+        let a = _mm_load_si128(ptr as *const __m128i);
+        let b = _mm_load_si128(ptr.add(VECTOR_SIZE) as *const __m128i);
+        let eqa1 = _mm_cmpeq_epi8(vn1, a);
+        let eqb1 = _mm_cmpeq_epi8(vn1, b);
+        let eqa2 = _mm_cmpeq_epi8(vn2, a);
+        let eqb2 = _mm_cmpeq_epi8(vn2, b);
+        let eqa3 = _mm_cmpeq_epi8(vn3, a);
+        let eqb3 = _mm_cmpeq_epi8(vn3, b);
+        let or1 = _mm_or_si128(eqa1, eqb1);
+        let or2 = _mm_or_si128(eqa2, eqb2);
+        let or3 = _mm_or_si128(eqa3, eqb3);
+        let or4 = _mm_or_si128(or1, or2);
+        let or5 = _mm_or_si128(or3, or4);
+        if _mm_movemask_epi8(or5) != 0 {
+            let mut at = sub(ptr.add(VECTOR_SIZE), start_ptr);
+            let mask1 = _mm_movemask_epi8(eqb1);
+            let mask2 = _mm_movemask_epi8(eqb2);
+            let mask3 = _mm_movemask_epi8(eqb3);
+            if mask1 != 0 || mask2 != 0 || mask3 != 0 {
+                return Some(at + reverse_pos3(mask1, mask2, mask3));
+            }
+
+            at -= VECTOR_SIZE;
+            let mask1 = _mm_movemask_epi8(eqa1);
+            let mask2 = _mm_movemask_epi8(eqa2);
+            let mask3 = _mm_movemask_epi8(eqa3);
+            return Some(at + reverse_pos3(mask1, mask2, mask3));
+        }
+    }
+    while ptr >= start_ptr.add(VECTOR_SIZE) {
+        ptr = ptr.sub(VECTOR_SIZE);
+        if let Some(i) = reverse_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3) {
+            return Some(i);
+        }
+    }
+    if ptr > start_ptr {
+        debug_assert!(sub(ptr, start_ptr) < VECTOR_SIZE);
+        return reverse_search3(start_ptr, end_ptr, start_ptr, vn1, vn2, vn3);
+    }
+    None
+}
+
+#[target_feature(enable = "sse2")]
+pub unsafe fn forward_search1(
+    start_ptr: *const u8,
+    end_ptr: *const u8,
+    ptr: *const u8,
+    vn1: __m128i,
+) -> Option<usize> {
+    debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE);
+    debug_assert!(start_ptr <= ptr);
+    debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE));
+
+    let chunk = _mm_loadu_si128(ptr as *const __m128i);
+    let mask = _mm_movemask_epi8(_mm_cmpeq_epi8(chunk, vn1));
+    if mask != 0 {
+        Some(sub(ptr, start_ptr) + forward_pos(mask))
+    } else {
+        None
+    }
+}
+
+#[target_feature(enable = "sse2")]
+unsafe fn forward_search2(
+    start_ptr: *const u8,
+    end_ptr: *const u8,
+    ptr: *const u8,
+    vn1: __m128i,
+    vn2: __m128i,
+) -> Option<usize> {
+    debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE);
+    debug_assert!(start_ptr <= ptr);
+    debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE));
+
+    let chunk = _mm_loadu_si128(ptr as *const __m128i);
+    let eq1 = _mm_cmpeq_epi8(chunk, vn1);
+    let eq2 = _mm_cmpeq_epi8(chunk, vn2);
+    if _mm_movemask_epi8(_mm_or_si128(eq1, eq2)) != 0 {
+        let mask1 = _mm_movemask_epi8(eq1);
+        let mask2 = _mm_movemask_epi8(eq2);
+        Some(sub(ptr, start_ptr) + forward_pos2(mask1, mask2))
+    } else {
+        None
+    }
+}
+
+#[target_feature(enable = "sse2")]
+pub unsafe fn forward_search3(
+    start_ptr: *const u8,
+    end_ptr: *const u8,
+    ptr: *const u8,
+    vn1: __m128i,
+    vn2: __m128i,
+    vn3: __m128i,
+) -> Option<usize> {
+    debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE);
+    debug_assert!(start_ptr <= ptr);
+    debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE));
+
+    let chunk = _mm_loadu_si128(ptr as *const __m128i);
+    let eq1 = _mm_cmpeq_epi8(chunk, vn1);
+    let eq2 = _mm_cmpeq_epi8(chunk, vn2);
+    let eq3 = _mm_cmpeq_epi8(chunk, vn3);
+    let or = _mm_or_si128(eq1, eq2);
+    if _mm_movemask_epi8(_mm_or_si128(or, eq3)) != 0 {
+        let mask1 = _mm_movemask_epi8(eq1);
+        let mask2 = _mm_movemask_epi8(eq2);
+        let mask3 = _mm_movemask_epi8(eq3);
+        Some(sub(ptr, start_ptr) + forward_pos3(mask1, mask2, mask3))
+    } else {
+        None
+    }
+}
+
+#[target_feature(enable = "sse2")]
+unsafe fn reverse_search1(
+    start_ptr: *const u8,
+    end_ptr: *const u8,
+    ptr: *const u8,
+    vn1: __m128i,
+) -> Option<usize> {
+    debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE);
+    debug_assert!(start_ptr <= ptr);
+    debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE));
+
+    let chunk = _mm_loadu_si128(ptr as *const __m128i);
+    let mask = _mm_movemask_epi8(_mm_cmpeq_epi8(vn1, chunk));
+    if mask != 0 {
+        Some(sub(ptr, start_ptr) + reverse_pos(mask))
+    } else {
+        None
+    }
+}
+
+#[target_feature(enable = "sse2")]
+unsafe fn reverse_search2(
+    start_ptr: *const u8,
+    end_ptr: *const u8,
+    ptr: *const u8,
+    vn1: __m128i,
+    vn2: __m128i,
+) -> Option<usize> {
+    debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE);
+    debug_assert!(start_ptr <= ptr);
+    debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE));
+
+    let chunk = _mm_loadu_si128(ptr as *const __m128i);
+    let eq1 = _mm_cmpeq_epi8(chunk, vn1);
+    let eq2 = _mm_cmpeq_epi8(chunk, vn2);
+    if _mm_movemask_epi8(_mm_or_si128(eq1, eq2)) != 0 {
+        let mask1 = _mm_movemask_epi8(eq1);
+        let mask2 = _mm_movemask_epi8(eq2);
+        Some(sub(ptr, start_ptr) + reverse_pos2(mask1, mask2))
+    } else {
+        None
+    }
+}
+
+#[target_feature(enable = "sse2")]
+unsafe fn reverse_search3(
+    start_ptr: *const u8,
+    end_ptr: *const u8,
+    ptr: *const u8,
+    vn1: __m128i,
+    vn2: __m128i,
+    vn3: __m128i,
+) -> Option<usize> {
+    debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE);
+    debug_assert!(start_ptr <= ptr);
+    debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE));
+
+    let chunk = _mm_loadu_si128(ptr as *const __m128i);
+    let eq1 = _mm_cmpeq_epi8(chunk, vn1);
+    let eq2 = _mm_cmpeq_epi8(chunk, vn2);
+    let eq3 = _mm_cmpeq_epi8(chunk, vn3);
+    let or = _mm_or_si128(eq1, eq2);
+    if _mm_movemask_epi8(_mm_or_si128(or, eq3)) != 0 {
+        let mask1 = _mm_movemask_epi8(eq1);
+        let mask2 = _mm_movemask_epi8(eq2);
+        let mask3 = _mm_movemask_epi8(eq3);
+        Some(sub(ptr, start_ptr) + reverse_pos3(mask1, mask2, mask3))
+    } else {
+        None
+    }
+}
+
+/// Compute the position of the first matching byte from the given mask. The
+/// position returned is always in the range [0, 15].
+///
+/// The mask given is expected to be the result of _mm_movemask_epi8.
+fn forward_pos(mask: i32) -> usize {
+    // We are dealing with little endian here, where the most significant byte
+    // is at a higher address. That means the least significant bit that is set
+    // corresponds to the position of our first matching byte. That position
+    // corresponds to the number of zeros after the least significant bit.
+    mask.trailing_zeros() as usize
+}
+
+/// Compute the position of the first matching byte from the given masks. The
+/// position returned is always in the range [0, 15]. Each mask corresponds to
+/// the equality comparison of a single byte.
+///
+/// The masks given are expected to be the result of _mm_movemask_epi8, where
+/// at least one of the masks is non-zero (i.e., indicates a match).
+fn forward_pos2(mask1: i32, mask2: i32) -> usize {
+    debug_assert!(mask1 != 0 || mask2 != 0);
+
+    forward_pos(mask1 | mask2)
+}
+
+/// Compute the position of the first matching byte from the given masks. The
+/// position returned is always in the range [0, 15]. Each mask corresponds to
+/// the equality comparison of a single byte.
+///
+/// The masks given are expected to be the result of _mm_movemask_epi8, where
+/// at least one of the masks is non-zero (i.e., indicates a match).
+fn forward_pos3(mask1: i32, mask2: i32, mask3: i32) -> usize {
+    debug_assert!(mask1 != 0 || mask2 != 0 || mask3 != 0);
+
+    forward_pos(mask1 | mask2 | mask3)
+}
+
+/// Compute the position of the last matching byte from the given mask. The
+/// position returned is always in the range [0, 15].
+///
+/// The mask given is expected to be the result of _mm_movemask_epi8.
+fn reverse_pos(mask: i32) -> usize {
+    // We are dealing with little endian here, where the most significant byte
+    // is at a higher address. That means the most significant bit that is set
+    // corresponds to the position of our last matching byte. The position from
+    // the end of the mask is therefore the number of leading zeros in a 16
+    // bit integer, and the position from the start of the mask is therefore
+    // 16 - (leading zeros) - 1.
+    VECTOR_SIZE - (mask as u16).leading_zeros() as usize - 1
+}
+
+/// Compute the position of the last matching byte from the given masks. The
+/// position returned is always in the range [0, 15]. Each mask corresponds to
+/// the equality comparison of a single byte.
+///
+/// The masks given are expected to be the result of _mm_movemask_epi8, where
+/// at least one of the masks is non-zero (i.e., indicates a match).
+fn reverse_pos2(mask1: i32, mask2: i32) -> usize {
+    debug_assert!(mask1 != 0 || mask2 != 0);
+
+    reverse_pos(mask1 | mask2)
+}
+
+/// Compute the position of the last matching byte from the given masks. The
+/// position returned is always in the range [0, 15]. Each mask corresponds to
+/// the equality comparison of a single byte.
+///
+/// The masks given are expected to be the result of _mm_movemask_epi8, where
+/// at least one of the masks is non-zero (i.e., indicates a match).
+fn reverse_pos3(mask1: i32, mask2: i32, mask3: i32) -> usize {
+    debug_assert!(mask1 != 0 || mask2 != 0 || mask3 != 0);
+
+    reverse_pos(mask1 | mask2 | mask3)
+}
+
+/// Subtract `b` from `a` and return the difference. `a` should be greater than
+/// or equal to `b`.
+fn sub(a: *const u8, b: *const u8) -> usize {
+    debug_assert!(a >= b);
+    (a as usize) - (b as usize)
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/owoify/lib.rs.html b/target/doc/src/owoify/lib.rs.html new file mode 100644 index 0000000..21c415c --- /dev/null +++ b/target/doc/src/owoify/lib.rs.html @@ -0,0 +1,119 @@ +lib.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+
+use rand::prelude::*;
+use regex::Regex;
+use std::str::FromStr;
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    #[test]
+    fn owo() {
+        let text = String::from("malfunction me mom.. t-till i break~~");
+        let owoified = text.owoify();
+        println!("\t\t{}", owoified);
+    }
+    #[test]
+    fn all_match_owo() {
+        let text = String::from("r l R L na Na NA ove !!");
+        println!("\t\t{}", text.owoify());
+    }
+}
+
+pub trait OwOifiable {
+    /// The owoification method
+    fn owoify(&self) -> Self;
+}
+
+impl OwOifiable for String {
+    /// Owoifies a String
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use use owoify::OwOifiable;
+    /// let owoified = String::from("Example text").owoify();
+    /// ```
+    fn owoify(&self) -> Self {
+        let mut rng = rand::thread_rng();
+        let faces = ["(・`ω´・)", "OwO", "owo", "oωo", "òωó", "°ω°", "UwU", ">w<", "^w^"];
+        let face = &format!(" {} ", faces[rng.gen_range(0, faces.len())]).to_owned();
+        let pats: Vec<(&str, &str)> = vec![
+            ("(?:r|l)", "w"),
+            ("(?:R|L)", "W"),
+            ("n([aeiou])", "ny$1"),
+            ("N([aeiou])", "Ny$1"),
+            ("N([AEIOU])", "Ny$1"),
+            ("ove", "uv"),
+            ("!+", face),
+        ];
+
+        let mut owoified = String::from_str(&self).unwrap();
+
+        for &(f, t) in &pats {
+            let re = Regex::new(f).unwrap();
+            owoified = re.replace_all(&owoified, t).to_string();
+        }
+
+        owoified
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/ppv_lite86/lib.rs.html b/target/doc/src/ppv_lite86/lib.rs.html new file mode 100644 index 0000000..011b9ec --- /dev/null +++ b/target/doc/src/ppv_lite86/lib.rs.html @@ -0,0 +1,47 @@ +lib.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+
+#![no_std]
+
+// Design:
+// - safety: safe creation of any machine type is done only by instance methods of a
+//   Machine (which is a ZST + Copy type), which can only by created unsafely or safely
+//   through feature detection (e.g. fn AVX2::try_get() -> Option<Machine>).
+
+mod soft;
+mod types;
+pub use self::types::*;
+
+#[cfg(all(feature = "simd", target_arch = "x86_64", not(miri)))]
+pub mod x86_64;
+#[cfg(all(feature = "simd", target_arch = "x86_64", not(miri)))]
+use self::x86_64 as arch;
+
+#[cfg(any(miri, not(all(feature = "simd", any(target_arch = "x86_64")))))]
+pub mod generic;
+#[cfg(any(miri, not(all(feature = "simd", any(target_arch = "x86_64")))))]
+use self::generic as arch;
+
+pub use self::arch::{vec128_storage, vec256_storage, vec512_storage};
+
+
\ No newline at end of file diff --git a/target/doc/src/ppv_lite86/soft.rs.html b/target/doc/src/ppv_lite86/soft.rs.html new file mode 100644 index 0000000..5d68347 --- /dev/null +++ b/target/doc/src/ppv_lite86/soft.rs.html @@ -0,0 +1,843 @@ +soft.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+
+//! Implement 256- and 512- bit in terms of 128-bit, for machines without native wide SIMD.
+
+use core::marker::PhantomData;
+use core::ops::*;
+use crate::types::*;
+use crate::{vec128_storage, vec256_storage, vec512_storage};
+
+#[derive(Copy, Clone, Default)]
+#[allow(non_camel_case_types)]
+pub struct x2<W, G>(pub [W; 2], PhantomData<G>);
+impl<W, G> x2<W, G> {
+    #[inline(always)]
+    pub fn new(xs: [W; 2]) -> Self {
+        x2(xs, PhantomData)
+    }
+}
+macro_rules! fwd_binop_x2 {
+    ($trait:ident, $fn:ident) => {
+        impl<W: $trait + Copy, G> $trait for x2<W, G> {
+            type Output = x2<W::Output, G>;
+            #[inline(always)]
+            fn $fn(self, rhs: Self) -> Self::Output {
+                x2::new([self.0[0].$fn(rhs.0[0]), self.0[1].$fn(rhs.0[1])])
+            }
+        }
+    };
+}
+macro_rules! fwd_binop_assign_x2 {
+    ($trait:ident, $fn_assign:ident) => {
+        impl<W: $trait + Copy, G> $trait for x2<W, G> {
+            #[inline(always)]
+            fn $fn_assign(&mut self, rhs: Self) {
+                (self.0[0]).$fn_assign(rhs.0[0]);
+                (self.0[1]).$fn_assign(rhs.0[1]);
+            }
+        }
+    };
+}
+macro_rules! fwd_unop_x2 {
+    ($fn:ident) => {
+        #[inline(always)]
+        fn $fn(self) -> Self {
+            x2::new([self.0[0].$fn(), self.0[1].$fn()])
+        }
+    };
+}
+impl<W, G> RotateEachWord32 for x2<W, G>
+where
+    W: Copy + RotateEachWord32,
+{
+    fwd_unop_x2!(rotate_each_word_right7);
+    fwd_unop_x2!(rotate_each_word_right8);
+    fwd_unop_x2!(rotate_each_word_right11);
+    fwd_unop_x2!(rotate_each_word_right12);
+    fwd_unop_x2!(rotate_each_word_right16);
+    fwd_unop_x2!(rotate_each_word_right20);
+    fwd_unop_x2!(rotate_each_word_right24);
+    fwd_unop_x2!(rotate_each_word_right25);
+}
+impl<W, G> RotateEachWord64 for x2<W, G>
+where
+    W: Copy + RotateEachWord64,
+{
+    fwd_unop_x2!(rotate_each_word_right32);
+}
+impl<W, G> RotateEachWord128 for x2<W, G> where W: RotateEachWord128 {}
+impl<W, G> BitOps0 for x2<W, G>
+where
+    W: BitOps0,
+    G: Copy,
+{
+}
+impl<W, G> BitOps32 for x2<W, G>
+where
+    W: BitOps32 + BitOps0,
+    G: Copy,
+{
+}
+impl<W, G> BitOps64 for x2<W, G>
+where
+    W: BitOps64 + BitOps0,
+    G: Copy,
+{
+}
+impl<W, G> BitOps128 for x2<W, G>
+where
+    W: BitOps128 + BitOps0,
+    G: Copy,
+{
+}
+fwd_binop_x2!(BitAnd, bitand);
+fwd_binop_x2!(BitOr, bitor);
+fwd_binop_x2!(BitXor, bitxor);
+fwd_binop_x2!(AndNot, andnot);
+fwd_binop_assign_x2!(BitAndAssign, bitand_assign);
+fwd_binop_assign_x2!(BitOrAssign, bitor_assign);
+fwd_binop_assign_x2!(BitXorAssign, bitxor_assign);
+impl<W, G> ArithOps for x2<W, G>
+where
+    W: ArithOps,
+    G: Copy,
+{
+}
+fwd_binop_x2!(Add, add);
+fwd_binop_assign_x2!(AddAssign, add_assign);
+impl<W: Not + Copy, G> Not for x2<W, G> {
+    type Output = x2<W::Output, G>;
+    #[inline(always)]
+    fn not(self) -> Self::Output {
+        x2::new([self.0[0].not(), self.0[1].not()])
+    }
+}
+impl<W, G> UnsafeFrom<[W; 2]> for x2<W, G> {
+    #[inline(always)]
+    unsafe fn unsafe_from(xs: [W; 2]) -> Self {
+        x2::new(xs)
+    }
+}
+impl<W: Copy, G> Vec2<W> for x2<W, G> {
+    #[inline(always)]
+    fn extract(self, i: u32) -> W {
+        self.0[i as usize]
+    }
+    #[inline(always)]
+    fn insert(mut self, w: W, i: u32) -> Self {
+        self.0[i as usize] = w;
+        self
+    }
+}
+impl<W: Copy + Store<vec128_storage>, G> Store<vec256_storage> for x2<W, G> {
+    #[inline(always)]
+    unsafe fn unpack(p: vec256_storage) -> Self {
+        let p = p.split128();
+        x2::new([W::unpack(p[0]), W::unpack(p[1])])
+    }
+}
+impl<W, G> From<x2<W, G>> for vec256_storage
+where
+    W: Copy,
+    vec128_storage: From<W>,
+{
+    #[inline(always)]
+    fn from(x: x2<W, G>) -> Self {
+        vec256_storage::new128([x.0[0].into(), x.0[1].into()])
+    }
+}
+impl<W, G> Swap64 for x2<W, G>
+where
+    W: Swap64 + Copy,
+{
+    fwd_unop_x2!(swap1);
+    fwd_unop_x2!(swap2);
+    fwd_unop_x2!(swap4);
+    fwd_unop_x2!(swap8);
+    fwd_unop_x2!(swap16);
+    fwd_unop_x2!(swap32);
+    fwd_unop_x2!(swap64);
+}
+impl<W: Copy, G> MultiLane<[W; 2]> for x2<W, G> {
+    #[inline(always)]
+    fn to_lanes(self) -> [W; 2] {
+        self.0
+    }
+    #[inline(always)]
+    fn from_lanes(lanes: [W; 2]) -> Self {
+        x2::new(lanes)
+    }
+}
+impl<W: BSwap + Copy, G> BSwap for x2<W, G> {
+    #[inline(always)]
+    fn bswap(self) -> Self {
+        x2::new([self.0[0].bswap(), self.0[1].bswap()])
+    }
+}
+impl<W: StoreBytes + BSwap + Copy, G> StoreBytes for x2<W, G> {
+    #[inline(always)]
+    unsafe fn unsafe_read_le(input: &[u8]) -> Self {
+        let input = input.split_at(16);
+        x2::new([W::unsafe_read_le(input.0), W::unsafe_read_le(input.1)])
+    }
+    #[inline(always)]
+    unsafe fn unsafe_read_be(input: &[u8]) -> Self {
+        x2::unsafe_read_le(input).bswap()
+    }
+    #[inline(always)]
+    fn write_le(self, out: &mut [u8]) {
+        let out = out.split_at_mut(16);
+        self.0[0].write_le(out.0);
+        self.0[1].write_le(out.1);
+    }
+    #[inline(always)]
+    fn write_be(self, out: &mut [u8]) {
+        let out = out.split_at_mut(16);
+        self.0[0].write_be(out.0);
+        self.0[1].write_be(out.1);
+    }
+}
+
+#[derive(Copy, Clone, Default)]
+#[allow(non_camel_case_types)]
+pub struct x4<W>(pub [W; 4]);
+impl<W> x4<W> {
+    #[inline(always)]
+    pub fn new(xs: [W; 4]) -> Self {
+        x4(xs)
+    }
+}
+macro_rules! fwd_binop_x4 {
+    ($trait:ident, $fn:ident) => {
+        impl<W: $trait + Copy> $trait for x4<W> {
+            type Output = x4<W::Output>;
+            #[inline(always)]
+            fn $fn(self, rhs: Self) -> Self::Output {
+                x4([
+                    self.0[0].$fn(rhs.0[0]),
+                    self.0[1].$fn(rhs.0[1]),
+                    self.0[2].$fn(rhs.0[2]),
+                    self.0[3].$fn(rhs.0[3]),
+                ])
+            }
+        }
+    };
+}
+macro_rules! fwd_binop_assign_x4 {
+    ($trait:ident, $fn_assign:ident) => {
+        impl<W: $trait + Copy> $trait for x4<W> {
+            #[inline(always)]
+            fn $fn_assign(&mut self, rhs: Self) {
+                self.0[0].$fn_assign(rhs.0[0]);
+                self.0[1].$fn_assign(rhs.0[1]);
+                self.0[2].$fn_assign(rhs.0[2]);
+                self.0[3].$fn_assign(rhs.0[3]);
+            }
+        }
+    };
+}
+macro_rules! fwd_unop_x4 {
+    ($fn:ident) => {
+        #[inline(always)]
+        fn $fn(self) -> Self {
+            x4([self.0[0].$fn(), self.0[1].$fn(), self.0[2].$fn(), self.0[3].$fn()])
+        }
+    };
+}
+impl<W> RotateEachWord32 for x4<W>
+where
+    W: Copy + RotateEachWord32,
+{
+    fwd_unop_x4!(rotate_each_word_right7);
+    fwd_unop_x4!(rotate_each_word_right8);
+    fwd_unop_x4!(rotate_each_word_right11);
+    fwd_unop_x4!(rotate_each_word_right12);
+    fwd_unop_x4!(rotate_each_word_right16);
+    fwd_unop_x4!(rotate_each_word_right20);
+    fwd_unop_x4!(rotate_each_word_right24);
+    fwd_unop_x4!(rotate_each_word_right25);
+}
+impl<W> RotateEachWord64 for x4<W>
+where
+    W: Copy + RotateEachWord64,
+{
+    fwd_unop_x4!(rotate_each_word_right32);
+}
+impl<W> RotateEachWord128 for x4<W> where W: RotateEachWord128 {}
+impl<W> BitOps0 for x4<W> where W: BitOps0 {}
+impl<W> BitOps32 for x4<W> where W: BitOps32 + BitOps0 {}
+impl<W> BitOps64 for x4<W> where W: BitOps64 + BitOps0 {}
+impl<W> BitOps128 for x4<W> where W: BitOps128 + BitOps0 {}
+fwd_binop_x4!(BitAnd, bitand);
+fwd_binop_x4!(BitOr, bitor);
+fwd_binop_x4!(BitXor, bitxor);
+fwd_binop_x4!(AndNot, andnot);
+fwd_binop_assign_x4!(BitAndAssign, bitand_assign);
+fwd_binop_assign_x4!(BitOrAssign, bitor_assign);
+fwd_binop_assign_x4!(BitXorAssign, bitxor_assign);
+impl<W> ArithOps for x4<W> where W: ArithOps {}
+fwd_binop_x4!(Add, add);
+fwd_binop_assign_x4!(AddAssign, add_assign);
+impl<W: Not + Copy> Not for x4<W> {
+    type Output = x4<W::Output>;
+    #[inline(always)]
+    fn not(self) -> Self::Output {
+        x4([
+            self.0[0].not(),
+            self.0[1].not(),
+            self.0[2].not(),
+            self.0[3].not(),
+        ])
+    }
+}
+impl<W> UnsafeFrom<[W; 4]> for x4<W> {
+    #[inline(always)]
+    unsafe fn unsafe_from(xs: [W; 4]) -> Self {
+        x4(xs)
+    }
+}
+impl<W: Copy> Vec4<W> for x4<W> {
+    #[inline(always)]
+    fn extract(self, i: u32) -> W {
+        self.0[i as usize]
+    }
+    #[inline(always)]
+    fn insert(mut self, w: W, i: u32) -> Self {
+        self.0[i as usize] = w;
+        self
+    }
+}
+impl<W: Copy + Store<vec128_storage>> Store<vec512_storage> for x4<W> {
+    #[inline(always)]
+    unsafe fn unpack(p: vec512_storage) -> Self {
+        let p = p.split128();
+        x4([
+            W::unpack(p[0]),
+            W::unpack(p[1]),
+            W::unpack(p[2]),
+            W::unpack(p[3]),
+        ])
+    }
+}
+impl<W> From<x4<W>> for vec512_storage
+where
+    W: Copy,
+    vec128_storage: From<W>,
+{
+    #[inline(always)]
+    fn from(x: x4<W>) -> Self {
+        vec512_storage::new128([x.0[0].into(), x.0[1].into(), x.0[2].into(), x.0[3].into()])
+    }
+}
+impl<W> Swap64 for x4<W>
+where
+    W: Swap64 + Copy,
+{
+    fwd_unop_x4!(swap1);
+    fwd_unop_x4!(swap2);
+    fwd_unop_x4!(swap4);
+    fwd_unop_x4!(swap8);
+    fwd_unop_x4!(swap16);
+    fwd_unop_x4!(swap32);
+    fwd_unop_x4!(swap64);
+}
+impl<W: Copy> MultiLane<[W; 4]> for x4<W> {
+    #[inline(always)]
+    fn to_lanes(self) -> [W; 4] {
+        self.0
+    }
+    #[inline(always)]
+    fn from_lanes(lanes: [W; 4]) -> Self {
+        x4(lanes)
+    }
+}
+impl<W: BSwap + Copy> BSwap for x4<W> {
+    #[inline(always)]
+    fn bswap(self) -> Self {
+        x4([
+            self.0[0].bswap(),
+            self.0[1].bswap(),
+            self.0[2].bswap(),
+            self.0[3].bswap(),
+        ])
+    }
+}
+impl<W: StoreBytes + BSwap + Copy> StoreBytes for x4<W> {
+    #[inline(always)]
+    unsafe fn unsafe_read_le(input: &[u8]) -> Self {
+        x4([
+            W::unsafe_read_le(&input[0..16]),
+            W::unsafe_read_le(&input[16..32]),
+            W::unsafe_read_le(&input[32..48]),
+            W::unsafe_read_le(&input[48..64]),
+        ])
+    }
+    #[inline(always)]
+    unsafe fn unsafe_read_be(input: &[u8]) -> Self {
+        x4::unsafe_read_le(input).bswap()
+    }
+    #[inline(always)]
+    fn write_le(self, out: &mut [u8]) {
+        self.0[0].write_le(&mut out[0..16]);
+        self.0[1].write_le(&mut out[16..32]);
+        self.0[2].write_le(&mut out[32..48]);
+        self.0[3].write_le(&mut out[48..64]);
+    }
+    #[inline(always)]
+    fn write_be(self, out: &mut [u8]) {
+        self.0[0].write_be(&mut out[0..16]);
+        self.0[1].write_be(&mut out[16..32]);
+        self.0[2].write_be(&mut out[32..48]);
+        self.0[3].write_be(&mut out[48..64]);
+    }
+}
+impl<W: Copy + LaneWords4> LaneWords4 for x4<W> {
+    #[inline(always)]
+    fn shuffle_lane_words2301(self) -> Self {
+        x4([
+            self.0[0].shuffle_lane_words2301(),
+            self.0[1].shuffle_lane_words2301(),
+            self.0[2].shuffle_lane_words2301(),
+            self.0[3].shuffle_lane_words2301(),
+        ])
+    }
+    #[inline(always)]
+    fn shuffle_lane_words1230(self) -> Self {
+        x4([
+            self.0[0].shuffle_lane_words1230(),
+            self.0[1].shuffle_lane_words1230(),
+            self.0[2].shuffle_lane_words1230(),
+            self.0[3].shuffle_lane_words1230(),
+        ])
+    }
+    #[inline(always)]
+    fn shuffle_lane_words3012(self) -> Self {
+        x4([
+            self.0[0].shuffle_lane_words3012(),
+            self.0[1].shuffle_lane_words3012(),
+            self.0[2].shuffle_lane_words3012(),
+            self.0[3].shuffle_lane_words3012(),
+        ])
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/ppv_lite86/types.rs.html b/target/doc/src/ppv_lite86/types.rs.html new file mode 100644 index 0000000..b569227 --- /dev/null +++ b/target/doc/src/ppv_lite86/types.rs.html @@ -0,0 +1,561 @@ +types.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+
+use core::ops::{Add, AddAssign, BitAnd, BitOr, BitXor, BitXorAssign, Not};
+
+pub trait AndNot {
+    type Output;
+    fn andnot(self, rhs: Self) -> Self::Output;
+}
+pub trait BSwap {
+    fn bswap(self) -> Self;
+}
+/// Ops that depend on word size
+pub trait ArithOps: Add<Output = Self> + AddAssign + Sized + Copy + Clone + BSwap {}
+/// Ops that are independent of word size and endian
+pub trait BitOps0:
+    BitAnd<Output = Self>
+    + BitOr<Output = Self>
+    + BitXor<Output = Self>
+    + BitXorAssign
+    + Not<Output = Self>
+    + AndNot<Output = Self>
+    + Sized
+    + Copy
+    + Clone
+{
+}
+
+pub trait BitOps32: BitOps0 + RotateEachWord32 {}
+pub trait BitOps64: BitOps32 + RotateEachWord64 {}
+pub trait BitOps128: BitOps64 + RotateEachWord128 {}
+
+pub trait RotateEachWord32 {
+    fn rotate_each_word_right7(self) -> Self;
+    fn rotate_each_word_right8(self) -> Self;
+    fn rotate_each_word_right11(self) -> Self;
+    fn rotate_each_word_right12(self) -> Self;
+    fn rotate_each_word_right16(self) -> Self;
+    fn rotate_each_word_right20(self) -> Self;
+    fn rotate_each_word_right24(self) -> Self;
+    fn rotate_each_word_right25(self) -> Self;
+}
+
+pub trait RotateEachWord64 {
+    fn rotate_each_word_right32(self) -> Self;
+}
+
+pub trait RotateEachWord128 {}
+
+#[allow(non_camel_case_types)]
+mod types {
+    //! Vector type naming scheme:
+    //! uN[xP]xL
+    //! Unsigned; N-bit words * P bits per lane * L lanes
+    //!
+    //! A lane is always 128-bits, chosen because common SIMD architectures treat 128-bit units of
+    //! wide vectors specially (supporting e.g. intra-lane shuffles), and tend to have limited and
+    //! slow inter-lane operations.
+
+    use crate::arch::{vec128_storage, vec256_storage, vec512_storage};
+    use crate::{ArithOps, BitOps128, BitOps32, BitOps64, Machine, Store, StoreBytes};
+
+    pub trait UnsafeFrom<T> {
+        unsafe fn unsafe_from(t: T) -> Self;
+    }
+
+    /// A vector composed of two elements, which may be words or themselves vectors.
+    pub trait Vec2<W> {
+        fn extract(self, i: u32) -> W;
+        fn insert(self, w: W, i: u32) -> Self;
+    }
+
+    /// A vector composed of four elements, which may be words or themselves vectors.
+    pub trait Vec4<W> {
+        fn extract(self, i: u32) -> W;
+        fn insert(self, w: W, i: u32) -> Self;
+    }
+
+    // TODO: multiples of 4 should inherit this
+    /// A vector composed of four words; depending on their size, operations may cross lanes.
+    pub trait Words4 {
+        fn shuffle1230(self) -> Self;
+        fn shuffle2301(self) -> Self;
+        fn shuffle3012(self) -> Self;
+    }
+
+    /// A vector composed one or more lanes each composed of four words.
+    pub trait LaneWords4 {
+        fn shuffle_lane_words1230(self) -> Self;
+        fn shuffle_lane_words2301(self) -> Self;
+        fn shuffle_lane_words3012(self) -> Self;
+    }
+
+    // TODO: make this a part of BitOps
+    /// Exchange neigboring ranges of bits of the specified size
+    pub trait Swap64 {
+        fn swap1(self) -> Self;
+        fn swap2(self) -> Self;
+        fn swap4(self) -> Self;
+        fn swap8(self) -> Self;
+        fn swap16(self) -> Self;
+        fn swap32(self) -> Self;
+        fn swap64(self) -> Self;
+    }
+
+    pub trait u32x4<M: Machine>:
+        BitOps32
+        + Store<vec128_storage>
+        + ArithOps
+        + Vec4<u32>
+        + Words4
+        + LaneWords4
+        + StoreBytes
+        + MultiLane<[u32; 4]>
+        + Into<vec128_storage>
+    {
+}
+    pub trait u64x2<M: Machine>:
+        BitOps64
+        + Store<vec128_storage>
+        + ArithOps
+        + Vec2<u64>
+        + MultiLane<[u64; 2]>
+        + Into<vec128_storage>
+    {
+}
+    pub trait u128x1<M: Machine>:
+        BitOps128 + Store<vec128_storage> + Swap64 + MultiLane<[u128; 1]> + Into<vec128_storage>
+    {
+}
+
+    pub trait u32x4x2<M: Machine>:
+        BitOps32
+        + Store<vec256_storage>
+        + Vec2<M::u32x4>
+        + MultiLane<[M::u32x4; 2]>
+        + ArithOps
+        + Into<vec256_storage>
+    {
+}
+    pub trait u64x2x2<M: Machine>:
+        BitOps64
+        + Store<vec256_storage>
+        + Vec2<M::u64x2>
+        + MultiLane<[M::u64x2; 2]>
+        + ArithOps
+        + StoreBytes
+        + Into<vec256_storage>
+    {
+}
+    pub trait u64x4<M: Machine>:
+        BitOps64
+        + Store<vec256_storage>
+        + Vec4<u64>
+        + MultiLane<[u64; 4]>
+        + ArithOps
+        + Words4
+        + StoreBytes
+        + Into<vec256_storage>
+    {
+}
+    pub trait u128x2<M: Machine>:
+        BitOps128
+        + Store<vec256_storage>
+        + Vec2<M::u128x1>
+        + MultiLane<[M::u128x1; 2]>
+        + Swap64
+        + Into<vec256_storage>
+    {
+}
+
+    pub trait u32x4x4<M: Machine>:
+        BitOps32
+        + Store<vec512_storage>
+        + Vec4<M::u32x4>
+        + MultiLane<[M::u32x4; 4]>
+        + ArithOps
+        + LaneWords4
+        + Into<vec512_storage>
+    {
+}
+    pub trait u64x2x4<M: Machine>:
+        BitOps64
+        + Store<vec512_storage>
+        + Vec4<M::u64x2>
+        + MultiLane<[M::u64x2; 4]>
+        + ArithOps
+        + Into<vec512_storage>
+    {
+}
+    // TODO: Words4
+    pub trait u128x4<M: Machine>:
+        BitOps128
+        + Store<vec512_storage>
+        + Vec4<M::u128x1>
+        + MultiLane<[M::u128x1; 4]>
+        + Swap64
+        + Into<vec512_storage>
+    {
+}
+
+    /// A vector composed of multiple 128-bit lanes.
+    pub trait MultiLane<Lanes> {
+        /// Split a multi-lane vector into single-lane vectors.
+        fn to_lanes(self) -> Lanes;
+        /// Build a multi-lane vector from individual lanes.
+        fn from_lanes(lanes: Lanes) -> Self;
+    }
+
+    /// Combine single vectors into a multi-lane vector.
+    pub trait VZip<V> {
+        fn vzip(self) -> V;
+    }
+
+    impl<V, T> VZip<V> for T
+    where
+        V: MultiLane<T>,
+    {
+        #[inline(always)]
+        fn vzip(self) -> V {
+            V::from_lanes(self)
+        }
+    }
+}
+pub use self::types::*;
+
+pub trait Machine: Sized + Copy {
+    type u32x4: u32x4<Self>;
+    type u64x2: u64x2<Self>;
+    type u128x1: u128x1<Self>;
+
+    type u32x4x2: u32x4x2<Self>;
+    type u64x2x2: u64x2x2<Self>;
+    type u64x4: u64x4<Self>;
+    type u128x2: u128x2<Self>;
+
+    type u32x4x4: u32x4x4<Self>;
+    type u64x2x4: u64x2x4<Self>;
+    type u128x4: u128x4<Self>;
+
+    #[inline(always)]
+    fn unpack<S, V: Store<S>>(self, s: S) -> V {
+        unsafe { V::unpack(s) }
+    }
+
+    #[inline(always)]
+    fn vec<V, A>(self, a: A) -> V
+    where
+        V: MultiLane<A>,
+    {
+        V::from_lanes(a)
+    }
+
+    #[inline(always)]
+    fn read_le<V>(self, input: &[u8]) -> V
+    where
+        V: StoreBytes,
+    {
+        unsafe { V::unsafe_read_le(input) }
+    }
+
+    #[inline(always)]
+    fn read_be<V>(self, input: &[u8]) -> V
+    where
+        V: StoreBytes,
+    {
+        unsafe { V::unsafe_read_be(input) }
+    }
+
+    unsafe fn instance() -> Self;
+}
+
+pub trait Store<S> {
+    unsafe fn unpack(p: S) -> Self;
+}
+
+pub trait StoreBytes {
+    unsafe fn unsafe_read_le(input: &[u8]) -> Self;
+    unsafe fn unsafe_read_be(input: &[u8]) -> Self;
+    fn write_le(self, out: &mut [u8]);
+    fn write_be(self, out: &mut [u8]);
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/ppv_lite86/x86_64/mod.rs.html b/target/doc/src/ppv_lite86/x86_64/mod.rs.html new file mode 100644 index 0000000..c4fa573 --- /dev/null +++ b/target/doc/src/ppv_lite86/x86_64/mod.rs.html @@ -0,0 +1,869 @@ +mod.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+
+// crate minimums: sse2, x86_64
+
+use crate::types::*;
+use core::arch::x86_64::{__m128i, __m256i};
+
+mod sse2;
+
+#[derive(Copy, Clone)]
+pub struct YesS3;
+#[derive(Copy, Clone)]
+pub struct NoS3;
+
+#[derive(Copy, Clone)]
+pub struct YesS4;
+#[derive(Copy, Clone)]
+pub struct NoS4;
+
+#[derive(Copy, Clone)]
+pub struct YesA1;
+#[derive(Copy, Clone)]
+pub struct NoA1;
+
+#[derive(Copy, Clone)]
+pub struct YesA2;
+#[derive(Copy, Clone)]
+pub struct NoA2;
+
+#[derive(Copy, Clone)]
+pub struct YesNI;
+#[derive(Copy, Clone)]
+pub struct NoNI;
+
+use core::marker::PhantomData;
+
+#[derive(Copy, Clone)]
+pub struct SseMachine<S3, S4, NI>(PhantomData<(S3, S4, NI)>);
+impl<S3: Copy, S4: Copy, NI: Copy> Machine for SseMachine<S3, S4, NI>
+where
+    sse2::u128x1_sse2<S3, S4, NI>: Swap64,
+    sse2::u64x2_sse2<S3, S4, NI>: BSwap + RotateEachWord32 + MultiLane<[u64; 2]> + Vec2<u64>,
+    sse2::u32x4_sse2<S3, S4, NI>: BSwap + RotateEachWord32 + MultiLane<[u32; 4]> + Vec4<u32>,
+    sse2::u64x4_sse2<S3, S4, NI>: BSwap + Words4,
+    sse2::u128x1_sse2<S3, S4, NI>: BSwap,
+    sse2::u128x2_sse2<S3, S4, NI>: Into<sse2::u64x2x2_sse2<S3, S4, NI>>,
+    sse2::u128x2_sse2<S3, S4, NI>: Into<sse2::u64x4_sse2<S3, S4, NI>>,
+    sse2::u128x2_sse2<S3, S4, NI>: Into<sse2::u32x4x2_sse2<S3, S4, NI>>,
+    sse2::u128x4_sse2<S3, S4, NI>: Into<sse2::u64x2x4_sse2<S3, S4, NI>>,
+    sse2::u128x4_sse2<S3, S4, NI>: Into<sse2::u32x4x4_sse2<S3, S4, NI>>,
+{
+    type u32x4 = sse2::u32x4_sse2<S3, S4, NI>;
+    type u64x2 = sse2::u64x2_sse2<S3, S4, NI>;
+    type u128x1 = sse2::u128x1_sse2<S3, S4, NI>;
+
+    type u32x4x2 = sse2::u32x4x2_sse2<S3, S4, NI>;
+    type u64x2x2 = sse2::u64x2x2_sse2<S3, S4, NI>;
+    type u64x4 = sse2::u64x4_sse2<S3, S4, NI>;
+    type u128x2 = sse2::u128x2_sse2<S3, S4, NI>;
+
+    type u32x4x4 = sse2::u32x4x4_sse2<S3, S4, NI>;
+    type u64x2x4 = sse2::u64x2x4_sse2<S3, S4, NI>;
+    type u128x4 = sse2::u128x4_sse2<S3, S4, NI>;
+
+    #[inline(always)]
+    unsafe fn instance() -> Self {
+        SseMachine(PhantomData)
+    }
+}
+
+#[derive(Copy, Clone)]
+pub struct Avx2Machine<NI>(PhantomData<NI>);
+impl<NI: Copy> Machine for Avx2Machine<NI>
+where
+    sse2::u128x1_sse2<YesS3, YesS4, NI>: BSwap + Swap64,
+    sse2::u64x2_sse2<YesS3, YesS4, NI>: BSwap + RotateEachWord32 + MultiLane<[u64; 2]> + Vec2<u64>,
+    sse2::u32x4_sse2<YesS3, YesS4, NI>: BSwap + RotateEachWord32 + MultiLane<[u32; 4]> + Vec4<u32>,
+    sse2::u64x4_sse2<YesS3, YesS4, NI>: BSwap + Words4,
+{
+    type u32x4 = sse2::u32x4_sse2<YesS3, YesS4, NI>;
+    type u64x2 = sse2::u64x2_sse2<YesS3, YesS4, NI>;
+    type u128x1 = sse2::u128x1_sse2<YesS3, YesS4, NI>;
+
+    type u32x4x2 = sse2::u32x4x2_sse2<YesS3, YesS4, NI>;
+    type u64x2x2 = sse2::u64x2x2_sse2<YesS3, YesS4, NI>;
+    type u64x4 = sse2::u64x4_sse2<YesS3, YesS4, NI>;
+    type u128x2 = sse2::u128x2_sse2<YesS3, YesS4, NI>;
+
+    type u32x4x4 = sse2::avx2::u32x4x4_avx2<NI>;
+    type u64x2x4 = sse2::u64x2x4_sse2<YesS3, YesS4, NI>;
+    type u128x4 = sse2::u128x4_sse2<YesS3, YesS4, NI>;
+
+    #[inline(always)]
+    unsafe fn instance() -> Self {
+        Avx2Machine(PhantomData)
+    }
+}
+
+pub type SSE2 = SseMachine<NoS3, NoS4, NoNI>;
+pub type SSSE3 = SseMachine<YesS3, NoS4, NoNI>;
+pub type SSE41 = SseMachine<YesS3, YesS4, NoNI>;
+/// AVX but not AVX2: only 128-bit integer operations, but use VEX versions of everything
+/// to avoid expensive SSE/VEX conflicts.
+pub type AVX = SseMachine<YesS3, YesS4, NoNI>;
+pub type AVX2 = Avx2Machine<NoNI>;
+
+/// Generic wrapper for unparameterized storage of any of the possible impls.
+/// Converting into and out of this type should be essentially free, although it may be more
+/// aligned than a particular impl requires.
+#[allow(non_camel_case_types)]
+#[derive(Copy, Clone)]
+pub union vec128_storage {
+    u32x4: [u32; 4],
+    u64x2: [u64; 2],
+    u128x1: [u128; 1],
+    sse2: __m128i,
+}
+impl Store<vec128_storage> for vec128_storage {
+    #[inline(always)]
+    unsafe fn unpack(p: vec128_storage) -> Self {
+        p
+    }
+}
+impl<'a> Into<&'a [u32; 4]> for &'a vec128_storage {
+    #[inline(always)]
+    fn into(self) -> &'a [u32; 4] {
+        unsafe { &self.u32x4 }
+    }
+}
+impl Into<vec128_storage> for [u32; 4] {
+    #[inline(always)]
+    fn into(self) -> vec128_storage {
+        vec128_storage { u32x4: self }
+    }
+}
+impl Default for vec128_storage {
+    #[inline(always)]
+    fn default() -> Self {
+        vec128_storage { u128x1: [0] }
+    }
+}
+
+#[allow(non_camel_case_types)]
+#[derive(Copy, Clone)]
+pub union vec256_storage {
+    u32x8: [u32; 8],
+    u64x4: [u64; 4],
+    u128x2: [u128; 2],
+    sse2: [vec128_storage; 2],
+    avx: __m256i,
+}
+impl Into<vec256_storage> for [u64; 4] {
+    #[inline(always)]
+    fn into(self) -> vec256_storage {
+        vec256_storage { u64x4: self }
+    }
+}
+impl Default for vec256_storage {
+    #[inline(always)]
+    fn default() -> Self {
+        vec256_storage { u128x2: [0, 0] }
+    }
+}
+impl vec256_storage {
+    pub fn new128(xs: [vec128_storage; 2]) -> Self {
+        Self { sse2: xs }
+    }
+    pub fn split128(self) -> [vec128_storage; 2] {
+        unsafe { self.sse2 }
+    }
+}
+
+#[allow(non_camel_case_types)]
+#[derive(Copy, Clone)]
+pub union vec512_storage {
+    u32x16: [u32; 16],
+    u64x8: [u64; 8],
+    u128x4: [u128; 4],
+    sse2: [vec128_storage; 4],
+    avx: [vec256_storage; 2],
+}
+impl Default for vec512_storage {
+    #[inline(always)]
+    fn default() -> Self {
+        vec512_storage {
+            u128x4: [0, 0, 0, 0],
+        }
+    }
+}
+impl vec512_storage {
+    pub fn new128(xs: [vec128_storage; 4]) -> Self {
+        Self { sse2: xs }
+    }
+    pub fn split128(self) -> [vec128_storage; 4] {
+        unsafe { self.sse2 }
+    }
+}
+
+macro_rules! impl_into {
+    ($storage:ident, $array:ty, $name:ident) => {
+        impl Into<$array> for $storage {
+            #[inline(always)]
+            fn into(self) -> $array {
+                unsafe { self.$name }
+            }
+        }
+    };
+}
+impl_into!(vec128_storage, [u32; 4], u32x4);
+impl_into!(vec128_storage, [u64; 2], u64x2);
+impl_into!(vec128_storage, [u128; 1], u128x1);
+impl_into!(vec256_storage, [u32; 8], u32x8);
+impl_into!(vec256_storage, [u64; 4], u64x4);
+impl_into!(vec256_storage, [u128; 2], u128x2);
+impl_into!(vec512_storage, [u32; 16], u32x16);
+impl_into!(vec512_storage, [u64; 8], u64x8);
+impl_into!(vec512_storage, [u128; 4], u128x4);
+
+/// Generate the full set of optimized implementations to take advantage of the most important
+/// hardware feature sets.
+///
+/// This dispatcher is suitable for maximizing throughput.
+#[macro_export]
+macro_rules! dispatch {
+    ($mach:ident, $MTy:ident, { $([$pub:tt$(($krate:tt))*])* fn $name:ident($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty $body:block }) => {
+        #[cfg(feature = "std")]
+        #[inline(always)]
+        $($pub$(($krate))*)* fn $name($($arg: $argty),*) -> $ret {
+            #[inline(always)]
+            fn fn_impl<$MTy: $crate::Machine>($mach: $MTy, $($arg: $argty),*) -> $ret $body
+            type FnTy = unsafe fn($($arg: $argty),*) -> $ret;
+            lazy_static! {
+                static ref IMPL: FnTy = { dispatch_init() };
+            }
+            #[cold]
+            fn dispatch_init() -> FnTy {
+                use std::arch::x86_64::*;
+                if is_x86_feature_detected!("avx2") {
+                    #[target_feature(enable = "avx2")]
+                    unsafe fn impl_avx2($($arg: $argty),*) -> $ret {
+                        let ret = fn_impl($crate::x86_64::AVX2::instance(), $($arg),*);
+                        _mm256_zeroupper();
+                        ret
+                    }
+                    impl_avx2
+                } else if is_x86_feature_detected!("avx") {
+                    #[target_feature(enable = "avx")]
+                    #[target_feature(enable = "sse4.1")]
+                    #[target_feature(enable = "ssse3")]
+                    unsafe fn impl_avx($($arg: $argty),*) -> $ret {
+                        let ret = fn_impl($crate::x86_64::AVX::instance(), $($arg),*);
+                        _mm256_zeroupper();
+                        ret
+                    }
+                    impl_avx
+                } else if is_x86_feature_detected!("sse4.1") {
+                    #[target_feature(enable = "sse4.1")]
+                    #[target_feature(enable = "ssse3")]
+                    unsafe fn impl_sse41($($arg: $argty),*) -> $ret {
+                        fn_impl($crate::x86_64::SSE41::instance(), $($arg),*)
+                    }
+                    impl_sse41
+                } else if is_x86_feature_detected!("ssse3") {
+                    #[target_feature(enable = "ssse3")]
+                    unsafe fn impl_ssse3($($arg: $argty),*) -> $ret {
+                        fn_impl($crate::x86_64::SSSE3::instance(), $($arg),*)
+                    }
+                    impl_ssse3
+                } else if is_x86_feature_detected!("sse2") {
+                    #[target_feature(enable = "sse2")]
+                    unsafe fn impl_sse2($($arg: $argty),*) -> $ret {
+                        fn_impl($crate::x86_64::SSE2::instance(), $($arg),*)
+                    }
+                    impl_sse2
+                } else {
+                    unimplemented!()
+                }
+            }
+            unsafe { IMPL($($arg),*) }
+        }
+        #[cfg(not(feature = "std"))]
+        #[inline(always)]
+        $($pub$(($krate))*)* fn $name($($arg: $argty),*) -> $ret {
+            unsafe fn fn_impl<$MTy: $crate::Machine>($mach: $MTy, $($arg: $argty),*) -> $ret $body
+            unsafe {
+                if cfg!(target_feature = "avx2") {
+                    fn_impl($crate::x86_64::AVX2::instance(), $($arg),*)
+                } else if cfg!(target_feature = "avx") {
+                    fn_impl($crate::x86_64::AVX::instance(), $($arg),*)
+                } else if cfg!(target_feature = "sse4.1") {
+                    fn_impl($crate::x86_64::SSE41::instance(), $($arg),*)
+                } else if cfg!(target_feature = "ssse3") {
+                    fn_impl($crate::x86_64::SSSE3::instance(), $($arg),*)
+                } else {
+                    fn_impl($crate::x86_64::SSE2::instance(), $($arg),*)
+                }
+            }
+        }
+    };
+    ($mach:ident, $MTy:ident, { $([$pub:tt $(($krate:tt))*])* fn $name:ident($($arg:ident: $argty:ty),* $(,)*) $body:block }) => {
+        dispatch!($mach, $MTy, {
+            $([$pub $(($krate))*])* fn $name($($arg: $argty),*) -> () $body
+        });
+    }
+}
+
+/// Generate only the basic implementations necessary to be able to operate efficiently on 128-bit
+/// vectors on this platfrom. For x86-64, that would mean SSE2 and AVX.
+///
+/// This dispatcher is suitable for vector operations that do not benefit from advanced hardware
+/// features (e.g. because they are done infrequently), so minimizing their contribution to code
+/// size is more important.
+#[macro_export]
+macro_rules! dispatch_light128 {
+    ($mach:ident, $MTy:ident, { $([$pub:tt$(($krate:tt))*])* fn $name:ident($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty $body:block }) => {
+        #[cfg(feature = "std")]
+        #[inline(always)]
+        $($pub $(($krate))*)* fn $name($($arg: $argty),*) -> $ret {
+            #[inline(always)]
+            fn fn_impl<$MTy: $crate::Machine>($mach: $MTy, $($arg: $argty),*) -> $ret $body
+            type FnTy = unsafe fn($($arg: $argty),*) -> $ret;
+            lazy_static! {
+                static ref IMPL: FnTy = { dispatch_init() };
+            }
+            #[cold]
+            fn dispatch_init() -> FnTy {
+                use std::arch::x86_64::*;
+                if is_x86_feature_detected!("avx") {
+                    #[target_feature(enable = "avx")]
+                    unsafe fn impl_avx($($arg: $argty),*) -> $ret {
+                        fn_impl($crate::x86_64::AVX::instance(), $($arg),*)
+                    }
+                    impl_avx
+                } else if is_x86_feature_detected!("sse2") {
+                    #[target_feature(enable = "sse2")]
+                    unsafe fn impl_sse2($($arg: $argty),*) -> $ret {
+                        fn_impl($crate::x86_64::SSE2::instance(), $($arg),*)
+                    }
+                    impl_sse2
+                } else {
+                    unimplemented!()
+                }
+            }
+            unsafe { IMPL($($arg),*) }
+        }
+        #[cfg(not(feature = "std"))]
+        #[inline(always)]
+        $($pub$(($krate))*)* fn $name($($arg: $argty),*) -> $ret {
+            unsafe fn fn_impl<$MTy: $crate::Machine>($mach: $MTy, $($arg: $argty),*) -> $ret $body
+            unsafe {
+                if cfg!(target_feature = "avx2") {
+                    fn_impl($crate::x86_64::AVX2::instance(), $($arg),*)
+                } else if cfg!(target_feature = "avx") {
+                    fn_impl($crate::x86_64::AVX::instance(), $($arg),*)
+                } else if cfg!(target_feature = "sse4.1") {
+                    fn_impl($crate::x86_64::SSE41::instance(), $($arg),*)
+                } else if cfg!(target_feature = "ssse3") {
+                    fn_impl($crate::x86_64::SSSE3::instance(), $($arg),*)
+                } else {
+                    fn_impl($crate::x86_64::SSE2::instance(), $($arg),*)
+                }
+            }
+        }
+    };
+    ($mach:ident, $MTy:ident, { $([$pub:tt$(($krate:tt))*])* fn $name:ident($($arg:ident: $argty:ty),* $(,)*) $body:block }) => {
+        dispatch_light128!($mach, $MTy, {
+            $([$pub $(($krate))*])* fn $name($($arg: $argty),*) -> () $body
+        });
+    }
+}
+
+/// Generate only the basic implementations necessary to be able to operate efficiently on 256-bit
+/// vectors on this platfrom. For x86-64, that would mean SSE2, AVX, and AVX2.
+///
+/// This dispatcher is suitable for vector operations that do not benefit from advanced hardware
+/// features (e.g. because they are done infrequently), so minimizing their contribution to code
+/// size is more important.
+#[macro_export]
+macro_rules! dispatch_light256 {
+    ($mach:ident, $MTy:ident, { $([$pub:tt$(($krate:tt))*])* fn $name:ident($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty $body:block }) => {
+        #[cfg(feature = "std")]
+        #[inline(always)]
+        $([$pub $(($krate))*])* fn $name($($arg: $argty),*) -> $ret {
+            #[inline(always)]
+            fn fn_impl<$MTy: $crate::Machine>($mach: $MTy, $($arg: $argty),*) -> $ret $body
+            type FnTy = unsafe fn($($arg: $argty),*) -> $ret;
+            lazy_static! {
+                static ref IMPL: FnTy = { dispatch_init() };
+            }
+            #[cold]
+            fn dispatch_init() -> FnTy {
+                use std::arch::x86_64::*;
+                if is_x86_feature_detected!("avx") {
+                    #[target_feature(enable = "avx")]
+                    unsafe fn impl_avx($($arg: $argty),*) -> $ret {
+                        fn_impl($crate::x86_64::AVX::instance(), $($arg),*)
+                    }
+                    impl_avx
+                } else if is_x86_feature_detected!("sse2") {
+                    #[target_feature(enable = "sse2")]
+                    unsafe fn impl_sse2($($arg: $argty),*) -> $ret {
+                        fn_impl($crate::x86_64::SSE2::instance(), $($arg),*)
+                    }
+                    impl_sse2
+                } else {
+                    unimplemented!()
+                }
+            }
+            unsafe { IMPL($($arg),*) }
+        }
+        #[cfg(not(feature = "std"))]
+        #[inline(always)]
+        $($pub$(($krate))*)* fn $name($($arg: $argty),*) -> $ret {
+            unsafe fn fn_impl<$MTy: $crate::Machine>($mach: $MTy, $($arg: $argty),*) -> $ret $body
+            unsafe {
+                if cfg!(target_feature = "avx2") {
+                    fn_impl($crate::x86_64::AVX2::instance(), $($arg),*)
+                } else if cfg!(target_feature = "avx") {
+                    fn_impl($crate::x86_64::AVX::instance(), $($arg),*)
+                } else if cfg!(target_feature = "sse4.1") {
+                    fn_impl($crate::x86_64::SSE41::instance(), $($arg),*)
+                } else if cfg!(target_feature = "ssse3") {
+                    fn_impl($crate::x86_64::SSSE3::instance(), $($arg),*)
+                } else {
+                    fn_impl($crate::x86_64::SSE2::instance(), $($arg),*)
+                }
+            }
+        }
+    };
+    ($mach:ident, $MTy:ident, { $([$pub:tt$(($krate:tt))*])* fn $name:ident($($arg:ident: $argty:ty),* $(,)*) $body:block }) => {
+        dispatch_light128!($mach, $MTy, {
+            $([$pub $(($krate))*])* fn $name($($arg: $argty),*) -> () $body
+        });
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/ppv_lite86/x86_64/sse2.rs.html b/target/doc/src/ppv_lite86/x86_64/sse2.rs.html new file mode 100644 index 0000000..b6bbbe0 --- /dev/null +++ b/target/doc/src/ppv_lite86/x86_64/sse2.rs.html @@ -0,0 +1,3269 @@ +sse2.rs.html -- source
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+
+use crate::soft::{x2, x4};
+use crate::types::*;
+use crate::vec128_storage;
+use crate::x86_64::Avx2Machine;
+use crate::x86_64::SseMachine as Machine86;
+use crate::x86_64::{NoS3, NoS4, YesS3, YesS4};
+use core::arch::x86_64::*;
+use core::marker::PhantomData;
+use core::ops::{
+    Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not,
+};
+
+macro_rules! impl_binop {
+    ($vec:ident, $trait:ident, $fn:ident, $impl_fn:ident) => {
+        impl<S3, S4, NI> $trait for $vec<S3, S4, NI> {
+            type Output = Self;
+            #[inline(always)]
+            fn $fn(self, rhs: Self) -> Self::Output {
+                Self::new(unsafe { $impl_fn(self.x, rhs.x) })
+            }
+        }
+    };
+}
+
+macro_rules! impl_binop_assign {
+    ($vec:ident, $trait:ident, $fn_assign:ident, $fn:ident) => {
+        impl<S3, S4, NI> $trait for $vec<S3, S4, NI>
+        where
+            $vec<S3, S4, NI>: Copy,
+        {
+            #[inline(always)]
+            fn $fn_assign(&mut self, rhs: Self) {
+                *self = self.$fn(rhs);
+            }
+        }
+    };
+}
+
+macro_rules! def_vec {
+    ($vec:ident, $word:ident) => {
+        #[allow(non_camel_case_types)]
+        #[derive(Copy, Clone)]
+        pub struct $vec<S3, S4, NI> {
+            x: __m128i,
+            s3: PhantomData<S3>,
+            s4: PhantomData<S4>,
+            ni: PhantomData<NI>,
+        }
+
+        impl<S3, S4, NI> Store<vec128_storage> for $vec<S3, S4, NI> {
+            #[inline(always)]
+            unsafe fn unpack(x: vec128_storage) -> Self {
+                Self::new(x.sse2)
+            }
+        }
+        impl<S3, S4, NI> From<$vec<S3, S4, NI>> for vec128_storage {
+            #[inline(always)]
+            fn from(x: $vec<S3, S4, NI>) -> Self {
+                vec128_storage { sse2: x.x }
+            }
+        }
+        impl<S3, S4, NI> $vec<S3, S4, NI> {
+            #[inline(always)]
+            fn new(x: __m128i) -> Self {
+                $vec {
+                    x,
+                    s3: PhantomData,
+                    s4: PhantomData,
+                    ni: PhantomData,
+                }
+            }
+        }
+
+        impl<S3, S4, NI> StoreBytes for $vec<S3, S4, NI>
+        where
+            Self: BSwap,
+        {
+            #[inline(always)]
+            unsafe fn unsafe_read_le(input: &[u8]) -> Self {
+                assert_eq!(input.len(), 16);
+                Self::new(_mm_loadu_si128(input.as_ptr() as *const _))
+            }
+            #[inline(always)]
+            unsafe fn unsafe_read_be(input: &[u8]) -> Self {
+                assert_eq!(input.len(), 16);
+                Self::new(_mm_loadu_si128(input.as_ptr() as *const _)).bswap()
+            }
+            #[inline(always)]
+            fn write_le(self, out: &mut [u8]) {
+                assert_eq!(out.len(), 16);
+                unsafe { _mm_storeu_si128(out.as_mut_ptr() as *mut _, self.x) }
+            }
+            #[inline(always)]
+            fn write_be(self, out: &mut [u8]) {
+                assert_eq!(out.len(), 16);
+                let x = self.bswap().x;
+                unsafe {
+                    _mm_storeu_si128(out.as_mut_ptr() as *mut _, x);
+                }
+            }
+        }
+
+        impl<S3, S4, NI> Default for $vec<S3, S4, NI> {
+            #[inline(always)]
+            fn default() -> Self {
+                Self::new(unsafe { _mm_setzero_si128() })
+            }
+        }
+
+        impl<S3, S4, NI> Not for $vec<S3, S4, NI> {
+            type Output = Self;
+            #[inline(always)]
+            fn not(self) -> Self::Output {
+                unsafe {
+                    let ff = _mm_set1_epi64x(-1i64);
+                    self ^ Self::new(ff)
+                }
+            }
+        }
+
+        impl<S3: Copy, S4: Copy, NI: Copy> BitOps0 for $vec<S3, S4, NI> {}
+        impl_binop!($vec, BitAnd, bitand, _mm_and_si128);
+        impl_binop!($vec, BitOr, bitor, _mm_or_si128);
+        impl_binop!($vec, BitXor, bitxor, _mm_xor_si128);
+        impl_binop_assign!($vec, BitAndAssign, bitand_assign, bitand);
+        impl_binop_assign!($vec, BitOrAssign, bitor_assign, bitor);
+        impl_binop_assign!($vec, BitXorAssign, bitxor_assign, bitxor);
+        impl<S3: Copy, S4: Copy, NI: Copy> AndNot for $vec<S3, S4, NI> {
+            type Output = Self;
+            #[inline(always)]
+            fn andnot(self, rhs: Self) -> Self {
+                Self::new(unsafe { _mm_andnot_si128(self.x, rhs.x) })
+            }
+        }
+    };
+}
+
+macro_rules! impl_bitops32 {
+    ($vec:ident) => {
+        impl<S3: Copy, S4: Copy, NI: Copy> BitOps32 for $vec<S3, S4, NI> where
+            $vec<S3, S4, NI>: RotateEachWord32
+        {
+        }
+    };
+}
+
+macro_rules! impl_bitops64 {
+    ($vec:ident) => {
+        impl_bitops32!($vec);
+        impl<S3: Copy, S4: Copy, NI: Copy> BitOps64 for $vec<S3, S4, NI> where
+            $vec<S3, S4, NI>: RotateEachWord64 + RotateEachWord32
+        {
+        }
+    };
+}
+
+macro_rules! impl_bitops128 {
+    ($vec:ident) => {
+        impl_bitops64!($vec);
+        impl<S3: Copy, S4: Copy, NI: Copy> BitOps128 for $vec<S3, S4, NI> where
+            $vec<S3, S4, NI>: RotateEachWord128
+        {
+        }
+    };
+}
+
+macro_rules! rotr_32_s3 {
+    ($name:ident, $k0:expr, $k1:expr) => {
+    #[inline(always)]
+    fn $name(self) -> Self {
+        Self::new(unsafe {
+                _mm_shuffle_epi8(
+                    self.x,
+                    _mm_set_epi64x($k0, $k1),
+                )
+            })
+        }
+    };
+}
+macro_rules! rotr_32 {
+    ($name:ident, $i:expr) => {
+    #[inline(always)]
+    fn $name(self) -> Self {
+        Self::new(unsafe {
+            _mm_or_si128(
+                _mm_srli_epi32(self.x, $i as i32),
+                _mm_slli_epi32(self.x, 32 - $i as i32),
+            )
+        })
+    }
+    };
+}
+impl<S4: Copy, NI: Copy> RotateEachWord32 for u32x4_sse2<YesS3, S4, NI> {
+    rotr_32!(rotate_each_word_right7, 7);
+    rotr_32_s3!(
+        rotate_each_word_right8,
+        0x0c0f0e0d_080b0a09,
+        0x04070605_00030201
+    );
+    rotr_32!(rotate_each_word_right11, 11);
+    rotr_32!(rotate_each_word_right12, 12);
+    rotr_32_s3!(
+        rotate_each_word_right16,
+        0x0d0c0f0e_09080b0a,
+        0x05040706_01000302
+    );
+    rotr_32!(rotate_each_word_right20, 20);
+    rotr_32_s3!(
+        rotate_each_word_right24,
+        0x0e0d0c0f_0a09080b,
+        0x06050407_02010003
+    );
+    rotr_32!(rotate_each_word_right25, 25);
+}
+impl<S4: Copy, NI: Copy> RotateEachWord32 for u32x4_sse2<NoS3, S4, NI> {
+    rotr_32!(rotate_each_word_right7, 7);
+    rotr_32!(rotate_each_word_right8, 8);
+    rotr_32!(rotate_each_word_right11, 11);
+    rotr_32!(rotate_each_word_right12, 12);
+    #[inline(always)]
+    fn rotate_each_word_right16(self) -> Self {
+        Self::new(swap16_s2(self.x))
+    }
+    rotr_32!(rotate_each_word_right20, 20);
+    rotr_32!(rotate_each_word_right24, 24);
+    rotr_32!(rotate_each_word_right25, 25);
+}
+
+macro_rules! rotr_64_s3 {
+    ($name:ident, $k0:expr, $k1:expr) => {
+    #[inline(always)]
+    fn $name(self) -> Self {
+        Self::new(unsafe {
+                _mm_shuffle_epi8(
+                    self.x,
+                    _mm_set_epi64x($k0, $k1),
+                )
+            })
+        }
+    };
+}
+macro_rules! rotr_64 {
+    ($name:ident, $i:expr) => {
+    #[inline(always)]
+    fn $name(self) -> Self {
+        Self::new(unsafe {
+            _mm_or_si128(
+                _mm_srli_epi64(self.x, $i as i32),
+                _mm_slli_epi64(self.x, 64 - $i as i32),
+            )
+        })
+    }
+    };
+}
+impl<S4: Copy, NI: Copy> RotateEachWord32 for u64x2_sse2<YesS3, S4, NI> {
+    rotr_64!(rotate_each_word_right7, 7);
+    rotr_64_s3!(
+        rotate_each_word_right8,
+        0x080f_0e0d_0c0b_0a09,
+        0x0007_0605_0403_0201
+    );
+    rotr_64!(rotate_each_word_right11, 11);
+    rotr_64!(rotate_each_word_right12, 12);
+    rotr_64_s3!(
+        rotate_each_word_right16,
+        0x0908_0f0e_0d0c_0b0a,
+        0x0100_0706_0504_0302
+    );
+    rotr_64!(rotate_each_word_right20, 20);
+    rotr_64_s3!(
+        rotate_each_word_right24,
+        0x0a09_080f_0e0d_0c0b,
+        0x0201_0007_0605_0403
+    );
+    rotr_64!(rotate_each_word_right25, 25);
+}
+impl<S4: Copy, NI: Copy> RotateEachWord32 for u64x2_sse2<NoS3, S4, NI> {
+    rotr_64!(rotate_each_word_right7, 7);
+    rotr_64!(rotate_each_word_right8, 8);
+    rotr_64!(rotate_each_word_right11, 11);
+    rotr_64!(rotate_each_word_right12, 12);
+    #[inline(always)]
+    fn rotate_each_word_right16(self) -> Self {
+        Self::new(swap16_s2(self.x))
+    }
+    rotr_64!(rotate_each_word_right20, 20);
+    rotr_64!(rotate_each_word_right24, 24);
+    rotr_64!(rotate_each_word_right25, 25);
+}
+impl<S3: Copy, S4: Copy, NI: Copy> RotateEachWord64 for u64x2_sse2<S3, S4, NI> {
+    #[inline(always)]
+    fn rotate_each_word_right32(self) -> Self {
+        Self::new(unsafe { _mm_shuffle_epi32(self.x, 0b10110001) })
+    }
+}
+
+macro_rules! rotr_128 {
+    ($name:ident, $i:expr) => {
+    #[inline(always)]
+    fn $name(self) -> Self {
+        Self::new(unsafe {
+            _mm_or_si128(
+                _mm_srli_si128(self.x, $i as i32),
+                _mm_slli_si128(self.x, 128 - $i as i32),
+            )
+        })
+    }
+    };
+}
+// TODO: completely unoptimized
+impl<S3: Copy, S4: Copy, NI: Copy> RotateEachWord32 for u128x1_sse2<S3, S4, NI> {
+    rotr_128!(rotate_each_word_right7, 7);
+    rotr_128!(rotate_each_word_right8, 8);
+    rotr_128!(rotate_each_word_right11, 11);
+    rotr_128!(rotate_each_word_right12, 12);
+    rotr_128!(rotate_each_word_right16, 16);
+    rotr_128!(rotate_each_word_right20, 20);
+    rotr_128!(rotate_each_word_right24, 24);
+    rotr_128!(rotate_each_word_right25, 25);
+}
+// TODO: completely unoptimized
+impl<S3: Copy, S4: Copy, NI: Copy> RotateEachWord64 for u128x1_sse2<S3, S4, NI> {
+    rotr_128!(rotate_each_word_right32, 32);
+}
+impl<S3: Copy, S4: Copy, NI: Copy> RotateEachWord128 for u128x1_sse2<S3, S4, NI> {}
+
+def_vec!(u32x4_sse2, u32);
+def_vec!(u64x2_sse2, u64);
+def_vec!(u128x1_sse2, u128);
+
+impl<S3, NI> MultiLane<[u32; 4]> for u32x4_sse2<S3, YesS4, NI> {
+    #[inline(always)]
+    fn to_lanes(self) -> [u32; 4] {
+        unsafe {
+            let x = _mm_cvtsi128_si64(self.x) as u64;
+            let y = _mm_extract_epi64(self.x, 1) as u64;
+            [x as u32, (x >> 32) as u32, y as u32, (y >> 32) as u32]
+        }
+    }
+    #[inline(always)]
+    fn from_lanes(xs: [u32; 4]) -> Self {
+        unsafe {
+            let mut x = _mm_cvtsi64_si128((xs[0] as u64 | ((xs[1] as u64) << 32)) as i64);
+            x = _mm_insert_epi64(x, (xs[2] as u64 | ((xs[3] as u64) << 32)) as i64, 1);
+            Self::new(x)
+        }
+    }
+}
+impl<S3, NI> MultiLane<[u32; 4]> for u32x4_sse2<S3, NoS4, NI> {
+    #[inline(always)]
+    fn to_lanes(self) -> [u32; 4] {
+        unsafe {
+            let x = _mm_cvtsi128_si64(self.x) as u64;
+            let y = _mm_cvtsi128_si64(_mm_shuffle_epi32(self.x, 0b11101110)) as u64;
+            [x as u32, (x >> 32) as u32, y as u32, (y >> 32) as u32]
+        }
+    }
+    #[inline(always)]
+    fn from_lanes(xs: [u32; 4]) -> Self {
+        unsafe {
+            let x = (xs[0] as u64 | ((xs[1] as u64) << 32)) as i64;
+            let y = (xs[2] as u64 | ((xs[3] as u64) << 32)) as i64;
+            let x = _mm_cvtsi64_si128(x);
+            let y = _mm_slli_si128(_mm_cvtsi64_si128(y), 8);
+            Self::new(_mm_or_si128(x, y))
+        }
+    }
+}
+impl<S3, NI> MultiLane<[u64; 2]> for u64x2_sse2<S3, YesS4, NI> {
+    #[inline(always)]
+    fn to_lanes(self) -> [u64; 2] {
+        unsafe {
+            [
+                _mm_cvtsi128_si64(self.x) as u64,
+                _mm_extract_epi64(self.x, 1) as u64,
+            ]
+        }
+    }
+    #[inline(always)]
+    fn from_lanes(xs: [u64; 2]) -> Self {
+        unsafe {
+            let mut x = _mm_cvtsi64_si128(xs[0] as i64);
+            x = _mm_insert_epi64(x, xs[1] as i64, 1);
+            Self::new(x)
+        }
+    }
+}
+impl<S3, NI> MultiLane<[u64; 2]> for u64x2_sse2<S3, NoS4, NI> {
+    #[inline(always)]
+    fn to_lanes(self) -> [u64; 2] {
+        unsafe {
+            [
+                _mm_cvtsi128_si64(self.x) as u64,
+                _mm_cvtsi128_si64(_mm_srli_si128(self.x, 8)) as u64,
+            ]
+        }
+    }
+    #[inline(always)]
+    fn from_lanes(xs: [u64; 2]) -> Self {
+        unsafe {
+            let x = _mm_cvtsi64_si128(xs[0] as i64);
+            let y = _mm_slli_si128(_mm_cvtsi64_si128(xs[1] as i64), 8);
+            Self::new(_mm_or_si128(x, y))
+        }
+    }
+}
+impl<S3, S4, NI> MultiLane<[u128; 1]> for u128x1_sse2<S3, S4, NI> {
+    #[inline(always)]
+    fn to_lanes(self) -> [u128; 1] {
+        unimplemented!()
+    }
+    #[inline(always)]
+    fn from_lanes(xs: [u128; 1]) -> Self {
+        unimplemented!()
+    }
+}
+
+impl<S3, S4, NI> MultiLane<[u64; 4]> for u64x4_sse2<S3, S4, NI>
+where
+    u64x2_sse2<S3, S4, NI>: MultiLane<[u64; 2]> + Copy,
+{
+    #[inline(always)]
+    fn to_lanes(self) -> [u64; 4] {
+        let (a, b) = (self.0[0].to_lanes(), self.0[1].to_lanes());
+        [a[0], a[1], b[0], b[1]]
+    }
+    #[inline(always)]
+    fn from_lanes(xs: [u64; 4]) -> Self {
+        let (a, b) = (
+            u64x2_sse2::from_lanes([xs[0], xs[1]]),
+            u64x2_sse2::from_lanes([xs[2], xs[3]]),
+        );
+        x2::new([a, b])
+    }
+}
+
+macro_rules! impl_into {
+    ($from:ident, $to:ident) => {
+        impl<S3, S4, NI> From<$from<S3, S4, NI>> for $to<S3, S4, NI> {
+            #[inline(always)]
+            fn from(x: $from<S3, S4, NI>) -> Self {
+                $to::new(x.x)
+            }
+        }
+    };
+}
+
+impl_into!(u128x1_sse2, u32x4_sse2);
+impl_into!(u128x1_sse2, u64x2_sse2);
+
+impl_bitops32!(u32x4_sse2);
+impl_bitops64!(u64x2_sse2);
+impl_bitops128!(u128x1_sse2);
+
+impl<S3: Copy, S4: Copy, NI: Copy> ArithOps for u32x4_sse2<S3, S4, NI> where
+    u32x4_sse2<S3, S4, NI>: BSwap
+{
+}
+impl<S3: Copy, S4: Copy, NI: Copy> ArithOps for u64x2_sse2<S3, S4, NI> where
+    u64x2_sse2<S3, S4, NI>: BSwap
+{
+}
+impl_binop!(u32x4_sse2, Add, add, _mm_add_epi32);
+impl_binop!(u64x2_sse2, Add, add, _mm_add_epi64);
+impl_binop_assign!(u32x4_sse2, AddAssign, add_assign, add);
+impl_binop_assign!(u64x2_sse2, AddAssign, add_assign, add);
+
+impl<S3: Copy, S4: Copy, NI: Copy> u32x4<Machine86<S3, S4, NI>> for u32x4_sse2<S3, S4, NI>
+where
+    u32x4_sse2<S3, S4, NI>: RotateEachWord32 + BSwap + MultiLane<[u32; 4]> + Vec4<u32>,
+    Machine86<S3, S4, NI>: Machine,
+{
+}
+impl<S3: Copy, S4: Copy, NI: Copy> u64x2<Machine86<S3, S4, NI>> for u64x2_sse2<S3, S4, NI>
+where
+    u64x2_sse2<S3, S4, NI>:
+        RotateEachWord64 + RotateEachWord32 + BSwap + MultiLane<[u64; 2]> + Vec2<u64>,
+    Machine86<S3, S4, NI>: Machine,
+{
+}
+impl<S3: Copy, S4: Copy, NI: Copy> u128x1<Machine86<S3, S4, NI>> for u128x1_sse2<S3, S4, NI>
+where
+    u128x1_sse2<S3, S4, NI>: Swap64 + RotateEachWord64 + RotateEachWord32 + BSwap,
+    Machine86<S3, S4, NI>: Machine,
+    u128x1_sse2<S3, S4, NI>: Into<<Machine86<S3, S4, NI> as Machine>::u32x4>,
+    u128x1_sse2<S3, S4, NI>: Into<<Machine86<S3, S4, NI> as Machine>::u64x2>,
+{
+}
+
+impl<NI: Copy> u32x4<Avx2Machine<NI>> for u32x4_sse2<YesS3, YesS4, NI>
+where
+    u32x4_sse2<YesS3, YesS4, NI>: RotateEachWord32 + BSwap + MultiLane<[u32; 4]> + Vec4<u32>,
+    Machine86<YesS3, YesS4, NI>: Machine,
+{
+}
+impl<NI: Copy> u64x2<Avx2Machine<NI>> for u64x2_sse2<YesS3, YesS4, NI>
+where
+    u64x2_sse2<YesS3, YesS4, NI>:
+        RotateEachWord64 + RotateEachWord32 + BSwap + MultiLane<[u64; 2]> + Vec2<u64>,
+    Machine86<YesS3, YesS4, NI>: Machine,
+{
+}
+impl<NI: Copy> u128x1<Avx2Machine<NI>> for u128x1_sse2<YesS3, YesS4, NI>
+where
+    u128x1_sse2<YesS3, YesS4, NI>: Swap64 + RotateEachWord64 + RotateEachWord32 + BSwap,
+    Machine86<YesS3, YesS4, NI>: Machine,
+    u128x1_sse2<YesS3, YesS4, NI>: Into<<Machine86<YesS3, YesS4, NI> as Machine>::u32x4>,
+    u128x1_sse2<YesS3, YesS4, NI>: Into<<Machine86<YesS3, YesS4, NI> as Machine>::u64x2>,
+{
+}
+
+impl<S3, S4, NI> UnsafeFrom<[u32; 4]> for u32x4_sse2<S3, S4, NI> {
+    #[inline(always)]
+    unsafe fn unsafe_from(xs: [u32; 4]) -> Self {
+        Self::new(_mm_set_epi32(
+            xs[3] as i32,
+            xs[2] as i32,
+            xs[1] as i32,
+            xs[0] as i32,
+        ))
+    }
+}
+
+impl<S3, NI> Vec4<u32> for u32x4_sse2<S3, YesS4, NI>
+where
+    Self: MultiLane<[u32; 4]>,
+{
+    #[inline(always)]
+    fn extract(self, i: u32) -> u32 {
+        self.to_lanes()[i as usize]
+    }
+    #[inline(always)]
+    fn insert(self, v: u32, i: u32) -> Self {
+        Self::new(unsafe {
+            match i {
+                0 => _mm_insert_epi32(self.x, v as i32, 0),
+                1 => _mm_insert_epi32(self.x, v as i32, 1),
+                2 => _mm_insert_epi32(self.x, v as i32, 2),
+                3 => _mm_insert_epi32(self.x, v as i32, 3),
+                _ => unreachable!(),
+            }
+        })
+    }
+}
+impl<S3, NI> Vec4<u32> for u32x4_sse2<S3, NoS4, NI>
+where
+    Self: MultiLane<[u32; 4]>,
+{
+    #[inline(always)]
+    fn extract(self, i: u32) -> u32 {
+        self.to_lanes()[i as usize]
+    }
+    #[inline(always)]
+    fn insert(self, v: u32, i: u32) -> Self {
+        Self::new(unsafe {
+            match i {
+                0 => {
+                    let x = _mm_andnot_si128(_mm_cvtsi32_si128(-1), self.x);
+                    _mm_or_si128(x, _mm_cvtsi32_si128(v as i32))
+                }
+                1 => {
+                    let mut x = _mm_shuffle_epi32(self.x, 0b0111_1000);
+                    x = _mm_slli_si128(x, 4);
+                    x = _mm_or_si128(x, _mm_cvtsi32_si128(v as i32));
+                    _mm_shuffle_epi32(x, 0b1110_0001)
+                }
+                2 => {
+                    let mut x = _mm_shuffle_epi32(self.x, 0b1011_0100);
+                    x = _mm_slli_si128(x, 4);
+                    x = _mm_or_si128(x, _mm_cvtsi32_si128(v as i32));
+                    _mm_shuffle_epi32(x, 0b1100_1001)
+                }
+                3 => {
+                    let mut x = _mm_slli_si128(self.x, 4);
+                    x = _mm_or_si128(x, _mm_cvtsi32_si128(v as i32));
+                    _mm_shuffle_epi32(x, 0b0011_1001)
+                }
+                _ => unreachable!(),
+            }
+        })
+    }
+}
+
+impl<S3, S4, NI> LaneWords4 for u32x4_sse2<S3, S4, NI> {
+    #[inline(always)]
+    fn shuffle_lane_words2301(self) -> Self {
+        self.shuffle2301()
+    }
+    #[inline(always)]
+    fn shuffle_lane_words1230(self) -> Self {
+        self.shuffle1230()
+    }
+    #[inline(always)]
+    fn shuffle_lane_words3012(self) -> Self {
+        self.shuffle3012()
+    }
+}
+
+impl<S3, S4, NI> Words4 for u32x4_sse2<S3, S4, NI> {
+    #[inline(always)]
+    fn shuffle2301(self) -> Self {
+        Self::new(unsafe { _mm_shuffle_epi32(self.x, 0b0100_1110) })
+    }
+    #[inline(always)]
+    fn shuffle1230(self) -> Self {
+        Self::new(unsafe { _mm_shuffle_epi32(self.x, 0b1001_0011) })
+    }
+    #[inline(always)]
+    fn shuffle3012(self) -> Self {
+        Self::new(unsafe { _mm_shuffle_epi32(self.x, 0b0011_1001) })
+    }
+}
+
+impl<S4, NI> Words4 for u64x4_sse2<YesS3, S4, NI> {
+    #[inline(always)]
+    fn shuffle2301(self) -> Self {
+        x2::new([u64x2_sse2::new(self.0[1].x), u64x2_sse2::new(self.0[0].x)])
+    }
+    #[inline(always)]
+    fn shuffle3012(self) -> Self {
+        unsafe {
+            x2::new([
+                u64x2_sse2::new(_mm_alignr_epi8(self.0[1].x, self.0[0].x, 8)),
+                u64x2_sse2::new(_mm_alignr_epi8(self.0[0].x, self.0[1].x, 8)),
+            ])
+        }
+    }
+    #[inline(always)]
+    fn shuffle1230(self) -> Self {
+        unsafe {
+            x2::new([
+                u64x2_sse2::new(_mm_alignr_epi8(self.0[0].x, self.0[1].x, 8)),
+                u64x2_sse2::new(_mm_alignr_epi8(self.0[1].x, self.0[0].x, 8)),
+            ])
+        }
+    }
+}
+impl<S4, NI> Words4 for u64x4_sse2<NoS3, S4, NI> {
+    #[inline(always)]
+    fn shuffle2301(self) -> Self {
+        x2::new([u64x2_sse2::new(self.0[1].x), u64x2_sse2::new(self.0[0].x)])
+    }
+    #[inline(always)]
+    fn shuffle3012(self) -> Self {
+        unsafe {
+            let a = _mm_srli_si128(self.0[0].x, 8);
+            let b = _mm_slli_si128(self.0[0].x, 8);
+            let c = _mm_srli_si128(self.0[1].x, 8);
+            let d = _mm_slli_si128(self.0[1].x, 8);
+            let da = _mm_or_si128(d, a);
+            let bc = _mm_or_si128(b, c);
+            x2::new([u64x2_sse2::new(da), u64x2_sse2::new(bc)])
+        }
+    }
+    #[inline(always)]
+    fn shuffle1230(self) -> Self {
+        unsafe {
+            let a = _mm_srli_si128(self.0[0].x, 8);
+            let b = _mm_slli_si128(self.0[0].x, 8);
+            let c = _mm_srli_si128(self.0[1].x, 8);
+            let d = _mm_slli_si128(self.0[1].x, 8);
+            let da = _mm_or_si128(d, a);
+            let bc = _mm_or_si128(b, c);
+            x2::new([u64x2_sse2::new(bc), u64x2_sse2::new(da)])
+        }
+    }
+}
+
+impl<S3, S4, NI> UnsafeFrom<[u64; 2]> for u64x2_sse2<S3, S4, NI> {
+    #[inline(always)]
+    unsafe fn unsafe_from(xs: [u64; 2]) -> Self {
+        Self::new(_mm_set_epi64x(xs[1] as i64, xs[0] as i64))
+    }
+}
+
+impl<S3, NI> Vec2<u64> for u64x2_sse2<S3, YesS4, NI> {
+    #[inline(always)]
+    fn extract(self, i: u32) -> u64 {
+        unsafe {
+            match i {
+                0 => _mm_cvtsi128_si64(self.x) as u64,
+                1 => _mm_extract_epi64(self.x, 1) as u64,
+                _ => unreachable!(),
+            }
+        }
+    }
+    #[inline(always)]
+    fn insert(self, x: u64, i: u32) -> Self {
+        Self::new(unsafe {
+            match i {
+                0 => _mm_insert_epi64(self.x, x as i64, 0),
+                1 => _mm_insert_epi64(self.x, x as i64, 1),
+                _ => unreachable!(),
+            }
+        })
+    }
+}
+impl<S3, NI> Vec2<u64> for u64x2_sse2<S3, NoS4, NI> {
+    #[inline(always)]
+    fn extract(self, i: u32) -> u64 {
+        unsafe {
+            match i {
+                0 => _mm_cvtsi128_si64(self.x) as u64,
+                1 => _mm_cvtsi128_si64(_mm_shuffle_epi32(self.x, 0b11101110)) as u64,
+                _ => unreachable!(),
+            }
+        }
+    }
+    #[inline(always)]
+    fn insert(self, x: u64, i: u32) -> Self {
+        Self::new(unsafe {
+            match i {
+                0 => _mm_or_si128(
+                    _mm_andnot_si128(_mm_cvtsi64_si128(-1), self.x),
+                    _mm_cvtsi64_si128(x as i64),
+                ),
+                1 => _mm_or_si128(
+                    _mm_move_epi64(self.x),
+                    _mm_slli_si128(_mm_cvtsi64_si128(x as i64), 8),
+                ),
+                _ => unreachable!(),
+            }
+        })
+    }
+}
+
+impl<S4, NI> BSwap for u32x4_sse2<YesS3, S4, NI> {
+    #[inline(always)]
+    fn bswap(self) -> Self {
+        Self::new(unsafe {
+            let k = _mm_set_epi64x(0x0c0d_0e0f_0809_0a0b, 0x0405_0607_0001_0203);
+            _mm_shuffle_epi8(self.x, k)
+        })
+    }
+}
+#[inline(always)]
+fn bswap32_s2(x: __m128i) -> __m128i {
+    unsafe {
+        let mut y = _mm_unpacklo_epi8(x, _mm_setzero_si128());
+        y = _mm_shufflehi_epi16(y, 0b0001_1011);
+        y = _mm_shufflelo_epi16(y, 0b0001_1011);
+        let mut z = _mm_unpackhi_epi8(x, _mm_setzero_si128());
+        z = _mm_shufflehi_epi16(z, 0b0001_1011);
+        z = _mm_shufflelo_epi16(z, 0b0001_1011);
+        _mm_packus_epi16(y, z)
+    }
+}
+impl<S4, NI> BSwap for u32x4_sse2<NoS3, S4, NI> {
+    #[inline(always)]
+    fn bswap(self) -> Self {
+        Self::new(bswap32_s2(self.x))
+    }
+}
+
+impl<S4, NI> BSwap for u64x2_sse2<YesS3, S4, NI> {
+    #[inline(always)]
+    fn bswap(self) -> Self {
+        Self::new(unsafe {
+            let k = _mm_set_epi64x(0x0809_0a0b_0c0d_0e0f, 0x0001_0203_0405_0607);
+            _mm_shuffle_epi8(self.x, k)
+        })
+    }
+}
+impl<S4, NI> BSwap for u64x2_sse2<NoS3, S4, NI> {
+    #[inline(always)]
+    fn bswap(self) -> Self {
+        Self::new(unsafe { bswap32_s2(_mm_shuffle_epi32(self.x, 0b1011_0001)) })
+    }
+}
+
+impl<S4, NI> BSwap for u128x1_sse2<YesS3, S4, NI> {
+    #[inline(always)]
+    fn bswap(self) -> Self {
+        Self::new(unsafe {
+            let k = _mm_set_epi64x(0x0f0e_0d0c_0b0a_0908, 0x0706_0504_0302_0100);
+            _mm_shuffle_epi8(self.x, k)
+        })
+    }
+}
+impl<S4, NI> BSwap for u128x1_sse2<NoS3, S4, NI> {
+    #[inline(always)]
+    fn bswap(self) -> Self {
+        Self::new(unsafe { unimplemented!() })
+    }
+}
+
+macro_rules! swapi {
+    ($x:expr, $i:expr, $k:expr) => {
+        unsafe {
+            const K: u8 = $k;
+            let k = _mm_set1_epi8(K as i8);
+            u128x1_sse2::new(_mm_or_si128(
+                _mm_srli_epi16(_mm_and_si128($x.x, k), $i),
+                _mm_and_si128(_mm_slli_epi16($x.x, $i), k),
+            ))
+        }
+    };
+}
+#[inline(always)]
+fn swap16_s2(x: __m128i) -> __m128i {
+    unsafe { _mm_shufflehi_epi16(_mm_shufflelo_epi16(x, 0b1011_0001), 0b1011_0001) }
+}
+impl<S4, NI> Swap64 for u128x1_sse2<YesS3, S4, NI> {
+    #[inline(always)]
+    fn swap1(self) -> Self {
+        swapi!(self, 1, 0xaa)
+    }
+    #[inline(always)]
+    fn swap2(self) -> Self {
+        swapi!(self, 2, 0xcc)
+    }
+    #[inline(always)]
+    fn swap4(self) -> Self {
+        swapi!(self, 4, 0xf0)
+    }
+    #[inline(always)]
+    fn swap8(self) -> Self {
+        u128x1_sse2::new(unsafe {
+            let k = _mm_set_epi64x(0x0e0f_0c0d_0a0b_0809, 0x0607_0405_0203_0001);
+            _mm_shuffle_epi8(self.x, k)
+        })
+    }
+    #[inline(always)]
+    fn swap16(self) -> Self {
+        u128x1_sse2::new(unsafe {
+            let k = _mm_set_epi64x(0x0d0c_0f0e_0908_0b0a, 0x0504_0706_0100_0302);
+            _mm_shuffle_epi8(self.x, k)
+        })
+    }
+    #[inline(always)]
+    fn swap32(self) -> Self {
+        u128x1_sse2::new(unsafe { _mm_shuffle_epi32(self.x, 0b1011_0001) })
+    }
+    #[inline(always)]
+    fn swap64(self) -> Self {
+        u128x1_sse2::new(unsafe { _mm_shuffle_epi32(self.x, 0b0100_1110) })
+    }
+}
+impl<S4, NI> Swap64 for u128x1_sse2<NoS3, S4, NI> {
+    #[inline(always)]
+    fn swap1(self) -> Self {
+        swapi!(self, 1, 0xaa)
+    }
+    #[inline(always)]
+    fn swap2(self) -> Self {
+        swapi!(self, 2, 0xcc)
+    }
+    #[inline(always)]
+    fn swap4(self) -> Self {
+        swapi!(self, 4, 0xf0)
+    }
+    #[inline(always)]
+    fn swap8(self) -> Self {
+        u128x1_sse2::new(unsafe {
+            _mm_or_si128(_mm_slli_epi16(self.x, 8), _mm_srli_epi16(self.x, 8))
+        })
+    }
+    #[inline(always)]
+    fn swap16(self) -> Self {
+        u128x1_sse2::new(swap16_s2(self.x))
+    }
+    #[inline(always)]
+    fn swap32(self) -> Self {
+        u128x1_sse2::new(unsafe { _mm_shuffle_epi32(self.x, 0b1011_0001) })
+    }
+    #[inline(always)]
+    fn swap64(self) -> Self {
+        u128x1_sse2::new(unsafe { _mm_shuffle_epi32(self.x, 0b0100_1110) })
+    }
+}
+
+#[derive(Copy, Clone)]
+pub struct G0;
+#[derive(Copy, Clone)]
+pub struct G1;
+
+#[allow(non_camel_case_types)]
+pub type u32x4x2_sse2<S3, S4, NI> = x2<u32x4_sse2<S3, S4, NI>, G0>;
+#[allow(non_camel_case_types)]
+pub type u64x2x2_sse2<S3, S4, NI> = x2<u64x2_sse2<S3, S4, NI>, G0>;
+#[allow(non_camel_case_types)]
+pub type u64x4_sse2<S3, S4, NI> = x2<u64x2_sse2<S3, S4, NI>, G1>;
+#[allow(non_camel_case_types)]
+pub type u128x2_sse2<S3, S4, NI> = x2<u128x1_sse2<S3, S4, NI>, G0>;
+
+#[allow(non_camel_case_types)]
+pub type u32x4x4_sse2<S3, S4, NI> = x4<u32x4_sse2<S3, S4, NI>>;
+#[allow(non_camel_case_types)]
+pub type u64x2x4_sse2<S3, S4, NI> = x4<u64x2_sse2<S3, S4, NI>>;
+#[allow(non_camel_case_types)]
+pub type u128x4_sse2<S3, S4, NI> = x4<u128x1_sse2<S3, S4, NI>>;
+
+impl<S3: Copy, S4: Copy, NI: Copy> u32x4x2<Machine86<S3, S4, NI>> for u32x4x2_sse2<S3, S4, NI>
+where
+    u32x4_sse2<S3, S4, NI>: RotateEachWord32 + BSwap,
+    Machine86<S3, S4, NI>: Machine,
+    u32x4x2_sse2<S3, S4, NI>: MultiLane<[<Machine86<S3, S4, NI> as Machine>::u32x4; 2]>,
+    u32x4x2_sse2<S3, S4, NI>: Vec2<<Machine86<S3, S4, NI> as Machine>::u32x4>,
+{
+}
+impl<S3: Copy, S4: Copy, NI: Copy> u64x2x2<Machine86<S3, S4, NI>> for u64x2x2_sse2<S3, S4, NI>
+where
+    u64x2_sse2<S3, S4, NI>: RotateEachWord64 + RotateEachWord32 + BSwap,
+    Machine86<S3, S4, NI>: Machine,
+    u64x2x2_sse2<S3, S4, NI>: MultiLane<[<Machine86<S3, S4, NI> as Machine>::u64x2; 2]>,
+    u64x2x2_sse2<S3, S4, NI>: Vec2<<Machine86<S3, S4, NI> as Machine>::u64x2>,
+{
+}
+impl<S3: Copy, S4: Copy, NI: Copy> u64x4<Machine86<S3, S4, NI>> for u64x4_sse2<S3, S4, NI>
+where
+    u64x2_sse2<S3, S4, NI>: RotateEachWord64 + RotateEachWord32 + BSwap,
+    Machine86<S3, S4, NI>: Machine,
+    u64x4_sse2<S3, S4, NI>: MultiLane<[u64; 4]> + Vec4<u64> + Words4,
+{
+}
+impl<S3: Copy, S4: Copy, NI: Copy> u128x2<Machine86<S3, S4, NI>> for u128x2_sse2<S3, S4, NI>
+where
+    u128x1_sse2<S3, S4, NI>: Swap64 + BSwap,
+    Machine86<S3, S4, NI>: Machine,
+    u128x2_sse2<S3, S4, NI>: MultiLane<[<Machine86<S3, S4, NI> as Machine>::u128x1; 2]>,
+    u128x2_sse2<S3, S4, NI>: Vec2<<Machine86<S3, S4, NI> as Machine>::u128x1>,
+    u128x2_sse2<S3, S4, NI>: Into<<Machine86<S3, S4, NI> as Machine>::u32x4x2>,
+    u128x2_sse2<S3, S4, NI>: Into<<Machine86<S3, S4, NI> as Machine>::u64x2x2>,
+    u128x2_sse2<S3, S4, NI>: Into<<Machine86<S3, S4, NI> as Machine>::u64x4>,
+{
+}
+
+impl<NI: Copy> u32x4x2<Avx2Machine<NI>> for u32x4x2_sse2<YesS3, YesS4, NI>
+where
+    u32x4_sse2<YesS3, YesS4, NI>: RotateEachWord32 + BSwap,
+    Avx2Machine<NI>: Machine,
+    u32x4x2_sse2<YesS3, YesS4, NI>: MultiLane<[<Avx2Machine<NI> as Machine>::u32x4; 2]>,
+    u32x4x2_sse2<YesS3, YesS4, NI>: Vec2<<Avx2Machine<NI> as Machine>::u32x4>,
+{
+}
+impl<NI: Copy> u64x2x2<Avx2Machine<NI>> for u64x2x2_sse2<YesS3, YesS4, NI>
+where
+    u64x2_sse2<YesS3, YesS4, NI>: RotateEachWord64 + RotateEachWord32 + BSwap,
+    Avx2Machine<NI>: Machine,
+    u64x2x2_sse2<YesS3, YesS4, NI>: MultiLane<[<Avx2Machine<NI> as Machine>::u64x2; 2]>,
+    u64x2x2_sse2<YesS3, YesS4, NI>: Vec2<<Avx2Machine<NI> as Machine>::u64x2>,
+{
+}
+impl<NI: Copy> u64x4<Avx2Machine<NI>> for u64x4_sse2<YesS3, YesS4, NI>
+where
+    u64x2_sse2<YesS3, YesS4, NI>: RotateEachWord64 + RotateEachWord32 + BSwap,
+    Avx2Machine<NI>: Machine,
+    u64x4_sse2<YesS3, YesS4, NI>: MultiLane<[u64; 4]> + Vec4<u64> + Words4,
+{
+}
+impl<NI: Copy> u128x2<Avx2Machine<NI>> for u128x2_sse2<YesS3, YesS4, NI>
+where
+    u128x1_sse2<YesS3, YesS4, NI>: Swap64 + BSwap,
+    Avx2Machine<NI>: Machine,
+    u128x2_sse2<YesS3, YesS4, NI>: MultiLane<[<Avx2Machine<NI> as Machine>::u128x1; 2]>,
+    u128x2_sse2<YesS3, YesS4, NI>: Vec2<<Avx2Machine<NI> as Machine>::u128x1>,
+    u128x2_sse2<YesS3, YesS4, NI>: Into<<Avx2Machine<NI> as Machine>::u32x4x2>,
+    u128x2_sse2<YesS3, YesS4, NI>: Into<<Avx2Machine<NI> as Machine>::u64x2x2>,
+    u128x2_sse2<YesS3, YesS4, NI>: Into<<Avx2Machine<NI> as Machine>::u64x4>,
+{
+}
+
+impl<S3, S4, NI> Vec4<u64> for u64x4_sse2<S3, S4, NI>
+where
+    u64x2_sse2<S3, S4, NI>: Copy + Vec2<u64>,
+{
+    #[inline(always)]
+    fn extract(self, i: u32) -> u64 {
+        match i {
+            0 => self.0[0].extract(0),
+            1 => self.0[0].extract(1),
+            2 => self.0[1].extract(0),
+            3 => self.0[1].extract(1),
+            _ => panic!(),
+        }
+    }
+    #[inline(always)]
+    fn insert(mut self, w: u64, i: u32) -> Self {
+        match i {
+            0 => self.0[0] = self.0[0].insert(w, 0),
+            1 => self.0[0] = self.0[0].insert(w, 1),
+            2 => self.0[1] = self.0[1].insert(w, 0),
+            3 => self.0[1] = self.0[1].insert(w, 1),
+            _ => panic!(),
+        };
+        self
+    }
+}
+
+impl<S3: Copy, S4: Copy, NI: Copy> u32x4x4<Machine86<S3, S4, NI>> for u32x4x4_sse2<S3, S4, NI>
+where
+    u32x4_sse2<S3, S4, NI>: RotateEachWord32 + BSwap,
+    Machine86<S3, S4, NI>: Machine,
+    u32x4x4_sse2<S3, S4, NI>: MultiLane<[<Machine86<S3, S4, NI> as Machine>::u32x4; 4]>,
+    u32x4x4_sse2<S3, S4, NI>: Vec4<<Machine86<S3, S4, NI> as Machine>::u32x4>,
+{
+}
+impl<S3: Copy, S4: Copy, NI: Copy> u64x2x4<Machine86<S3, S4, NI>> for u64x2x4_sse2<S3, S4, NI>
+where
+    u64x2_sse2<S3, S4, NI>: RotateEachWord64 + RotateEachWord32 + BSwap,
+    Machine86<S3, S4, NI>: Machine,
+    u64x2x4_sse2<S3, S4, NI>: MultiLane<[<Machine86<S3, S4, NI> as Machine>::u64x2; 4]>,
+    u64x2x4_sse2<S3, S4, NI>: Vec4<<Machine86<S3, S4, NI> as Machine>::u64x2>,
+{
+}
+impl<S3: Copy, S4: Copy, NI: Copy> u128x4<Machine86<S3, S4, NI>> for u128x4_sse2<S3, S4, NI>
+where
+    u128x1_sse2<S3, S4, NI>: Swap64 + BSwap,
+    Machine86<S3, S4, NI>: Machine,
+    u128x4_sse2<S3, S4, NI>: MultiLane<[<Machine86<S3, S4, NI> as Machine>::u128x1; 4]>,
+    u128x4_sse2<S3, S4, NI>: Vec4<<Machine86<S3, S4, NI> as Machine>::u128x1>,
+    u128x4_sse2<S3, S4, NI>: Into<<Machine86<S3, S4, NI> as Machine>::u32x4x4>,
+    u128x4_sse2<S3, S4, NI>: Into<<Machine86<S3, S4, NI> as Machine>::u64x2x4>,
+{
+}
+
+impl<NI: Copy> u32x4x4<Avx2Machine<NI>> for u32x4x4_sse2<YesS3, YesS4, NI>
+where
+    u32x4_sse2<YesS3, YesS4, NI>: RotateEachWord32 + BSwap,
+    Avx2Machine<NI>: Machine,
+    u32x4x4_sse2<YesS3, YesS4, NI>: MultiLane<[<Avx2Machine<NI> as Machine>::u32x4; 4]>,
+    u32x4x4_sse2<YesS3, YesS4, NI>: Vec4<<Avx2Machine<NI> as Machine>::u32x4>,
+{
+}
+impl<NI: Copy> u64x2x4<Avx2Machine<NI>> for u64x2x4_sse2<YesS3, YesS4, NI>
+where
+    u64x2_sse2<YesS3, YesS4, NI>: RotateEachWord64 + RotateEachWord32 + BSwap,
+    Avx2Machine<NI>: Machine,
+    u64x2x4_sse2<YesS3, YesS4, NI>: MultiLane<[<Avx2Machine<NI> as Machine>::u64x2; 4]>,
+    u64x2x4_sse2<YesS3, YesS4, NI>: Vec4<<Avx2Machine<NI> as Machine>::u64x2>,
+{
+}
+impl<NI: Copy> u128x4<Avx2Machine<NI>> for u128x4_sse2<YesS3, YesS4, NI>
+where
+    u128x1_sse2<YesS3, YesS4, NI>: Swap64 + BSwap,
+    Avx2Machine<NI>: Machine,
+    u128x4_sse2<YesS3, YesS4, NI>: MultiLane<[<Avx2Machine<NI> as Machine>::u128x1; 4]>,
+    u128x4_sse2<YesS3, YesS4, NI>: Vec4<<Avx2Machine<NI> as Machine>::u128x1>,
+    u128x4_sse2<YesS3, YesS4, NI>: Into<<Avx2Machine<NI> as Machine>::u32x4x4>,
+    u128x4_sse2<YesS3, YesS4, NI>: Into<<Avx2Machine<NI> as Machine>::u64x2x4>,
+{
+}
+
+macro_rules! impl_into_x {
+    ($from:ident, $to:ident) => {
+        impl<S3: Copy, S4: Copy, NI: Copy, Gf, Gt> From<x2<$from<S3, S4, NI>, Gf>>
+            for x2<$to<S3, S4, NI>, Gt>
+        {
+            #[inline(always)]
+            fn from(x: x2<$from<S3, S4, NI>, Gf>) -> Self {
+                x2::new([$to::from(x.0[0]), $to::from(x.0[1])])
+            }
+        }
+        impl<S3: Copy, S4: Copy, NI: Copy> From<x4<$from<S3, S4, NI>>> for x4<$to<S3, S4, NI>> {
+            #[inline(always)]
+            fn from(x: x4<$from<S3, S4, NI>>) -> Self {
+                x4::new([
+                    $to::from(x.0[0]),
+                    $to::from(x.0[1]),
+                    $to::from(x.0[2]),
+                    $to::from(x.0[3]),
+                ])
+            }
+        }
+    };
+}
+impl_into_x!(u128x1_sse2, u64x2_sse2);
+impl_into_x!(u128x1_sse2, u32x4_sse2);
+
+///// Debugging
+
+use core::fmt::{Debug, Formatter, Result};
+
+impl<W: PartialEq, G> PartialEq for x2<W, G> {
+    #[inline(always)]
+    fn eq(&self, rhs: &Self) -> bool {
+        self.0[0] == rhs.0[0] && self.0[1] == rhs.0[1]
+    }
+}
+
+#[inline(always)]
+unsafe fn eq128_s4(x: __m128i, y: __m128i) -> bool {
+    let q = _mm_shuffle_epi32(_mm_cmpeq_epi64(x, y), 0b1100_0110);
+    _mm_cvtsi128_si64(q) == -1
+}
+
+#[inline(always)]
+unsafe fn eq128_s2(x: __m128i, y: __m128i) -> bool {
+    let q = _mm_cmpeq_epi32(x, y);
+    let p = _mm_cvtsi128_si64(_mm_srli_si128(q, 8));
+    let q = _mm_cvtsi128_si64(q);
+    (p & q) == -1
+}
+
+impl<S3, S4, NI> PartialEq for u32x4_sse2<S3, S4, NI> {
+    #[inline(always)]
+    fn eq(&self, rhs: &Self) -> bool {
+        unsafe { eq128_s2(self.x, rhs.x) }
+    }
+}
+impl<S3, S4, NI> Debug for u32x4_sse2<S3, S4, NI>
+where
+    Self: Copy + MultiLane<[u32; 4]>,
+{
+    #[cold]
+    fn fmt(&self, fmt: &mut Formatter) -> Result {
+        fmt.write_fmt(format_args!("{:08x?}", &self.to_lanes()))
+    }
+}
+
+impl<S3, S4, NI> PartialEq for u64x2_sse2<S3, S4, NI> {
+    #[inline(always)]
+    fn eq(&self, rhs: &Self) -> bool {
+        unsafe { eq128_s2(self.x, rhs.x) }
+    }
+}
+impl<S3, S4, NI> Debug for u64x2_sse2<S3, S4, NI>
+where
+    Self: Copy + MultiLane<[u64; 2]>,
+{
+    #[cold]
+    fn fmt(&self, fmt: &mut Formatter) -> Result {
+        fmt.write_fmt(format_args!("{:016x?}", &self.to_lanes()))
+    }
+}
+
+impl<S3, S4, NI> Debug for u64x4_sse2<S3, S4, NI>
+where
+    u64x2_sse2<S3, S4, NI>: Copy + MultiLane<[u64; 2]>,
+{
+    #[cold]
+    fn fmt(&self, fmt: &mut Formatter) -> Result {
+        let (a, b) = (self.0[0].to_lanes(), self.0[1].to_lanes());
+        fmt.write_fmt(format_args!("{:016x?}", &[a[0], a[1], b[0], b[1]]))
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use crate::x86_64::{SSE2, SSE41, SSSE3};
+    use crate::Machine;
+
+    #[test]
+    #[cfg(target_arch = "x86_64")]
+    fn test_bswap32_s2_vs_s3() {
+        let xs = [0x0f0e_0d0c, 0x0b0a_0908, 0x0706_0504, 0x0302_0100];
+        let ys = [0x0c0d_0e0f, 0x0809_0a0b, 0x0405_0607, 0x0001_0203];
+
+        let s2 = unsafe { SSE2::instance() };
+        let s3 = unsafe { SSSE3::instance() };
+
+        let x_s2 = {
+            let x_s2: <SSE2 as Machine>::u32x4 = s2.vec(xs);
+            x_s2.bswap()
+        };
+
+        let x_s3 = {
+            let x_s3: <SSSE3 as Machine>::u32x4 = s3.vec(xs);
+            x_s3.bswap()
+        };
+
+        assert_eq!(x_s2, unsafe { core::mem::transmute(x_s3) });
+        assert_eq!(x_s2, s2.vec(ys));
+    }
+
+    #[test]
+    #[cfg(target_arch = "x86_64")]
+    fn test_bswap64_s2_vs_s3() {
+        let xs = [0x0f0e_0d0c_0b0a_0908, 0x0706_0504_0302_0100];
+        let ys = [0x0809_0a0b_0c0d_0e0f, 0x0001_0203_0405_0607];
+
+        let s2 = unsafe { SSE2::instance() };
+        let s3 = unsafe { SSSE3::instance() };
+
+        let x_s2 = {
+            let x_s2: <SSE2 as Machine>::u64x2 = s2.vec(xs);
+            x_s2.bswap()
+        };
+
+        let x_s3 = {
+            let x_s3: <SSSE3 as Machine>::u64x2 = s3.vec(xs);
+            x_s3.bswap()
+        };
+
+        assert_eq!(x_s2, s2.vec(ys));
+        assert_eq!(x_s3, unsafe { core::mem::transmute(x_s3) });
+    }
+
+    #[test]
+    #[cfg(target_arch = "x86_64")]
+    fn test_shuffle32_s2_vs_s3() {
+        let xs = [0x0, 0x1, 0x2, 0x3];
+        let ys = [0x2, 0x3, 0x0, 0x1];
+        let zs = [0x1, 0x2, 0x3, 0x0];
+
+        let s2 = unsafe { SSE2::instance() };
+        let s3 = unsafe { SSSE3::instance() };
+
+        let x_s2 = {
+            let x_s2: <SSE2 as Machine>::u32x4 = s2.vec(xs);
+            x_s2.shuffle2301()
+        };
+        let x_s3 = {
+            let x_s3: <SSSE3 as Machine>::u32x4 = s3.vec(xs);
+            x_s3.shuffle2301()
+        };
+        assert_eq!(x_s2, s2.vec(ys));
+        assert_eq!(x_s3, unsafe { core::mem::transmute(x_s3) });
+
+        let x_s2 = {
+            let x_s2: <SSE2 as Machine>::u32x4 = s2.vec(xs);
+            x_s2.shuffle3012()
+        };
+        let x_s3 = {
+            let x_s3: <SSSE3 as Machine>::u32x4 = s3.vec(xs);
+            x_s3.shuffle3012()
+        };
+        assert_eq!(x_s2, s2.vec(zs));
+        assert_eq!(x_s3, unsafe { core::mem::transmute(x_s3) });
+
+        let x_s2 = x_s2.shuffle1230();
+        let x_s3 = x_s3.shuffle1230();
+        assert_eq!(x_s2, s2.vec(xs));
+        assert_eq!(x_s3, unsafe { core::mem::transmute(x_s3) });
+    }
+
+    #[test]
+    #[cfg(target_arch = "x86_64")]
+    fn test_shuffle64_s2_vs_s3() {
+        let xs = [0x0, 0x1, 0x2, 0x3];
+        let ys = [0x2, 0x3, 0x0, 0x1];
+        let zs = [0x1, 0x2, 0x3, 0x0];
+
+        let s2 = unsafe { SSE2::instance() };
+        let s3 = unsafe { SSSE3::instance() };
+
+        let x_s2 = {
+            let x_s2: <SSE2 as Machine>::u64x4 = s2.vec(xs);
+            x_s2.shuffle2301()
+        };
+        let x_s3 = {
+            let x_s3: <SSSE3 as Machine>::u64x4 = s3.vec(xs);
+            x_s3.shuffle2301()
+        };
+        assert_eq!(x_s2, s2.vec(ys));
+        assert_eq!(x_s3, unsafe { core::mem::transmute(x_s3) });
+
+        let x_s2 = {
+            let x_s2: <SSE2 as Machine>::u64x4 = s2.vec(xs);
+            x_s2.shuffle3012()
+        };
+        let x_s3 = {
+            let x_s3: <SSSE3 as Machine>::u64x4 = s3.vec(xs);
+            x_s3.shuffle3012()
+        };
+        assert_eq!(x_s2, s2.vec(zs));
+        assert_eq!(x_s3, unsafe { core::mem::transmute(x_s3) });
+
+        let x_s2 = x_s2.shuffle1230();
+        let x_s3 = x_s3.shuffle1230();
+        assert_eq!(x_s2, s2.vec(xs));
+        assert_eq!(x_s3, unsafe { core::mem::transmute(x_s3) });
+    }
+
+    #[test]
+    #[cfg(target_arch = "x86_64")]
+    fn test_lanes_u32x4() {
+        let xs = [0x1, 0x2, 0x3, 0x4];
+
+        let s2 = unsafe { SSE2::instance() };
+        let s3 = unsafe { SSSE3::instance() };
+        let s4 = unsafe { SSE41::instance() };
+
+        {
+            let x_s2: <SSE2 as Machine>::u32x4 = s2.vec(xs);
+            let y_s2 = <SSE2 as Machine>::u32x4::from_lanes(xs);
+            assert_eq!(x_s2, y_s2);
+            assert_eq!(xs, y_s2.to_lanes());
+        }
+
+        {
+            let x_s3: <SSSE3 as Machine>::u32x4 = s3.vec(xs);
+            let y_s3 = <SSSE3 as Machine>::u32x4::from_lanes(xs);
+            assert_eq!(x_s3, y_s3);
+            assert_eq!(xs, y_s3.to_lanes());
+        }
+
+        {
+            let x_s4: <SSE41 as Machine>::u32x4 = s4.vec(xs);
+            let y_s4 = <SSE41 as Machine>::u32x4::from_lanes(xs);
+            assert_eq!(x_s4, y_s4);
+            assert_eq!(xs, y_s4.to_lanes());
+        }
+    }
+
+    #[test]
+    #[cfg(target_arch = "x86_64")]
+    fn test_lanes_u64x2() {
+        let xs = [0x1, 0x2];
+
+        let s2 = unsafe { SSE2::instance() };
+        let s3 = unsafe { SSSE3::instance() };
+        let s4 = unsafe { SSE41::instance() };
+
+        {
+            let x_s2: <SSE2 as Machine>::u64x2 = s2.vec(xs);
+            let y_s2 = <SSE2 as Machine>::u64x2::from_lanes(xs);
+            assert_eq!(x_s2, y_s2);
+            assert_eq!(xs, y_s2.to_lanes());
+        }
+
+        {
+            let x_s3: <SSSE3 as Machine>::u64x2 = s3.vec(xs);
+            let y_s3 = <SSSE3 as Machine>::u64x2::from_lanes(xs);
+            assert_eq!(x_s3, y_s3);
+            assert_eq!(xs, y_s3.to_lanes());
+        }
+
+        {
+            let x_s4: <SSE41 as Machine>::u64x2 = s4.vec(xs);
+            let y_s4 = <SSE41 as Machine>::u64x2::from_lanes(xs);
+            assert_eq!(x_s4, y_s4);
+            assert_eq!(xs, y_s4.to_lanes());
+        }
+    }
+
+    #[test]
+    #[cfg(target_arch = "x86_64")]
+    fn test_vec4_u32x4_s2() {
+        let xs = [1, 2, 3, 4];
+        let s2 = unsafe { SSE2::instance() };
+        let x_s2: <SSE2 as Machine>::u32x4 = s2.vec(xs);
+        assert_eq!(x_s2.extract(0), 1);
+        assert_eq!(x_s2.extract(1), 2);
+        assert_eq!(x_s2.extract(2), 3);
+        assert_eq!(x_s2.extract(3), 4);
+        assert_eq!(x_s2.insert(0xf, 0), s2.vec([0xf, 2, 3, 4]));
+        assert_eq!(x_s2.insert(0xf, 1), s2.vec([1, 0xf, 3, 4]));
+        assert_eq!(x_s2.insert(0xf, 2), s2.vec([1, 2, 0xf, 4]));
+        assert_eq!(x_s2.insert(0xf, 3), s2.vec([1, 2, 3, 0xf]));
+    }
+
+    #[test]
+    #[cfg(target_arch = "x86_64")]
+    fn test_vec4_u32x4_s4() {
+        let xs = [1, 2, 3, 4];
+        let s4 = unsafe { SSE41::instance() };
+        let x_s4: <SSE41 as Machine>::u32x4 = s4.vec(xs);
+        assert_eq!(x_s4.extract(0), 1);
+        assert_eq!(x_s4.extract(1), 2);
+        assert_eq!(x_s4.extract(2), 3);
+        assert_eq!(x_s4.extract(3), 4);
+        assert_eq!(x_s4.insert(0xf, 0), s4.vec([0xf, 2, 3, 4]));
+        assert_eq!(x_s4.insert(0xf, 1), s4.vec([1, 0xf, 3, 4]));
+        assert_eq!(x_s4.insert(0xf, 2), s4.vec([1, 2, 0xf, 4]));
+        assert_eq!(x_s4.insert(0xf, 3), s4.vec([1, 2, 3, 0xf]));
+    }
+
+    #[test]
+    #[cfg(target_arch = "x86_64")]
+    fn test_vec2_u64x2_s2() {
+        let xs = [0x1, 0x2];
+        let s2 = unsafe { SSE2::instance() };
+        let x_s2: <SSE2 as Machine>::u64x2 = s2.vec(xs);
+        assert_eq!(x_s2.extract(0), 1);
+        assert_eq!(x_s2.extract(1), 2);
+        assert_eq!(x_s2.insert(0xf, 0), s2.vec([0xf, 2]));
+        assert_eq!(x_s2.insert(0xf, 1), s2.vec([1, 0xf]));
+    }
+
+    #[test]
+    #[cfg(target_arch = "x86_64")]
+    fn test_vec4_u64x2_s4() {
+        let xs = [0x1, 0x2];
+        let s4 = unsafe { SSE41::instance() };
+        let x_s4: <SSE41 as Machine>::u64x2 = s4.vec(xs);
+        assert_eq!(x_s4.extract(0), 1);
+        assert_eq!(x_s4.extract(1), 2);
+        assert_eq!(x_s4.insert(0xf, 0), s4.vec([0xf, 2]));
+        assert_eq!(x_s4.insert(0xf, 1), s4.vec([1, 0xf]));
+    }
+}
+
+pub mod avx2 {
+    #![allow(non_camel_case_types)]
+    use crate::soft::x4;
+    use crate::types::*;
+    use crate::x86_64::sse2::{u128x1_sse2, u32x4_sse2};
+    use crate::x86_64::{vec256_storage, vec512_storage, Avx2Machine, YesS3, YesS4};
+    use core::arch::x86_64::*;
+    use core::marker::PhantomData;
+    use core::ops::*;
+
+    #[derive(Copy, Clone)]
+    pub struct u32x4x4_avx2<NI> {
+        x: [__m256i; 2],
+        ni: PhantomData<NI>,
+    }
+
+    impl<NI> u32x4x4_avx2<NI> {
+        #[inline(always)]
+        fn new(x: [__m256i; 2]) -> Self {
+            Self { x, ni: PhantomData }
+        }
+    }
+
+    impl<NI> u32x4x4<Avx2Machine<NI>> for u32x4x4_avx2<NI> where NI: Copy {}
+    impl<NI> Store<vec512_storage> for u32x4x4_avx2<NI> {
+        #[inline(always)]
+        unsafe fn unpack(p: vec512_storage) -> Self {
+            Self::new([p.avx[0].avx, p.avx[1].avx])
+        }
+    }
+    impl<NI> MultiLane<[u32x4_sse2<YesS3, YesS4, NI>; 4]> for u32x4x4_avx2<NI> {
+        #[inline(always)]
+        fn to_lanes(self) -> [u32x4_sse2<YesS3, YesS4, NI>; 4] {
+            unsafe {
+                [
+                    u32x4_sse2::new(_mm256_extracti128_si256(self.x[0], 0)),
+                    u32x4_sse2::new(_mm256_extracti128_si256(self.x[0], 1)),
+                    u32x4_sse2::new(_mm256_extracti128_si256(self.x[1], 0)),
+                    u32x4_sse2::new(_mm256_extracti128_si256(self.x[1], 1)),
+                ]
+            }
+        }
+        #[inline(always)]
+        fn from_lanes(x: [u32x4_sse2<YesS3, YesS4, NI>; 4]) -> Self {
+            Self::new(unsafe {
+                [
+                    _mm256_setr_m128i(x[0].x, x[1].x),
+                    _mm256_setr_m128i(x[2].x, x[3].x),
+                ]
+            })
+        }
+    }
+    impl<NI> Vec4<u32x4_sse2<YesS3, YesS4, NI>> for u32x4x4_avx2<NI> {
+        #[inline(always)]
+        fn extract(self, i: u32) -> u32x4_sse2<YesS3, YesS4, NI> {
+            unsafe {
+                match i {
+                    0 => u32x4_sse2::new(_mm256_extracti128_si256(self.x[0], 0)),
+                    1 => u32x4_sse2::new(_mm256_extracti128_si256(self.x[0], 1)),
+                    2 => u32x4_sse2::new(_mm256_extracti128_si256(self.x[1], 0)),
+                    3 => u32x4_sse2::new(_mm256_extracti128_si256(self.x[1], 1)),
+                    _ => panic!(),
+                }
+            }
+        }
+        #[inline(always)]
+        fn insert(self, w: u32x4_sse2<YesS3, YesS4, NI>, i: u32) -> Self {
+            Self::new(unsafe {
+                match i {
+                    0 => [_mm256_inserti128_si256(self.x[0], w.x, 0), self.x[1]],
+                    1 => [_mm256_inserti128_si256(self.x[0], w.x, 1), self.x[1]],
+                    2 => [self.x[0], _mm256_inserti128_si256(self.x[1], w.x, 0)],
+                    3 => [self.x[0], _mm256_inserti128_si256(self.x[1], w.x, 1)],
+                    _ => panic!(),
+                }
+            })
+        }
+    }
+    impl<NI> LaneWords4 for u32x4x4_avx2<NI> {
+        #[inline(always)]
+        fn shuffle_lane_words1230(self) -> Self {
+            Self::new(unsafe {
+                [
+                    _mm256_shuffle_epi32(self.x[0], 0b1001_0011),
+                    _mm256_shuffle_epi32(self.x[1], 0b1001_0011),
+                ]
+            })
+        }
+        #[inline(always)]
+        fn shuffle_lane_words2301(self) -> Self {
+            Self::new(unsafe {
+                [
+                    _mm256_shuffle_epi32(self.x[0], 0b0100_1110),
+                    _mm256_shuffle_epi32(self.x[1], 0b0100_1110),
+                ]
+            })
+        }
+        #[inline(always)]
+        fn shuffle_lane_words3012(self) -> Self {
+            Self::new(unsafe {
+                [
+                    _mm256_shuffle_epi32(self.x[0], 0b0011_1001),
+                    _mm256_shuffle_epi32(self.x[1], 0b0011_1001),
+                ]
+            })
+        }
+    }
+    impl<NI> BitOps32 for u32x4x4_avx2<NI> where NI: Copy {}
+    impl<NI> ArithOps for u32x4x4_avx2<NI> where NI: Copy {}
+    macro_rules! shuf_lane_bytes {
+        ($name:ident, $k0:expr, $k1:expr) => {
+        #[inline(always)]
+        fn $name(self) -> Self {
+            Self::new(unsafe {
+                [
+                    _mm256_shuffle_epi8(
+                        self.x[0],
+                        _mm256_set_epi64x($k0, $k1, $k0, $k1),
+                    ),
+                    _mm256_shuffle_epi8(
+                        self.x[1],
+                        _mm256_set_epi64x($k0, $k1, $k0, $k1),
+                    )
+                ]
+                })
+            }
+        };
+    }
+    macro_rules! rotr_32 {
+        ($name:ident, $i:expr) => {
+            #[inline(always)]
+            fn $name(self) -> Self {
+                Self::new(unsafe {
+                    [
+                        _mm256_or_si256(
+                            _mm256_srli_epi32(self.x[0], $i as i32),
+                            _mm256_slli_epi32(self.x[0], 32 - $i as i32),
+                        ),
+                        _mm256_or_si256(
+                            _mm256_srli_epi32(self.x[1], $i as i32),
+                            _mm256_slli_epi32(self.x[1], 32 - $i as i32),
+                        )
+                    ]
+                })
+            }
+        };
+    }
+    impl<NI: Copy> RotateEachWord32 for u32x4x4_avx2<NI> {
+        rotr_32!(rotate_each_word_right7, 7);
+        shuf_lane_bytes!(
+            rotate_each_word_right8,
+            0x0c0f0e0d_080b0a09,
+            0x04070605_00030201
+        );
+        rotr_32!(rotate_each_word_right11, 11);
+        rotr_32!(rotate_each_word_right12, 12);
+        shuf_lane_bytes!(
+            rotate_each_word_right16,
+            0x0d0c0f0e_09080b0a,
+            0x05040706_01000302
+        );
+        rotr_32!(rotate_each_word_right20, 20);
+        shuf_lane_bytes!(
+            rotate_each_word_right24,
+            0x0e0d0c0f_0a09080b,
+            0x06050407_02010003
+        );
+        rotr_32!(rotate_each_word_right25, 25);
+    }
+    impl<NI> BitOps0 for u32x4x4_avx2<NI> where NI: Copy {}
+    impl<NI> From<u32x4x4_avx2<NI>> for vec512_storage {
+        #[inline(always)]
+        fn from(x: u32x4x4_avx2<NI>) -> Self {
+            Self {
+                avx: [
+                    vec256_storage { avx: x.x[0] },
+                    vec256_storage { avx: x.x[1] },
+                ],
+            }
+        }
+    }
+
+    macro_rules! impl_assign {
+        ($vec:ident, $Assign:ident, $assign_fn:ident, $bin_fn:ident) => {
+            impl<NI> $Assign for $vec<NI>
+            where
+                NI: Copy,
+            {
+                #[inline(always)]
+                fn $assign_fn(&mut self, rhs: Self) {
+                    *self = self.$bin_fn(rhs);
+                }
+            }
+        };
+    }
+    impl_assign!(u32x4x4_avx2, BitXorAssign, bitxor_assign, bitxor);
+    impl_assign!(u32x4x4_avx2, BitOrAssign, bitor_assign, bitor);
+    impl_assign!(u32x4x4_avx2, BitAndAssign, bitand_assign, bitand);
+    impl_assign!(u32x4x4_avx2, AddAssign, add_assign, add);
+
+    macro_rules! impl_bitop_x2 {
+        ($vec:ident, $Op:ident, $op_fn:ident, $impl_fn:ident) => {
+            impl<NI> $Op for $vec<NI> {
+                type Output = Self;
+                #[inline(always)]
+                fn $op_fn(self, rhs: Self) -> Self::Output {
+                    Self::new(unsafe {
+                        [$impl_fn(self.x[0], rhs.x[0]), $impl_fn(self.x[1], rhs.x[1])]
+                    })
+                }
+            }
+        };
+    }
+    impl_bitop_x2!(u32x4x4_avx2, BitXor, bitxor, _mm256_xor_si256);
+    impl_bitop_x2!(u32x4x4_avx2, BitOr, bitor, _mm256_or_si256);
+    impl_bitop_x2!(u32x4x4_avx2, BitAnd, bitand, _mm256_and_si256);
+    impl_bitop_x2!(u32x4x4_avx2, AndNot, andnot, _mm256_andnot_si256);
+    impl_bitop_x2!(u32x4x4_avx2, Add, add, _mm256_add_epi32);
+
+    impl<NI> Not for u32x4x4_avx2<NI> {
+        type Output = Self;
+        #[inline(always)]
+        fn not(self) -> Self::Output {
+            unsafe {
+                let f = _mm256_set1_epi8(-0x7f);
+                Self::new([f, f]) ^ self
+            }
+        }
+    }
+
+    impl<NI> BSwap for u32x4x4_avx2<NI> {
+        shuf_lane_bytes!(bswap, 0x0c0d_0e0f_0809_0a0b, 0x0405_0607_0001_0203);
+    }
+
+    impl<NI> From<x4<u128x1_sse2<YesS3, YesS4, NI>>> for u32x4x4_avx2<NI>
+    where
+        NI: Copy,
+    {
+        #[inline(always)]
+        fn from(x: x4<u128x1_sse2<YesS3, YesS4, NI>>) -> Self {
+            Self::new(unsafe {
+                [
+                    _mm256_setr_m128i(x.0[0].x, x.0[1].x),
+                    _mm256_setr_m128i(x.0[2].x, x.0[3].x),
+                ]
+            })
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/bernoulli.rs.html b/target/doc/src/rand/distributions/bernoulli.rs.html new file mode 100644 index 0000000..737bc29 --- /dev/null +++ b/target/doc/src/rand/distributions/bernoulli.rs.html @@ -0,0 +1,335 @@ +bernoulli.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The Bernoulli distribution.
+
+use crate::Rng;
+use crate::distributions::Distribution;
+
+/// The Bernoulli distribution.
+///
+/// This is a special case of the Binomial distribution where `n = 1`.
+///
+/// # Example
+///
+/// ```rust
+/// use rand::distributions::{Bernoulli, Distribution};
+///
+/// let d = Bernoulli::new(0.3).unwrap();
+/// let v = d.sample(&mut rand::thread_rng());
+/// println!("{} is from a Bernoulli distribution", v);
+/// ```
+///
+/// # Precision
+///
+/// This `Bernoulli` distribution uses 64 bits from the RNG (a `u64`),
+/// so only probabilities that are multiples of 2<sup>-64</sup> can be
+/// represented.
+#[derive(Clone, Copy, Debug)]
+pub struct Bernoulli {
+    /// Probability of success, relative to the maximal integer.
+    p_int: u64,
+}
+
+// To sample from the Bernoulli distribution we use a method that compares a
+// random `u64` value `v < (p * 2^64)`.
+//
+// If `p == 1.0`, the integer `v` to compare against can not represented as a
+// `u64`. We manually set it to `u64::MAX` instead (2^64 - 1 instead of 2^64).
+// Note that  value of `p < 1.0` can never result in `u64::MAX`, because an
+// `f64` only has 53 bits of precision, and the next largest value of `p` will
+// result in `2^64 - 2048`.
+//
+// Also there is a 100% theoretical concern: if someone consistenly wants to
+// generate `true` using the Bernoulli distribution (i.e. by using a probability
+// of `1.0`), just using `u64::MAX` is not enough. On average it would return
+// false once every 2^64 iterations. Some people apparently care about this
+// case.
+//
+// That is why we special-case `u64::MAX` to always return `true`, without using
+// the RNG, and pay the performance price for all uses that *are* reasonable.
+// Luckily, if `new()` and `sample` are close, the compiler can optimize out the
+// extra check.
+const ALWAYS_TRUE: u64 = ::core::u64::MAX;
+
+// This is just `2.0.powi(64)`, but written this way because it is not available
+// in `no_std` mode.
+const SCALE: f64 = 2.0 * (1u64 << 63) as f64;
+
+/// Error type returned from `Bernoulli::new`.
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum BernoulliError {
+    /// `p < 0` or `p > 1`.
+    InvalidProbability,
+}
+
+impl Bernoulli {
+    /// Construct a new `Bernoulli` with the given probability of success `p`.
+    ///
+    /// # Precision
+    ///
+    /// For `p = 1.0`, the resulting distribution will always generate true.
+    /// For `p = 0.0`, the resulting distribution will always generate false.
+    ///
+    /// This method is accurate for any input `p` in the range `[0, 1]` which is
+    /// a multiple of 2<sup>-64</sup>. (Note that not all multiples of
+    /// 2<sup>-64</sup> in `[0, 1]` can be represented as a `f64`.)
+    #[inline]
+    pub fn new(p: f64) -> Result<Bernoulli, BernoulliError> {
+        if p < 0.0 || p >= 1.0 {
+            if p == 1.0 { return Ok(Bernoulli { p_int: ALWAYS_TRUE }) }
+            return Err(BernoulliError::InvalidProbability);
+        }
+        Ok(Bernoulli { p_int: (p * SCALE) as u64 })
+    }
+
+    /// Construct a new `Bernoulli` with the probability of success of
+    /// `numerator`-in-`denominator`. I.e. `new_ratio(2, 3)` will return
+    /// a `Bernoulli` with a 2-in-3 chance, or about 67%, of returning `true`.
+    ///
+    /// If `numerator == denominator` then the returned `Bernoulli` will always
+    /// return `true`. If `numerator == 0` it will always return `false`.
+    #[inline]
+    pub fn from_ratio(numerator: u32, denominator: u32) -> Result<Bernoulli, BernoulliError> {
+        if !(numerator <= denominator) {
+            return Err(BernoulliError::InvalidProbability);
+        }
+        if numerator == denominator {
+            return Ok(Bernoulli { p_int: ALWAYS_TRUE })
+        }
+        let p_int = ((numerator as f64 / denominator as f64) * SCALE) as u64;
+        Ok(Bernoulli { p_int })
+    }
+}
+
+impl Distribution<bool> for Bernoulli {
+    #[inline]
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> bool {
+        // Make sure to always return true for p = 1.0.
+        if self.p_int == ALWAYS_TRUE { return true; }
+        let v: u64 = rng.gen();
+        v < self.p_int
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use crate::Rng;
+    use crate::distributions::Distribution;
+    use super::Bernoulli;
+
+    #[test]
+    fn test_trivial() {
+        let mut r = crate::test::rng(1);
+        let always_false = Bernoulli::new(0.0).unwrap();
+        let always_true = Bernoulli::new(1.0).unwrap();
+        for _ in 0..5 {
+            assert_eq!(r.sample::<bool, _>(&always_false), false);
+            assert_eq!(r.sample::<bool, _>(&always_true), true);
+            assert_eq!(Distribution::<bool>::sample(&always_false, &mut r), false);
+            assert_eq!(Distribution::<bool>::sample(&always_true, &mut r), true);
+        }
+    }
+
+    #[test]
+    #[cfg(not(miri))] // Miri is too slow
+    fn test_average() {
+        const P: f64 = 0.3;
+        const NUM: u32 = 3;
+        const DENOM: u32 = 10;
+        let d1 = Bernoulli::new(P).unwrap();
+        let d2 = Bernoulli::from_ratio(NUM, DENOM).unwrap();
+        const N: u32 = 100_000;
+
+        let mut sum1: u32 = 0;
+        let mut sum2: u32 = 0;
+        let mut rng = crate::test::rng(2);
+        for _ in 0..N {
+            if d1.sample(&mut rng) {
+                sum1 += 1;
+            }
+            if d2.sample(&mut rng) {
+                sum2 += 1;
+            }
+        }
+        let avg1 = (sum1 as f64) / (N as f64);
+        assert!((avg1 - P).abs() < 5e-3);
+
+        let avg2 = (sum2 as f64) / (N as f64);
+        assert!((avg2 - (NUM as f64)/(DENOM as f64)).abs() < 5e-3);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/binomial.rs.html b/target/doc/src/rand/distributions/binomial.rs.html new file mode 100644 index 0000000..e03a669 --- /dev/null +++ b/target/doc/src/rand/distributions/binomial.rs.html @@ -0,0 +1,627 @@ +binomial.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+
+// Copyright 2018 Developers of the Rand project.
+// Copyright 2016-2017 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The binomial distribution.
+#![allow(deprecated)]
+
+use crate::Rng;
+use crate::distributions::{Distribution, Uniform};
+
+/// The binomial distribution `Binomial(n, p)`.
+///
+/// This distribution has density function:
+/// `f(k) = n!/(k! (n-k)!) p^k (1-p)^(n-k)` for `k >= 0`.
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Copy, Debug)]
+pub struct Binomial {
+    /// Number of trials.
+    n: u64,
+    /// Probability of success.
+    p: f64,
+}
+
+impl Binomial {
+    /// Construct a new `Binomial` with the given shape parameters `n` (number
+    /// of trials) and `p` (probability of success).
+    ///
+    /// Panics if `p < 0` or `p > 1`.
+    pub fn new(n: u64, p: f64) -> Binomial {
+        assert!(p >= 0.0, "Binomial::new called with p < 0");
+        assert!(p <= 1.0, "Binomial::new called with p > 1");
+        Binomial { n, p }
+    }
+}
+
+/// Convert a `f64` to an `i64`, panicing on overflow.
+// In the future (Rust 1.34), this might be replaced with `TryFrom`.
+fn f64_to_i64(x: f64) -> i64 {
+    assert!(x < (::std::i64::MAX as f64));
+    x as i64
+}
+
+impl Distribution<u64> for Binomial {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u64 {
+        // Handle these values directly.
+        if self.p == 0.0 {
+            return 0;
+        } else if self.p == 1.0 {
+            return self.n;
+        }
+
+        // The binomial distribution is symmetrical with respect to p -> 1-p,
+        // k -> n-k switch p so that it is less than 0.5 - this allows for lower
+        // expected values we will just invert the result at the end
+        let p = if self.p <= 0.5 {
+            self.p
+        } else {
+            1.0 - self.p
+        };
+
+        let result;
+        let q = 1. - p;
+
+        // For small n * min(p, 1 - p), the BINV algorithm based on the inverse
+        // transformation of the binomial distribution is efficient. Otherwise,
+        // the BTPE algorithm is used.
+        //
+        // Voratas Kachitvichyanukul and Bruce W. Schmeiser. 1988. Binomial
+        // random variate generation. Commun. ACM 31, 2 (February 1988),
+        // 216-222. http://dx.doi.org/10.1145/42372.42381
+
+        // Threshold for prefering the BINV algorithm. The paper suggests 10,
+        // Ranlib uses 30, and GSL uses 14.
+        const BINV_THRESHOLD: f64 = 10.;
+
+        if (self.n as f64) * p < BINV_THRESHOLD &&
+           self.n <= (::std::i32::MAX as u64) {
+            // Use the BINV algorithm.
+            let s = p / q;
+            let a = ((self.n + 1) as f64) * s;
+            let mut r = q.powi(self.n as i32);
+            let mut u: f64 = rng.gen();
+            let mut x = 0;
+            while u > r as f64 {
+                u -= r;
+                x += 1;
+                r *= a / (x as f64) - s;
+            }
+            result = x;
+        } else {
+            // Use the BTPE algorithm.
+
+            // Threshold for using the squeeze algorithm. This can be freely
+            // chosen based on performance. Ranlib and GSL use 20.
+            const SQUEEZE_THRESHOLD: i64 = 20;
+
+            // Step 0: Calculate constants as functions of `n` and `p`.
+            let n = self.n as f64;
+            let np = n * p;
+            let npq = np * q;
+            let f_m = np + p;
+            let m = f64_to_i64(f_m);
+            // radius of triangle region, since height=1 also area of region
+            let p1 = (2.195 * npq.sqrt() - 4.6 * q).floor() + 0.5;
+            // tip of triangle
+            let x_m = (m as f64) + 0.5;
+            // left edge of triangle
+            let x_l = x_m - p1;
+            // right edge of triangle
+            let x_r = x_m + p1;
+            let c = 0.134 + 20.5 / (15.3 + (m as f64));
+            // p1 + area of parallelogram region
+            let p2 = p1 * (1. + 2. * c);
+
+            fn lambda(a: f64) -> f64 {
+                a * (1. + 0.5 * a)
+            }
+
+            let lambda_l = lambda((f_m - x_l) / (f_m - x_l * p));
+            let lambda_r = lambda((x_r - f_m) / (x_r * q));
+            // p1 + area of left tail
+            let p3 = p2 + c / lambda_l;
+            // p1 + area of right tail
+            let p4 = p3 + c / lambda_r;
+
+            // return value
+            let mut y: i64;
+
+            let gen_u = Uniform::new(0., p4);
+            let gen_v = Uniform::new(0., 1.);
+
+            loop {
+                // Step 1: Generate `u` for selecting the region. If region 1 is
+                // selected, generate a triangularly distributed variate.
+                let u = gen_u.sample(rng);
+                let mut v = gen_v.sample(rng);
+                if !(u > p1) {
+                    y = f64_to_i64(x_m - p1 * v + u);
+                    break;
+                }
+
+                if !(u > p2) {
+                    // Step 2: Region 2, parallelograms. Check if region 2 is
+                    // used. If so, generate `y`.
+                    let x = x_l + (u - p1) / c;
+                    v = v * c + 1.0 - (x - x_m).abs() / p1;
+                    if v > 1. {
+                        continue;
+                    } else {
+                        y = f64_to_i64(x);
+                    }
+                } else if !(u > p3) {
+                    // Step 3: Region 3, left exponential tail.
+                    y = f64_to_i64(x_l + v.ln() / lambda_l);
+                    if y < 0 {
+                        continue;
+                    } else {
+                        v *= (u - p2) * lambda_l;
+                    }
+                } else {
+                    // Step 4: Region 4, right exponential tail.
+                    y = f64_to_i64(x_r - v.ln() / lambda_r);
+                    if y > 0 && (y as u64) > self.n {
+                        continue;
+                    } else {
+                        v *= (u - p3) * lambda_r;
+                    }
+                }
+
+                // Step 5: Acceptance/rejection comparison.
+
+                // Step 5.0: Test for appropriate method of evaluating f(y).
+                let k = (y - m).abs();
+                if !(k > SQUEEZE_THRESHOLD && (k as f64) < 0.5 * npq - 1.) {
+                    // Step 5.1: Evaluate f(y) via the recursive relationship. Start the
+                    // search from the mode.
+                    let s = p / q;
+                    let a = s * (n + 1.);
+                    let mut f = 1.0;
+                    if m < y {
+                        let mut i = m;
+                        loop {
+                            i += 1;
+                            f *= a / (i as f64) - s;
+                            if i == y {
+                                break;
+                            }
+                        }
+                    } else if m > y {
+                        let mut i = y;
+                        loop {
+                            i += 1;
+                            f /= a / (i as f64) - s;
+                            if i == m {
+                                break;
+                            }
+                        }
+                    }
+                    if v > f {
+                        continue;
+                    } else {
+                        break;
+                    }
+                }
+
+                // Step 5.2: Squeezing. Check the value of ln(v) againts upper and
+                // lower bound of ln(f(y)).
+                let k = k as f64;
+                let rho = (k / npq) * ((k * (k / 3. + 0.625) + 1./6.) / npq + 0.5);
+                let t = -0.5 * k*k / npq;
+                let alpha = v.ln();
+                if alpha < t - rho {
+                    break;
+                }
+                if alpha > t + rho {
+                    continue;
+                }
+
+                // Step 5.3: Final acceptance/rejection test.
+                let x1 = (y + 1) as f64;
+                let f1 = (m + 1) as f64;
+                let z = (f64_to_i64(n) + 1 - m) as f64;
+                let w = (f64_to_i64(n) - y + 1) as f64;
+
+                fn stirling(a: f64) -> f64 {
+                    let a2 = a * a;
+                    (13860. - (462. - (132. - (99. - 140. / a2) / a2) / a2) / a2) / a / 166320.
+                }
+
+                if alpha > x_m * (f1 / x1).ln()
+                    + (n - (m as f64) + 0.5) * (z / w).ln()
+                    + ((y - m) as f64) * (w * p / (x1 * q)).ln()
+                    // We use the signs from the GSL implementation, which are
+                    // different than the ones in the reference. According to
+                    // the GSL authors, the new signs were verified to be
+                    // correct by one of the original designers of the
+                    // algorithm.
+                    + stirling(f1) + stirling(z) - stirling(x1) - stirling(w)
+                {
+                    continue;
+                }
+
+                break;
+            }
+            assert!(y >= 0);
+            result = y as u64;
+        }
+
+        // Invert the result for p < 0.5.
+        if p != self.p {
+            self.n - result
+        } else {
+            result
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use crate::Rng;
+    use crate::distributions::Distribution;
+    use super::Binomial;
+
+    fn test_binomial_mean_and_variance<R: Rng>(n: u64, p: f64, rng: &mut R) {
+        let binomial = Binomial::new(n, p);
+
+        let expected_mean = n as f64 * p;
+        let expected_variance = n as f64 * p * (1.0 - p);
+
+        let mut results = [0.0; 1000];
+        for i in results.iter_mut() { *i = binomial.sample(rng) as f64; }
+
+        let mean = results.iter().sum::<f64>() / results.len() as f64;
+        assert!((mean as f64 - expected_mean).abs() < expected_mean / 50.0,
+                "mean: {}, expected_mean: {}", mean, expected_mean);
+
+        let variance =
+            results.iter().map(|x| (x - mean) * (x - mean)).sum::<f64>()
+            / results.len() as f64;
+        assert!((variance - expected_variance).abs() < expected_variance / 10.0,
+                "variance: {}, expected_variance: {}", variance, expected_variance);
+    }
+
+    #[test]
+    #[cfg(not(miri))] // Miri is too slow
+    fn test_binomial() {
+        let mut rng = crate::test::rng(351);
+        test_binomial_mean_and_variance(150, 0.1, &mut rng);
+        test_binomial_mean_and_variance(70, 0.6, &mut rng);
+        test_binomial_mean_and_variance(40, 0.5, &mut rng);
+        test_binomial_mean_and_variance(20, 0.7, &mut rng);
+        test_binomial_mean_and_variance(20, 0.5, &mut rng);
+    }
+
+    #[test]
+    fn test_binomial_end_points() {
+        let mut rng = crate::test::rng(352);
+        assert_eq!(rng.sample(Binomial::new(20, 0.0)), 0);
+        assert_eq!(rng.sample(Binomial::new(20, 1.0)), 20);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_binomial_invalid_lambda_neg() {
+        Binomial::new(20, -10.0);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/cauchy.rs.html b/target/doc/src/rand/distributions/cauchy.rs.html new file mode 100644 index 0000000..9b44c58 --- /dev/null +++ b/target/doc/src/rand/distributions/cauchy.rs.html @@ -0,0 +1,207 @@ +cauchy.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+
+// Copyright 2018 Developers of the Rand project.
+// Copyright 2016-2017 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The Cauchy distribution.
+#![allow(deprecated)]
+
+use crate::Rng;
+use crate::distributions::Distribution;
+use std::f64::consts::PI;
+
+/// The Cauchy distribution `Cauchy(median, scale)`.
+///
+/// This distribution has a density function:
+/// `f(x) = 1 / (pi * scale * (1 + ((x - median) / scale)^2))`
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Copy, Debug)]
+pub struct Cauchy {
+    median: f64,
+    scale: f64
+}
+
+impl Cauchy {
+    /// Construct a new `Cauchy` with the given shape parameters
+    /// `median` the peak location and `scale` the scale factor.
+    /// Panics if `scale <= 0`.
+    pub fn new(median: f64, scale: f64) -> Cauchy {
+        assert!(scale > 0.0, "Cauchy::new called with scale factor <= 0");
+        Cauchy {
+            median,
+            scale
+        }
+    }
+}
+
+impl Distribution<f64> for Cauchy {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
+        // sample from [0, 1)
+        let x = rng.gen::<f64>();
+        // get standard cauchy random number
+        // note that π/2 is not exactly representable, even if x=0.5 the result is finite
+        let comp_dev = (PI * x).tan();
+        // shift and scale according to parameters
+        let result = self.median + self.scale * comp_dev;
+        result
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use crate::distributions::Distribution;
+    use super::Cauchy;
+
+    fn median(mut numbers: &mut [f64]) -> f64 {
+        sort(&mut numbers);
+        let mid = numbers.len() / 2;
+        numbers[mid]
+    }
+
+    fn sort(numbers: &mut [f64]) {
+        numbers.sort_by(|a, b| a.partial_cmp(b).unwrap());
+    }
+
+    #[test]
+    #[cfg(not(miri))] // Miri doesn't support transcendental functions
+    fn test_cauchy_averages() {
+        // NOTE: given that the variance and mean are undefined,
+        // this test does not have any rigorous statistical meaning.
+        let cauchy = Cauchy::new(10.0, 5.0);
+        let mut rng = crate::test::rng(123);
+        let mut numbers: [f64; 1000] = [0.0; 1000];
+        let mut sum = 0.0;
+        for i in 0..1000 {
+            numbers[i] = cauchy.sample(&mut rng);
+            sum += numbers[i];
+        }
+        let median = median(&mut numbers);
+        println!("Cauchy median: {}", median);
+        assert!((median - 10.0).abs() < 0.4); // not 100% certain, but probable enough
+        let mean = sum / 1000.0;
+        println!("Cauchy mean: {}", mean);
+        // for a Cauchy distribution the mean should not converge
+        assert!((mean - 10.0).abs() > 0.4); // not 100% certain, but probable enough
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_cauchy_invalid_scale_zero() {
+        Cauchy::new(0.0, 0.0);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_cauchy_invalid_scale_neg() {
+        Cauchy::new(0.0, -10.0);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/dirichlet.rs.html b/target/doc/src/rand/distributions/dirichlet.rs.html new file mode 100644 index 0000000..7153619 --- /dev/null +++ b/target/doc/src/rand/distributions/dirichlet.rs.html @@ -0,0 +1,257 @@ +dirichlet.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+
+// Copyright 2018 Developers of the Rand project.
+// Copyright 2013 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The dirichlet distribution.
+#![allow(deprecated)]
+
+use crate::Rng;
+use crate::distributions::Distribution;
+use crate::distributions::gamma::Gamma;
+
+/// The dirichelet distribution `Dirichlet(alpha)`.
+///
+/// The Dirichlet distribution is a family of continuous multivariate
+/// probability distributions parameterized by a vector alpha of positive reals.
+/// It is a multivariate generalization of the beta distribution.
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Debug)]
+pub struct Dirichlet {
+    /// Concentration parameters (alpha)
+    alpha: Vec<f64>,
+}
+
+impl Dirichlet {
+    /// Construct a new `Dirichlet` with the given alpha parameter `alpha`.
+    ///
+    /// # Panics
+    /// - if `alpha.len() < 2`
+    ///
+    #[inline]
+    pub fn new<V: Into<Vec<f64>>>(alpha: V) -> Dirichlet {
+        let a = alpha.into();
+        assert!(a.len() > 1);
+        for i in 0..a.len() {
+            assert!(a[i] > 0.0);
+        }
+
+        Dirichlet { alpha: a }
+    }
+
+    /// Construct a new `Dirichlet` with the given shape parameter `alpha` and `size`.
+    ///
+    /// # Panics
+    /// - if `alpha <= 0.0`
+    /// - if `size < 2`
+    ///
+    #[inline]
+    pub fn new_with_param(alpha: f64, size: usize) -> Dirichlet {
+        assert!(alpha > 0.0);
+        assert!(size > 1);
+        Dirichlet {
+            alpha: vec![alpha; size],
+        }
+    }
+}
+
+impl Distribution<Vec<f64>> for Dirichlet {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec<f64> {
+        let n = self.alpha.len();
+        let mut samples = vec![0.0f64; n];
+        let mut sum = 0.0f64;
+
+        for i in 0..n {
+            let g = Gamma::new(self.alpha[i], 1.0);
+            samples[i] = g.sample(rng);
+            sum += samples[i];
+        }
+        let invacc = 1.0 / sum;
+        for i in 0..n {
+            samples[i] *= invacc;
+        }
+        samples
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::Dirichlet;
+    use crate::distributions::Distribution;
+
+    #[test]
+    fn test_dirichlet() {
+        let d = Dirichlet::new(vec![1.0, 2.0, 3.0]);
+        let mut rng = crate::test::rng(221);
+        let samples = d.sample(&mut rng);
+        let _: Vec<f64> = samples
+            .into_iter()
+            .map(|x| {
+                assert!(x > 0.0);
+                x
+            })
+            .collect();
+    }
+
+    #[test]
+    fn test_dirichlet_with_param() {
+        let alpha = 0.5f64;
+        let size = 2;
+        let d = Dirichlet::new_with_param(alpha, size);
+        let mut rng = crate::test::rng(221);
+        let samples = d.sample(&mut rng);
+        let _: Vec<f64> = samples
+            .into_iter()
+            .map(|x| {
+                assert!(x > 0.0);
+                x
+            })
+            .collect();
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_dirichlet_invalid_length() {
+        Dirichlet::new_with_param(0.5f64, 1);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_dirichlet_invalid_alpha() {
+        Dirichlet::new_with_param(0.0f64, 2);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/exponential.rs.html b/target/doc/src/rand/distributions/exponential.rs.html new file mode 100644 index 0000000..7043bab --- /dev/null +++ b/target/doc/src/rand/distributions/exponential.rs.html @@ -0,0 +1,219 @@ +exponential.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+
+// Copyright 2018 Developers of the Rand project.
+// Copyright 2013 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The exponential distribution.
+#![allow(deprecated)]
+
+use crate::{Rng};
+use crate::distributions::{ziggurat_tables, Distribution};
+use crate::distributions::utils::ziggurat;
+
+/// Samples floating-point numbers according to the exponential distribution,
+/// with rate parameter `λ = 1`. This is equivalent to `Exp::new(1.0)` or
+/// sampling with `-rng.gen::<f64>().ln()`, but faster.
+///
+/// See `Exp` for the general exponential distribution.
+///
+/// Implemented via the ZIGNOR variant[^1] of the Ziggurat method. The exact
+/// description in the paper was adjusted to use tables for the exponential
+/// distribution rather than normal.
+///
+/// [^1]: Jurgen A. Doornik (2005). [*An Improved Ziggurat Method to
+///       Generate Normal Random Samples*](
+///       https://www.doornik.com/research/ziggurat.pdf).
+///       Nuffield College, Oxford
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Copy, Debug)]
+pub struct Exp1;
+
+// This could be done via `-rng.gen::<f64>().ln()` but that is slower.
+impl Distribution<f64> for Exp1 {
+    #[inline]
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
+        #[inline]
+        fn pdf(x: f64) -> f64 {
+            (-x).exp()
+        }
+        #[inline]
+        fn zero_case<R: Rng + ?Sized>(rng: &mut R, _u: f64) -> f64 {
+            ziggurat_tables::ZIG_EXP_R - rng.gen::<f64>().ln()
+        }
+
+        ziggurat(rng, false,
+                 &ziggurat_tables::ZIG_EXP_X,
+                 &ziggurat_tables::ZIG_EXP_F,
+                 pdf, zero_case)
+    }
+}
+
+/// The exponential distribution `Exp(lambda)`.
+///
+/// This distribution has density function: `f(x) = lambda * exp(-lambda * x)`
+/// for `x > 0`.
+/// 
+/// Note that [`Exp1`][crate::distributions::Exp1] is an optimised implementation for `lambda = 1`.
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Copy, Debug)]
+pub struct Exp {
+    /// `lambda` stored as `1/lambda`, since this is what we scale by.
+    lambda_inverse: f64
+}
+
+impl Exp {
+    /// Construct a new `Exp` with the given shape parameter
+    /// `lambda`. Panics if `lambda <= 0`.
+    #[inline]
+    pub fn new(lambda: f64) -> Exp {
+        assert!(lambda > 0.0, "Exp::new called with `lambda` <= 0");
+        Exp { lambda_inverse: 1.0 / lambda }
+    }
+}
+
+impl Distribution<f64> for Exp {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
+        let n: f64 = rng.sample(Exp1);
+        n * self.lambda_inverse
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use crate::distributions::Distribution;
+    use super::Exp;
+
+    #[test]
+    fn test_exp() {
+        let exp = Exp::new(10.0);
+        let mut rng = crate::test::rng(221);
+        for _ in 0..1000 {
+            assert!(exp.sample(&mut rng) >= 0.0);
+        }
+    }
+    #[test]
+    #[should_panic]
+    fn test_exp_invalid_lambda_zero() {
+        Exp::new(0.0);
+    }
+    #[test]
+    #[should_panic]
+    fn test_exp_invalid_lambda_neg() {
+        Exp::new(-10.0);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/float.rs.html b/target/doc/src/rand/distributions/float.rs.html new file mode 100644 index 0000000..0814b62 --- /dev/null +++ b/target/doc/src/rand/distributions/float.rs.html @@ -0,0 +1,525 @@ +float.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Basic floating-point number distributions
+
+use core::mem;
+use crate::Rng;
+use crate::distributions::{Distribution, Standard};
+use crate::distributions::utils::FloatSIMDUtils;
+#[cfg(feature="simd_support")]
+use packed_simd::*;
+
+/// A distribution to sample floating point numbers uniformly in the half-open
+/// interval `(0, 1]`, i.e. including 1 but not 0.
+///
+/// All values that can be generated are of the form `n * ε/2`. For `f32`
+/// the 23 most significant random bits of a `u32` are used and for `f64` the
+/// 53 most significant bits of a `u64` are used. The conversion uses the
+/// multiplicative method.
+///
+/// See also: [`Standard`] which samples from `[0, 1)`, [`Open01`]
+/// which samples from `(0, 1)` and [`Uniform`] which samples from arbitrary
+/// ranges.
+///
+/// # Example
+/// ```
+/// use rand::{thread_rng, Rng};
+/// use rand::distributions::OpenClosed01;
+///
+/// let val: f32 = thread_rng().sample(OpenClosed01);
+/// println!("f32 from (0, 1): {}", val);
+/// ```
+///
+/// [`Standard`]: crate::distributions::Standard
+/// [`Open01`]: crate::distributions::Open01
+/// [`Uniform`]: crate::distributions::uniform::Uniform
+#[derive(Clone, Copy, Debug)]
+pub struct OpenClosed01;
+
+/// A distribution to sample floating point numbers uniformly in the open
+/// interval `(0, 1)`, i.e. not including either endpoint.
+///
+/// All values that can be generated are of the form `n * ε + ε/2`. For `f32`
+/// the 22 most significant random bits of an `u32` are used, for `f64` 52 from
+/// an `u64`. The conversion uses a transmute-based method.
+///
+/// See also: [`Standard`] which samples from `[0, 1)`, [`OpenClosed01`]
+/// which samples from `(0, 1]` and [`Uniform`] which samples from arbitrary
+/// ranges.
+///
+/// # Example
+/// ```
+/// use rand::{thread_rng, Rng};
+/// use rand::distributions::Open01;
+///
+/// let val: f32 = thread_rng().sample(Open01);
+/// println!("f32 from (0, 1): {}", val);
+/// ```
+///
+/// [`Standard`]: crate::distributions::Standard
+/// [`OpenClosed01`]: crate::distributions::OpenClosed01
+/// [`Uniform`]: crate::distributions::uniform::Uniform
+#[derive(Clone, Copy, Debug)]
+pub struct Open01;
+
+
+// This trait is needed by both this lib and rand_distr hence is a hidden export
+#[doc(hidden)]
+pub trait IntoFloat {
+    type F;
+
+    /// Helper method to combine the fraction and a contant exponent into a
+    /// float.
+    ///
+    /// Only the least significant bits of `self` may be set, 23 for `f32` and
+    /// 52 for `f64`.
+    /// The resulting value will fall in a range that depends on the exponent.
+    /// As an example the range with exponent 0 will be
+    /// [2<sup>0</sup>..2<sup>1</sup>), which is [1..2).
+    fn into_float_with_exponent(self, exponent: i32) -> Self::F;
+}
+
+macro_rules! float_impls {
+    ($ty:ident, $uty:ident, $f_scalar:ident, $u_scalar:ty,
+     $fraction_bits:expr, $exponent_bias:expr) => {
+        impl IntoFloat for $uty {
+            type F = $ty;
+            #[inline(always)]
+            fn into_float_with_exponent(self, exponent: i32) -> $ty {
+                // The exponent is encoded using an offset-binary representation
+                let exponent_bits: $u_scalar =
+                    (($exponent_bias + exponent) as $u_scalar) << $fraction_bits;
+                // TODO: use from_bits when min compiler > 1.25 (see #545)
+                // $ty::from_bits(self | exponent_bits)
+                unsafe{ mem::transmute(self | exponent_bits) }
+            }
+        }
+
+        impl Distribution<$ty> for Standard {
+            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $ty {
+                // Multiply-based method; 24/53 random bits; [0, 1) interval.
+                // We use the most significant bits because for simple RNGs
+                // those are usually more random.
+                let float_size = mem::size_of::<$f_scalar>() as u32 * 8;
+                let precision = $fraction_bits + 1;
+                let scale = 1.0 / ((1 as $u_scalar << precision) as $f_scalar);
+
+                let value: $uty = rng.gen();
+                let value = value >> (float_size - precision);
+                scale * $ty::cast_from_int(value)
+            }
+        }
+
+        impl Distribution<$ty> for OpenClosed01 {
+            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $ty {
+                // Multiply-based method; 24/53 random bits; (0, 1] interval.
+                // We use the most significant bits because for simple RNGs
+                // those are usually more random.
+                let float_size = mem::size_of::<$f_scalar>() as u32 * 8;
+                let precision = $fraction_bits + 1;
+                let scale = 1.0 / ((1 as $u_scalar << precision) as $f_scalar);
+
+                let value: $uty = rng.gen();
+                let value = value >> (float_size - precision);
+                // Add 1 to shift up; will not overflow because of right-shift:
+                scale * $ty::cast_from_int(value + 1)
+            }
+        }
+
+        impl Distribution<$ty> for Open01 {
+            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $ty {
+                // Transmute-based method; 23/52 random bits; (0, 1) interval.
+                // We use the most significant bits because for simple RNGs
+                // those are usually more random.
+                use core::$f_scalar::EPSILON;
+                let float_size = mem::size_of::<$f_scalar>() as u32 * 8;
+
+                let value: $uty = rng.gen();
+                let fraction = value >> (float_size - $fraction_bits);
+                fraction.into_float_with_exponent(0) - (1.0 - EPSILON / 2.0)
+            }
+        }
+    }
+}
+
+float_impls! { f32, u32, f32, u32, 23, 127 }
+float_impls! { f64, u64, f64, u64, 52, 1023 }
+
+#[cfg(feature="simd_support")]
+float_impls! { f32x2, u32x2, f32, u32, 23, 127 }
+#[cfg(feature="simd_support")]
+float_impls! { f32x4, u32x4, f32, u32, 23, 127 }
+#[cfg(feature="simd_support")]
+float_impls! { f32x8, u32x8, f32, u32, 23, 127 }
+#[cfg(feature="simd_support")]
+float_impls! { f32x16, u32x16, f32, u32, 23, 127 }
+
+#[cfg(feature="simd_support")]
+float_impls! { f64x2, u64x2, f64, u64, 52, 1023 }
+#[cfg(feature="simd_support")]
+float_impls! { f64x4, u64x4, f64, u64, 52, 1023 }
+#[cfg(feature="simd_support")]
+float_impls! { f64x8, u64x8, f64, u64, 52, 1023 }
+
+
+#[cfg(test)]
+mod tests {
+    use crate::Rng;
+    use crate::distributions::{Open01, OpenClosed01};
+    use crate::rngs::mock::StepRng;
+    #[cfg(feature="simd_support")]
+    use packed_simd::*;
+
+    const EPSILON32: f32 = ::core::f32::EPSILON;
+    const EPSILON64: f64 = ::core::f64::EPSILON;
+
+    macro_rules! test_f32 {
+        ($fnn:ident, $ty:ident, $ZERO:expr, $EPSILON:expr) => {
+            #[test]
+            fn $fnn() {
+                // Standard
+                let mut zeros = StepRng::new(0, 0);
+                assert_eq!(zeros.gen::<$ty>(), $ZERO);
+                let mut one = StepRng::new(1 << 8 | 1 << (8 + 32), 0);
+                assert_eq!(one.gen::<$ty>(), $EPSILON / 2.0);
+                let mut max = StepRng::new(!0, 0);
+                assert_eq!(max.gen::<$ty>(), 1.0 - $EPSILON / 2.0);
+
+                // OpenClosed01
+                let mut zeros = StepRng::new(0, 0);
+                assert_eq!(zeros.sample::<$ty, _>(OpenClosed01),
+                           0.0 + $EPSILON / 2.0);
+                let mut one = StepRng::new(1 << 8 | 1 << (8 + 32), 0);
+                assert_eq!(one.sample::<$ty, _>(OpenClosed01), $EPSILON);
+                let mut max = StepRng::new(!0, 0);
+                assert_eq!(max.sample::<$ty, _>(OpenClosed01), $ZERO + 1.0);
+
+                // Open01
+                let mut zeros = StepRng::new(0, 0);
+                assert_eq!(zeros.sample::<$ty, _>(Open01), 0.0 + $EPSILON / 2.0);
+                let mut one = StepRng::new(1 << 9 | 1 << (9 + 32), 0);
+                assert_eq!(one.sample::<$ty, _>(Open01), $EPSILON / 2.0 * 3.0);
+                let mut max = StepRng::new(!0, 0);
+                assert_eq!(max.sample::<$ty, _>(Open01), 1.0 - $EPSILON / 2.0);
+            }
+        }
+    }
+    test_f32! { f32_edge_cases, f32, 0.0, EPSILON32 }
+    #[cfg(feature="simd_support")]
+    test_f32! { f32x2_edge_cases, f32x2, f32x2::splat(0.0), f32x2::splat(EPSILON32) }
+    #[cfg(feature="simd_support")]
+    test_f32! { f32x4_edge_cases, f32x4, f32x4::splat(0.0), f32x4::splat(EPSILON32) }
+    #[cfg(feature="simd_support")]
+    test_f32! { f32x8_edge_cases, f32x8, f32x8::splat(0.0), f32x8::splat(EPSILON32) }
+    #[cfg(feature="simd_support")]
+    test_f32! { f32x16_edge_cases, f32x16, f32x16::splat(0.0), f32x16::splat(EPSILON32) }
+
+    macro_rules! test_f64 {
+        ($fnn:ident, $ty:ident, $ZERO:expr, $EPSILON:expr) => {
+            #[test]
+            fn $fnn() {
+                // Standard
+                let mut zeros = StepRng::new(0, 0);
+                assert_eq!(zeros.gen::<$ty>(), $ZERO);
+                let mut one = StepRng::new(1 << 11, 0);
+                assert_eq!(one.gen::<$ty>(), $EPSILON / 2.0);
+                let mut max = StepRng::new(!0, 0);
+                assert_eq!(max.gen::<$ty>(), 1.0 - $EPSILON / 2.0);
+
+                // OpenClosed01
+                let mut zeros = StepRng::new(0, 0);
+                assert_eq!(zeros.sample::<$ty, _>(OpenClosed01),
+                           0.0 + $EPSILON / 2.0);
+                let mut one = StepRng::new(1 << 11, 0);
+                assert_eq!(one.sample::<$ty, _>(OpenClosed01), $EPSILON);
+                let mut max = StepRng::new(!0, 0);
+                assert_eq!(max.sample::<$ty, _>(OpenClosed01), $ZERO + 1.0);
+
+                // Open01
+                let mut zeros = StepRng::new(0, 0);
+                assert_eq!(zeros.sample::<$ty, _>(Open01), 0.0 + $EPSILON / 2.0);
+                let mut one = StepRng::new(1 << 12, 0);
+                assert_eq!(one.sample::<$ty, _>(Open01), $EPSILON / 2.0 * 3.0);
+                let mut max = StepRng::new(!0, 0);
+                assert_eq!(max.sample::<$ty, _>(Open01), 1.0 - $EPSILON / 2.0);
+            }
+        }
+    }
+    test_f64! { f64_edge_cases, f64, 0.0, EPSILON64 }
+    #[cfg(feature="simd_support")]
+    test_f64! { f64x2_edge_cases, f64x2, f64x2::splat(0.0), f64x2::splat(EPSILON64) }
+    #[cfg(feature="simd_support")]
+    test_f64! { f64x4_edge_cases, f64x4, f64x4::splat(0.0), f64x4::splat(EPSILON64) }
+    #[cfg(feature="simd_support")]
+    test_f64! { f64x8_edge_cases, f64x8, f64x8::splat(0.0), f64x8::splat(EPSILON64) }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/gamma.rs.html b/target/doc/src/rand/distributions/gamma.rs.html new file mode 100644 index 0000000..33fd78e --- /dev/null +++ b/target/doc/src/rand/distributions/gamma.rs.html @@ -0,0 +1,745 @@ +gamma.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+
+// Copyright 2018 Developers of the Rand project.
+// Copyright 2013 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The Gamma and derived distributions.
+#![allow(deprecated)]
+
+use self::GammaRepr::*;
+use self::ChiSquaredRepr::*;
+
+use crate::Rng;
+use crate::distributions::normal::StandardNormal;
+use crate::distributions::{Distribution, Exp, Open01};
+
+/// The Gamma distribution `Gamma(shape, scale)` distribution.
+///
+/// The density function of this distribution is
+///
+/// ```text
+/// f(x) =  x^(k - 1) * exp(-x / θ) / (Γ(k) * θ^k)
+/// ```
+///
+/// where `Γ` is the Gamma function, `k` is the shape and `θ` is the
+/// scale and both `k` and `θ` are strictly positive.
+///
+/// The algorithm used is that described by Marsaglia & Tsang 2000[^1],
+/// falling back to directly sampling from an Exponential for `shape
+/// == 1`, and using the boosting technique described in that paper for
+/// `shape < 1`.
+///
+/// [^1]: George Marsaglia and Wai Wan Tsang. 2000. "A Simple Method for
+///       Generating Gamma Variables" *ACM Trans. Math. Softw.* 26, 3
+///       (September 2000), 363-372.
+///       DOI:[10.1145/358407.358414](https://doi.acm.org/10.1145/358407.358414)
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Copy, Debug)]
+pub struct Gamma {
+    repr: GammaRepr,
+}
+
+#[derive(Clone, Copy, Debug)]
+enum GammaRepr {
+    Large(GammaLargeShape),
+    One(Exp),
+    Small(GammaSmallShape)
+}
+
+// These two helpers could be made public, but saving the
+// match-on-Gamma-enum branch from using them directly (e.g. if one
+// knows that the shape is always > 1) doesn't appear to be much
+// faster.
+
+/// Gamma distribution where the shape parameter is less than 1.
+///
+/// Note, samples from this require a compulsory floating-point `pow`
+/// call, which makes it significantly slower than sampling from a
+/// gamma distribution where the shape parameter is greater than or
+/// equal to 1.
+///
+/// See `Gamma` for sampling from a Gamma distribution with general
+/// shape parameters.
+#[derive(Clone, Copy, Debug)]
+struct GammaSmallShape {
+    inv_shape: f64,
+    large_shape: GammaLargeShape
+}
+
+/// Gamma distribution where the shape parameter is larger than 1.
+///
+/// See `Gamma` for sampling from a Gamma distribution with general
+/// shape parameters.
+#[derive(Clone, Copy, Debug)]
+struct GammaLargeShape {
+    scale: f64,
+    c: f64,
+    d: f64
+}
+
+impl Gamma {
+    /// Construct an object representing the `Gamma(shape, scale)`
+    /// distribution.
+    ///
+    /// Panics if `shape <= 0` or `scale <= 0`.
+    #[inline]
+    pub fn new(shape: f64, scale: f64) -> Gamma {
+        assert!(shape > 0.0, "Gamma::new called with shape <= 0");
+        assert!(scale > 0.0, "Gamma::new called with scale <= 0");
+
+        let repr = if shape == 1.0 {
+            One(Exp::new(1.0 / scale))
+        } else if shape < 1.0 {
+            Small(GammaSmallShape::new_raw(shape, scale))
+        } else {
+            Large(GammaLargeShape::new_raw(shape, scale))
+        };
+        Gamma { repr }
+    }
+}
+
+impl GammaSmallShape {
+    fn new_raw(shape: f64, scale: f64) -> GammaSmallShape {
+        GammaSmallShape {
+            inv_shape: 1. / shape,
+            large_shape: GammaLargeShape::new_raw(shape + 1.0, scale)
+        }
+    }
+}
+
+impl GammaLargeShape {
+    fn new_raw(shape: f64, scale: f64) -> GammaLargeShape {
+        let d = shape - 1. / 3.;
+        GammaLargeShape {
+            scale,
+            c: 1. / (9. * d).sqrt(),
+            d
+        }
+    }
+}
+
+impl Distribution<f64> for Gamma {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
+        match self.repr {
+            Small(ref g) => g.sample(rng),
+            One(ref g) => g.sample(rng),
+            Large(ref g) => g.sample(rng),
+        }
+    }
+}
+impl Distribution<f64> for GammaSmallShape {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
+        let u: f64 = rng.sample(Open01);
+
+        self.large_shape.sample(rng) * u.powf(self.inv_shape)
+    }
+}
+impl Distribution<f64> for GammaLargeShape {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
+        loop {
+            let x = rng.sample(StandardNormal);
+            let v_cbrt = 1.0 + self.c * x;
+            if v_cbrt <= 0.0 { // a^3 <= 0 iff a <= 0
+                continue
+            }
+
+            let v = v_cbrt * v_cbrt * v_cbrt;
+            let u: f64 = rng.sample(Open01);
+
+            let x_sqr = x * x;
+            if u < 1.0 - 0.0331 * x_sqr * x_sqr ||
+                u.ln() < 0.5 * x_sqr + self.d * (1.0 - v + v.ln()) {
+                return self.d * v * self.scale
+            }
+        }
+    }
+}
+
+/// The chi-squared distribution `χ²(k)`, where `k` is the degrees of
+/// freedom.
+///
+/// For `k > 0` integral, this distribution is the sum of the squares
+/// of `k` independent standard normal random variables. For other
+/// `k`, this uses the equivalent characterisation
+/// `χ²(k) = Gamma(k/2, 2)`.
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Copy, Debug)]
+pub struct ChiSquared {
+    repr: ChiSquaredRepr,
+}
+
+#[derive(Clone, Copy, Debug)]
+enum ChiSquaredRepr {
+    // k == 1, Gamma(alpha, ..) is particularly slow for alpha < 1,
+    // e.g. when alpha = 1/2 as it would be for this case, so special-
+    // casing and using the definition of N(0,1)^2 is faster.
+    DoFExactlyOne,
+    DoFAnythingElse(Gamma),
+}
+
+impl ChiSquared {
+    /// Create a new chi-squared distribution with degrees-of-freedom
+    /// `k`. Panics if `k < 0`.
+    pub fn new(k: f64) -> ChiSquared {
+        let repr = if k == 1.0 {
+            DoFExactlyOne
+        } else {
+            assert!(k > 0.0, "ChiSquared::new called with `k` < 0");
+            DoFAnythingElse(Gamma::new(0.5 * k, 2.0))
+        };
+        ChiSquared { repr }
+    }
+}
+impl Distribution<f64> for ChiSquared {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
+        match self.repr {
+            DoFExactlyOne => {
+                // k == 1 => N(0,1)^2
+                let norm = rng.sample(StandardNormal);
+                norm * norm
+            }
+            DoFAnythingElse(ref g) => g.sample(rng)
+        }
+    }
+}
+
+/// The Fisher F distribution `F(m, n)`.
+///
+/// This distribution is equivalent to the ratio of two normalised
+/// chi-squared distributions, that is, `F(m,n) = (χ²(m)/m) /
+/// (χ²(n)/n)`.
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Copy, Debug)]
+pub struct FisherF {
+    numer: ChiSquared,
+    denom: ChiSquared,
+    // denom_dof / numer_dof so that this can just be a straight
+    // multiplication, rather than a division.
+    dof_ratio: f64,
+}
+
+impl FisherF {
+    /// Create a new `FisherF` distribution, with the given
+    /// parameter. Panics if either `m` or `n` are not positive.
+    pub fn new(m: f64, n: f64) -> FisherF {
+        assert!(m > 0.0, "FisherF::new called with `m < 0`");
+        assert!(n > 0.0, "FisherF::new called with `n < 0`");
+
+        FisherF {
+            numer: ChiSquared::new(m),
+            denom: ChiSquared::new(n),
+            dof_ratio: n / m
+        }
+    }
+}
+impl Distribution<f64> for FisherF {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
+        self.numer.sample(rng) / self.denom.sample(rng) * self.dof_ratio
+    }
+}
+
+/// The Student t distribution, `t(nu)`, where `nu` is the degrees of
+/// freedom.
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Copy, Debug)]
+pub struct StudentT {
+    chi: ChiSquared,
+    dof: f64
+}
+
+impl StudentT {
+    /// Create a new Student t distribution with `n` degrees of
+    /// freedom. Panics if `n <= 0`.
+    pub fn new(n: f64) -> StudentT {
+        assert!(n > 0.0, "StudentT::new called with `n <= 0`");
+        StudentT {
+            chi: ChiSquared::new(n),
+            dof: n
+        }
+    }
+}
+impl Distribution<f64> for StudentT {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
+        let norm = rng.sample(StandardNormal);
+        norm * (self.dof / self.chi.sample(rng)).sqrt()
+    }
+}
+
+/// The Beta distribution with shape parameters `alpha` and `beta`.
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Copy, Debug)]
+pub struct Beta {
+    gamma_a: Gamma,
+    gamma_b: Gamma,
+}
+
+impl Beta {
+    /// Construct an object representing the `Beta(alpha, beta)`
+    /// distribution.
+    ///
+    /// Panics if `shape <= 0` or `scale <= 0`.
+    pub fn new(alpha: f64, beta: f64) -> Beta {
+        assert!((alpha > 0.) & (beta > 0.));
+        Beta {
+            gamma_a: Gamma::new(alpha, 1.),
+            gamma_b: Gamma::new(beta, 1.),
+        }
+    }
+}
+
+impl Distribution<f64> for Beta {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
+        let x = self.gamma_a.sample(rng);
+        let y = self.gamma_b.sample(rng);
+        x / (x + y)
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use crate::distributions::Distribution;
+    use super::{Beta, ChiSquared, StudentT, FisherF};
+
+    const N: u32 = 100;
+
+    #[test]
+    fn test_chi_squared_one() {
+        let chi = ChiSquared::new(1.0);
+        let mut rng = crate::test::rng(201);
+        for _ in 0..N {
+            chi.sample(&mut rng);
+        }
+    }
+    #[test]
+    fn test_chi_squared_small() {
+        let chi = ChiSquared::new(0.5);
+        let mut rng = crate::test::rng(202);
+        for _ in 0..N {
+            chi.sample(&mut rng);
+        }
+    }
+    #[test]
+    fn test_chi_squared_large() {
+        let chi = ChiSquared::new(30.0);
+        let mut rng = crate::test::rng(203);
+        for _ in 0..N {
+            chi.sample(&mut rng);
+        }
+    }
+    #[test]
+    #[should_panic]
+    fn test_chi_squared_invalid_dof() {
+        ChiSquared::new(-1.0);
+    }
+
+    #[test]
+    fn test_f() {
+        let f = FisherF::new(2.0, 32.0);
+        let mut rng = crate::test::rng(204);
+        for _ in 0..N {
+            f.sample(&mut rng);
+        }
+    }
+
+    #[test]
+    fn test_t() {
+        let t = StudentT::new(11.0);
+        let mut rng = crate::test::rng(205);
+        for _ in 0..N {
+            t.sample(&mut rng);
+        }
+    }
+
+    #[test]
+    fn test_beta() {
+        let beta = Beta::new(1.0, 2.0);
+        let mut rng = crate::test::rng(201);
+        for _ in 0..N {
+            beta.sample(&mut rng);
+        }
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_beta_invalid_dof() {
+        Beta::new(0., 0.);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/integer.rs.html b/target/doc/src/rand/distributions/integer.rs.html new file mode 100644 index 0000000..b4cb430 --- /dev/null +++ b/target/doc/src/rand/distributions/integer.rs.html @@ -0,0 +1,371 @@ +integer.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The implementations of the `Standard` distribution for integer types.
+
+use crate::{Rng};
+use crate::distributions::{Distribution, Standard};
+use core::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroUsize};
+#[cfg(not(target_os = "emscripten"))] use core::num::NonZeroU128;
+#[cfg(feature="simd_support")]
+use packed_simd::*;
+#[cfg(all(target_arch = "x86", feature="nightly"))]
+use core::arch::x86::*;
+#[cfg(all(target_arch = "x86_64", feature="nightly"))]
+use core::arch::x86_64::*;
+
+impl Distribution<u8> for Standard {
+    #[inline]
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u8 {
+        rng.next_u32() as u8
+    }
+}
+
+impl Distribution<u16> for Standard {
+    #[inline]
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u16 {
+        rng.next_u32() as u16
+    }
+}
+
+impl Distribution<u32> for Standard {
+    #[inline]
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u32 {
+        rng.next_u32()
+    }
+}
+
+impl Distribution<u64> for Standard {
+    #[inline]
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u64 {
+        rng.next_u64()
+    }
+}
+
+#[cfg(not(target_os = "emscripten"))]
+impl Distribution<u128> for Standard {
+    #[inline]
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u128 {
+        // Use LE; we explicitly generate one value before the next.
+        let x = rng.next_u64() as u128;
+        let y = rng.next_u64() as u128;
+        (y << 64) | x
+    }
+}
+
+impl Distribution<usize> for Standard {
+    #[inline]
+    #[cfg(any(target_pointer_width = "32", target_pointer_width = "16"))]
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> usize {
+        rng.next_u32() as usize
+    }
+
+    #[inline]
+    #[cfg(target_pointer_width = "64")]
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> usize {
+        rng.next_u64() as usize
+    }
+}
+
+macro_rules! impl_int_from_uint {
+    ($ty:ty, $uty:ty) => {
+        impl Distribution<$ty> for Standard {
+            #[inline]
+            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $ty {
+                rng.gen::<$uty>() as $ty
+            }
+        }
+    }
+}
+
+impl_int_from_uint! { i8, u8 }
+impl_int_from_uint! { i16, u16 }
+impl_int_from_uint! { i32, u32 }
+impl_int_from_uint! { i64, u64 }
+#[cfg(not(target_os = "emscripten"))] impl_int_from_uint! { i128, u128 }
+impl_int_from_uint! { isize, usize }
+
+macro_rules! impl_nzint {
+    ($ty:ty, $new:path) => {
+        impl Distribution<$ty> for Standard {
+            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $ty {
+                loop {
+                    if let Some(nz) = $new(rng.gen()) {
+                        break nz;
+                    }
+                }
+            }
+        }
+    }
+}
+
+impl_nzint!(NonZeroU8, NonZeroU8::new);
+impl_nzint!(NonZeroU16, NonZeroU16::new);
+impl_nzint!(NonZeroU32, NonZeroU32::new);
+impl_nzint!(NonZeroU64, NonZeroU64::new);
+#[cfg(not(target_os = "emscripten"))] impl_nzint!(NonZeroU128, NonZeroU128::new);
+impl_nzint!(NonZeroUsize, NonZeroUsize::new);
+
+#[cfg(feature="simd_support")]
+macro_rules! simd_impl {
+    ($(($intrinsic:ident, $vec:ty),)+) => {$(
+        impl Distribution<$intrinsic> for Standard {
+            #[inline]
+            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $intrinsic {
+                $intrinsic::from_bits(rng.gen::<$vec>())
+            }
+        }
+    )+};
+
+    ($bits:expr,) => {};
+    ($bits:expr, $ty:ty, $($ty_more:ty,)*) => {
+        simd_impl!($bits, $($ty_more,)*);
+
+        impl Distribution<$ty> for Standard {
+            #[inline]
+            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $ty {
+                let mut vec: $ty = Default::default();
+                unsafe {
+                    let ptr = &mut vec;
+                    let b_ptr = &mut *(ptr as *mut $ty as *mut [u8; $bits/8]);
+                    rng.fill_bytes(b_ptr);
+                }
+                vec.to_le()
+            }
+        }
+    };
+}
+
+#[cfg(feature="simd_support")]
+simd_impl!(16, u8x2, i8x2,);
+#[cfg(feature="simd_support")]
+simd_impl!(32, u8x4, i8x4, u16x2, i16x2,);
+#[cfg(feature="simd_support")]
+simd_impl!(64, u8x8, i8x8, u16x4, i16x4, u32x2, i32x2,);
+#[cfg(feature="simd_support")]
+simd_impl!(128, u8x16, i8x16, u16x8, i16x8, u32x4, i32x4, u64x2, i64x2,);
+#[cfg(feature="simd_support")]
+simd_impl!(256, u8x32, i8x32, u16x16, i16x16, u32x8, i32x8, u64x4, i64x4,);
+#[cfg(feature="simd_support")]
+simd_impl!(512, u8x64, i8x64, u16x32, i16x32, u32x16, i32x16, u64x8, i64x8,);
+#[cfg(all(feature="simd_support", feature="nightly", any(target_arch="x86", target_arch="x86_64")))]
+simd_impl!((__m64, u8x8), (__m128i, u8x16), (__m256i, u8x32),);
+
+#[cfg(test)]
+mod tests {
+    use crate::Rng;
+    use crate::distributions::{Standard};
+    
+    #[test]
+    fn test_integers() {
+        let mut rng = crate::test::rng(806);
+        
+        rng.sample::<isize, _>(Standard);
+        rng.sample::<i8, _>(Standard);
+        rng.sample::<i16, _>(Standard);
+        rng.sample::<i32, _>(Standard);
+        rng.sample::<i64, _>(Standard);
+        #[cfg(not(target_os = "emscripten"))]
+        rng.sample::<i128, _>(Standard);
+        
+        rng.sample::<usize, _>(Standard);
+        rng.sample::<u8, _>(Standard);
+        rng.sample::<u16, _>(Standard);
+        rng.sample::<u32, _>(Standard);
+        rng.sample::<u64, _>(Standard);
+        #[cfg(not(target_os = "emscripten"))]
+        rng.sample::<u128, _>(Standard);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/mod.rs.html b/target/doc/src/rand/distributions/mod.rs.html new file mode 100644 index 0000000..a3cbd80 --- /dev/null +++ b/target/doc/src/rand/distributions/mod.rs.html @@ -0,0 +1,765 @@ +mod.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+
+// Copyright 2018 Developers of the Rand project.
+// Copyright 2013-2017 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Generating random samples from probability distributions
+//!
+//! This module is the home of the [`Distribution`] trait and several of its
+//! implementations. It is the workhorse behind some of the convenient
+//! functionality of the [`Rng`] trait, e.g. [`Rng::gen`], [`Rng::gen_range`] and
+//! of course [`Rng::sample`].
+//!
+//! Abstractly, a [probability distribution] describes the probability of
+//! occurance of each value in its sample space.
+//!
+//! More concretely, an implementation of `Distribution<T>` for type `X` is an
+//! algorithm for choosing values from the sample space (a subset of `T`)
+//! according to the distribution `X` represents, using an external source of
+//! randomness (an RNG supplied to the `sample` function).
+//!
+//! A type `X` may implement `Distribution<T>` for multiple types `T`.
+//! Any type implementing [`Distribution`] is stateless (i.e. immutable),
+//! but it may have internal parameters set at construction time (for example,
+//! [`Uniform`] allows specification of its sample space as a range within `T`).
+//!
+//!
+//! # The `Standard` distribution
+//!
+//! The [`Standard`] distribution is important to mention. This is the
+//! distribution used by [`Rng::gen()`] and represents the "default" way to
+//! produce a random value for many different types, including most primitive
+//! types, tuples, arrays, and a few derived types. See the documentation of
+//! [`Standard`] for more details.
+//!
+//! Implementing `Distribution<T>` for [`Standard`] for user types `T` makes it
+//! possible to generate type `T` with [`Rng::gen()`], and by extension also
+//! with the [`random()`] function.
+//!
+//! ## Random characters
+//! 
+//! [`Alphanumeric`] is a simple distribution to sample random letters and
+//! numbers of the `char` type; in contrast [`Standard`] may sample any valid
+//! `char`.
+//!
+//!
+//! # Uniform numeric ranges
+//!
+//! The [`Uniform`] distribution is more flexible than [`Standard`], but also
+//! more specialised: it supports fewer target types, but allows the sample
+//! space to be specified as an arbitrary range within its target type `T`.
+//! Both [`Standard`] and [`Uniform`] are in some sense uniform distributions.
+//!
+//! Values may be sampled from this distribution using [`Rng::gen_range`] or
+//! by creating a distribution object with [`Uniform::new`],
+//! [`Uniform::new_inclusive`] or `From<Range>`. When the range limits are not
+//! known at compile time it is typically faster to reuse an existing
+//! distribution object than to call [`Rng::gen_range`].
+//!
+//! User types `T` may also implement `Distribution<T>` for [`Uniform`],
+//! although this is less straightforward than for [`Standard`] (see the
+//! documentation in the [`uniform`] module. Doing so enables generation of
+//! values of type `T` with  [`Rng::gen_range`].
+//!
+//! ## Open and half-open ranges
+//!
+//! There are surprisingly many ways to uniformly generate random floats. A
+//! range between 0 and 1 is standard, but the exact bounds (open vs closed)
+//! and accuracy differ. In addition to the [`Standard`] distribution Rand offers
+//! [`Open01`] and [`OpenClosed01`]. See "Floating point implementation" section of
+//! [`Standard`] documentation for more details.
+//!
+//! # Non-uniform sampling
+//!
+//! Sampling a simple true/false outcome with a given probability has a name:
+//! the [`Bernoulli`] distribution (this is used by [`Rng::gen_bool`]).
+//!
+//! For weighted sampling from a sequence of discrete values, use the
+//! [`weighted`] module.
+//!
+//! This crate no longer includes other non-uniform distributions; instead
+//! it is recommended that you use either [`rand_distr`] or [`statrs`].
+//!
+//!
+//! [probability distribution]: https://en.wikipedia.org/wiki/Probability_distribution
+//! [`rand_distr`]: https://crates.io/crates/rand_distr
+//! [`statrs`]: https://crates.io/crates/statrs
+
+//! [`Alphanumeric`]: distributions::Alphanumeric
+//! [`Bernoulli`]: distributions::Bernoulli
+//! [`Open01`]: distributions::Open01
+//! [`OpenClosed01`]: distributions::OpenClosed01
+//! [`Standard`]: distributions::Standard
+//! [`Uniform`]: distributions::Uniform
+//! [`Uniform::new`]: distributions::Uniform::new
+//! [`Uniform::new_inclusive`]: distributions::Uniform::new_inclusive
+//! [`weighted`]: distributions::weighted
+//! [`rand_distr`]: https://crates.io/crates/rand_distr
+//! [`statrs`]: https://crates.io/crates/statrs
+
+use core::iter;
+use crate::Rng;
+
+pub use self::other::Alphanumeric;
+#[doc(inline)] pub use self::uniform::Uniform;
+pub use self::float::{OpenClosed01, Open01};
+pub use self::bernoulli::{Bernoulli, BernoulliError};
+#[cfg(feature="alloc")] pub use self::weighted::{WeightedIndex, WeightedError};
+
+// The following are all deprecated after being moved to rand_distr
+#[allow(deprecated)]
+#[cfg(feature="std")] pub use self::unit_sphere::UnitSphereSurface;
+#[allow(deprecated)]
+#[cfg(feature="std")] pub use self::unit_circle::UnitCircle;
+#[allow(deprecated)]
+#[cfg(feature="std")] pub use self::gamma::{Gamma, ChiSquared, FisherF,
+    StudentT, Beta};
+#[allow(deprecated)]
+#[cfg(feature="std")] pub use self::normal::{Normal, LogNormal, StandardNormal};
+#[allow(deprecated)]
+#[cfg(feature="std")] pub use self::exponential::{Exp, Exp1};
+#[allow(deprecated)]
+#[cfg(feature="std")] pub use self::pareto::Pareto;
+#[allow(deprecated)]
+#[cfg(feature="std")] pub use self::poisson::Poisson;
+#[allow(deprecated)]
+#[cfg(feature="std")] pub use self::binomial::Binomial;
+#[allow(deprecated)]
+#[cfg(feature="std")] pub use self::cauchy::Cauchy;
+#[allow(deprecated)]
+#[cfg(feature="std")] pub use self::dirichlet::Dirichlet;
+#[allow(deprecated)]
+#[cfg(feature="std")] pub use self::triangular::Triangular;
+#[allow(deprecated)]
+#[cfg(feature="std")] pub use self::weibull::Weibull;
+
+pub mod uniform;
+mod bernoulli;
+#[cfg(feature="alloc")] pub mod weighted;
+#[cfg(feature="std")] mod unit_sphere;
+#[cfg(feature="std")] mod unit_circle;
+#[cfg(feature="std")] mod gamma;
+#[cfg(feature="std")] mod normal;
+#[cfg(feature="std")] mod exponential;
+#[cfg(feature="std")] mod pareto;
+#[cfg(feature="std")] mod poisson;
+#[cfg(feature="std")] mod binomial;
+#[cfg(feature="std")] mod cauchy;
+#[cfg(feature="std")] mod dirichlet;
+#[cfg(feature="std")] mod triangular;
+#[cfg(feature="std")] mod weibull;
+
+mod float;
+#[doc(hidden)] pub mod hidden_export {
+    pub use super::float::IntoFloat;   // used by rand_distr
+}
+mod integer;
+mod other;
+mod utils;
+#[cfg(feature="std")] mod ziggurat_tables;
+
+/// Types (distributions) that can be used to create a random instance of `T`.
+///
+/// It is possible to sample from a distribution through both the
+/// `Distribution` and [`Rng`] traits, via `distr.sample(&mut rng)` and
+/// `rng.sample(distr)`. They also both offer the [`sample_iter`] method, which
+/// produces an iterator that samples from the distribution.
+///
+/// All implementations are expected to be immutable; this has the significant
+/// advantage of not needing to consider thread safety, and for most
+/// distributions efficient state-less sampling algorithms are available.
+///
+/// [`sample_iter`]: Distribution::method.sample_iter
+pub trait Distribution<T> {
+    /// Generate a random value of `T`, using `rng` as the source of randomness.
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> T;
+
+    /// Create an iterator that generates random values of `T`, using `rng` as
+    /// the source of randomness.
+    ///
+    /// Note that this function takes `self` by value. This works since
+    /// `Distribution<T>` is impl'd for `&D` where `D: Distribution<T>`,
+    /// however borrowing is not automatic hence `distr.sample_iter(...)` may
+    /// need to be replaced with `(&distr).sample_iter(...)` to borrow or
+    /// `(&*distr).sample_iter(...)` to reborrow an existing reference.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use rand::thread_rng;
+    /// use rand::distributions::{Distribution, Alphanumeric, Uniform, Standard};
+    ///
+    /// let rng = thread_rng();
+    ///
+    /// // Vec of 16 x f32:
+    /// let v: Vec<f32> = Standard.sample_iter(rng).take(16).collect();
+    ///
+    /// // String:
+    /// let s: String = Alphanumeric.sample_iter(rng).take(7).collect();
+    ///
+    /// // Dice-rolling:
+    /// let die_range = Uniform::new_inclusive(1, 6);
+    /// let mut roll_die = die_range.sample_iter(rng);
+    /// while roll_die.next().unwrap() != 6 {
+    ///     println!("Not a 6; rolling again!");
+    /// }
+    /// ```
+    fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T>
+    where R: Rng, Self: Sized
+    {
+        DistIter {
+            distr: self,
+            rng: rng,
+            phantom: ::core::marker::PhantomData,
+        }
+    }
+}
+
+impl<'a, T, D: Distribution<T>> Distribution<T> for &'a D {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> T {
+        (*self).sample(rng)
+    }
+}
+
+
+/// An iterator that generates random values of `T` with distribution `D`,
+/// using `R` as the source of randomness.
+///
+/// This `struct` is created by the [`sample_iter`] method on [`Distribution`].
+/// See its documentation for more.
+///
+/// [`sample_iter`]: Distribution::sample_iter
+#[derive(Debug)]
+pub struct DistIter<D, R, T> {
+    distr: D,
+    rng: R,
+    phantom: ::core::marker::PhantomData<T>,
+}
+
+impl<D, R, T> Iterator for DistIter<D, R, T>
+    where D: Distribution<T>, R: Rng
+{
+    type Item = T;
+
+    #[inline(always)]
+    fn next(&mut self) -> Option<T> {
+        // Here, self.rng may be a reference, but we must take &mut anyway.
+        // Even if sample could take an R: Rng by value, we would need to do this
+        // since Rng is not copyable and we cannot enforce that this is "reborrowable".
+        Some(self.distr.sample(&mut self.rng))
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (usize::max_value(), None)
+    }
+}
+
+impl<D, R, T> iter::FusedIterator for DistIter<D, R, T>
+    where D: Distribution<T>, R: Rng {}
+
+#[cfg(features = "nightly")]
+impl<D, R, T> iter::TrustedLen for DistIter<D, R, T>
+    where D: Distribution<T>, R: Rng {}
+
+
+/// A generic random value distribution, implemented for many primitive types.
+/// Usually generates values with a numerically uniform distribution, and with a
+/// range appropriate to the type.
+///
+/// ## Provided implementations
+///
+/// Assuming the provided `Rng` is well-behaved, these implementations
+/// generate values with the following ranges and distributions:
+///
+/// * Integers (`i32`, `u32`, `isize`, `usize`, etc.): Uniformly distributed
+///   over all values of the type.
+/// * `char`: Uniformly distributed over all Unicode scalar values, i.e. all
+///   code points in the range `0...0x10_FFFF`, except for the range
+///   `0xD800...0xDFFF` (the surrogate code points). This includes
+///   unassigned/reserved code points.
+/// * `bool`: Generates `false` or `true`, each with probability 0.5.
+/// * Floating point types (`f32` and `f64`): Uniformly distributed in the
+///   half-open range `[0, 1)`. See notes below.
+/// * Wrapping integers (`Wrapping<T>`), besides the type identical to their
+///   normal integer variants.
+///
+/// The `Standard` distribution also supports generation of the following
+/// compound types where all component types are supported:
+///
+/// *   Tuples (up to 12 elements): each element is generated sequentially.
+/// *   Arrays (up to 32 elements): each element is generated sequentially;
+///     see also [`Rng::fill`] which supports arbitrary array length for integer
+///     types and tends to be faster for `u32` and smaller types.
+/// *   `Option<T>` first generates a `bool`, and if true generates and returns
+///     `Some(value)` where `value: T`, otherwise returning `None`.
+///
+/// ## Custom implementations
+///
+/// The [`Standard`] distribution may be implemented for user types as follows:
+///
+/// ```
+/// # #![allow(dead_code)]
+/// use rand::Rng;
+/// use rand::distributions::{Distribution, Standard};
+///
+/// struct MyF32 {
+///     x: f32,
+/// }
+///
+/// impl Distribution<MyF32> for Standard {
+///     fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> MyF32 {
+///         MyF32 { x: rng.gen() }
+///     }
+/// }
+/// ```
+///
+/// ## Example usage
+/// ```
+/// use rand::prelude::*;
+/// use rand::distributions::Standard;
+///
+/// let val: f32 = StdRng::from_entropy().sample(Standard);
+/// println!("f32 from [0, 1): {}", val);
+/// ```
+///
+/// # Floating point implementation
+/// The floating point implementations for `Standard` generate a random value in
+/// the half-open interval `[0, 1)`, i.e. including 0 but not 1.
+///
+/// All values that can be generated are of the form `n * ε/2`. For `f32`
+/// the 23 most significant random bits of a `u32` are used and for `f64` the
+/// 53 most significant bits of a `u64` are used. The conversion uses the
+/// multiplicative method: `(rng.gen::<$uty>() >> N) as $ty * (ε/2)`.
+///
+/// See also: [`Open01`] which samples from `(0, 1)`, [`OpenClosed01`] which
+/// samples from `(0, 1]` and `Rng::gen_range(0, 1)` which also samples from
+/// `[0, 1)`. Note that `Open01` and `gen_range` (which uses [`Uniform`]) use
+/// transmute-based methods which yield 1 bit less precision but may perform
+/// faster on some architectures (on modern Intel CPUs all methods have
+/// approximately equal performance).
+///
+/// [`Uniform`]: uniform::Uniform
+#[derive(Clone, Copy, Debug)]
+pub struct Standard;
+
+
+#[cfg(all(test, feature = "std"))]
+mod tests {
+    use crate::Rng;
+    use super::{Distribution, Uniform};
+
+    #[test]
+    fn test_distributions_iter() {
+        use crate::distributions::Open01;
+        let mut rng = crate::test::rng(210);
+        let distr = Open01;
+        let results: Vec<f32> = distr.sample_iter(&mut rng).take(100).collect();
+        println!("{:?}", results);
+    }
+    
+    #[test]
+    fn test_make_an_iter() {
+        fn ten_dice_rolls_other_than_five<'a, R: Rng>(rng: &'a mut R) -> impl Iterator<Item = i32> + 'a {
+            Uniform::new_inclusive(1, 6)
+                .sample_iter(rng)
+                .filter(|x| *x != 5)
+                .take(10)
+        }
+        
+        let mut rng = crate::test::rng(211);
+        let mut count = 0;
+        for val in ten_dice_rolls_other_than_five(&mut rng) {
+            assert!(val >= 1 && val <= 6 && val != 5);
+            count += 1;
+        }
+        assert_eq!(count, 10);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/normal.rs.html b/target/doc/src/rand/distributions/normal.rs.html new file mode 100644 index 0000000..34c1860 --- /dev/null +++ b/target/doc/src/rand/distributions/normal.rs.html @@ -0,0 +1,343 @@ +normal.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+
+// Copyright 2018 Developers of the Rand project.
+// Copyright 2013 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The normal and derived distributions.
+#![allow(deprecated)]
+
+use crate::Rng;
+use crate::distributions::{ziggurat_tables, Distribution, Open01};
+use crate::distributions::utils::ziggurat;
+
+/// Samples floating-point numbers according to the normal distribution
+/// `N(0, 1)` (a.k.a. a standard normal, or Gaussian). This is equivalent to
+/// `Normal::new(0.0, 1.0)` but faster.
+///
+/// See `Normal` for the general normal distribution.
+///
+/// Implemented via the ZIGNOR variant[^1] of the Ziggurat method.
+///
+/// [^1]: Jurgen A. Doornik (2005). [*An Improved Ziggurat Method to
+///       Generate Normal Random Samples*](
+///       https://www.doornik.com/research/ziggurat.pdf).
+///       Nuffield College, Oxford
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Copy, Debug)]
+pub struct StandardNormal;
+
+impl Distribution<f64> for StandardNormal {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
+        #[inline]
+        fn pdf(x: f64) -> f64 {
+            (-x*x/2.0).exp()
+        }
+        #[inline]
+        fn zero_case<R: Rng + ?Sized>(rng: &mut R, u: f64) -> f64 {
+            // compute a random number in the tail by hand
+
+            // strange initial conditions, because the loop is not
+            // do-while, so the condition should be true on the first
+            // run, they get overwritten anyway (0 < 1, so these are
+            // good).
+            let mut x = 1.0f64;
+            let mut y = 0.0f64;
+
+            while -2.0 * y < x * x {
+                let x_: f64 = rng.sample(Open01);
+                let y_: f64 = rng.sample(Open01);
+
+                x = x_.ln() / ziggurat_tables::ZIG_NORM_R;
+                y = y_.ln();
+            }
+
+            if u < 0.0 { x - ziggurat_tables::ZIG_NORM_R } else { ziggurat_tables::ZIG_NORM_R - x }
+        }
+
+        ziggurat(rng, true, // this is symmetric
+                 &ziggurat_tables::ZIG_NORM_X,
+                 &ziggurat_tables::ZIG_NORM_F,
+                 pdf, zero_case)
+    }
+}
+
+/// The normal distribution `N(mean, std_dev**2)`.
+///
+/// This uses the ZIGNOR variant of the Ziggurat method, see [`StandardNormal`]
+/// for more details.
+/// 
+/// Note that [`StandardNormal`] is an optimised implementation for mean 0, and
+/// standard deviation 1.
+///
+/// [`StandardNormal`]: crate::distributions::StandardNormal
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Copy, Debug)]
+pub struct Normal {
+    mean: f64,
+    std_dev: f64,
+}
+
+impl Normal {
+    /// Construct a new `Normal` distribution with the given mean and
+    /// standard deviation.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `std_dev < 0`.
+    #[inline]
+    pub fn new(mean: f64, std_dev: f64) -> Normal {
+        assert!(std_dev >= 0.0, "Normal::new called with `std_dev` < 0");
+        Normal {
+            mean,
+            std_dev
+        }
+    }
+}
+impl Distribution<f64> for Normal {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
+        let n = rng.sample(StandardNormal);
+        self.mean + self.std_dev * n
+    }
+}
+
+
+/// The log-normal distribution `ln N(mean, std_dev**2)`.
+///
+/// If `X` is log-normal distributed, then `ln(X)` is `N(mean, std_dev**2)`
+/// distributed.
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Copy, Debug)]
+pub struct LogNormal {
+    norm: Normal
+}
+
+impl LogNormal {
+    /// Construct a new `LogNormal` distribution with the given mean
+    /// and standard deviation.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `std_dev < 0`.
+    #[inline]
+    pub fn new(mean: f64, std_dev: f64) -> LogNormal {
+        assert!(std_dev >= 0.0, "LogNormal::new called with `std_dev` < 0");
+        LogNormal { norm: Normal::new(mean, std_dev) }
+    }
+}
+impl Distribution<f64> for LogNormal {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
+        self.norm.sample(rng).exp()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::distributions::Distribution;
+    use super::{Normal, LogNormal};
+
+    #[test]
+    fn test_normal() {
+        let norm = Normal::new(10.0, 10.0);
+        let mut rng = crate::test::rng(210);
+        for _ in 0..1000 {
+            norm.sample(&mut rng);
+        }
+    }
+    #[test]
+    #[should_panic]
+    fn test_normal_invalid_sd() {
+        Normal::new(10.0, -1.0);
+    }
+
+
+    #[test]
+    fn test_log_normal() {
+        let lnorm = LogNormal::new(10.0, 10.0);
+        let mut rng = crate::test::rng(211);
+        for _ in 0..1000 {
+            lnorm.sample(&mut rng);
+        }
+    }
+    #[test]
+    #[should_panic]
+    fn test_log_normal_invalid_sd() {
+        LogNormal::new(10.0, -1.0);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/other.rs.html b/target/doc/src/rand/distributions/other.rs.html new file mode 100644 index 0000000..2cba1ff --- /dev/null +++ b/target/doc/src/rand/distributions/other.rs.html @@ -0,0 +1,441 @@ +other.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The implementations of the `Standard` distribution for other built-in types.
+
+use core::char;
+use core::num::Wrapping;
+
+use crate::{Rng};
+use crate::distributions::{Distribution, Standard, Uniform};
+
+// ----- Sampling distributions -----
+
+/// Sample a `char`, uniformly distributed over ASCII letters and numbers:
+/// a-z, A-Z and 0-9.
+/// 
+/// # Example
+///
+/// ```
+/// use std::iter;
+/// use rand::{Rng, thread_rng};
+/// use rand::distributions::Alphanumeric;
+/// 
+/// let mut rng = thread_rng();
+/// let chars: String = iter::repeat(())
+///         .map(|()| rng.sample(Alphanumeric))
+///         .take(7)
+///         .collect();
+/// println!("Random chars: {}", chars);
+/// ```
+#[derive(Debug)]
+pub struct Alphanumeric;
+
+
+// ----- Implementations of distributions -----
+
+impl Distribution<char> for Standard {
+    #[inline]
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> char {
+        // A valid `char` is either in the interval `[0, 0xD800)` or
+        // `(0xDFFF, 0x11_0000)`. All `char`s must therefore be in
+        // `[0, 0x11_0000)` but not in the "gap" `[0xD800, 0xDFFF]` which is
+        // reserved for surrogates. This is the size of that gap.
+        const GAP_SIZE: u32 = 0xDFFF - 0xD800 + 1;
+
+        // Uniform::new(0, 0x11_0000 - GAP_SIZE) can also be used but it
+        // seemed slower.
+        let range = Uniform::new(GAP_SIZE, 0x11_0000);
+
+        let mut n = range.sample(rng);
+        if n <= 0xDFFF {
+            n -= GAP_SIZE;
+        }
+        unsafe { char::from_u32_unchecked(n) }
+    }
+}
+
+impl Distribution<char> for Alphanumeric {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> char {
+        const RANGE: u32 = 26 + 26 + 10;
+        const GEN_ASCII_STR_CHARSET: &[u8] =
+            b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+                abcdefghijklmnopqrstuvwxyz\
+                0123456789";
+        // We can pick from 62 characters. This is so close to a power of 2, 64,
+        // that we can do better than `Uniform`. Use a simple bitshift and
+        // rejection sampling. We do not use a bitmask, because for small RNGs
+        // the most significant bits are usually of higher quality.
+        loop {
+            let var = rng.next_u32() >> (32 - 6);
+            if var < RANGE {
+                return GEN_ASCII_STR_CHARSET[var as usize] as char
+            }
+        }
+    }
+}
+
+impl Distribution<bool> for Standard {
+    #[inline]
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> bool {
+        // We can compare against an arbitrary bit of an u32 to get a bool.
+        // Because the least significant bits of a lower quality RNG can have
+        // simple patterns, we compare against the most significant bit. This is
+        // easiest done using a sign test.
+        (rng.next_u32() as i32) < 0
+    }
+}
+
+macro_rules! tuple_impl {
+    // use variables to indicate the arity of the tuple
+    ($($tyvar:ident),* ) => {
+        // the trailing commas are for the 1 tuple
+        impl< $( $tyvar ),* >
+            Distribution<( $( $tyvar ),* , )>
+            for Standard
+            where $( Standard: Distribution<$tyvar> ),*
+        {
+            #[inline]
+            fn sample<R: Rng + ?Sized>(&self, _rng: &mut R) -> ( $( $tyvar ),* , ) {
+                (
+                    // use the $tyvar's to get the appropriate number of
+                    // repeats (they're not actually needed)
+                    $(
+                        _rng.gen::<$tyvar>()
+                    ),*
+                    ,
+                )
+            }
+        }
+    }
+}
+
+impl Distribution<()> for Standard {
+    #[inline]
+    fn sample<R: Rng + ?Sized>(&self, _: &mut R) -> () { () }
+}
+tuple_impl!{A}
+tuple_impl!{A, B}
+tuple_impl!{A, B, C}
+tuple_impl!{A, B, C, D}
+tuple_impl!{A, B, C, D, E}
+tuple_impl!{A, B, C, D, E, F}
+tuple_impl!{A, B, C, D, E, F, G}
+tuple_impl!{A, B, C, D, E, F, G, H}
+tuple_impl!{A, B, C, D, E, F, G, H, I}
+tuple_impl!{A, B, C, D, E, F, G, H, I, J}
+tuple_impl!{A, B, C, D, E, F, G, H, I, J, K}
+tuple_impl!{A, B, C, D, E, F, G, H, I, J, K, L}
+
+macro_rules! array_impl {
+    // recursive, given at least one type parameter:
+    {$n:expr, $t:ident, $($ts:ident,)*} => {
+        array_impl!{($n - 1), $($ts,)*}
+
+        impl<T> Distribution<[T; $n]> for Standard where Standard: Distribution<T> {
+            #[inline]
+            fn sample<R: Rng + ?Sized>(&self, _rng: &mut R) -> [T; $n] {
+                [_rng.gen::<$t>(), $(_rng.gen::<$ts>()),*]
+            }
+        }
+    };
+    // empty case:
+    {$n:expr,} => {
+        impl<T> Distribution<[T; $n]> for Standard {
+            fn sample<R: Rng + ?Sized>(&self, _rng: &mut R) -> [T; $n] { [] }
+        }
+    };
+}
+
+array_impl!{32, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,}
+
+impl<T> Distribution<Option<T>> for Standard where Standard: Distribution<T> {
+    #[inline]
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Option<T> {
+        // UFCS is needed here: https://github.com/rust-lang/rust/issues/24066
+        if rng.gen::<bool>() {
+            Some(rng.gen())
+        } else {
+            None
+        }
+    }
+}
+
+impl<T> Distribution<Wrapping<T>> for Standard where Standard: Distribution<T> {
+    #[inline]
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Wrapping<T> {
+        Wrapping(rng.gen())
+    }
+}
+
+
+#[cfg(test)]
+mod tests {
+    use crate::{Rng, RngCore, Standard};
+    use crate::distributions::Alphanumeric;
+    #[cfg(all(not(feature="std"), feature="alloc"))] use alloc::string::String;
+
+    #[test]
+    fn test_misc() {
+        let rng: &mut dyn RngCore = &mut crate::test::rng(820);
+        
+        rng.sample::<char, _>(Standard);
+        rng.sample::<bool, _>(Standard);
+    }
+    
+    #[cfg(feature="alloc")]
+    #[test]
+    fn test_chars() {
+        use core::iter;
+        let mut rng = crate::test::rng(805);
+
+        // Test by generating a relatively large number of chars, so we also
+        // take the rejection sampling path.
+        let word: String = iter::repeat(())
+                .map(|()| rng.gen::<char>()).take(1000).collect();
+        assert!(word.len() != 0);
+    }
+
+    #[test]
+    fn test_alphanumeric() {
+        let mut rng = crate::test::rng(806);
+
+        // Test by generating a relatively large number of chars, so we also
+        // take the rejection sampling path.
+        let mut incorrect = false;
+        for _ in 0..100 {
+            let c = rng.sample(Alphanumeric);
+            incorrect |= !((c >= '0' && c <= '9') ||
+                           (c >= 'A' && c <= 'Z') ||
+                           (c >= 'a' && c <= 'z') );
+        }
+        assert!(incorrect == false);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/pareto.rs.html b/target/doc/src/rand/distributions/pareto.rs.html new file mode 100644 index 0000000..dba682b --- /dev/null +++ b/target/doc/src/rand/distributions/pareto.rs.html @@ -0,0 +1,137 @@ +pareto.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The Pareto distribution.
+#![allow(deprecated)]
+
+use crate::Rng;
+use crate::distributions::{Distribution, OpenClosed01};
+
+/// Samples floating-point numbers according to the Pareto distribution
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Copy, Debug)]
+pub struct Pareto {
+    scale: f64,
+    inv_neg_shape: f64,
+}
+
+impl Pareto {
+    /// Construct a new Pareto distribution with given `scale` and `shape`.
+    ///
+    /// In the literature, `scale` is commonly written as x<sub>m</sub> or k and
+    /// `shape` is often written as α.
+    ///
+    /// # Panics
+    ///
+    /// `scale` and `shape` have to be non-zero and positive.
+    pub fn new(scale: f64, shape: f64) -> Pareto {
+        assert!((scale > 0.) & (shape > 0.));
+        Pareto { scale, inv_neg_shape: -1.0 / shape }
+    }
+}
+
+impl Distribution<f64> for Pareto {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
+        let u: f64 = rng.sample(OpenClosed01);
+        self.scale * u.powf(self.inv_neg_shape)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::distributions::Distribution;
+    use super::Pareto;
+
+    #[test]
+    #[should_panic]
+    fn invalid() {
+        Pareto::new(0., 0.);
+    }
+
+    #[test]
+    fn sample() {
+        let scale = 1.0;
+        let shape = 2.0;
+        let d = Pareto::new(scale, shape);
+        let mut rng = crate::test::rng(1);
+        for _ in 0..1000 {
+            let r = d.sample(&mut rng);
+            assert!(r >= scale);
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/poisson.rs.html b/target/doc/src/rand/distributions/poisson.rs.html new file mode 100644 index 0000000..fba4ebf --- /dev/null +++ b/target/doc/src/rand/distributions/poisson.rs.html @@ -0,0 +1,305 @@ +poisson.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+
+// Copyright 2018 Developers of the Rand project.
+// Copyright 2016-2017 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The Poisson distribution.
+#![allow(deprecated)]
+
+use crate::Rng;
+use crate::distributions::{Distribution, Cauchy};
+use crate::distributions::utils::log_gamma;
+
+/// The Poisson distribution `Poisson(lambda)`.
+///
+/// This distribution has a density function:
+/// `f(k) = lambda^k * exp(-lambda) / k!` for `k >= 0`.
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Copy, Debug)]
+pub struct Poisson {
+    lambda: f64,
+    // precalculated values
+    exp_lambda: f64,
+    log_lambda: f64,
+    sqrt_2lambda: f64,
+    magic_val: f64,
+}
+
+impl Poisson {
+    /// Construct a new `Poisson` with the given shape parameter
+    /// `lambda`. Panics if `lambda <= 0`.
+    pub fn new(lambda: f64) -> Poisson {
+        assert!(lambda > 0.0, "Poisson::new called with lambda <= 0");
+        let log_lambda = lambda.ln();
+        Poisson {
+            lambda,
+            exp_lambda: (-lambda).exp(),
+            log_lambda,
+            sqrt_2lambda: (2.0 * lambda).sqrt(),
+            magic_val: lambda * log_lambda - log_gamma(1.0 + lambda),
+        }
+    }
+}
+
+impl Distribution<u64> for Poisson {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u64 {
+        // using the algorithm from Numerical Recipes in C
+
+        // for low expected values use the Knuth method
+        if self.lambda < 12.0 {
+            let mut result = 0;
+            let mut p = 1.0;
+            while p > self.exp_lambda {
+                p *= rng.gen::<f64>();
+                result += 1;
+            }
+            result - 1
+        }
+        // high expected values - rejection method
+        else {
+            let mut int_result: u64;
+
+            // we use the Cauchy distribution as the comparison distribution
+            // f(x) ~ 1/(1+x^2)
+            let cauchy = Cauchy::new(0.0, 1.0);
+
+            loop {
+                let mut result;
+                let mut comp_dev;
+
+                loop {
+                    // draw from the Cauchy distribution
+                    comp_dev = rng.sample(cauchy);
+                    // shift the peak of the comparison ditribution
+                    result = self.sqrt_2lambda * comp_dev + self.lambda;
+                    // repeat the drawing until we are in the range of possible values
+                    if result >= 0.0 {
+                        break;
+                    }
+                }
+                // now the result is a random variable greater than 0 with Cauchy distribution
+                // the result should be an integer value
+                result = result.floor();
+                int_result = result as u64;
+
+                // this is the ratio of the Poisson distribution to the comparison distribution
+                // the magic value scales the distribution function to a range of approximately 0-1
+                // since it is not exact, we multiply the ratio by 0.9 to avoid ratios greater than 1
+                // this doesn't change the resulting distribution, only increases the rate of failed drawings
+                let check = 0.9 * (1.0 + comp_dev * comp_dev)
+                    * (result * self.log_lambda - log_gamma(1.0 + result) - self.magic_val).exp();
+
+                // check with uniform random value - if below the threshold, we are within the target distribution
+                if rng.gen::<f64>() <= check {
+                    break;
+                }
+            }
+            int_result
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use crate::distributions::Distribution;
+    use super::Poisson;
+
+    #[test]
+    #[cfg(not(miri))] // Miri is too slow
+    fn test_poisson_10() {
+        let poisson = Poisson::new(10.0);
+        let mut rng = crate::test::rng(123);
+        let mut sum = 0;
+        for _ in 0..1000 {
+            sum += poisson.sample(&mut rng);
+        }
+        let avg = (sum as f64) / 1000.0;
+        println!("Poisson average: {}", avg);
+        assert!((avg - 10.0).abs() < 0.5); // not 100% certain, but probable enough
+    }
+
+    #[test]
+    #[cfg(not(miri))] // Miri doesn't support transcendental functions
+    fn test_poisson_15() {
+        // Take the 'high expected values' path
+        let poisson = Poisson::new(15.0);
+        let mut rng = crate::test::rng(123);
+        let mut sum = 0;
+        for _ in 0..1000 {
+            sum += poisson.sample(&mut rng);
+        }
+        let avg = (sum as f64) / 1000.0;
+        println!("Poisson average: {}", avg);
+        assert!((avg - 15.0).abs() < 0.5); // not 100% certain, but probable enough
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_poisson_invalid_lambda_zero() {
+        Poisson::new(0.0);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_poisson_invalid_lambda_neg() {
+        Poisson::new(-10.0);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/triangular.rs.html b/target/doc/src/rand/distributions/triangular.rs.html new file mode 100644 index 0000000..efebd7f --- /dev/null +++ b/target/doc/src/rand/distributions/triangular.rs.html @@ -0,0 +1,161 @@ +triangular.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The triangular distribution.
+#![allow(deprecated)]
+
+use crate::Rng;
+use crate::distributions::{Distribution, Standard};
+
+/// The triangular distribution.
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Copy, Debug)]
+pub struct Triangular {
+    min: f64,
+    max: f64,
+    mode: f64,
+}
+
+impl Triangular {
+    /// Construct a new `Triangular` with minimum `min`, maximum `max` and mode
+    /// `mode`.
+    ///
+    /// # Panics
+    ///
+    /// If `max < mode`, `mode < max` or `max == min`.
+    ///
+    #[inline]
+    pub fn new(min: f64, max: f64, mode: f64) -> Triangular {
+        assert!(max >= mode);
+        assert!(mode >= min);
+        assert!(max != min);
+        Triangular { min, max, mode }
+    }
+}
+
+impl Distribution<f64> for Triangular {
+    #[inline]
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
+        let f: f64 = rng.sample(Standard);
+        let diff_mode_min = self.mode - self.min;
+        let diff_max_min = self.max - self.min;
+        if f * diff_max_min < diff_mode_min {
+            self.min + (f * diff_max_min * diff_mode_min).sqrt()
+        } else {
+            self.max - ((1. - f) * diff_max_min * (self.max - self.mode)).sqrt()
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use crate::distributions::Distribution;
+    use super::Triangular;
+
+    #[test]
+    fn test_new() {
+        for &(min, max, mode) in &[
+            (-1., 1., 0.), (1., 2., 1.), (5., 25., 25.), (1e-5, 1e5, 1e-3),
+            (0., 1., 0.9), (-4., -0.5, -2.), (-13.039, 8.41, 1.17),
+        ] {
+            println!("{} {} {}", min, max, mode);
+            let _ = Triangular::new(min, max, mode);
+        }
+    }
+
+    #[test]
+    fn test_sample() {
+        let norm = Triangular::new(0., 1., 0.5);
+        let mut rng = crate::test::rng(1);
+        for _ in 0..1000 {
+            norm.sample(&mut rng);
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/uniform.rs.html b/target/doc/src/rand/distributions/uniform.rs.html new file mode 100644 index 0000000..853e3cd --- /dev/null +++ b/target/doc/src/rand/distributions/uniform.rs.html @@ -0,0 +1,2543 @@ +uniform.rs.html -- source
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+
+// Copyright 2018 Developers of the Rand project.
+// Copyright 2017 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! A distribution uniformly sampling numbers within a given range.
+//!
+//! [`Uniform`] is the standard distribution to sample uniformly from a range;
+//! e.g. `Uniform::new_inclusive(1, 6)` can sample integers from 1 to 6, like a
+//! standard die. [`Rng::gen_range`] supports any type supported by
+//! [`Uniform`].
+//!
+//! This distribution is provided with support for several primitive types
+//! (all integer and floating-point types) as well as [`std::time::Duration`],
+//! and supports extension to user-defined types via a type-specific *back-end*
+//! implementation.
+//!
+//! The types [`UniformInt`], [`UniformFloat`] and [`UniformDuration`] are the
+//! back-ends supporting sampling from primitive integer and floating-point
+//! ranges as well as from [`std::time::Duration`]; these types do not normally
+//! need to be used directly (unless implementing a derived back-end).
+//!
+//! # Example usage
+//!
+//! ```
+//! use rand::{Rng, thread_rng};
+//! use rand::distributions::Uniform;
+//!
+//! let mut rng = thread_rng();
+//! let side = Uniform::new(-10.0, 10.0);
+//!
+//! // sample between 1 and 10 points
+//! for _ in 0..rng.gen_range(1, 11) {
+//!     // sample a point from the square with sides -10 - 10 in two dimensions
+//!     let (x, y) = (rng.sample(side), rng.sample(side));
+//!     println!("Point: {}, {}", x, y);
+//! }
+//! ```
+//!
+//! # Extending `Uniform` to support a custom type
+//!
+//! To extend [`Uniform`] to support your own types, write a back-end which
+//! implements the [`UniformSampler`] trait, then implement the [`SampleUniform`]
+//! helper trait to "register" your back-end. See the `MyF32` example below.
+//!
+//! At a minimum, the back-end needs to store any parameters needed for sampling
+//! (e.g. the target range) and implement `new`, `new_inclusive` and `sample`.
+//! Those methods should include an assert to check the range is valid (i.e.
+//! `low < high`). The example below merely wraps another back-end.
+//!
+//! The `new`, `new_inclusive` and `sample_single` functions use arguments of
+//! type SampleBorrow<X> in order to support passing in values by reference or
+//! by value. In the implementation of these functions, you can choose to
+//! simply use the reference returned by [`SampleBorrow::borrow`], or you can choose
+//! to copy or clone the value, whatever is appropriate for your type.
+//!
+//! ```
+//! use rand::prelude::*;
+//! use rand::distributions::uniform::{Uniform, SampleUniform,
+//!         UniformSampler, UniformFloat, SampleBorrow};
+//!
+//! struct MyF32(f32);
+//!
+//! #[derive(Clone, Copy, Debug)]
+//! struct UniformMyF32 {
+//!     inner: UniformFloat<f32>,
+//! }
+//!
+//! impl UniformSampler for UniformMyF32 {
+//!     type X = MyF32;
+//!     fn new<B1, B2>(low: B1, high: B2) -> Self
+//!         where B1: SampleBorrow<Self::X> + Sized,
+//!               B2: SampleBorrow<Self::X> + Sized
+//!     {
+//!         UniformMyF32 {
+//!             inner: UniformFloat::<f32>::new(low.borrow().0, high.borrow().0),
+//!         }
+//!     }
+//!     fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self
+//!         where B1: SampleBorrow<Self::X> + Sized,
+//!               B2: SampleBorrow<Self::X> + Sized
+//!     {
+//!         UniformSampler::new(low, high)
+//!     }
+//!     fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
+//!         MyF32(self.inner.sample(rng))
+//!     }
+//! }
+//!
+//! impl SampleUniform for MyF32 {
+//!     type Sampler = UniformMyF32;
+//! }
+//!
+//! let (low, high) = (MyF32(17.0f32), MyF32(22.0f32));
+//! let uniform = Uniform::new(low, high);
+//! let x = uniform.sample(&mut thread_rng());
+//! ```
+//!
+//! [`SampleUniform`]: crate::distributions::uniform::SampleUniform
+//! [`UniformSampler`]: crate::distributions::uniform::UniformSampler
+//! [`UniformInt`]: crate::distributions::uniform::UniformInt
+//! [`UniformFloat`]: crate::distributions::uniform::UniformFloat
+//! [`UniformDuration`]: crate::distributions::uniform::UniformDuration
+//! [`SampleBorrow::borrow`]: crate::distributions::uniform::SampleBorrow::borrow
+
+#[cfg(feature = "std")]
+use std::time::Duration;
+#[cfg(not(feature = "std"))]
+use core::time::Duration;
+
+use crate::Rng;
+use crate::distributions::Distribution;
+use crate::distributions::float::IntoFloat;
+use crate::distributions::utils::{WideningMultiply, FloatSIMDUtils, FloatAsSIMD, BoolAsSIMD};
+
+#[cfg(not(feature = "std"))]
+#[allow(unused_imports)] // rustc doesn't detect that this is actually used
+use crate::distributions::utils::Float;
+
+
+#[cfg(feature="simd_support")]
+use packed_simd::*;
+
+/// Sample values uniformly between two bounds.
+///
+/// [`Uniform::new`] and [`Uniform::new_inclusive`] construct a uniform
+/// distribution sampling from the given range; these functions may do extra
+/// work up front to make sampling of multiple values faster.
+///
+/// When sampling from a constant range, many calculations can happen at
+/// compile-time and all methods should be fast; for floating-point ranges and
+/// the full range of integer types this should have comparable performance to
+/// the `Standard` distribution.
+///
+/// Steps are taken to avoid bias which might be present in naive
+/// implementations; for example `rng.gen::<u8>() % 170` samples from the range
+/// `[0, 169]` but is twice as likely to select numbers less than 85 than other
+/// values. Further, the implementations here give more weight to the high-bits
+/// generated by the RNG than the low bits, since with some RNGs the low-bits
+/// are of lower quality than the high bits.
+///
+/// Implementations must sample in `[low, high)` range for
+/// `Uniform::new(low, high)`, i.e., excluding `high`. In particular care must
+/// be taken to ensure that rounding never results values `< low` or `>= high`.
+///
+/// # Example
+///
+/// ```
+/// use rand::distributions::{Distribution, Uniform};
+///
+/// fn main() {
+///     let between = Uniform::from(10..10000);
+///     let mut rng = rand::thread_rng();
+///     let mut sum = 0;
+///     for _ in 0..1000 {
+///         sum += between.sample(&mut rng);
+///     }
+///     println!("{}", sum);
+/// }
+/// ```
+///
+/// [`new`]: Uniform::new
+/// [`new_inclusive`]: Uniform::new_inclusive
+#[derive(Clone, Copy, Debug)]
+pub struct Uniform<X: SampleUniform> {
+    inner: X::Sampler,
+}
+
+impl<X: SampleUniform> Uniform<X> {
+    /// Create a new `Uniform` instance which samples uniformly from the half
+    /// open range `[low, high)` (excluding `high`). Panics if `low >= high`.
+    pub fn new<B1, B2>(low: B1, high: B2) -> Uniform<X>
+        where B1: SampleBorrow<X> + Sized,
+              B2: SampleBorrow<X> + Sized
+    {
+        Uniform { inner: X::Sampler::new(low, high) }
+    }
+
+    /// Create a new `Uniform` instance which samples uniformly from the closed
+    /// range `[low, high]` (inclusive). Panics if `low > high`.
+    pub fn new_inclusive<B1, B2>(low: B1, high: B2) -> Uniform<X>
+        where B1: SampleBorrow<X> + Sized,
+              B2: SampleBorrow<X> + Sized
+    {
+        Uniform { inner: X::Sampler::new_inclusive(low, high) }
+    }
+}
+
+impl<X: SampleUniform> Distribution<X> for Uniform<X> {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> X {
+        self.inner.sample(rng)
+    }
+}
+
+/// Helper trait for creating objects using the correct implementation of
+/// [`UniformSampler`] for the sampling type.
+///
+/// See the [module documentation] on how to implement [`Uniform`] range
+/// sampling for a custom type.
+///
+/// [module documentation]: crate::distributions::uniform
+pub trait SampleUniform: Sized {
+    /// The `UniformSampler` implementation supporting type `X`.
+    type Sampler: UniformSampler<X = Self>;
+}
+
+/// Helper trait handling actual uniform sampling.
+///
+/// See the [module documentation] on how to implement [`Uniform`] range
+/// sampling for a custom type.
+///
+/// Implementation of [`sample_single`] is optional, and is only useful when
+/// the implementation can be faster than `Self::new(low, high).sample(rng)`.
+///
+/// [module documentation]: crate::distributions::uniform
+/// [`sample_single`]: UniformSampler::sample_single
+pub trait UniformSampler: Sized {
+    /// The type sampled by this implementation.
+    type X;
+
+    /// Construct self, with inclusive lower bound and exclusive upper bound
+    /// `[low, high)`.
+    ///
+    /// Usually users should not call this directly but instead use
+    /// `Uniform::new`, which asserts that `low < high` before calling this.
+    fn new<B1, B2>(low: B1, high: B2) -> Self
+        where B1: SampleBorrow<Self::X> + Sized,
+              B2: SampleBorrow<Self::X> + Sized;
+
+    /// Construct self, with inclusive bounds `[low, high]`.
+    ///
+    /// Usually users should not call this directly but instead use
+    /// `Uniform::new_inclusive`, which asserts that `low <= high` before
+    /// calling this.
+    fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self
+        where B1: SampleBorrow<Self::X> + Sized,
+              B2: SampleBorrow<Self::X> + Sized;
+
+    /// Sample a value.
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X;
+
+    /// Sample a single value uniformly from a range with inclusive lower bound
+    /// and exclusive upper bound `[low, high)`.
+    ///
+    /// By default this is implemented using
+    /// `UniformSampler::new(low, high).sample(rng)`. However, for some types
+    /// more optimal implementations for single usage may be provided via this
+    /// method (which is the case for integers and floats).
+    /// Results may not be identical.
+    fn sample_single<R: Rng + ?Sized, B1, B2>(low: B1, high: B2, rng: &mut R)
+        -> Self::X
+        where B1: SampleBorrow<Self::X> + Sized,
+              B2: SampleBorrow<Self::X> + Sized
+    {
+        let uniform: Self = UniformSampler::new(low, high);
+        uniform.sample(rng)
+    }
+}
+
+impl<X: SampleUniform> From<::core::ops::Range<X>> for Uniform<X> {
+    fn from(r: ::core::ops::Range<X>) -> Uniform<X> {
+        Uniform::new(r.start, r.end)
+    }
+}
+
+impl<X: SampleUniform> From<::core::ops::RangeInclusive<X>> for Uniform<X> {
+    fn from(r: ::core::ops::RangeInclusive<X>) -> Uniform<X> {
+        Uniform::new_inclusive(r.start(), r.end())
+    }
+}
+
+/// Helper trait similar to [`Borrow`] but implemented
+/// only for SampleUniform and references to SampleUniform in
+/// order to resolve ambiguity issues.
+///
+/// [`Borrow`]: std::borrow::Borrow
+pub trait SampleBorrow<Borrowed> {
+    /// Immutably borrows from an owned value. See [`Borrow::borrow`]
+    ///
+    /// [`Borrow::borrow`]: std::borrow::Borrow::borrow
+    fn borrow(&self) -> &Borrowed;
+}
+impl<Borrowed> SampleBorrow<Borrowed> for Borrowed where Borrowed: SampleUniform {
+    #[inline(always)]
+    fn borrow(&self) -> &Borrowed { self }
+}
+impl<'a, Borrowed> SampleBorrow<Borrowed> for &'a Borrowed where Borrowed: SampleUniform {
+    #[inline(always)]
+   fn borrow(&self) -> &Borrowed { *self }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// What follows are all back-ends.
+
+
+/// The back-end implementing [`UniformSampler`] for integer types.
+///
+/// Unless you are implementing [`UniformSampler`] for your own type, this type
+/// should not be used directly, use [`Uniform`] instead.
+///
+/// # Implementation notes
+///
+/// For simplicity, we use the same generic struct `UniformInt<X>` for all
+/// integer types `X`. This gives us only one field type, `X`; to store unsigned
+/// values of this size, we take use the fact that these conversions are no-ops.
+///
+/// For a closed range, the number of possible numbers we should generate is
+/// `range = (high - low + 1)`. To avoid bias, we must ensure that the size of
+/// our sample space, `zone`, is a multiple of `range`; other values must be
+/// rejected (by replacing with a new random sample).
+///
+/// As a special case, we use `range = 0` to represent the full range of the
+/// result type (i.e. for `new_inclusive($ty::MIN, $ty::MAX)`).
+///
+/// The optimum `zone` is the largest product of `range` which fits in our
+/// (unsigned) target type. We calculate this by calculating how many numbers we
+/// must reject: `reject = (MAX + 1) % range = (MAX - range + 1) % range`. Any (large)
+/// product of `range` will suffice, thus in `sample_single` we multiply by a
+/// power of 2 via bit-shifting (faster but may cause more rejections).
+///
+/// The smallest integer PRNGs generate is `u32`. For 8- and 16-bit outputs we
+/// use `u32` for our `zone` and samples (because it's not slower and because
+/// it reduces the chance of having to reject a sample). In this case we cannot
+/// store `zone` in the target type since it is too large, however we know
+/// `ints_to_reject < range <= $unsigned::MAX`.
+///
+/// An alternative to using a modulus is widening multiply: After a widening
+/// multiply by `range`, the result is in the high word. Then comparing the low
+/// word against `zone` makes sure our distribution is uniform.
+#[derive(Clone, Copy, Debug)]
+pub struct UniformInt<X> {
+    low: X,
+    range: X,
+    z: X,   // either ints_to_reject or zone depending on implementation
+}
+
+macro_rules! uniform_int_impl {
+    ($ty:ty, $unsigned:ident, $u_large:ident) => {
+        impl SampleUniform for $ty {
+            type Sampler = UniformInt<$ty>;
+        }
+
+        impl UniformSampler for UniformInt<$ty> {
+            // We play free and fast with unsigned vs signed here
+            // (when $ty is signed), but that's fine, since the
+            // contract of this macro is for $ty and $unsigned to be
+            // "bit-equal", so casting between them is a no-op.
+
+            type X = $ty;
+
+            #[inline] // if the range is constant, this helps LLVM to do the
+                      // calculations at compile-time.
+            fn new<B1, B2>(low_b: B1, high_b: B2) -> Self
+                where B1: SampleBorrow<Self::X> + Sized,
+                      B2: SampleBorrow<Self::X> + Sized
+            {
+                let low = *low_b.borrow();
+                let high = *high_b.borrow();
+                assert!(low < high, "Uniform::new called with `low >= high`");
+                UniformSampler::new_inclusive(low, high - 1)
+            }
+
+            #[inline] // if the range is constant, this helps LLVM to do the
+                      // calculations at compile-time.
+            fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Self
+                where B1: SampleBorrow<Self::X> + Sized,
+                      B2: SampleBorrow<Self::X> + Sized
+            {
+                let low = *low_b.borrow();
+                let high = *high_b.borrow();
+                assert!(low <= high,
+                        "Uniform::new_inclusive called with `low > high`");
+                let unsigned_max = ::core::$u_large::MAX;
+
+                let range = high.wrapping_sub(low).wrapping_add(1) as $unsigned;
+                let ints_to_reject =
+                    if range > 0 {
+                        let range = range as $u_large;
+                        (unsigned_max - range + 1) % range
+                    } else {
+                        0
+                    };
+
+                UniformInt {
+                    low: low,
+                    // These are really $unsigned values, but store as $ty:
+                    range: range as $ty,
+                    z: ints_to_reject as $unsigned as $ty
+                }
+            }
+
+            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
+                let range = self.range as $unsigned as $u_large;
+                if range > 0 {
+                    let unsigned_max = ::core::$u_large::MAX;
+                    let zone = unsigned_max - (self.z as $unsigned as $u_large);
+                    loop {
+                        let v: $u_large = rng.gen();
+                        let (hi, lo) = v.wmul(range);
+                        if lo <= zone {
+                            return self.low.wrapping_add(hi as $ty);
+                        }
+                    }
+                } else {
+                    // Sample from the entire integer range.
+                    rng.gen()
+                }
+            }
+
+            fn sample_single<R: Rng + ?Sized, B1, B2>(low_b: B1, high_b: B2, rng: &mut R)
+                -> Self::X
+                where B1: SampleBorrow<Self::X> + Sized,
+                      B2: SampleBorrow<Self::X> + Sized
+            {
+                let low = *low_b.borrow();
+                let high = *high_b.borrow();
+                assert!(low < high,
+                        "UniformSampler::sample_single: low >= high");
+                let range = high.wrapping_sub(low) as $unsigned as $u_large;
+                let zone =
+                    if ::core::$unsigned::MAX <= ::core::u16::MAX as $unsigned {
+                        // Using a modulus is faster than the approximation for
+                        // i8 and i16. I suppose we trade the cost of one
+                        // modulus for near-perfect branch prediction.
+                        let unsigned_max: $u_large = ::core::$u_large::MAX;
+                        let ints_to_reject = (unsigned_max - range + 1) % range;
+                        unsigned_max - ints_to_reject
+                    } else {
+                        // conservative but fast approximation. `- 1` is necessary to allow the
+                        // same comparison without bias.
+                        (range << range.leading_zeros()).wrapping_sub(1)
+                    };
+
+                loop {
+                    let v: $u_large = rng.gen();
+                    let (hi, lo) = v.wmul(range);
+                    if lo <= zone {
+                        return low.wrapping_add(hi as $ty);
+                    }
+                }
+            }
+        }
+    }
+}
+
+uniform_int_impl! { i8, u8, u32 }
+uniform_int_impl! { i16, u16, u32 }
+uniform_int_impl! { i32, u32, u32 }
+uniform_int_impl! { i64, u64, u64 }
+#[cfg(not(target_os = "emscripten"))]
+uniform_int_impl! { i128, u128, u128 }
+uniform_int_impl! { isize, usize, usize }
+uniform_int_impl! { u8, u8, u32 }
+uniform_int_impl! { u16, u16, u32 }
+uniform_int_impl! { u32, u32, u32 }
+uniform_int_impl! { u64, u64, u64 }
+uniform_int_impl! { usize, usize, usize }
+#[cfg(not(target_os = "emscripten"))]
+uniform_int_impl! { u128, u128, u128 }
+
+#[cfg(all(feature = "simd_support", feature = "nightly"))]
+macro_rules! uniform_simd_int_impl {
+    ($ty:ident, $unsigned:ident, $u_scalar:ident) => {
+        // The "pick the largest zone that can fit in an `u32`" optimization
+        // is less useful here. Multiple lanes complicate things, we don't
+        // know the PRNG's minimal output size, and casting to a larger vector
+        // is generally a bad idea for SIMD performance. The user can still
+        // implement it manually.
+
+        // TODO: look into `Uniform::<u32x4>::new(0u32, 100)` functionality
+        //       perhaps `impl SampleUniform for $u_scalar`?
+        impl SampleUniform for $ty {
+            type Sampler = UniformInt<$ty>;
+        }
+
+        impl UniformSampler for UniformInt<$ty> {
+            type X = $ty;
+
+            #[inline] // if the range is constant, this helps LLVM to do the
+                      // calculations at compile-time.
+            fn new<B1, B2>(low_b: B1, high_b: B2) -> Self
+                where B1: SampleBorrow<Self::X> + Sized,
+                      B2: SampleBorrow<Self::X> + Sized
+            {
+                let low = *low_b.borrow();
+                let high = *high_b.borrow();
+                assert!(low.lt(high).all(), "Uniform::new called with `low >= high`");
+                UniformSampler::new_inclusive(low, high - 1)
+            }
+
+            #[inline] // if the range is constant, this helps LLVM to do the
+                      // calculations at compile-time.
+            fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Self
+                where B1: SampleBorrow<Self::X> + Sized,
+                      B2: SampleBorrow<Self::X> + Sized
+            {
+                let low = *low_b.borrow();
+                let high = *high_b.borrow();
+                assert!(low.le(high).all(),
+                        "Uniform::new_inclusive called with `low > high`");
+                let unsigned_max = ::core::$u_scalar::MAX;
+
+                // NOTE: these may need to be replaced with explicitly
+                // wrapping operations if `packed_simd` changes
+                let range: $unsigned = ((high - low) + 1).cast();
+                // `% 0` will panic at runtime.
+                let not_full_range = range.gt($unsigned::splat(0));
+                // replacing 0 with `unsigned_max` allows a faster `select`
+                // with bitwise OR
+                let modulo = not_full_range.select(range, $unsigned::splat(unsigned_max));
+                // wrapping addition
+                let ints_to_reject = (unsigned_max - range + 1) % modulo;
+                // When `range` is 0, `lo` of `v.wmul(range)` will always be
+                // zero which means only one sample is needed.
+                let zone = unsigned_max - ints_to_reject;
+
+                UniformInt {
+                    low: low,
+                    // These are really $unsigned values, but store as $ty:
+                    range: range.cast(),
+                    z: zone.cast(),
+                }
+            }
+
+            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
+                let range: $unsigned = self.range.cast();
+                let zone: $unsigned = self.z.cast();
+
+                // This might seem very slow, generating a whole new
+                // SIMD vector for every sample rejection. For most uses
+                // though, the chance of rejection is small and provides good
+                // general performance. With multiple lanes, that chance is
+                // multiplied. To mitigate this, we replace only the lanes of
+                // the vector which fail, iteratively reducing the chance of
+                // rejection. The replacement method does however add a little
+                // overhead. Benchmarking or calculating probabilities might
+                // reveal contexts where this replacement method is slower.
+                let mut v: $unsigned = rng.gen();
+                loop {
+                    let (hi, lo) = v.wmul(range);
+                    let mask = lo.le(zone);
+                    if mask.all() {
+                        let hi: $ty = hi.cast();
+                        // wrapping addition
+                        let result = self.low + hi;
+                        // `select` here compiles to a blend operation
+                        // When `range.eq(0).none()` the compare and blend
+                        // operations are avoided.
+                        let v: $ty = v.cast();
+                        return range.gt($unsigned::splat(0)).select(result, v);
+                    }
+                    // Replace only the failing lanes
+                    v = mask.select(v, rng.gen());
+                }
+            }
+        }
+    };
+
+    // bulk implementation
+    ($(($unsigned:ident, $signed:ident),)+ $u_scalar:ident) => {
+        $(
+            uniform_simd_int_impl!($unsigned, $unsigned, $u_scalar);
+            uniform_simd_int_impl!($signed, $unsigned, $u_scalar);
+        )+
+    };
+}
+
+#[cfg(all(feature = "simd_support", feature = "nightly"))]
+uniform_simd_int_impl! {
+    (u64x2, i64x2),
+    (u64x4, i64x4),
+    (u64x8, i64x8),
+    u64
+}
+
+#[cfg(all(feature = "simd_support", feature = "nightly"))]
+uniform_simd_int_impl! {
+    (u32x2, i32x2),
+    (u32x4, i32x4),
+    (u32x8, i32x8),
+    (u32x16, i32x16),
+    u32
+}
+
+#[cfg(all(feature = "simd_support", feature = "nightly"))]
+uniform_simd_int_impl! {
+    (u16x2, i16x2),
+    (u16x4, i16x4),
+    (u16x8, i16x8),
+    (u16x16, i16x16),
+    (u16x32, i16x32),
+    u16
+}
+
+#[cfg(all(feature = "simd_support", feature = "nightly"))]
+uniform_simd_int_impl! {
+    (u8x2, i8x2),
+    (u8x4, i8x4),
+    (u8x8, i8x8),
+    (u8x16, i8x16),
+    (u8x32, i8x32),
+    (u8x64, i8x64),
+    u8
+}
+
+
+/// The back-end implementing [`UniformSampler`] for floating-point types.
+///
+/// Unless you are implementing [`UniformSampler`] for your own type, this type
+/// should not be used directly, use [`Uniform`] instead.
+///
+/// # Implementation notes
+///
+/// Instead of generating a float in the `[0, 1)` range using [`Standard`], the
+/// `UniformFloat` implementation converts the output of an PRNG itself. This
+/// way one or two steps can be optimized out.
+///
+/// The floats are first converted to a value in the `[1, 2)` interval using a
+/// transmute-based method, and then mapped to the expected range with a
+/// multiply and addition. Values produced this way have what equals 22 bits of
+/// random digits for an `f32`, and 52 for an `f64`.
+///
+/// [`new`]: UniformSampler::new
+/// [`new_inclusive`]: UniformSampler::new_inclusive
+/// [`Standard`]: crate::distributions::Standard
+#[derive(Clone, Copy, Debug)]
+pub struct UniformFloat<X> {
+    low: X,
+    scale: X,
+}
+
+macro_rules! uniform_float_impl {
+    ($ty:ty, $uty:ident, $f_scalar:ident, $u_scalar:ident, $bits_to_discard:expr) => {
+        impl SampleUniform for $ty {
+            type Sampler = UniformFloat<$ty>;
+        }
+
+        impl UniformSampler for UniformFloat<$ty> {
+            type X = $ty;
+
+            fn new<B1, B2>(low_b: B1, high_b: B2) -> Self
+                where B1: SampleBorrow<Self::X> + Sized,
+                      B2: SampleBorrow<Self::X> + Sized
+            {
+                let low = *low_b.borrow();
+                let high = *high_b.borrow();
+                assert!(low.all_lt(high),
+                        "Uniform::new called with `low >= high`");
+                assert!(low.all_finite() && high.all_finite(),
+                        "Uniform::new called with non-finite boundaries");
+                let max_rand = <$ty>::splat((::core::$u_scalar::MAX >> $bits_to_discard)
+                                            .into_float_with_exponent(0) - 1.0);
+
+                let mut scale = high - low;
+
+                loop {
+                    let mask = (scale * max_rand + low).ge_mask(high);
+                    if mask.none() {
+                        break;
+                    }
+                    scale = scale.decrease_masked(mask);
+                }
+
+                debug_assert!(<$ty>::splat(0.0).all_le(scale));
+
+                UniformFloat { low, scale }
+            }
+
+            fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Self
+                where B1: SampleBorrow<Self::X> + Sized,
+                      B2: SampleBorrow<Self::X> + Sized
+            {
+                let low = *low_b.borrow();
+                let high = *high_b.borrow();
+                assert!(low.all_le(high),
+                        "Uniform::new_inclusive called with `low > high`");
+                assert!(low.all_finite() && high.all_finite(),
+                        "Uniform::new_inclusive called with non-finite boundaries");
+                let max_rand = <$ty>::splat((::core::$u_scalar::MAX >> $bits_to_discard)
+                                            .into_float_with_exponent(0) - 1.0);
+
+                let mut scale = (high - low) / max_rand;
+
+                loop {
+                    let mask = (scale * max_rand + low).gt_mask(high);
+                    if mask.none() {
+                        break;
+                    }
+                    scale = scale.decrease_masked(mask);
+                }
+
+                debug_assert!(<$ty>::splat(0.0).all_le(scale));
+
+                UniformFloat { low, scale }
+            }
+
+            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
+                // Generate a value in the range [1, 2)
+                let value1_2 = (rng.gen::<$uty>() >> $bits_to_discard)
+                               .into_float_with_exponent(0);
+
+                // Get a value in the range [0, 1) in order to avoid
+                // overflowing into infinity when multiplying with scale
+                let value0_1 = value1_2 - 1.0;
+
+                // We don't use `f64::mul_add`, because it is not available with
+                // `no_std`. Furthermore, it is slower for some targets (but
+                // faster for others). However, the order of multiplication and
+                // addition is important, because on some platforms (e.g. ARM)
+                // it will be optimized to a single (non-FMA) instruction.
+                value0_1 * self.scale + self.low
+            }
+
+            #[inline]
+            fn sample_single<R: Rng + ?Sized, B1, B2>(low_b: B1, high_b: B2, rng: &mut R)
+                -> Self::X
+                where B1: SampleBorrow<Self::X> + Sized,
+                      B2: SampleBorrow<Self::X> + Sized
+            {
+                let low = *low_b.borrow();
+                let high = *high_b.borrow();
+                assert!(low.all_lt(high),
+                        "UniformSampler::sample_single: low >= high");
+                let mut scale = high - low;
+
+                loop {
+                    // Generate a value in the range [1, 2)
+                    let value1_2 = (rng.gen::<$uty>() >> $bits_to_discard)
+                                   .into_float_with_exponent(0);
+
+                    // Get a value in the range [0, 1) in order to avoid
+                    // overflowing into infinity when multiplying with scale
+                    let value0_1 = value1_2 - 1.0;
+
+                    // Doing multiply before addition allows some architectures
+                    // to use a single instruction.
+                    let res = value0_1 * scale + low;
+
+                    debug_assert!(low.all_le(res) || !scale.all_finite());
+                    if res.all_lt(high) {
+                        return res;
+                    }
+
+                    // This handles a number of edge cases.
+                    // * `low` or `high` is NaN. In this case `scale` and
+                    //   `res` are going to end up as NaN.
+                    // * `low` is negative infinity and `high` is finite.
+                    //   `scale` is going to be infinite and `res` will be
+                    //   NaN.
+                    // * `high` is positive infinity and `low` is finite.
+                    //   `scale` is going to be infinite and `res` will
+                    //   be infinite or NaN (if value0_1 is 0).
+                    // * `low` is negative infinity and `high` is positive
+                    //   infinity. `scale` will be infinite and `res` will
+                    //   be NaN.
+                    // * `low` and `high` are finite, but `high - low`
+                    //   overflows to infinite. `scale` will be infinite
+                    //   and `res` will be infinite or NaN (if value0_1 is 0).
+                    // So if `high` or `low` are non-finite, we are guaranteed
+                    // to fail the `res < high` check above and end up here.
+                    //
+                    // While we technically should check for non-finite `low`
+                    // and `high` before entering the loop, by doing the checks
+                    // here instead, we allow the common case to avoid these
+                    // checks. But we are still guaranteed that if `low` or
+                    // `high` are non-finite we'll end up here and can do the
+                    // appropriate checks.
+                    //
+                    // Likewise `high - low` overflowing to infinity is also
+                    // rare, so handle it here after the common case.
+                    let mask = !scale.finite_mask();
+                    if mask.any() {
+                        assert!(low.all_finite() && high.all_finite(),
+                                "Uniform::sample_single: low and high must be finite");
+                        scale = scale.decrease_masked(mask);
+                    }
+                }
+            }
+        }
+    }
+}
+
+uniform_float_impl! { f32, u32, f32, u32, 32 - 23 }
+uniform_float_impl! { f64, u64, f64, u64, 64 - 52 }
+
+#[cfg(feature="simd_support")]
+uniform_float_impl! { f32x2, u32x2, f32, u32, 32 - 23 }
+#[cfg(feature="simd_support")]
+uniform_float_impl! { f32x4, u32x4, f32, u32, 32 - 23 }
+#[cfg(feature="simd_support")]
+uniform_float_impl! { f32x8, u32x8, f32, u32, 32 - 23 }
+#[cfg(feature="simd_support")]
+uniform_float_impl! { f32x16, u32x16, f32, u32, 32 - 23 }
+
+#[cfg(feature="simd_support")]
+uniform_float_impl! { f64x2, u64x2, f64, u64, 64 - 52 }
+#[cfg(feature="simd_support")]
+uniform_float_impl! { f64x4, u64x4, f64, u64, 64 - 52 }
+#[cfg(feature="simd_support")]
+uniform_float_impl! { f64x8, u64x8, f64, u64, 64 - 52 }
+
+
+
+/// The back-end implementing [`UniformSampler`] for `Duration`.
+///
+/// Unless you are implementing [`UniformSampler`] for your own types, this type
+/// should not be used directly, use [`Uniform`] instead.
+#[derive(Clone, Copy, Debug)]
+pub struct UniformDuration {
+    mode: UniformDurationMode,
+    offset: u32,
+}
+
+#[derive(Debug, Copy, Clone)]
+enum UniformDurationMode {
+    Small {
+        secs: u64,
+        nanos: Uniform<u32>,
+    },
+    Medium {
+        nanos: Uniform<u64>,
+    },
+    Large {
+        max_secs: u64,
+        max_nanos: u32,
+        secs: Uniform<u64>,
+    }
+}
+
+impl SampleUniform for Duration {
+    type Sampler = UniformDuration;
+}
+
+impl UniformSampler for UniformDuration {
+    type X = Duration;
+
+    #[inline]
+    fn new<B1, B2>(low_b: B1, high_b: B2) -> Self
+        where B1: SampleBorrow<Self::X> + Sized,
+              B2: SampleBorrow<Self::X> + Sized
+    {
+        let low = *low_b.borrow();
+        let high = *high_b.borrow();
+        assert!(low < high, "Uniform::new called with `low >= high`");
+        UniformDuration::new_inclusive(low, high - Duration::new(0, 1))
+    }
+
+    #[inline]
+    fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Self
+        where B1: SampleBorrow<Self::X> + Sized,
+              B2: SampleBorrow<Self::X> + Sized
+    {
+        let low = *low_b.borrow();
+        let high = *high_b.borrow();
+        assert!(low <= high, "Uniform::new_inclusive called with `low > high`");
+
+        let low_s = low.as_secs();
+        let low_n = low.subsec_nanos();
+        let mut high_s = high.as_secs();
+        let mut high_n = high.subsec_nanos();
+
+        if high_n < low_n {
+            high_s = high_s - 1;
+            high_n = high_n + 1_000_000_000;
+        }
+
+        let mode = if low_s == high_s {
+            UniformDurationMode::Small {
+                secs: low_s,
+                nanos: Uniform::new_inclusive(low_n, high_n),
+            }
+        } else {
+            let max = high_s
+                .checked_mul(1_000_000_000)
+                .and_then(|n| n.checked_add(high_n as u64));
+
+            if let Some(higher_bound) = max {
+                let lower_bound = low_s * 1_000_000_000 + low_n as u64;
+                UniformDurationMode::Medium {
+                    nanos: Uniform::new_inclusive(lower_bound, higher_bound),
+                }
+            } else {
+                // An offset is applied to simplify generation of nanoseconds
+                let max_nanos = high_n - low_n;
+                UniformDurationMode::Large {
+                    max_secs: high_s,
+                    max_nanos,
+                    secs: Uniform::new_inclusive(low_s, high_s),
+                }
+            }
+        };
+        UniformDuration {
+            mode,
+            offset: low_n,
+        }
+    }
+
+    #[inline]
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Duration {
+        match self.mode {
+            UniformDurationMode::Small { secs, nanos } => {
+                let n = nanos.sample(rng);
+                Duration::new(secs, n)
+            }
+            UniformDurationMode::Medium { nanos } => {
+                let nanos = nanos.sample(rng);
+                Duration::new(nanos / 1_000_000_000, (nanos % 1_000_000_000) as u32)
+            }
+            UniformDurationMode::Large { max_secs, max_nanos, secs } => {
+                // constant folding means this is at least as fast as `gen_range`
+                let nano_range = Uniform::new(0, 1_000_000_000);
+                loop {
+                    let s = secs.sample(rng);
+                    let n = nano_range.sample(rng);
+                    if !(s == max_secs && n > max_nanos) {
+                        let sum = n + self.offset;
+                        break Duration::new(s, sum);
+                    }
+                }
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::Rng;
+    use crate::rngs::mock::StepRng;
+    use crate::distributions::uniform::Uniform;
+    use crate::distributions::utils::FloatAsSIMD;
+    #[cfg(feature="simd_support")] use packed_simd::*;
+
+    #[should_panic]
+    #[test]
+    fn test_uniform_bad_limits_equal_int() {
+        Uniform::new(10, 10);
+    }
+
+    #[test]
+    fn test_uniform_good_limits_equal_int() {
+        let mut rng = crate::test::rng(804);
+        let dist = Uniform::new_inclusive(10, 10);
+        for _ in 0..20 {
+            assert_eq!(rng.sample(dist), 10);
+        }
+    }
+
+    #[should_panic]
+    #[test]
+    fn test_uniform_bad_limits_flipped_int() {
+        Uniform::new(10, 5);
+    }
+
+    #[test]
+    #[cfg(not(miri))] // Miri is too slow
+    fn test_integers() {
+        use core::{i8, i16, i32, i64, isize};
+        use core::{u8, u16, u32, u64, usize};
+        #[cfg(not(target_os = "emscripten"))]
+        use core::{i128, u128};
+
+        let mut rng = crate::test::rng(251);
+        macro_rules! t {
+            ($ty:ident, $v:expr, $le:expr, $lt:expr) => {{
+                for &(low, high) in $v.iter() {
+                    let my_uniform = Uniform::new(low, high);
+                    for _ in 0..1000 {
+                        let v: $ty = rng.sample(my_uniform);
+                        assert!($le(low, v) && $lt(v, high));
+                    }
+
+                    let my_uniform = Uniform::new_inclusive(low, high);
+                    for _ in 0..1000 {
+                        let v: $ty = rng.sample(my_uniform);
+                        assert!($le(low, v) && $le(v, high));
+                    }
+
+                    let my_uniform = Uniform::new(&low, high);
+                    for _ in 0..1000 {
+                        let v: $ty = rng.sample(my_uniform);
+                        assert!($le(low, v) && $lt(v, high));
+                    }
+
+                    let my_uniform = Uniform::new_inclusive(&low, &high);
+                    for _ in 0..1000 {
+                        let v: $ty = rng.sample(my_uniform);
+                        assert!($le(low, v) && $le(v, high));
+                    }
+
+                    for _ in 0..1000 {
+                        let v: $ty = rng.gen_range(low, high);
+                        assert!($le(low, v) && $lt(v, high));
+                    }
+                }
+            }};
+
+            // scalar bulk
+            ($($ty:ident),*) => {{
+                $(t!(
+                    $ty,
+                    [(0, 10), (10, 127), ($ty::MIN, $ty::MAX)],
+                    |x, y| x <= y,
+                    |x, y| x < y
+                );)*
+            }};
+
+            // simd bulk
+            ($($ty:ident),* => $scalar:ident) => {{
+                $(t!(
+                    $ty,
+                    [
+                        ($ty::splat(0), $ty::splat(10)),
+                        ($ty::splat(10), $ty::splat(127)),
+                        ($ty::splat($scalar::MIN), $ty::splat($scalar::MAX)),
+                    ],
+                    |x: $ty, y| x.le(y).all(),
+                    |x: $ty, y| x.lt(y).all()
+                );)*
+            }};
+        }
+        t!(i8, i16, i32, i64, isize,
+           u8, u16, u32, u64, usize);
+        #[cfg(not(target_os = "emscripten"))]
+        t!(i128, u128);
+
+        #[cfg(all(feature = "simd_support", feature = "nightly"))]
+        {
+            t!(u8x2, u8x4, u8x8, u8x16, u8x32, u8x64 => u8);
+            t!(i8x2, i8x4, i8x8, i8x16, i8x32, i8x64 => i8);
+            t!(u16x2, u16x4, u16x8, u16x16, u16x32 => u16);
+            t!(i16x2, i16x4, i16x8, i16x16, i16x32 => i16);
+            t!(u32x2, u32x4, u32x8, u32x16 => u32);
+            t!(i32x2, i32x4, i32x8, i32x16 => i32);
+            t!(u64x2, u64x4, u64x8 => u64);
+            t!(i64x2, i64x4, i64x8 => i64);
+        }
+    }
+
+    #[test]
+    #[cfg(not(miri))] // Miri is too slow
+    fn test_floats() {
+        let mut rng = crate::test::rng(252);
+        let mut zero_rng = StepRng::new(0, 0);
+        let mut max_rng = StepRng::new(0xffff_ffff_ffff_ffff, 0);
+        macro_rules! t {
+            ($ty:ty, $f_scalar:ident, $bits_shifted:expr) => {{
+                let v: &[($f_scalar, $f_scalar)]=
+                    &[(0.0, 100.0),
+                      (-1e35, -1e25),
+                      (1e-35, 1e-25),
+                      (-1e35, 1e35),
+                      (<$f_scalar>::from_bits(0), <$f_scalar>::from_bits(3)),
+                      (-<$f_scalar>::from_bits(10), -<$f_scalar>::from_bits(1)),
+                      (-<$f_scalar>::from_bits(5), 0.0),
+                      (-<$f_scalar>::from_bits(7), -0.0),
+                      (10.0, ::core::$f_scalar::MAX),
+                      (-100.0, ::core::$f_scalar::MAX),
+                      (-::core::$f_scalar::MAX / 5.0, ::core::$f_scalar::MAX),
+                      (-::core::$f_scalar::MAX, ::core::$f_scalar::MAX / 5.0),
+                      (-::core::$f_scalar::MAX * 0.8, ::core::$f_scalar::MAX * 0.7),
+                      (-::core::$f_scalar::MAX, ::core::$f_scalar::MAX),
+                     ];
+                for &(low_scalar, high_scalar) in v.iter() {
+                    for lane in 0..<$ty>::lanes() {
+                        let low = <$ty>::splat(0.0 as $f_scalar).replace(lane, low_scalar);
+                        let high = <$ty>::splat(1.0 as $f_scalar).replace(lane, high_scalar);
+                        let my_uniform = Uniform::new(low, high);
+                        let my_incl_uniform = Uniform::new_inclusive(low, high);
+                        for _ in 0..100 {
+                            let v = rng.sample(my_uniform).extract(lane);
+                            assert!(low_scalar <= v && v < high_scalar);
+                            let v = rng.sample(my_incl_uniform).extract(lane);
+                            assert!(low_scalar <= v && v <= high_scalar);
+                            let v = rng.gen_range(low, high).extract(lane);
+                            assert!(low_scalar <= v && v < high_scalar);
+                        }
+
+                        assert_eq!(rng.sample(Uniform::new_inclusive(low, low)).extract(lane), low_scalar);
+
+                        assert_eq!(zero_rng.sample(my_uniform).extract(lane), low_scalar);
+                        assert_eq!(zero_rng.sample(my_incl_uniform).extract(lane), low_scalar);
+                        assert_eq!(zero_rng.gen_range(low, high).extract(lane), low_scalar);
+                        assert!(max_rng.sample(my_uniform).extract(lane) < high_scalar);
+                        assert!(max_rng.sample(my_incl_uniform).extract(lane) <= high_scalar);
+
+                        // Don't run this test for really tiny differences between high and low
+                        // since for those rounding might result in selecting high for a very
+                        // long time.
+                        if (high_scalar - low_scalar) > 0.0001 {
+                            let mut lowering_max_rng =
+                                StepRng::new(0xffff_ffff_ffff_ffff,
+                                             (-1i64 << $bits_shifted) as u64);
+                            assert!(lowering_max_rng.gen_range(low, high).extract(lane) < high_scalar);
+                        }
+                    }
+                }
+
+                assert_eq!(rng.sample(Uniform::new_inclusive(::core::$f_scalar::MAX,
+                                                             ::core::$f_scalar::MAX)),
+                           ::core::$f_scalar::MAX);
+                assert_eq!(rng.sample(Uniform::new_inclusive(-::core::$f_scalar::MAX,
+                                                             -::core::$f_scalar::MAX)),
+                           -::core::$f_scalar::MAX);
+            }}
+        }
+
+        t!(f32, f32, 32 - 23);
+        t!(f64, f64, 64 - 52);
+        #[cfg(feature="simd_support")]
+        {
+            t!(f32x2, f32, 32 - 23);
+            t!(f32x4, f32, 32 - 23);
+            t!(f32x8, f32, 32 - 23);
+            t!(f32x16, f32, 32 - 23);
+            t!(f64x2, f64, 64 - 52);
+            t!(f64x4, f64, 64 - 52);
+            t!(f64x8, f64, 64 - 52);
+        }
+    }
+
+    #[test]
+    #[cfg(all(feature="std",
+              not(target_arch = "wasm32"),
+              not(target_arch = "asmjs")))]
+    #[cfg(not(miri))] // Miri does not support catching panics
+    fn test_float_assertions() {
+        use std::panic::catch_unwind;
+        use super::SampleUniform;
+        fn range<T: SampleUniform>(low: T, high: T) {
+            let mut rng = crate::test::rng(253);
+            rng.gen_range(low, high);
+        }
+
+        macro_rules! t {
+            ($ty:ident, $f_scalar:ident) => {{
+                let v: &[($f_scalar, $f_scalar)] =
+                    &[(::std::$f_scalar::NAN, 0.0),
+                      (1.0, ::std::$f_scalar::NAN),
+                      (::std::$f_scalar::NAN, ::std::$f_scalar::NAN),
+                      (1.0, 0.5),
+                      (::std::$f_scalar::MAX, -::std::$f_scalar::MAX),
+                      (::std::$f_scalar::INFINITY, ::std::$f_scalar::INFINITY),
+                      (::std::$f_scalar::NEG_INFINITY, ::std::$f_scalar::NEG_INFINITY),
+                      (::std::$f_scalar::NEG_INFINITY, 5.0),
+                      (5.0, ::std::$f_scalar::INFINITY),
+                      (::std::$f_scalar::NAN, ::std::$f_scalar::INFINITY),
+                      (::std::$f_scalar::NEG_INFINITY, ::std::$f_scalar::NAN),
+                      (::std::$f_scalar::NEG_INFINITY, ::std::$f_scalar::INFINITY),
+                     ];
+                for &(low_scalar, high_scalar) in v.iter() {
+                    for lane in 0..<$ty>::lanes() {
+                        let low = <$ty>::splat(0.0 as $f_scalar).replace(lane, low_scalar);
+                        let high = <$ty>::splat(1.0 as $f_scalar).replace(lane, high_scalar);
+                        assert!(catch_unwind(|| range(low, high)).is_err());
+                        assert!(catch_unwind(|| Uniform::new(low, high)).is_err());
+                        assert!(catch_unwind(|| Uniform::new_inclusive(low, high)).is_err());
+                        assert!(catch_unwind(|| range(low, low)).is_err());
+                        assert!(catch_unwind(|| Uniform::new(low, low)).is_err());
+                    }
+                }
+            }}
+        }
+
+        t!(f32, f32);
+        t!(f64, f64);
+        #[cfg(feature="simd_support")]
+        {
+            t!(f32x2, f32);
+            t!(f32x4, f32);
+            t!(f32x8, f32);
+            t!(f32x16, f32);
+            t!(f64x2, f64);
+            t!(f64x4, f64);
+            t!(f64x8, f64);
+        }
+    }
+
+
+    #[test]
+    #[cfg(not(miri))] // Miri is too slow
+    fn test_durations() {
+        #[cfg(feature = "std")]
+        use std::time::Duration;
+        #[cfg(not(feature = "std"))]
+        use core::time::Duration;
+
+        let mut rng = crate::test::rng(253);
+
+        let v = &[(Duration::new(10, 50000), Duration::new(100, 1234)),
+                  (Duration::new(0, 100), Duration::new(1, 50)),
+                  (Duration::new(0, 0), Duration::new(u64::max_value(), 999_999_999))];
+        for &(low, high) in v.iter() {
+            let my_uniform = Uniform::new(low, high);
+            for _ in 0..1000 {
+                let v = rng.sample(my_uniform);
+                assert!(low <= v && v < high);
+            }
+        }
+    }
+
+    #[test]
+    fn test_custom_uniform() {
+        use crate::distributions::uniform::{UniformSampler, UniformFloat, SampleUniform, SampleBorrow};
+        #[derive(Clone, Copy, PartialEq, PartialOrd)]
+        struct MyF32 {
+            x: f32,
+        }
+        #[derive(Clone, Copy, Debug)]
+        struct UniformMyF32 {
+            inner: UniformFloat<f32>,
+        }
+        impl UniformSampler for UniformMyF32 {
+            type X = MyF32;
+            fn new<B1, B2>(low: B1, high: B2) -> Self
+                where B1: SampleBorrow<Self::X> + Sized,
+                      B2: SampleBorrow<Self::X> + Sized
+            {
+                UniformMyF32 {
+                    inner: UniformFloat::<f32>::new(low.borrow().x, high.borrow().x),
+                }
+            }
+            fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self
+                where B1: SampleBorrow<Self::X> + Sized,
+                      B2: SampleBorrow<Self::X> + Sized
+            {
+                UniformSampler::new(low, high)
+            }
+            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
+                MyF32 { x: self.inner.sample(rng) }
+            }
+        }
+        impl SampleUniform for MyF32 {
+            type Sampler = UniformMyF32;
+        }
+
+        let (low, high) = (MyF32{ x: 17.0f32 }, MyF32{ x: 22.0f32 });
+        let uniform = Uniform::new(low, high);
+        let mut rng = crate::test::rng(804);
+        for _ in 0..100 {
+            let x: MyF32 = rng.sample(uniform);
+            assert!(low <= x && x < high);
+        }
+    }
+
+    #[test]
+    fn test_uniform_from_std_range() {
+        let r = Uniform::from(2u32..7);
+        assert_eq!(r.inner.low, 2);
+        assert_eq!(r.inner.range, 5);
+        let r = Uniform::from(2.0f64..7.0);
+        assert_eq!(r.inner.low, 2.0);
+        assert_eq!(r.inner.scale, 5.0);
+    }
+
+    #[test]
+    fn test_uniform_from_std_range_inclusive() {
+        let r = Uniform::from(2u32..=6);
+        assert_eq!(r.inner.low, 2);
+        assert_eq!(r.inner.range, 5);
+        let r = Uniform::from(2.0f64..=7.0);
+        assert_eq!(r.inner.low, 2.0);
+        assert!(r.inner.scale > 5.0);
+        assert!(r.inner.scale < 5.0 + 1e-14);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/unit_circle.rs.html b/target/doc/src/rand/distributions/unit_circle.rs.html new file mode 100644 index 0000000..d06ba9a --- /dev/null +++ b/target/doc/src/rand/distributions/unit_circle.rs.html @@ -0,0 +1,203 @@ +unit_circle.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(deprecated)]
+
+use crate::Rng;
+use crate::distributions::{Distribution, Uniform};
+
+/// Samples uniformly from the edge of the unit circle in two dimensions.
+///
+/// Implemented via a method by von Neumann[^1].
+///
+/// [^1]: von Neumann, J. (1951) [*Various Techniques Used in Connection with
+///       Random Digits.*](https://mcnp.lanl.gov/pdf_files/nbs_vonneumann.pdf)
+///       NBS Appl. Math. Ser., No. 12. Washington, DC: U.S. Government Printing
+///       Office, pp. 36-38.
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Copy, Debug)]
+pub struct UnitCircle;
+
+impl UnitCircle {
+    /// Construct a new `UnitCircle` distribution.
+    #[inline]
+    pub fn new() -> UnitCircle {
+        UnitCircle
+    }
+}
+
+impl Distribution<[f64; 2]> for UnitCircle {
+    #[inline]
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> [f64; 2] {
+        let uniform = Uniform::new(-1., 1.);
+        let mut x1;
+        let mut x2;
+        let mut sum;
+        loop {
+            x1 = uniform.sample(rng);
+            x2 = uniform.sample(rng);
+            sum = x1*x1 + x2*x2;
+            if sum < 1. {
+                break;
+            }
+        }
+        let diff = x1*x1 - x2*x2;
+        [diff / sum, 2.*x1*x2 / sum]
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::distributions::Distribution;
+    use super::UnitCircle;
+
+    /// Assert that two numbers are almost equal to each other.
+    ///
+    /// On panic, this macro will print the values of the expressions with their
+    /// debug representations.
+    macro_rules! assert_almost_eq {
+        ($a:expr, $b:expr, $prec:expr) => (
+            let diff = ($a - $b).abs();
+            if diff > $prec {
+                panic!(format!(
+                    "assertion failed: `abs(left - right) = {:.1e} < {:e}`, \
+                     (left: `{}`, right: `{}`)",
+                    diff, $prec, $a, $b));
+            }
+        );
+    }
+
+    #[test]
+    fn norm() {
+        let mut rng = crate::test::rng(1);
+        let dist = UnitCircle::new();
+        for _ in 0..1000 {
+            let x = dist.sample(&mut rng);
+            assert_almost_eq!(x[0]*x[0] + x[1]*x[1], 1., 1e-15);
+        }
+    }
+
+    #[test]
+    fn value_stability() {
+        let mut rng = crate::test::rng(2);
+        let expected = [
+                [-0.9965658683520504, -0.08280380447614634],
+                [-0.9790853270389644, -0.20345004884984505],
+                [-0.8449189758898707, 0.5348943112253227],
+            ];
+        let samples = [
+                UnitCircle.sample(&mut rng),
+                UnitCircle.sample(&mut rng),
+                UnitCircle.sample(&mut rng),
+            ];
+        assert_eq!(samples, expected);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/unit_sphere.rs.html b/target/doc/src/rand/distributions/unit_sphere.rs.html new file mode 100644 index 0000000..81368de --- /dev/null +++ b/target/doc/src/rand/distributions/unit_sphere.rs.html @@ -0,0 +1,193 @@ +unit_sphere.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(deprecated)]
+
+use crate::Rng;
+use crate::distributions::{Distribution, Uniform};
+
+/// Samples uniformly from the surface of the unit sphere in three dimensions.
+///
+/// Implemented via a method by Marsaglia[^1].
+///
+/// [^1]: Marsaglia, George (1972). [*Choosing a Point from the Surface of a
+///       Sphere.*](https://doi.org/10.1214/aoms/1177692644)
+///       Ann. Math. Statist. 43, no. 2, 645--646.
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Copy, Debug)]
+pub struct UnitSphereSurface;
+
+impl UnitSphereSurface {
+    /// Construct a new `UnitSphereSurface` distribution.
+    #[inline]
+    pub fn new() -> UnitSphereSurface {
+        UnitSphereSurface
+    }
+}
+
+impl Distribution<[f64; 3]> for UnitSphereSurface {
+    #[inline]
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> [f64; 3] {
+        let uniform = Uniform::new(-1., 1.);
+        loop {
+            let (x1, x2) = (uniform.sample(rng), uniform.sample(rng));
+            let sum = x1*x1 + x2*x2;
+            if sum >= 1. {
+                continue;
+            }
+            let factor = 2. * (1.0_f64 - sum).sqrt();
+            return [x1 * factor, x2 * factor, 1. - 2.*sum];
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::distributions::Distribution;
+    use super::UnitSphereSurface;
+
+    /// Assert that two numbers are almost equal to each other.
+    ///
+    /// On panic, this macro will print the values of the expressions with their
+    /// debug representations.
+    macro_rules! assert_almost_eq {
+        ($a:expr, $b:expr, $prec:expr) => (
+            let diff = ($a - $b).abs();
+            if diff > $prec {
+                panic!(format!(
+                    "assertion failed: `abs(left - right) = {:.1e} < {:e}`, \
+                     (left: `{}`, right: `{}`)",
+                    diff, $prec, $a, $b));
+            }
+        );
+    }
+
+    #[test]
+    fn norm() {
+        let mut rng = crate::test::rng(1);
+        let dist = UnitSphereSurface::new();
+        for _ in 0..1000 {
+            let x = dist.sample(&mut rng);
+            assert_almost_eq!(x[0]*x[0] + x[1]*x[1] + x[2]*x[2], 1., 1e-15);
+        }
+    }
+
+    #[test]
+    fn value_stability() {
+        let mut rng = crate::test::rng(2);
+        let expected = [
+                [0.03247542860231647, -0.7830477442152738, 0.6211131755296027],
+                [-0.09978440840914075, 0.9706650829833128, -0.21875184231323952],
+                [0.2735582468624679, 0.9435374242279655, -0.1868234852870203],
+            ];
+        let samples = [
+                UnitSphereSurface.sample(&mut rng),
+                UnitSphereSurface.sample(&mut rng),
+                UnitSphereSurface.sample(&mut rng),
+            ];
+        assert_eq!(samples, expected);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/utils.rs.html b/target/doc/src/rand/distributions/utils.rs.html new file mode 100644 index 0000000..09ff3e5 --- /dev/null +++ b/target/doc/src/rand/distributions/utils.rs.html @@ -0,0 +1,1013 @@ +utils.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Math helper functions
+
+#[cfg(feature="simd_support")]
+use packed_simd::*;
+#[cfg(feature="std")]
+use crate::distributions::ziggurat_tables;
+#[cfg(feature="std")]
+use crate::Rng;
+
+
+pub trait WideningMultiply<RHS = Self> {
+    type Output;
+
+    fn wmul(self, x: RHS) -> Self::Output;
+}
+
+macro_rules! wmul_impl {
+    ($ty:ty, $wide:ty, $shift:expr) => {
+        impl WideningMultiply for $ty {
+            type Output = ($ty, $ty);
+
+            #[inline(always)]
+            fn wmul(self, x: $ty) -> Self::Output {
+                let tmp = (self as $wide) * (x as $wide);
+                ((tmp >> $shift) as $ty, tmp as $ty)
+            }
+        }
+    };
+
+    // simd bulk implementation
+    ($(($ty:ident, $wide:ident),)+, $shift:expr) => {
+        $(
+            impl WideningMultiply for $ty {
+                type Output = ($ty, $ty);
+
+                #[inline(always)]
+                fn wmul(self, x: $ty) -> Self::Output {
+                    // For supported vectors, this should compile to a couple
+                    // supported multiply & swizzle instructions (no actual
+                    // casting).
+                    // TODO: optimize
+                    let y: $wide = self.cast();
+                    let x: $wide = x.cast();
+                    let tmp = y * x;
+                    let hi: $ty = (tmp >> $shift).cast();
+                    let lo: $ty = tmp.cast();
+                    (hi, lo)
+                }
+            }
+        )+
+    };
+}
+wmul_impl! { u8, u16, 8 }
+wmul_impl! { u16, u32, 16 }
+wmul_impl! { u32, u64, 32 }
+#[cfg(not(target_os = "emscripten"))]
+wmul_impl! { u64, u128, 64 }
+
+// This code is a translation of the __mulddi3 function in LLVM's
+// compiler-rt. It is an optimised variant of the common method
+// `(a + b) * (c + d) = ac + ad + bc + bd`.
+//
+// For some reason LLVM can optimise the C version very well, but
+// keeps shuffling registers in this Rust translation.
+macro_rules! wmul_impl_large {
+    ($ty:ty, $half:expr) => {
+        impl WideningMultiply for $ty {
+            type Output = ($ty, $ty);
+
+            #[inline(always)]
+            fn wmul(self, b: $ty) -> Self::Output {
+                const LOWER_MASK: $ty = !0 >> $half;
+                let mut low = (self & LOWER_MASK).wrapping_mul(b & LOWER_MASK);
+                let mut t = low >> $half;
+                low &= LOWER_MASK;
+                t += (self >> $half).wrapping_mul(b & LOWER_MASK);
+                low += (t & LOWER_MASK) << $half;
+                let mut high = t >> $half;
+                t = low >> $half;
+                low &= LOWER_MASK;
+                t += (b >> $half).wrapping_mul(self & LOWER_MASK);
+                low += (t & LOWER_MASK) << $half;
+                high += t >> $half;
+                high += (self >> $half).wrapping_mul(b >> $half);
+
+                (high, low)
+            }
+        }
+    };
+
+    // simd bulk implementation
+    (($($ty:ty,)+) $scalar:ty, $half:expr) => {
+        $(
+            impl WideningMultiply for $ty {
+                type Output = ($ty, $ty);
+
+                #[inline(always)]
+                fn wmul(self, b: $ty) -> Self::Output {
+                    // needs wrapping multiplication
+                    const LOWER_MASK: $scalar = !0 >> $half;
+                    let mut low = (self & LOWER_MASK) * (b & LOWER_MASK);
+                    let mut t = low >> $half;
+                    low &= LOWER_MASK;
+                    t += (self >> $half) * (b & LOWER_MASK);
+                    low += (t & LOWER_MASK) << $half;
+                    let mut high = t >> $half;
+                    t = low >> $half;
+                    low &= LOWER_MASK;
+                    t += (b >> $half) * (self & LOWER_MASK);
+                    low += (t & LOWER_MASK) << $half;
+                    high += t >> $half;
+                    high += (self >> $half) * (b >> $half);
+
+                    (high, low)
+                }
+            }
+        )+
+    };
+}
+#[cfg(target_os = "emscripten")]
+wmul_impl_large! { u64, 32 }
+#[cfg(not(target_os = "emscripten"))]
+wmul_impl_large! { u128, 64 }
+
+macro_rules! wmul_impl_usize {
+    ($ty:ty) => {
+        impl WideningMultiply for usize {
+            type Output = (usize, usize);
+
+            #[inline(always)]
+            fn wmul(self, x: usize) -> Self::Output {
+                let (high, low) = (self as $ty).wmul(x as $ty);
+                (high as usize, low as usize)
+            }
+        }
+    }
+}
+#[cfg(target_pointer_width = "32")]
+wmul_impl_usize! { u32 }
+#[cfg(target_pointer_width = "64")]
+wmul_impl_usize! { u64 }
+
+#[cfg(all(feature = "simd_support", feature = "nightly"))]
+mod simd_wmul {
+    #[cfg(target_arch = "x86")]
+    use core::arch::x86::*;
+    #[cfg(target_arch = "x86_64")]
+    use core::arch::x86_64::*;
+    use super::*;
+
+    wmul_impl! {
+        (u8x2, u16x2),
+        (u8x4, u16x4),
+        (u8x8, u16x8),
+        (u8x16, u16x16),
+        (u8x32, u16x32),,
+        8
+    }
+
+    wmul_impl! { (u16x2, u32x2),, 16 }
+    #[cfg(not(target_feature = "sse2"))]
+    wmul_impl! { (u16x4, u32x4),, 16 }
+    #[cfg(not(target_feature = "sse4.2"))]
+    wmul_impl! { (u16x8, u32x8),, 16 }
+    #[cfg(not(target_feature = "avx2"))]
+    wmul_impl! { (u16x16, u32x16),, 16 }
+
+    // 16-bit lane widths allow use of the x86 `mulhi` instructions, which
+    // means `wmul` can be implemented with only two instructions.
+    #[allow(unused_macros)]
+    macro_rules! wmul_impl_16 {
+        ($ty:ident, $intrinsic:ident, $mulhi:ident, $mullo:ident) => {
+            impl WideningMultiply for $ty {
+                type Output = ($ty, $ty);
+
+                #[inline(always)]
+                fn wmul(self, x: $ty) -> Self::Output {
+                    let b = $intrinsic::from_bits(x);
+                    let a = $intrinsic::from_bits(self);
+                    let hi = $ty::from_bits(unsafe { $mulhi(a, b) });
+                    let lo = $ty::from_bits(unsafe { $mullo(a, b) });
+                    (hi, lo)
+                }
+            }
+        };
+    }
+
+    #[cfg(target_feature = "sse2")]
+    wmul_impl_16! { u16x4, __m64, _mm_mulhi_pu16, _mm_mullo_pi16 }
+    #[cfg(target_feature = "sse4.2")]
+    wmul_impl_16! { u16x8, __m128i, _mm_mulhi_epu16, _mm_mullo_epi16 }
+    #[cfg(target_feature = "avx2")]
+    wmul_impl_16! { u16x16, __m256i, _mm256_mulhi_epu16, _mm256_mullo_epi16 }
+    // FIXME: there are no `__m512i` types in stdsimd yet, so `wmul::<u16x32>`
+    // cannot use the same implementation.
+
+    wmul_impl! {
+        (u32x2, u64x2),
+        (u32x4, u64x4),
+        (u32x8, u64x8),,
+        32
+    }
+
+    // TODO: optimize, this seems to seriously slow things down
+    wmul_impl_large! { (u8x64,) u8, 4 }
+    wmul_impl_large! { (u16x32,) u16, 8 }
+    wmul_impl_large! { (u32x16,) u32, 16 }
+    wmul_impl_large! { (u64x2, u64x4, u64x8,) u64, 32 }
+}
+#[cfg(all(feature = "simd_support", feature = "nightly"))]
+pub use self::simd_wmul::*;
+
+
+/// Helper trait when dealing with scalar and SIMD floating point types.
+pub(crate) trait FloatSIMDUtils {
+    // `PartialOrd` for vectors compares lexicographically. We want to compare all
+    // the individual SIMD lanes instead, and get the combined result over all
+    // lanes. This is possible using something like `a.lt(b).all()`, but we
+    // implement it as a trait so we can write the same code for `f32` and `f64`.
+    // Only the comparison functions we need are implemented.
+    fn all_lt(self, other: Self) -> bool;
+    fn all_le(self, other: Self) -> bool;
+    fn all_finite(self) -> bool;
+
+    type Mask;
+    fn finite_mask(self) -> Self::Mask;
+    fn gt_mask(self, other: Self) -> Self::Mask;
+    fn ge_mask(self, other: Self) -> Self::Mask;
+
+    // Decrease all lanes where the mask is `true` to the next lower value
+    // representable by the floating-point type. At least one of the lanes
+    // must be set.
+    fn decrease_masked(self, mask: Self::Mask) -> Self;
+
+    // Convert from int value. Conversion is done while retaining the numerical
+    // value, not by retaining the binary representation.
+    type UInt;
+    fn cast_from_int(i: Self::UInt) -> Self;
+}
+
+/// Implement functions available in std builds but missing from core primitives
+#[cfg(not(std))]
+pub(crate) trait Float : Sized {
+    type Bits;
+
+    fn is_nan(self) -> bool;
+    fn is_infinite(self) -> bool;
+    fn is_finite(self) -> bool;
+    fn to_bits(self) -> Self::Bits;
+    fn from_bits(v: Self::Bits) -> Self;
+}
+
+/// Implement functions on f32/f64 to give them APIs similar to SIMD types
+pub(crate) trait FloatAsSIMD : Sized {
+    #[inline(always)]
+    fn lanes() -> usize { 1 }
+    #[inline(always)]
+    fn splat(scalar: Self) -> Self { scalar }
+    #[inline(always)]
+    fn extract(self, index: usize) -> Self { debug_assert_eq!(index, 0); self }
+    #[inline(always)]
+    fn replace(self, index: usize, new_value: Self) -> Self { debug_assert_eq!(index, 0); new_value }
+}
+
+pub(crate) trait BoolAsSIMD : Sized {
+    fn any(self) -> bool;
+    fn all(self) -> bool;
+    fn none(self) -> bool;
+}
+
+impl BoolAsSIMD for bool {
+    #[inline(always)]
+    fn any(self) -> bool { self }
+    #[inline(always)]
+    fn all(self) -> bool { self }
+    #[inline(always)]
+    fn none(self) -> bool { !self }
+}
+
+macro_rules! scalar_float_impl {
+    ($ty:ident, $uty:ident) => {
+        #[cfg(not(std))]
+        impl Float for $ty {
+            type Bits = $uty;
+
+            #[inline]
+            fn is_nan(self) -> bool {
+                self != self
+            }
+
+            #[inline]
+            fn is_infinite(self) -> bool {
+                self == ::core::$ty::INFINITY || self == ::core::$ty::NEG_INFINITY
+            }
+
+            #[inline]
+            fn is_finite(self) -> bool {
+                !(self.is_nan() || self.is_infinite())
+            }
+
+            #[inline]
+            fn to_bits(self) -> Self::Bits {
+                unsafe { ::core::mem::transmute(self) }
+            }
+
+            #[inline]
+            fn from_bits(v: Self::Bits) -> Self {
+                // It turns out the safety issues with sNaN were overblown! Hooray!
+                unsafe { ::core::mem::transmute(v) }
+            }
+        }
+
+        impl FloatSIMDUtils for $ty {
+            type Mask = bool;
+            #[inline(always)]
+            fn all_lt(self, other: Self) -> bool { self < other }
+            #[inline(always)]
+            fn all_le(self, other: Self) -> bool { self <= other }
+            #[inline(always)]
+            fn all_finite(self) -> bool { self.is_finite() }
+            #[inline(always)]
+            fn finite_mask(self) -> Self::Mask { self.is_finite() }
+            #[inline(always)]
+            fn gt_mask(self, other: Self) -> Self::Mask { self > other }
+            #[inline(always)]
+            fn ge_mask(self, other: Self) -> Self::Mask { self >= other }
+            #[inline(always)]
+            fn decrease_masked(self, mask: Self::Mask) -> Self {
+                debug_assert!(mask, "At least one lane must be set");
+                <$ty>::from_bits(self.to_bits() - 1)
+            }
+            type UInt = $uty;
+            fn cast_from_int(i: Self::UInt) -> Self { i as $ty }
+        }
+
+        impl FloatAsSIMD for $ty {}
+    }
+}
+
+scalar_float_impl!(f32, u32);
+scalar_float_impl!(f64, u64);
+
+
+#[cfg(feature="simd_support")]
+macro_rules! simd_impl {
+    ($ty:ident, $f_scalar:ident, $mty:ident, $uty:ident) => {
+        impl FloatSIMDUtils for $ty {
+            type Mask = $mty;
+            #[inline(always)]
+            fn all_lt(self, other: Self) -> bool { self.lt(other).all() }
+            #[inline(always)]
+            fn all_le(self, other: Self) -> bool { self.le(other).all() }
+            #[inline(always)]
+            fn all_finite(self) -> bool { self.finite_mask().all() }
+            #[inline(always)]
+            fn finite_mask(self) -> Self::Mask {
+                // This can possibly be done faster by checking bit patterns
+                let neg_inf = $ty::splat(::core::$f_scalar::NEG_INFINITY);
+                let pos_inf = $ty::splat(::core::$f_scalar::INFINITY);
+                self.gt(neg_inf) & self.lt(pos_inf)
+            }
+            #[inline(always)]
+            fn gt_mask(self, other: Self) -> Self::Mask { self.gt(other) }
+            #[inline(always)]
+            fn ge_mask(self, other: Self) -> Self::Mask { self.ge(other) }
+            #[inline(always)]
+            fn decrease_masked(self, mask: Self::Mask) -> Self {
+                // Casting a mask into ints will produce all bits set for
+                // true, and 0 for false. Adding that to the binary
+                // representation of a float means subtracting one from
+                // the binary representation, resulting in the next lower
+                // value representable by $ty. This works even when the
+                // current value is infinity.
+                debug_assert!(mask.any(), "At least one lane must be set");
+                <$ty>::from_bits(<$uty>::from_bits(self) + <$uty>::from_bits(mask))
+            }
+            type UInt = $uty;
+            #[inline]
+            fn cast_from_int(i: Self::UInt) -> Self { i.cast() }
+        }
+    }
+}
+
+#[cfg(feature="simd_support")] simd_impl! { f32x2, f32, m32x2, u32x2 }
+#[cfg(feature="simd_support")] simd_impl! { f32x4, f32, m32x4, u32x4 }
+#[cfg(feature="simd_support")] simd_impl! { f32x8, f32, m32x8, u32x8 }
+#[cfg(feature="simd_support")] simd_impl! { f32x16, f32, m32x16, u32x16 }
+#[cfg(feature="simd_support")] simd_impl! { f64x2, f64, m64x2, u64x2 }
+#[cfg(feature="simd_support")] simd_impl! { f64x4, f64, m64x4, u64x4 }
+#[cfg(feature="simd_support")] simd_impl! { f64x8, f64, m64x8, u64x8 }
+
+/// Calculates ln(gamma(x)) (natural logarithm of the gamma
+/// function) using the Lanczos approximation.
+///
+/// The approximation expresses the gamma function as:
+/// `gamma(z+1) = sqrt(2*pi)*(z+g+0.5)^(z+0.5)*exp(-z-g-0.5)*Ag(z)`
+/// `g` is an arbitrary constant; we use the approximation with `g=5`.
+///
+/// Noting that `gamma(z+1) = z*gamma(z)` and applying `ln` to both sides:
+/// `ln(gamma(z)) = (z+0.5)*ln(z+g+0.5)-(z+g+0.5) + ln(sqrt(2*pi)*Ag(z)/z)`
+///
+/// `Ag(z)` is an infinite series with coefficients that can be calculated
+/// ahead of time - we use just the first 6 terms, which is good enough
+/// for most purposes.
+#[cfg(feature="std")]
+pub fn log_gamma(x: f64) -> f64 {
+    // precalculated 6 coefficients for the first 6 terms of the series
+    let coefficients: [f64; 6] = [
+        76.18009172947146,
+        -86.50532032941677,
+        24.01409824083091,
+        -1.231739572450155,
+        0.1208650973866179e-2,
+        -0.5395239384953e-5,
+    ];
+
+    // (x+0.5)*ln(x+g+0.5)-(x+g+0.5)
+    let tmp = x + 5.5;
+    let log = (x + 0.5) * tmp.ln() - tmp;
+
+    // the first few terms of the series for Ag(x)
+    let mut a = 1.000000000190015;
+    let mut denom = x;
+    for coeff in &coefficients {
+        denom += 1.0;
+        a += coeff / denom;
+    }
+
+    // get everything together
+    // a is Ag(x)
+    // 2.5066... is sqrt(2pi)
+    log + (2.5066282746310005 * a / x).ln()
+}
+
+/// Sample a random number using the Ziggurat method (specifically the
+/// ZIGNOR variant from Doornik 2005). Most of the arguments are
+/// directly from the paper:
+///
+/// * `rng`: source of randomness
+/// * `symmetric`: whether this is a symmetric distribution, or one-sided with P(x < 0) = 0.
+/// * `X`: the $x_i$ abscissae.
+/// * `F`: precomputed values of the PDF at the $x_i$, (i.e. $f(x_i)$)
+/// * `F_DIFF`: precomputed values of $f(x_i) - f(x_{i+1})$
+/// * `pdf`: the probability density function
+/// * `zero_case`: manual sampling from the tail when we chose the
+///    bottom box (i.e. i == 0)
+
+// the perf improvement (25-50%) is definitely worth the extra code
+// size from force-inlining.
+#[cfg(feature="std")]
+#[inline(always)]
+pub fn ziggurat<R: Rng + ?Sized, P, Z>(
+            rng: &mut R,
+            symmetric: bool,
+            x_tab: ziggurat_tables::ZigTable,
+            f_tab: ziggurat_tables::ZigTable,
+            mut pdf: P,
+            mut zero_case: Z)
+            -> f64 where P: FnMut(f64) -> f64, Z: FnMut(&mut R, f64) -> f64 {
+    use crate::distributions::float::IntoFloat;
+    loop {
+        // As an optimisation we re-implement the conversion to a f64.
+        // From the remaining 12 most significant bits we use 8 to construct `i`.
+        // This saves us generating a whole extra random number, while the added
+        // precision of using 64 bits for f64 does not buy us much.
+        let bits = rng.next_u64();
+        let i = bits as usize & 0xff;
+
+        let u = if symmetric {
+            // Convert to a value in the range [2,4) and substract to get [-1,1)
+            // We can't convert to an open range directly, that would require
+            // substracting `3.0 - EPSILON`, which is not representable.
+            // It is possible with an extra step, but an open range does not
+            // seem neccesary for the ziggurat algorithm anyway.
+            (bits >> 12).into_float_with_exponent(1) - 3.0
+        } else {
+            // Convert to a value in the range [1,2) and substract to get (0,1)
+            (bits >> 12).into_float_with_exponent(0)
+            - (1.0 - ::core::f64::EPSILON / 2.0)
+        };
+        let x = u * x_tab[i];
+
+        let test_x = if symmetric { x.abs() } else {x};
+
+        // algebraically equivalent to |u| < x_tab[i+1]/x_tab[i] (or u < x_tab[i+1]/x_tab[i])
+        if test_x < x_tab[i + 1] {
+            return x;
+        }
+        if i == 0 {
+            return zero_case(rng, u);
+        }
+        // algebraically equivalent to f1 + DRanU()*(f0 - f1) < 1
+        if f_tab[i + 1] + (f_tab[i] - f_tab[i + 1]) * rng.gen::<f64>() < pdf(x) {
+            return x;
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/weibull.rs.html b/target/doc/src/rand/distributions/weibull.rs.html new file mode 100644 index 0000000..b9573c4 --- /dev/null +++ b/target/doc/src/rand/distributions/weibull.rs.html @@ -0,0 +1,131 @@ +weibull.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The Weibull distribution.
+#![allow(deprecated)]
+
+use crate::Rng;
+use crate::distributions::{Distribution, OpenClosed01};
+
+/// Samples floating-point numbers according to the Weibull distribution
+#[deprecated(since="0.7.0", note="moved to rand_distr crate")]
+#[derive(Clone, Copy, Debug)]
+pub struct Weibull {
+    inv_shape: f64,
+    scale: f64,
+}
+
+impl Weibull {
+    /// Construct a new `Weibull` distribution with given `scale` and `shape`.
+    ///
+    /// # Panics
+    ///
+    /// `scale` and `shape` have to be non-zero and positive.
+    pub fn new(scale: f64, shape: f64) -> Weibull {
+        assert!((scale > 0.) & (shape > 0.));
+        Weibull { inv_shape: 1./shape, scale }
+    }
+}
+
+impl Distribution<f64> for Weibull {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
+        let x: f64 = rng.sample(OpenClosed01);
+        self.scale * (-x.ln()).powf(self.inv_shape)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::distributions::Distribution;
+    use super::Weibull;
+
+    #[test]
+    #[should_panic]
+    fn invalid() {
+        Weibull::new(0., 0.);
+    }
+
+    #[test]
+    fn sample() {
+        let scale = 1.0;
+        let shape = 2.0;
+        let d = Weibull::new(scale, shape);
+        let mut rng = crate::test::rng(1);
+        for _ in 0..1000 {
+            let r = d.sample(&mut rng);
+            assert!(r >= 0.);
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/weighted/alias_method.rs.html b/target/doc/src/rand/distributions/weighted/alias_method.rs.html new file mode 100644 index 0000000..405d704 --- /dev/null +++ b/target/doc/src/rand/distributions/weighted/alias_method.rs.html @@ -0,0 +1,1001 @@ +alias_method.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+
+//! This module contains an implementation of alias method for sampling random
+//! indices with probabilities proportional to a collection of weights.
+
+use super::WeightedError;
+#[cfg(not(feature = "std"))]
+use crate::alloc::vec::Vec;
+#[cfg(not(feature = "std"))]
+use crate::alloc::vec;
+use core::fmt;
+use core::iter::Sum;
+use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
+use crate::distributions::uniform::SampleUniform;
+use crate::distributions::Distribution;
+use crate::distributions::Uniform;
+use crate::Rng;
+
+/// A distribution using weighted sampling to pick a discretely selected item.
+///
+/// Sampling a [`WeightedIndex<W>`] distribution returns the index of a randomly
+/// selected element from the vector used to create the [`WeightedIndex<W>`].
+/// The chance of a given element being picked is proportional to the value of
+/// the element. The weights can have any type `W` for which a implementation of
+/// [`Weight`] exists.
+///
+/// # Performance
+///
+/// Given that `n` is the number of items in the vector used to create an
+/// [`WeightedIndex<W>`], [`WeightedIndex<W>`] will require `O(n)` amount of
+/// memory. More specifically it takes up some constant amount of memory plus
+/// the vector used to create it and a [`Vec<u32>`] with capacity `n`.
+///
+/// Time complexity for the creation of a [`WeightedIndex<W>`] is `O(n)`.
+/// Sampling is `O(1)`, it makes a call to [`Uniform<u32>::sample`] and a call
+/// to [`Uniform<W>::sample`].
+///
+/// # Example
+///
+/// ```
+/// use rand::distributions::weighted::alias_method::WeightedIndex;
+/// use rand::prelude::*;
+///
+/// let choices = vec!['a', 'b', 'c'];
+/// let weights = vec![2, 1, 1];
+/// let dist = WeightedIndex::new(weights).unwrap();
+/// let mut rng = thread_rng();
+/// for _ in 0..100 {
+///     // 50% chance to print 'a', 25% chance to print 'b', 25% chance to print 'c'
+///     println!("{}", choices[dist.sample(&mut rng)]);
+/// }
+///
+/// let items = [('a', 0), ('b', 3), ('c', 7)];
+/// let dist2 = WeightedIndex::new(items.iter().map(|item| item.1).collect()).unwrap();
+/// for _ in 0..100 {
+///     // 0% chance to print 'a', 30% chance to print 'b', 70% chance to print 'c'
+///     println!("{}", items[dist2.sample(&mut rng)].0);
+/// }
+/// ```
+///
+/// [`WeightedIndex<W>`]: crate::distributions::weighted::alias_method::WeightedIndex
+/// [`Weight`]: crate::distributions::weighted::alias_method::Weight
+/// [`Vec<u32>`]: Vec
+/// [`Uniform<u32>::sample`]: Distribution::sample
+/// [`Uniform<W>::sample`]: Distribution::sample
+pub struct WeightedIndex<W: Weight> {
+    aliases: Vec<u32>,
+    no_alias_odds: Vec<W>,
+    uniform_index: Uniform<u32>,
+    uniform_within_weight_sum: Uniform<W>,
+}
+
+impl<W: Weight> WeightedIndex<W> {
+    /// Creates a new [`WeightedIndex`].
+    ///
+    /// Returns an error if:
+    /// - The vector is empty.
+    /// - The vector is longer than `u32::MAX`.
+    /// - For any weight `w`: `w < 0` or `w > max` where `max = W::MAX /
+    ///   weights.len()`.
+    /// - The sum of weights is zero.
+    pub fn new(weights: Vec<W>) -> Result<Self, WeightedError> {
+        let n = weights.len();
+        if n == 0 {
+            return Err(WeightedError::NoItem);
+        } else if n > ::core::u32::MAX as usize {
+            return Err(WeightedError::TooMany);
+        }
+        let n = n as u32;
+
+        let max_weight_size = W::try_from_u32_lossy(n)
+            .map(|n| W::MAX / n)
+            .unwrap_or(W::ZERO);
+        if !weights
+            .iter()
+            .all(|&w| W::ZERO <= w && w <= max_weight_size)
+        {
+            return Err(WeightedError::InvalidWeight);
+        }
+
+        // The sum of weights will represent 100% of no alias odds.
+        let weight_sum = Weight::sum(weights.as_slice());
+        // Prevent floating point overflow due to rounding errors.
+        let weight_sum = if weight_sum > W::MAX {
+            W::MAX
+        } else {
+            weight_sum
+        };
+        if weight_sum == W::ZERO {
+            return Err(WeightedError::AllWeightsZero);
+        }
+
+        // `weight_sum` would have been zero if `try_from_lossy` causes an error here.
+        let n_converted = W::try_from_u32_lossy(n).unwrap();
+
+        let mut no_alias_odds = weights;
+        for odds in no_alias_odds.iter_mut() {
+            *odds *= n_converted;
+            // Prevent floating point overflow due to rounding errors.
+            *odds = if *odds > W::MAX { W::MAX } else { *odds };
+        }
+
+        /// This struct is designed to contain three data structures at once,
+        /// sharing the same memory. More precisely it contains two linked lists
+        /// and an alias map, which will be the output of this method. To keep
+        /// the three data structures from getting in each other's way, it must
+        /// be ensured that a single index is only ever in one of them at the
+        /// same time.
+        struct Aliases {
+            aliases: Vec<u32>,
+            smalls_head: u32,
+            bigs_head: u32,
+        }
+
+        impl Aliases {
+            fn new(size: u32) -> Self {
+                Aliases {
+                    aliases: vec![0; size as usize],
+                    smalls_head: ::core::u32::MAX,
+                    bigs_head: ::core::u32::MAX,
+                }
+            }
+
+            fn push_small(&mut self, idx: u32) {
+                self.aliases[idx as usize] = self.smalls_head;
+                self.smalls_head = idx;
+            }
+
+            fn push_big(&mut self, idx: u32) {
+                self.aliases[idx as usize] = self.bigs_head;
+                self.bigs_head = idx;
+            }
+
+            fn pop_small(&mut self) -> u32 {
+                let popped = self.smalls_head;
+                self.smalls_head = self.aliases[popped as usize];
+                popped
+            }
+
+            fn pop_big(&mut self) -> u32 {
+                let popped = self.bigs_head;
+                self.bigs_head = self.aliases[popped as usize];
+                popped
+            }
+
+            fn smalls_is_empty(&self) -> bool {
+                self.smalls_head == ::core::u32::MAX
+            }
+
+            fn bigs_is_empty(&self) -> bool {
+                self.bigs_head == ::core::u32::MAX
+            }
+
+            fn set_alias(&mut self, idx: u32, alias: u32) {
+                self.aliases[idx as usize] = alias;
+            }
+        }
+
+        let mut aliases = Aliases::new(n);
+
+        // Split indices into those with small weights and those with big weights.
+        for (index, &odds) in no_alias_odds.iter().enumerate() {
+            if odds < weight_sum {
+                aliases.push_small(index as u32);
+            } else {
+                aliases.push_big(index as u32);
+            }
+        }
+
+        // Build the alias map by finding an alias with big weight for each index with
+        // small weight.
+        while !aliases.smalls_is_empty() && !aliases.bigs_is_empty() {
+            let s = aliases.pop_small();
+            let b = aliases.pop_big();
+
+            aliases.set_alias(s, b);
+            no_alias_odds[b as usize] = no_alias_odds[b as usize]
+                    - weight_sum
+                    + no_alias_odds[s as usize];
+
+            if no_alias_odds[b as usize] < weight_sum {
+                aliases.push_small(b);
+            } else {
+                aliases.push_big(b);
+            }
+        }
+
+        // The remaining indices should have no alias odds of about 100%. This is due to
+        // numeric accuracy. Otherwise they would be exactly 100%.
+        while !aliases.smalls_is_empty() {
+            no_alias_odds[aliases.pop_small() as usize] = weight_sum;
+        }
+        while !aliases.bigs_is_empty() {
+            no_alias_odds[aliases.pop_big() as usize] = weight_sum;
+        }
+
+        // Prepare distributions for sampling. Creating them beforehand improves
+        // sampling performance.
+        let uniform_index = Uniform::new(0, n);
+        let uniform_within_weight_sum = Uniform::new(W::ZERO, weight_sum);
+
+        Ok(Self {
+            aliases: aliases.aliases,
+            no_alias_odds,
+            uniform_index,
+            uniform_within_weight_sum,
+        })
+    }
+}
+
+impl<W: Weight> Distribution<usize> for WeightedIndex<W> {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> usize {
+        let candidate = rng.sample(self.uniform_index);
+        if rng.sample(&self.uniform_within_weight_sum) < self.no_alias_odds[candidate as usize] {
+            candidate as usize
+        } else {
+            self.aliases[candidate as usize] as usize
+        }
+    }
+}
+
+impl<W: Weight> fmt::Debug for WeightedIndex<W>
+where
+    W: fmt::Debug,
+    Uniform<W>: fmt::Debug,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("WeightedIndex")
+            .field("aliases", &self.aliases)
+            .field("no_alias_odds", &self.no_alias_odds)
+            .field("uniform_index", &self.uniform_index)
+            .field("uniform_within_weight_sum", &self.uniform_within_weight_sum)
+            .finish()
+    }
+}
+
+impl<W: Weight> Clone for WeightedIndex<W>
+where
+    Uniform<W>: Clone,
+{
+    fn clone(&self) -> Self {
+        Self {
+            aliases: self.aliases.clone(),
+            no_alias_odds: self.no_alias_odds.clone(),
+            uniform_index: self.uniform_index.clone(),
+            uniform_within_weight_sum: self.uniform_within_weight_sum.clone(),
+        }
+    }
+}
+
+/// Trait that must be implemented for weights, that are used with
+/// [`WeightedIndex`]. Currently no guarantees on the correctness of
+/// [`WeightedIndex`] are given for custom implementations of this trait.
+pub trait Weight:
+    Sized
+    + Copy
+    + SampleUniform
+    + PartialOrd
+    + Add<Output = Self>
+    + AddAssign
+    + Sub<Output = Self>
+    + SubAssign
+    + Mul<Output = Self>
+    + MulAssign
+    + Div<Output = Self>
+    + DivAssign
+    + Sum
+{
+    /// Maximum number representable by `Self`.
+    const MAX: Self;
+
+    /// Element of `Self` equivalent to 0.
+    const ZERO: Self;
+
+    /// Produce an instance of `Self` from a `u32` value, or return `None` if
+    /// out of range. Loss of precision (where `Self` is a floating point type)
+    /// is acceptable.
+    fn try_from_u32_lossy(n: u32) -> Option<Self>;
+
+    /// Sums all values in slice `values`.
+    fn sum(values: &[Self]) -> Self {
+        values.iter().map(|x| *x).sum()
+    }
+}
+
+macro_rules! impl_weight_for_float {
+    ($T: ident) => {
+        impl Weight for $T {
+            const MAX: Self = ::core::$T::MAX;
+            const ZERO: Self = 0.0;
+
+            fn try_from_u32_lossy(n: u32) -> Option<Self> {
+                Some(n as $T)
+            }
+
+            fn sum(values: &[Self]) -> Self {
+                pairwise_sum(values)
+            }
+        }
+    };
+}
+
+/// In comparison to naive accumulation, the pairwise sum algorithm reduces
+/// rounding errors when there are many floating point values.
+fn pairwise_sum<T: Weight>(values: &[T]) -> T {
+    if values.len() <= 32 {
+        values.iter().map(|x| *x).sum()
+    } else {
+        let mid = values.len() / 2;
+        let (a, b) = values.split_at(mid);
+        pairwise_sum(a) + pairwise_sum(b)
+    }
+}
+
+macro_rules! impl_weight_for_int {
+    ($T: ident) => {
+        impl Weight for $T {
+            const MAX: Self = ::core::$T::MAX;
+            const ZERO: Self = 0;
+
+            fn try_from_u32_lossy(n: u32) -> Option<Self> {
+                let n_converted = n as Self;
+                if n_converted >= Self::ZERO && n_converted as u32 == n {
+                    Some(n_converted)
+                } else {
+                    None
+                }
+            }
+        }
+    };
+}
+
+impl_weight_for_float!(f64);
+impl_weight_for_float!(f32);
+impl_weight_for_int!(usize);
+#[cfg(not(target_os = "emscripten"))]
+impl_weight_for_int!(u128);
+impl_weight_for_int!(u64);
+impl_weight_for_int!(u32);
+impl_weight_for_int!(u16);
+impl_weight_for_int!(u8);
+impl_weight_for_int!(isize);
+#[cfg(not(target_os = "emscripten"))]
+impl_weight_for_int!(i128);
+impl_weight_for_int!(i64);
+impl_weight_for_int!(i32);
+impl_weight_for_int!(i16);
+impl_weight_for_int!(i8);
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[test]
+    #[cfg(not(miri))] // Miri is too slow
+    fn test_weighted_index_f32() {
+        test_weighted_index(f32::into);
+
+        // Floating point special cases
+        assert_eq!(
+            WeightedIndex::new(vec![::core::f32::INFINITY]).unwrap_err(),
+            WeightedError::InvalidWeight
+        );
+        assert_eq!(
+            WeightedIndex::new(vec![-0_f32]).unwrap_err(),
+            WeightedError::AllWeightsZero
+        );
+        assert_eq!(
+            WeightedIndex::new(vec![-1_f32]).unwrap_err(),
+            WeightedError::InvalidWeight
+        );
+        assert_eq!(
+            WeightedIndex::new(vec![-::core::f32::INFINITY]).unwrap_err(),
+            WeightedError::InvalidWeight
+        );
+        assert_eq!(
+            WeightedIndex::new(vec![::core::f32::NAN]).unwrap_err(),
+            WeightedError::InvalidWeight
+        );
+    }
+
+    #[cfg(not(target_os = "emscripten"))]
+    #[test]
+    #[cfg(not(miri))] // Miri is too slow
+    fn test_weighted_index_u128() {
+        test_weighted_index(|x: u128| x as f64);
+    }
+
+    #[cfg(all(rustc_1_26, not(target_os = "emscripten")))]
+    #[test]
+    #[cfg(not(miri))] // Miri is too slow
+    fn test_weighted_index_i128() {
+        test_weighted_index(|x: i128| x as f64);
+
+        // Signed integer special cases
+        assert_eq!(
+            WeightedIndex::new(vec![-1_i128]).unwrap_err(),
+            WeightedError::InvalidWeight
+        );
+        assert_eq!(
+            WeightedIndex::new(vec![::core::i128::MIN]).unwrap_err(),
+            WeightedError::InvalidWeight
+        );
+    }
+
+    #[test]
+    #[cfg(not(miri))] // Miri is too slow
+    fn test_weighted_index_u8() {
+        test_weighted_index(u8::into);
+    }
+
+    #[test]
+    #[cfg(not(miri))] // Miri is too slow
+    fn test_weighted_index_i8() {
+        test_weighted_index(i8::into);
+
+        // Signed integer special cases
+        assert_eq!(
+            WeightedIndex::new(vec![-1_i8]).unwrap_err(),
+            WeightedError::InvalidWeight
+        );
+        assert_eq!(
+            WeightedIndex::new(vec![::core::i8::MIN]).unwrap_err(),
+            WeightedError::InvalidWeight
+        );
+    }
+
+    fn test_weighted_index<W: Weight, F: Fn(W) -> f64>(w_to_f64: F)
+    where
+        WeightedIndex<W>: fmt::Debug,
+    {
+        const NUM_WEIGHTS: u32 = 10;
+        const ZERO_WEIGHT_INDEX: u32 = 3;
+        const NUM_SAMPLES: u32 = 15000;
+        let mut rng = crate::test::rng(0x9c9fa0b0580a7031);
+
+        let weights = {
+            let mut weights = Vec::with_capacity(NUM_WEIGHTS as usize);
+            let random_weight_distribution = crate::distributions::Uniform::new_inclusive(
+                W::ZERO,
+                W::MAX / W::try_from_u32_lossy(NUM_WEIGHTS).unwrap(),
+            );
+            for _ in 0..NUM_WEIGHTS {
+                weights.push(rng.sample(&random_weight_distribution));
+            }
+            weights[ZERO_WEIGHT_INDEX as usize] = W::ZERO;
+            weights
+        };
+        let weight_sum = weights.iter().map(|w| *w).sum::<W>();
+        let expected_counts = weights
+            .iter()
+            .map(|&w| w_to_f64(w) / w_to_f64(weight_sum) * NUM_SAMPLES as f64)
+            .collect::<Vec<f64>>();
+        let weight_distribution = WeightedIndex::new(weights).unwrap();
+
+        let mut counts = vec![0; NUM_WEIGHTS as usize];
+        for _ in 0..NUM_SAMPLES {
+            counts[rng.sample(&weight_distribution)] += 1;
+        }
+
+        assert_eq!(counts[ZERO_WEIGHT_INDEX as usize], 0);
+        for (count, expected_count) in counts.into_iter().zip(expected_counts) {
+            let difference = (count as f64 - expected_count).abs();
+            let max_allowed_difference = NUM_SAMPLES as f64 / NUM_WEIGHTS as f64 * 0.1;
+            assert!(difference <= max_allowed_difference);
+        }
+
+        assert_eq!(
+            WeightedIndex::<W>::new(vec![]).unwrap_err(),
+            WeightedError::NoItem
+        );
+        assert_eq!(
+            WeightedIndex::new(vec![W::ZERO]).unwrap_err(),
+            WeightedError::AllWeightsZero
+        );
+        assert_eq!(
+            WeightedIndex::new(vec![W::MAX, W::MAX]).unwrap_err(),
+            WeightedError::InvalidWeight
+        );
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/weighted/mod.rs.html b/target/doc/src/rand/distributions/weighted/mod.rs.html new file mode 100644 index 0000000..46d567b --- /dev/null +++ b/target/doc/src/rand/distributions/weighted/mod.rs.html @@ -0,0 +1,499 @@ +mod.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Weighted index sampling
+//! 
+//! This module provides two implementations for sampling indices:
+//! 
+//! *   [`WeightedIndex`] allows `O(log N)` sampling
+//! *   [`alias_method::WeightedIndex`] allows `O(1)` sampling, but with
+//!      much greater set-up cost
+//!      
+//! [`alias_method::WeightedIndex`]: alias_method/struct.WeightedIndex.html
+
+pub mod alias_method;
+
+use crate::Rng;
+use crate::distributions::Distribution;
+use crate::distributions::uniform::{UniformSampler, SampleUniform, SampleBorrow};
+use core::cmp::PartialOrd;
+use core::fmt;
+
+// Note that this whole module is only imported if feature="alloc" is enabled.
+#[cfg(not(feature="std"))] use crate::alloc::vec::Vec;
+
+/// A distribution using weighted sampling to pick a discretely selected
+/// item.
+///
+/// Sampling a `WeightedIndex` distribution returns the index of a randomly
+/// selected element from the iterator used when the `WeightedIndex` was
+/// created. The chance of a given element being picked is proportional to the
+/// value of the element. The weights can use any type `X` for which an
+/// implementation of [`Uniform<X>`] exists.
+///
+/// # Performance
+///
+/// A `WeightedIndex<X>` contains a `Vec<X>` and a [`Uniform<X>`] and so its
+/// size is the sum of the size of those objects, possibly plus some alignment.
+///
+/// Creating a `WeightedIndex<X>` will allocate enough space to hold `N - 1`
+/// weights of type `X`, where `N` is the number of weights. However, since
+/// `Vec` doesn't guarantee a particular growth strategy, additional memory
+/// might be allocated but not used. Since the `WeightedIndex` object also
+/// contains, this might cause additional allocations, though for primitive
+/// types, ['Uniform<X>`] doesn't allocate any memory.
+///
+/// Time complexity of sampling from `WeightedIndex` is `O(log N)` where
+/// `N` is the number of weights.
+///
+/// Sampling from `WeightedIndex` will result in a single call to
+/// `Uniform<X>::sample` (method of the [`Distribution`] trait), which typically
+/// will request a single value from the underlying [`RngCore`], though the
+/// exact number depends on the implementaiton of `Uniform<X>::sample`.
+///
+/// # Example
+///
+/// ```
+/// use rand::prelude::*;
+/// use rand::distributions::WeightedIndex;
+///
+/// let choices = ['a', 'b', 'c'];
+/// let weights = [2,   1,   1];
+/// let dist = WeightedIndex::new(&weights).unwrap();
+/// let mut rng = thread_rng();
+/// for _ in 0..100 {
+///     // 50% chance to print 'a', 25% chance to print 'b', 25% chance to print 'c'
+///     println!("{}", choices[dist.sample(&mut rng)]);
+/// }
+///
+/// let items = [('a', 0), ('b', 3), ('c', 7)];
+/// let dist2 = WeightedIndex::new(items.iter().map(|item| item.1)).unwrap();
+/// for _ in 0..100 {
+///     // 0% chance to print 'a', 30% chance to print 'b', 70% chance to print 'c'
+///     println!("{}", items[dist2.sample(&mut rng)].0);
+/// }
+/// ```
+///
+/// [`Uniform<X>`]: crate::distributions::uniform::Uniform
+/// [`RngCore`]: crate::RngCore
+#[derive(Debug, Clone)]
+pub struct WeightedIndex<X: SampleUniform + PartialOrd> {
+    cumulative_weights: Vec<X>,
+    weight_distribution: X::Sampler,
+}
+
+impl<X: SampleUniform + PartialOrd> WeightedIndex<X> {
+    /// Creates a new a `WeightedIndex` [`Distribution`] using the values
+    /// in `weights`. The weights can use any type `X` for which an
+    /// implementation of [`Uniform<X>`] exists.
+    ///
+    /// Returns an error if the iterator is empty, if any weight is `< 0`, or
+    /// if its total value is 0.
+    ///
+    /// [`Uniform<X>`]: crate::distributions::uniform::Uniform
+    pub fn new<I>(weights: I) -> Result<WeightedIndex<X>, WeightedError>
+        where I: IntoIterator,
+              I::Item: SampleBorrow<X>,
+              X: for<'a> ::core::ops::AddAssign<&'a X> +
+                 Clone +
+                 Default {
+        let mut iter = weights.into_iter();
+        let mut total_weight: X = iter.next()
+                                      .ok_or(WeightedError::NoItem)?
+                                      .borrow()
+                                      .clone();
+
+        let zero = <X as Default>::default();
+        if total_weight < zero {
+            return Err(WeightedError::InvalidWeight);
+        }
+
+        let mut weights = Vec::<X>::with_capacity(iter.size_hint().0);
+        for w in iter {
+            if *w.borrow() < zero {
+                return Err(WeightedError::InvalidWeight);
+            }
+            weights.push(total_weight.clone());
+            total_weight += w.borrow();
+        }
+
+        if total_weight == zero {
+            return Err(WeightedError::AllWeightsZero);
+        }
+        let distr = X::Sampler::new(zero, total_weight);
+
+        Ok(WeightedIndex { cumulative_weights: weights, weight_distribution: distr })
+    }
+}
+
+impl<X> Distribution<usize> for WeightedIndex<X> where
+    X: SampleUniform + PartialOrd {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> usize {
+        use ::core::cmp::Ordering;
+        let chosen_weight = self.weight_distribution.sample(rng);
+        // Find the first item which has a weight *higher* than the chosen weight.
+        self.cumulative_weights.binary_search_by(
+            |w| if *w <= chosen_weight { Ordering::Less } else { Ordering::Greater }).unwrap_err()
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[test]
+    #[cfg(not(miri))] // Miri is too slow
+    fn test_weightedindex() {
+        let mut r = crate::test::rng(700);
+        const N_REPS: u32 = 5000;
+        let weights = [1u32, 2, 3, 0, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7];
+        let total_weight = weights.iter().sum::<u32>() as f32;
+
+        let verify = |result: [i32; 14]| {
+            for (i, count) in result.iter().enumerate() {
+                let exp = (weights[i] * N_REPS) as f32 / total_weight;
+                let mut err = (*count as f32 - exp).abs();
+                if err != 0.0 {
+                    err /= exp;
+                }
+                assert!(err <= 0.25);
+            }
+        };
+
+        // WeightedIndex from vec
+        let mut chosen = [0i32; 14];
+        let distr = WeightedIndex::new(weights.to_vec()).unwrap();
+        for _ in 0..N_REPS {
+            chosen[distr.sample(&mut r)] += 1;
+        }
+        verify(chosen);
+
+        // WeightedIndex from slice
+        chosen = [0i32; 14];
+        let distr = WeightedIndex::new(&weights[..]).unwrap();
+        for _ in 0..N_REPS {
+            chosen[distr.sample(&mut r)] += 1;
+        }
+        verify(chosen);
+
+        // WeightedIndex from iterator
+        chosen = [0i32; 14];
+        let distr = WeightedIndex::new(weights.iter()).unwrap();
+        for _ in 0..N_REPS {
+            chosen[distr.sample(&mut r)] += 1;
+        }
+        verify(chosen);
+
+        for _ in 0..5 {
+            assert_eq!(WeightedIndex::new(&[0, 1]).unwrap().sample(&mut r), 1);
+            assert_eq!(WeightedIndex::new(&[1, 0]).unwrap().sample(&mut r), 0);
+            assert_eq!(WeightedIndex::new(&[0, 0, 0, 0, 10, 0]).unwrap().sample(&mut r), 4);
+        }
+
+        assert_eq!(WeightedIndex::new(&[10][0..0]).unwrap_err(), WeightedError::NoItem);
+        assert_eq!(WeightedIndex::new(&[0]).unwrap_err(), WeightedError::AllWeightsZero);
+        assert_eq!(WeightedIndex::new(&[10, 20, -1, 30]).unwrap_err(), WeightedError::InvalidWeight);
+        assert_eq!(WeightedIndex::new(&[-10, 20, 1, 30]).unwrap_err(), WeightedError::InvalidWeight);
+        assert_eq!(WeightedIndex::new(&[-10]).unwrap_err(), WeightedError::InvalidWeight);
+    }
+}
+
+/// Error type returned from `WeightedIndex::new`.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum WeightedError {
+    /// The provided weight collection contains no items.
+    NoItem,
+
+    /// A weight is either less than zero, greater than the supported maximum or
+    /// otherwise invalid.
+    InvalidWeight,
+
+    /// All items in the provided weight collection are zero.
+    AllWeightsZero,
+    
+    /// Too many weights are provided (length greater than `u32::MAX`)
+    TooMany,
+}
+
+impl WeightedError {
+    fn msg(&self) -> &str {
+        match *self {
+            WeightedError::NoItem => "No weights provided.",
+            WeightedError::InvalidWeight => "A weight is invalid.",
+            WeightedError::AllWeightsZero => "All weights are zero.",
+            WeightedError::TooMany => "Too many weights (hit u32::MAX)",
+        }
+    }
+}
+
+#[cfg(feature="std")]
+impl ::std::error::Error for WeightedError {
+    fn description(&self) -> &str {
+        self.msg()
+    }
+    fn cause(&self) -> Option<&dyn (::std::error::Error)> {
+        None
+    }
+}
+
+impl fmt::Display for WeightedError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}", self.msg())
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/distributions/ziggurat_tables.rs.html b/target/doc/src/rand/distributions/ziggurat_tables.rs.html new file mode 100644 index 0000000..2f13187 --- /dev/null +++ b/target/doc/src/rand/distributions/ziggurat_tables.rs.html @@ -0,0 +1,561 @@ +ziggurat_tables.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+
+// Copyright 2018 Developers of the Rand project.
+// Copyright 2013 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Tables for distributions which are sampled using the ziggurat
+// algorithm. Autogenerated by `ziggurat_tables.py`.
+
+pub type ZigTable = &'static [f64; 257];
+pub const ZIG_NORM_R: f64 = 3.654152885361008796;
+pub static ZIG_NORM_X: [f64; 257] =
+    [3.910757959537090045, 3.654152885361008796, 3.449278298560964462, 3.320244733839166074,
+     3.224575052047029100, 3.147889289517149969, 3.083526132001233044, 3.027837791768635434,
+     2.978603279880844834, 2.934366867207854224, 2.894121053612348060, 2.857138730872132548,
+     2.822877396825325125, 2.790921174000785765, 2.760944005278822555, 2.732685359042827056,
+     2.705933656121858100, 2.680514643284522158, 2.656283037575502437, 2.633116393630324570,
+     2.610910518487548515, 2.589575986706995181, 2.569035452680536569, 2.549221550323460761,
+     2.530075232158516929, 2.511544441625342294, 2.493583041269680667, 2.476149939669143318,
+     2.459208374333311298, 2.442725318198956774, 2.426670984935725972, 2.411018413899685520,
+     2.395743119780480601, 2.380822795170626005, 2.366237056715818632, 2.351967227377659952,
+     2.337996148795031370, 2.324308018869623016, 2.310888250599850036, 2.297723348901329565,
+     2.284800802722946056, 2.272108990226823888, 2.259637095172217780, 2.247375032945807760,
+     2.235313384928327984, 2.223443340090905718, 2.211756642882544366, 2.200245546609647995,
+     2.188902771624720689, 2.177721467738641614, 2.166695180352645966, 2.155817819875063268,
+     2.145083634046203613, 2.134487182844320152, 2.124023315687815661, 2.113687150684933957,
+     2.103474055713146829, 2.093379631137050279, 2.083399693996551783, 2.073530263516978778,
+     2.063767547809956415, 2.054107931648864849, 2.044547965215732788, 2.035084353727808715,
+     2.025713947862032960, 2.016433734904371722, 2.007240830558684852, 1.998132471356564244,
+     1.989106007615571325, 1.980158896898598364, 1.971288697931769640, 1.962493064942461896,
+     1.953769742382734043, 1.945116560006753925, 1.936531428273758904, 1.928012334050718257,
+     1.919557336591228847, 1.911164563769282232, 1.902832208548446369, 1.894558525668710081,
+     1.886341828534776388, 1.878180486290977669, 1.870072921069236838, 1.862017605397632281,
+     1.854013059758148119, 1.846057850283119750, 1.838150586580728607, 1.830289919680666566,
+     1.822474540091783224, 1.814703175964167636, 1.806974591348693426, 1.799287584547580199,
+     1.791640986550010028, 1.784033659547276329, 1.776464495522344977, 1.768932414909077933,
+     1.761436365316706665, 1.753975320315455111, 1.746548278279492994, 1.739154261283669012,
+     1.731792314050707216, 1.724461502945775715, 1.717160915015540690, 1.709889657069006086,
+     1.702646854797613907, 1.695431651932238548, 1.688243209434858727, 1.681080704722823338,
+     1.673943330923760353, 1.666830296159286684, 1.659740822855789499, 1.652674147080648526,
+     1.645629517902360339, 1.638606196773111146, 1.631603456932422036, 1.624620582830568427,
+     1.617656869570534228, 1.610711622367333673, 1.603784156023583041, 1.596873794420261339,
+     1.589979870021648534, 1.583101723393471438, 1.576238702733332886, 1.569390163412534456,
+     1.562555467528439657, 1.555733983466554893, 1.548925085471535512, 1.542128153226347553,
+     1.535342571438843118, 1.528567729435024614, 1.521803020758293101, 1.515047842773992404,
+     1.508301596278571965, 1.501563685112706548, 1.494833515777718391, 1.488110497054654369,
+     1.481394039625375747, 1.474683555695025516, 1.467978458615230908, 1.461278162507407830,
+     1.454582081885523293, 1.447889631277669675, 1.441200224845798017, 1.434513276002946425,
+     1.427828197027290358, 1.421144398672323117, 1.414461289772464658, 1.407778276843371534,
+     1.401094763676202559, 1.394410150925071257, 1.387723835686884621, 1.381035211072741964,
+     1.374343665770030531, 1.367648583594317957, 1.360949343030101844, 1.354245316759430606,
+     1.347535871177359290, 1.340820365893152122, 1.334098153216083604, 1.327368577624624679,
+     1.320630975217730096, 1.313884673146868964, 1.307128989027353860, 1.300363230327433728,
+     1.293586693733517645, 1.286798664489786415, 1.279998415710333237, 1.273185207661843732,
+     1.266358287014688333, 1.259516886060144225, 1.252660221891297887, 1.245787495544997903,
+     1.238897891102027415, 1.231990574742445110, 1.225064693752808020, 1.218119375481726552,
+     1.211153726239911244, 1.204166830140560140, 1.197157747875585931, 1.190125515422801650,
+     1.183069142678760732, 1.175987612011489825, 1.168879876726833800, 1.161744859441574240,
+     1.154581450355851802, 1.147388505416733873, 1.140164844363995789, 1.132909248648336975,
+     1.125620459211294389, 1.118297174115062909, 1.110938046009249502, 1.103541679420268151,
+     1.096106627847603487, 1.088631390649514197, 1.081114409698889389, 1.073554065787871714,
+     1.065948674757506653, 1.058296483326006454, 1.050595664586207123, 1.042844313139370538,
+     1.035040439828605274, 1.027181966030751292, 1.019266717460529215, 1.011292417434978441,
+     1.003256679539591412, 0.995156999629943084, 0.986990747093846266, 0.978755155288937750,
+     0.970447311058864615, 0.962064143217605250, 0.953602409875572654, 0.945058684462571130,
+     0.936429340280896860, 0.927710533396234771, 0.918898183643734989, 0.909987953490768997,
+     0.900975224455174528, 0.891855070726792376, 0.882622229578910122, 0.873271068082494550,
+     0.863795545546826915, 0.854189171001560554, 0.844444954902423661, 0.834555354079518752,
+     0.824512208745288633, 0.814306670128064347, 0.803929116982664893, 0.793369058833152785,
+     0.782615023299588763, 0.771654424216739354, 0.760473406422083165, 0.749056662009581653,
+     0.737387211425838629, 0.725446140901303549, 0.713212285182022732, 0.700661841097584448,
+     0.687767892786257717, 0.674499822827436479, 0.660822574234205984, 0.646695714884388928,
+     0.632072236375024632, 0.616896989996235545, 0.601104617743940417, 0.584616766093722262,
+     0.567338257040473026, 0.549151702313026790, 0.529909720646495108, 0.509423329585933393,
+     0.487443966121754335, 0.463634336771763245, 0.437518402186662658, 0.408389134588000746,
+     0.375121332850465727, 0.335737519180459465, 0.286174591747260509, 0.215241895913273806,
+     0.000000000000000000];
+pub static ZIG_NORM_F: [f64; 257] =
+    [0.000477467764586655, 0.001260285930498598, 0.002609072746106363, 0.004037972593371872,
+     0.005522403299264754, 0.007050875471392110, 0.008616582769422917, 0.010214971439731100,
+     0.011842757857943104, 0.013497450601780807, 0.015177088307982072, 0.016880083152595839,
+     0.018605121275783350, 0.020351096230109354, 0.022117062707379922, 0.023902203305873237,
+     0.025705804008632656, 0.027527235669693315, 0.029365939758230111, 0.031221417192023690,
+     0.033093219458688698, 0.034980941461833073, 0.036884215688691151, 0.038802707404656918,
+     0.040736110656078753, 0.042684144916619378, 0.044646552251446536, 0.046623094902089664,
+     0.048613553216035145, 0.050617723861121788, 0.052635418276973649, 0.054666461325077916,
+     0.056710690106399467, 0.058767952921137984, 0.060838108349751806, 0.062921024437977854,
+     0.065016577971470438, 0.067124653828023989, 0.069245144397250269, 0.071377949059141965,
+     0.073522973714240991, 0.075680130359194964, 0.077849336702372207, 0.080030515814947509,
+     0.082223595813495684, 0.084428509570654661, 0.086645194450867782, 0.088873592068594229,
+     0.091113648066700734, 0.093365311913026619, 0.095628536713353335, 0.097903279039215627,
+     0.100189498769172020, 0.102487158942306270, 0.104796225622867056, 0.107116667775072880,
+     0.109448457147210021, 0.111791568164245583, 0.114145977828255210, 0.116511665626037014,
+     0.118888613443345698, 0.121276805485235437, 0.123676228202051403, 0.126086870220650349,
+     0.128508722280473636, 0.130941777174128166, 0.133386029692162844, 0.135841476571757352,
+     0.138308116449064322, 0.140785949814968309, 0.143274978974047118, 0.145775208006537926,
+     0.148286642733128721, 0.150809290682410169, 0.153343161060837674, 0.155888264725064563,
+     0.158444614156520225, 0.161012223438117663, 0.163591108232982951, 0.166181285765110071,
+     0.168782774801850333, 0.171395595638155623, 0.174019770082499359, 0.176655321444406654,
+     0.179302274523530397, 0.181960655600216487, 0.184630492427504539, 0.187311814224516926,
+     0.190004651671193070, 0.192709036904328807, 0.195425003514885592, 0.198152586546538112,
+     0.200891822495431333, 0.203642749311121501, 0.206405406398679298, 0.209179834621935651,
+     0.211966076307852941, 0.214764175252008499, 0.217574176725178370, 0.220396127481011589,
+     0.223230075764789593, 0.226076071323264877, 0.228934165415577484, 0.231804410825248525,
+     0.234686861873252689, 0.237581574432173676, 0.240488605941449107, 0.243408015423711988,
+     0.246339863502238771, 0.249284212419516704, 0.252241126056943765, 0.255210669955677150,
+     0.258192911338648023, 0.261187919133763713, 0.264195763998317568, 0.267216518344631837,
+     0.270250256366959984, 0.273297054069675804, 0.276356989296781264, 0.279430141762765316,
+     0.282516593084849388, 0.285616426816658109, 0.288729728483353931, 0.291856585618280984,
+     0.294997087801162572, 0.298151326697901342, 0.301319396102034120, 0.304501391977896274,
+     0.307697412505553769, 0.310907558127563710, 0.314131931597630143, 0.317370638031222396,
+     0.320623784958230129, 0.323891482377732021, 0.327173842814958593, 0.330470981380537099,
+     0.333783015832108509, 0.337110066638412809, 0.340452257045945450, 0.343809713148291340,
+     0.347182563958251478, 0.350570941482881204, 0.353974980801569250, 0.357394820147290515,
+     0.360830600991175754, 0.364282468130549597, 0.367750569780596226, 0.371235057669821344,
+     0.374736087139491414, 0.378253817247238111, 0.381788410875031348, 0.385340034841733958,
+     0.388908860020464597, 0.392495061461010764, 0.396098818517547080, 0.399720314981931668,
+     0.403359739222868885, 0.407017284331247953, 0.410693148271983222, 0.414387534042706784,
+     0.418100649839684591, 0.421832709231353298, 0.425583931339900579, 0.429354541031341519,
+     0.433144769114574058, 0.436954852549929273, 0.440785034667769915, 0.444635565397727750,
+     0.448506701509214067, 0.452398706863882505, 0.456311852680773566, 0.460246417814923481,
+     0.464202689050278838, 0.468180961407822172, 0.472181538469883255, 0.476204732721683788,
+     0.480250865911249714, 0.484320269428911598, 0.488413284707712059, 0.492530263646148658,
+     0.496671569054796314, 0.500837575128482149, 0.505028667945828791, 0.509245245998136142,
+     0.513487720749743026, 0.517756517232200619, 0.522052074674794864, 0.526374847174186700,
+     0.530725304406193921, 0.535103932383019565, 0.539511234259544614, 0.543947731192649941,
+     0.548413963257921133, 0.552910490428519918, 0.557437893621486324, 0.561996775817277916,
+     0.566587763258951771, 0.571211506738074970, 0.575868682975210544, 0.580559996103683473,
+     0.585286179266300333, 0.590047996335791969, 0.594846243770991268, 0.599681752622167719,
+     0.604555390700549533, 0.609468064928895381, 0.614420723892076803, 0.619414360609039205,
+     0.624450015550274240, 0.629528779928128279, 0.634651799290960050, 0.639820277456438991,
+     0.645035480824251883, 0.650298743114294586, 0.655611470583224665, 0.660975147780241357,
+     0.666391343912380640, 0.671861719900766374, 0.677388036222513090, 0.682972161648791376,
+     0.688616083008527058, 0.694321916130032579, 0.700091918140490099, 0.705928501336797409,
+     0.711834248882358467, 0.717811932634901395, 0.723864533472881599, 0.729995264565802437,
+     0.736207598131266683, 0.742505296344636245, 0.748892447223726720, 0.755373506511754500,
+     0.761953346841546475, 0.768637315803334831, 0.775431304986138326, 0.782341832659861902,
+     0.789376143571198563, 0.796542330428254619, 0.803849483176389490, 0.811307874318219935,
+     0.818929191609414797, 0.826726833952094231, 0.834716292992930375, 0.842915653118441077,
+     0.851346258465123684, 0.860033621203008636, 0.869008688043793165, 0.878309655816146839,
+     0.887984660763399880, 0.898095921906304051, 0.908726440060562912, 0.919991505048360247,
+     0.932060075968990209, 0.945198953453078028, 0.959879091812415930, 0.977101701282731328,
+     1.000000000000000000];
+pub const ZIG_EXP_R: f64 = 7.697117470131050077;
+pub static ZIG_EXP_X: [f64; 257] =
+    [8.697117470131052741, 7.697117470131050077, 6.941033629377212577, 6.478378493832569696,
+     6.144164665772472667, 5.882144315795399869, 5.666410167454033697, 5.482890627526062488,
+     5.323090505754398016, 5.181487281301500047, 5.054288489981304089, 4.938777085901250530,
+     4.832939741025112035, 4.735242996601741083, 4.644491885420085175, 4.559737061707351380,
+     4.480211746528421912, 4.405287693473573185, 4.334443680317273007, 4.267242480277365857,
+     4.203313713735184365, 4.142340865664051464, 4.084051310408297830, 4.028208544647936762,
+     3.974606066673788796, 3.923062500135489739, 3.873417670399509127, 3.825529418522336744,
+     3.779270992411667862, 3.734528894039797375, 3.691201090237418825, 3.649195515760853770,
+     3.608428813128909507, 3.568825265648337020, 3.530315889129343354, 3.492837654774059608,
+     3.456332821132760191, 3.420748357251119920, 3.386035442460300970, 3.352149030900109405,
+     3.319047470970748037, 3.286692171599068679, 3.255047308570449882, 3.224079565286264160,
+     3.193757903212240290, 3.164053358025972873, 3.134938858084440394, 3.106389062339824481,
+     3.078380215254090224, 3.050890016615455114, 3.023897504455676621, 2.997382949516130601,
+     2.971327759921089662, 2.945714394895045718, 2.920526286512740821, 2.895747768600141825,
+     2.871364012015536371, 2.847360965635188812, 2.823725302450035279, 2.800444370250737780,
+     2.777506146439756574, 2.754899196562344610, 2.732612636194700073, 2.710636095867928752,
+     2.688959688741803689, 2.667573980773266573, 2.646469963151809157, 2.625639026797788489,
+     2.605072938740835564, 2.584763820214140750, 2.564704126316905253, 2.544886627111869970,
+     2.525304390037828028, 2.505950763528594027, 2.486819361740209455, 2.467904050297364815,
+     2.449198932978249754, 2.430698339264419694, 2.412396812688870629, 2.394289099921457886,
+     2.376370140536140596, 2.358635057409337321, 2.341079147703034380, 2.323697874390196372,
+     2.306486858283579799, 2.289441870532269441, 2.272558825553154804, 2.255833774367219213,
+     2.239262898312909034, 2.222842503111036816, 2.206569013257663858, 2.190438966723220027,
+     2.174449009937774679, 2.158595893043885994, 2.142876465399842001, 2.127287671317368289,
+     2.111826546019042183, 2.096490211801715020, 2.081275874393225145, 2.066180819490575526,
+     2.051202409468584786, 2.036338080248769611, 2.021585338318926173, 2.006941757894518563,
+     1.992404978213576650, 1.977972700957360441, 1.963642687789548313, 1.949412758007184943,
+     1.935280786297051359, 1.921244700591528076, 1.907302480018387536, 1.893452152939308242,
+     1.879691795072211180, 1.866019527692827973, 1.852433515911175554, 1.838931967018879954,
+     1.825513128903519799, 1.812175288526390649, 1.798916770460290859, 1.785735935484126014,
+     1.772631179231305643, 1.759600930889074766, 1.746643651946074405, 1.733757834985571566,
+     1.720942002521935299, 1.708194705878057773, 1.695514524101537912, 1.682900062917553896,
+     1.670349953716452118, 1.657862852574172763, 1.645437439303723659, 1.633072416535991334,
+     1.620766508828257901, 1.608518461798858379, 1.596327041286483395, 1.584191032532688892,
+     1.572109239386229707, 1.560080483527888084, 1.548103603714513499, 1.536177455041032092,
+     1.524300908219226258, 1.512472848872117082, 1.500692176842816750, 1.488957805516746058,
+     1.477268661156133867, 1.465623682245745352, 1.454021818848793446, 1.442462031972012504,
+     1.430943292938879674, 1.419464582769983219, 1.408024891569535697, 1.396623217917042137,
+     1.385258568263121992, 1.373929956328490576, 1.362636402505086775, 1.351376933258335189,
+     1.340150580529504643, 1.328956381137116560, 1.317793376176324749, 1.306660610415174117,
+     1.295557131686601027, 1.284481990275012642, 1.273434238296241139, 1.262412929069615330,
+     1.251417116480852521, 1.240445854334406572, 1.229498195693849105, 1.218573192208790124,
+     1.207669893426761121, 1.196787346088403092, 1.185924593404202199, 1.175080674310911677,
+     1.164254622705678921, 1.153445466655774743, 1.142652227581672841, 1.131873919411078511,
+     1.121109547701330200, 1.110358108727411031, 1.099618588532597308, 1.088889961938546813,
+     1.078171191511372307, 1.067461226479967662, 1.056759001602551429, 1.046063435977044209,
+     1.035373431790528542, 1.024687873002617211, 1.014005623957096480, 1.003325527915696735,
+     0.992646405507275897, 0.981967053085062602, 0.971286240983903260, 0.960602711668666509,
+     0.949915177764075969, 0.939222319955262286, 0.928522784747210395, 0.917815182070044311,
+     0.907098082715690257, 0.896370015589889935, 0.885629464761751528, 0.874874866291025066,
+     0.864104604811004484, 0.853317009842373353, 0.842510351810368485, 0.831682837734273206,
+     0.820832606554411814, 0.809957724057418282, 0.799056177355487174, 0.788125868869492430,
+     0.777164609759129710, 0.766170112735434672, 0.755139984181982249, 0.744071715500508102,
+     0.732962673584365398, 0.721810090308756203, 0.710611050909655040, 0.699362481103231959,
+     0.688061132773747808, 0.676703568029522584, 0.665286141392677943, 0.653804979847664947,
+     0.642255960424536365, 0.630634684933490286, 0.618936451394876075, 0.607156221620300030,
+     0.595288584291502887, 0.583327712748769489, 0.571267316532588332, 0.559100585511540626,
+     0.546820125163310577, 0.534417881237165604, 0.521885051592135052, 0.509211982443654398,
+     0.496388045518671162, 0.483401491653461857, 0.470239275082169006, 0.456886840931420235,
+     0.443327866073552401, 0.429543940225410703, 0.415514169600356364, 0.401214678896277765,
+     0.386617977941119573, 0.371692145329917234, 0.356399760258393816, 0.340696481064849122,
+     0.324529117016909452, 0.307832954674932158, 0.290527955491230394, 0.272513185478464703,
+     0.253658363385912022, 0.233790483059674731, 0.212671510630966620, 0.189958689622431842,
+     0.165127622564187282, 0.137304980940012589, 0.104838507565818778, 0.063852163815001570,
+     0.000000000000000000];
+pub static ZIG_EXP_F: [f64; 257] =
+    [0.000167066692307963, 0.000454134353841497, 0.000967269282327174, 0.001536299780301573,
+     0.002145967743718907, 0.002788798793574076, 0.003460264777836904, 0.004157295120833797,
+     0.004877655983542396, 0.005619642207205489, 0.006381905937319183, 0.007163353183634991,
+     0.007963077438017043, 0.008780314985808977, 0.009614413642502212, 0.010464810181029981,
+     0.011331013597834600, 0.012212592426255378, 0.013109164931254991, 0.014020391403181943,
+     0.014945968011691148, 0.015885621839973156, 0.016839106826039941, 0.017806200410911355,
+     0.018786700744696024, 0.019780424338009740, 0.020787204072578114, 0.021806887504283581,
+     0.022839335406385240, 0.023884420511558174, 0.024942026419731787, 0.026012046645134221,
+     0.027094383780955803, 0.028188948763978646, 0.029295660224637411, 0.030414443910466622,
+     0.031545232172893622, 0.032687963508959555, 0.033842582150874358, 0.035009037697397431,
+     0.036187284781931443, 0.037377282772959382, 0.038578995503074871, 0.039792391023374139,
+     0.041017441380414840, 0.042254122413316254, 0.043502413568888197, 0.044762297732943289,
+     0.046033761076175184, 0.047316792913181561, 0.048611385573379504, 0.049917534282706379,
+     0.051235237055126281, 0.052564494593071685, 0.053905310196046080, 0.055257689676697030,
+     0.056621641283742870, 0.057997175631200659, 0.059384305633420280, 0.060783046445479660,
+     0.062193415408541036, 0.063615431999807376, 0.065049117786753805, 0.066494496385339816,
+     0.067951593421936643, 0.069420436498728783, 0.070901055162371843, 0.072393480875708752,
+     0.073897746992364746, 0.075413888734058410, 0.076941943170480517, 0.078481949201606435,
+     0.080033947542319905, 0.081597980709237419, 0.083174093009632397, 0.084762330532368146,
+     0.086362741140756927, 0.087975374467270231, 0.089600281910032886, 0.091237516631040197,
+     0.092887133556043569, 0.094549189376055873, 0.096223742550432825, 0.097910853311492213,
+     0.099610583670637132, 0.101322997425953631, 0.103048160171257702, 0.104786139306570145,
+     0.106537004050001632, 0.108300825451033755, 0.110077676405185357, 0.111867631670056283,
+     0.113670767882744286, 0.115487163578633506, 0.117316899211555525, 0.119160057175327641,
+     0.121016721826674792, 0.122886979509545108, 0.124770918580830933, 0.126668629437510671,
+     0.128580204545228199, 0.130505738468330773, 0.132445327901387494, 0.134399071702213602,
+     0.136367070926428829, 0.138349428863580176, 0.140346251074862399, 0.142357645432472146,
+     0.144383722160634720, 0.146424593878344889, 0.148480375643866735, 0.150551185001039839,
+     0.152637142027442801, 0.154738369384468027, 0.156854992369365148, 0.158987138969314129,
+     0.161134939917591952, 0.163298528751901734, 0.165478041874935922, 0.167673618617250081,
+     0.169885401302527550, 0.172113535315319977, 0.174358169171353411, 0.176619454590494829,
+     0.178897546572478278, 0.181192603475496261, 0.183504787097767436, 0.185834262762197083,
+     0.188181199404254262, 0.190545769663195363, 0.192928149976771296, 0.195328520679563189,
+     0.197747066105098818, 0.200183974691911210, 0.202639439093708962, 0.205113656293837654,
+     0.207606827724221982, 0.210119159388988230, 0.212650861992978224, 0.215202151075378628,
+     0.217773247148700472, 0.220364375843359439, 0.222975768058120111, 0.225607660116683956,
+     0.228260293930716618, 0.230933917169627356, 0.233628783437433291, 0.236345152457059560,
+     0.239083290262449094, 0.241843469398877131, 0.244625969131892024, 0.247431075665327543,
+     0.250259082368862240, 0.253110290015629402, 0.255985007030415324, 0.258883549749016173,
+     0.261806242689362922, 0.264753418835062149, 0.267725419932044739, 0.270722596799059967,
+     0.273745309652802915, 0.276793928448517301, 0.279868833236972869, 0.282970414538780746,
+     0.286099073737076826, 0.289255223489677693, 0.292439288161892630, 0.295651704281261252,
+     0.298892921015581847, 0.302163400675693528, 0.305463619244590256, 0.308794066934560185,
+     0.312155248774179606, 0.315547685227128949, 0.318971912844957239, 0.322428484956089223,
+     0.325917972393556354, 0.329440964264136438, 0.332998068761809096, 0.336589914028677717,
+     0.340217149066780189, 0.343880444704502575, 0.347580494621637148, 0.351318016437483449,
+     0.355093752866787626, 0.358908472948750001, 0.362762973354817997, 0.366658079781514379,
+     0.370594648435146223, 0.374573567615902381, 0.378595759409581067, 0.382662181496010056,
+     0.386773829084137932, 0.390931736984797384, 0.395136981833290435, 0.399390684475231350,
+     0.403694012530530555, 0.408048183152032673, 0.412454465997161457, 0.416914186433003209,
+     0.421428728997616908, 0.425999541143034677, 0.430628137288459167, 0.435316103215636907,
+     0.440065100842354173, 0.444876873414548846, 0.449753251162755330, 0.454696157474615836,
+     0.459707615642138023, 0.464789756250426511, 0.469944825283960310, 0.475175193037377708,
+     0.480483363930454543, 0.485871987341885248, 0.491343869594032867, 0.496901987241549881,
+     0.502549501841348056, 0.508289776410643213, 0.514126393814748894, 0.520063177368233931,
+     0.526104213983620062, 0.532253880263043655, 0.538516872002862246, 0.544898237672440056,
+     0.551403416540641733, 0.558038282262587892, 0.564809192912400615, 0.571723048664826150,
+     0.578787358602845359, 0.586010318477268366, 0.593400901691733762, 0.600968966365232560,
+     0.608725382079622346, 0.616682180915207878, 0.624852738703666200, 0.633251994214366398,
+     0.641896716427266423, 0.650805833414571433, 0.660000841079000145, 0.669506316731925177,
+     0.679350572264765806, 0.689566496117078431, 0.700192655082788606, 0.711274760805076456,
+     0.722867659593572465, 0.735038092431424039, 0.747868621985195658, 0.761463388849896838,
+     0.775956852040116218, 0.791527636972496285, 0.808421651523009044, 0.826993296643051101,
+     0.847785500623990496, 0.871704332381204705, 0.900469929925747703, 0.938143680862176477,
+     1.000000000000000000];
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/lib.rs.html b/target/doc/src/rand/lib.rs.html new file mode 100644 index 0000000..a5e4eb9 --- /dev/null +++ b/target/doc/src/rand/lib.rs.html @@ -0,0 +1,1441 @@ +lib.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+
+// Copyright 2018 Developers of the Rand project.
+// Copyright 2013-2017 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Utilities for random number generation
+//!
+//! Rand provides utilities to generate random numbers, to convert them to
+//! useful types and distributions, and some randomness-related algorithms.
+//!
+//! # Quick Start
+//!
+//! To get you started quickly, the easiest and highest-level way to get
+//! a random value is to use [`random()`]; alternatively you can use
+//! [`thread_rng()`]. The [`Rng`] trait provides a useful API on all RNGs, while
+//! the [`distributions`] and [`seq`] modules provide further
+//! functionality on top of RNGs.
+//!
+//! ```
+//! use rand::prelude::*;
+//!
+//! if rand::random() { // generates a boolean
+//!     // Try printing a random unicode code point (probably a bad idea)!
+//!     println!("char: {}", rand::random::<char>());
+//! }
+//!
+//! let mut rng = rand::thread_rng();
+//! let y: f64 = rng.gen(); // generates a float between 0 and 1
+//!
+//! let mut nums: Vec<i32> = (1..100).collect();
+//! nums.shuffle(&mut rng);
+//! ```
+//!
+//! # The Book
+//!
+//! For the user guide and futher documentation, please read
+//! [The Rust Rand Book](https://rust-random.github.io/book).
+
+
+#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
+       html_favicon_url = "https://www.rust-lang.org/favicon.ico",
+       html_root_url = "https://rust-random.github.io/rand/")]
+
+#![deny(missing_docs)]
+#![deny(missing_debug_implementations)]
+#![doc(test(attr(allow(unused_variables), deny(warnings))))]
+
+#![cfg_attr(not(feature="std"), no_std)]
+#![cfg_attr(all(feature="alloc", not(feature="std")), feature(alloc))]
+#![cfg_attr(all(feature="simd_support", feature="nightly"), feature(stdsimd))]
+
+#[cfg(all(feature="alloc", not(feature="std")))]
+extern crate alloc;
+
+#[cfg(feature = "getrandom")]
+use getrandom_package as getrandom;
+
+#[allow(unused)]
+macro_rules! trace { ($($x:tt)*) => (
+    #[cfg(feature = "log")] {
+        log::trace!($($x)*)
+    }
+) }
+#[allow(unused)]
+macro_rules! debug { ($($x:tt)*) => (
+    #[cfg(feature = "log")] {
+        log::debug!($($x)*)
+    }
+) }
+#[allow(unused)]
+macro_rules! info { ($($x:tt)*) => (
+    #[cfg(feature = "log")] {
+        log::info!($($x)*)
+    }
+) }
+#[allow(unused)]
+macro_rules! warn { ($($x:tt)*) => (
+    #[cfg(feature = "log")] {
+        log::warn!($($x)*)
+    }
+) }
+#[allow(unused)]
+macro_rules! error { ($($x:tt)*) => (
+    #[cfg(feature = "log")] {
+        log::error!($($x)*)
+    }
+) }
+
+// Re-exports from rand_core
+pub use rand_core::{RngCore, CryptoRng, SeedableRng, Error};
+
+// Public exports
+#[cfg(feature="std")] pub use crate::rngs::thread::thread_rng;
+
+// Public modules
+pub mod distributions;
+pub mod prelude;
+pub mod rngs;
+pub mod seq;
+
+
+use core::{mem, slice};
+use core::num::Wrapping;
+use crate::distributions::{Distribution, Standard};
+use crate::distributions::uniform::{SampleUniform, UniformSampler, SampleBorrow};
+
+/// An automatically-implemented extension trait on [`RngCore`] providing high-level
+/// generic methods for sampling values and other convenience methods.
+///
+/// This is the primary trait to use when generating random values.
+///
+/// # Generic usage
+///
+/// The basic pattern is `fn foo<R: Rng + ?Sized>(rng: &mut R)`. Some
+/// things are worth noting here:
+///
+/// - Since `Rng: RngCore` and every `RngCore` implements `Rng`, it makes no
+///   difference whether we use `R: Rng` or `R: RngCore`.
+/// - The `+ ?Sized` un-bounding allows functions to be called directly on
+///   type-erased references; i.e. `foo(r)` where `r: &mut RngCore`. Without
+///   this it would be necessary to write `foo(&mut r)`.
+///
+/// An alternative pattern is possible: `fn foo<R: Rng>(rng: R)`. This has some
+/// trade-offs. It allows the argument to be consumed directly without a `&mut`
+/// (which is how `from_rng(thread_rng())` works); also it still works directly
+/// on references (including type-erased references). Unfortunately within the
+/// function `foo` it is not known whether `rng` is a reference type or not,
+/// hence many uses of `rng` require an extra reference, either explicitly
+/// (`distr.sample(&mut rng)`) or implicitly (`rng.gen()`); one may hope the
+/// optimiser can remove redundant references later.
+///
+/// Example:
+///
+/// ```
+/// # use rand::thread_rng;
+/// use rand::Rng;
+///
+/// fn foo<R: Rng + ?Sized>(rng: &mut R) -> f32 {
+///     rng.gen()
+/// }
+///
+/// # let v = foo(&mut thread_rng());
+/// ```
+pub trait Rng: RngCore {
+    /// Return a random value supporting the [`Standard`] distribution.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use rand::{thread_rng, Rng};
+    ///
+    /// let mut rng = thread_rng();
+    /// let x: u32 = rng.gen();
+    /// println!("{}", x);
+    /// println!("{:?}", rng.gen::<(f64, bool)>());
+    /// ```
+    ///
+    /// # Arrays and tuples
+    ///
+    /// The `rng.gen()` method is able to generate arrays (up to 32 elements)
+    /// and tuples (up to 12 elements), so long as all element types can be
+    /// generated.
+    ///
+    /// For arrays of integers, especially for those with small element types
+    /// (< 64 bit), it will likely be faster to instead use [`Rng::fill`].
+    ///
+    /// ```
+    /// use rand::{thread_rng, Rng};
+    ///
+    /// let mut rng = thread_rng();
+    /// let tuple: (u8, i32, char) = rng.gen(); // arbitrary tuple support
+    ///
+    /// let arr1: [f32; 32] = rng.gen();        // array construction
+    /// let mut arr2 = [0u8; 128];
+    /// rng.fill(&mut arr2);                    // array fill
+    /// ```
+    ///
+    /// [`Standard`]: distributions::Standard
+    #[inline]
+    fn gen<T>(&mut self) -> T
+    where Standard: Distribution<T> {
+        Standard.sample(self)
+    }
+
+    /// Generate a random value in the range [`low`, `high`), i.e. inclusive of
+    /// `low` and exclusive of `high`.
+    ///
+    /// This function is optimised for the case that only a single sample is
+    /// made from the given range. See also the [`Uniform`] distribution
+    /// type which may be faster if sampling from the same range repeatedly.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `low >= high`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use rand::{thread_rng, Rng};
+    ///
+    /// let mut rng = thread_rng();
+    /// let n: u32 = rng.gen_range(0, 10);
+    /// println!("{}", n);
+    /// let m: f64 = rng.gen_range(-40.0f64, 1.3e5f64);
+    /// println!("{}", m);
+    /// ```
+    ///
+    /// [`Uniform`]: distributions::uniform::Uniform
+    fn gen_range<T: SampleUniform, B1, B2>(&mut self, low: B1, high: B2) -> T
+    where
+        B1: SampleBorrow<T> + Sized,
+        B2: SampleBorrow<T> + Sized,
+    {
+        T::Sampler::sample_single(low, high, self)
+    }
+
+    /// Sample a new value, using the given distribution.
+    ///
+    /// ### Example
+    ///
+    /// ```
+    /// use rand::{thread_rng, Rng};
+    /// use rand::distributions::Uniform;
+    ///
+    /// let mut rng = thread_rng();
+    /// let x = rng.sample(Uniform::new(10u32, 15));
+    /// // Type annotation requires two types, the type and distribution; the
+    /// // distribution can be inferred.
+    /// let y = rng.sample::<u16, _>(Uniform::new(10, 15));
+    /// ```
+    fn sample<T, D: Distribution<T>>(&mut self, distr: D) -> T {
+        distr.sample(self)
+    }
+
+    /// Create an iterator that generates values using the given distribution.
+    ///
+    /// Note that this function takes its arguments by value. This works since
+    /// `(&mut R): Rng where R: Rng` and
+    /// `(&D): Distribution where D: Distribution`,
+    /// however borrowing is not automatic hence `rng.sample_iter(...)` may
+    /// need to be replaced with `(&mut rng).sample_iter(...)`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use rand::{thread_rng, Rng};
+    /// use rand::distributions::{Alphanumeric, Uniform, Standard};
+    ///
+    /// let rng = thread_rng();
+    ///
+    /// // Vec of 16 x f32:
+    /// let v: Vec<f32> = rng.sample_iter(Standard).take(16).collect();
+    ///
+    /// // String:
+    /// let s: String = rng.sample_iter(Alphanumeric).take(7).collect();
+    ///
+    /// // Combined values
+    /// println!("{:?}", rng.sample_iter(Standard).take(5)
+    ///                              .collect::<Vec<(f64, bool)>>());
+    ///
+    /// // Dice-rolling:
+    /// let die_range = Uniform::new_inclusive(1, 6);
+    /// let mut roll_die = rng.sample_iter(die_range);
+    /// while roll_die.next().unwrap() != 6 {
+    ///     println!("Not a 6; rolling again!");
+    /// }
+    /// ```
+    fn sample_iter<T, D>(self, distr: D) -> distributions::DistIter<D, Self, T>
+    where D: Distribution<T>, Self: Sized {
+        distr.sample_iter(self)
+    }
+
+    /// Fill `dest` entirely with random bytes (uniform value distribution),
+    /// where `dest` is any type supporting [`AsByteSliceMut`], namely slices
+    /// and arrays over primitive integer types (`i8`, `i16`, `u32`, etc.).
+    ///
+    /// On big-endian platforms this performs byte-swapping to ensure
+    /// portability of results from reproducible generators.
+    ///
+    /// This uses [`fill_bytes`] internally which may handle some RNG errors
+    /// implicitly (e.g. waiting if the OS generator is not ready), but panics
+    /// on other errors. See also [`try_fill`] which returns errors.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use rand::{thread_rng, Rng};
+    ///
+    /// let mut arr = [0i8; 20];
+    /// thread_rng().fill(&mut arr[..]);
+    /// ```
+    ///
+    /// [`fill_bytes`]: RngCore::fill_bytes
+    /// [`try_fill`]: Rng::try_fill
+    fn fill<T: AsByteSliceMut + ?Sized>(&mut self, dest: &mut T) {
+        self.fill_bytes(dest.as_byte_slice_mut());
+        dest.to_le();
+    }
+
+    /// Fill `dest` entirely with random bytes (uniform value distribution),
+    /// where `dest` is any type supporting [`AsByteSliceMut`], namely slices
+    /// and arrays over primitive integer types (`i8`, `i16`, `u32`, etc.).
+    ///
+    /// On big-endian platforms this performs byte-swapping to ensure
+    /// portability of results from reproducible generators.
+    ///
+    /// This is identical to [`fill`] except that it uses [`try_fill_bytes`]
+    /// internally and forwards RNG errors.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # use rand::Error;
+    /// use rand::{thread_rng, Rng};
+    ///
+    /// # fn try_inner() -> Result<(), Error> {
+    /// let mut arr = [0u64; 4];
+    /// thread_rng().try_fill(&mut arr[..])?;
+    /// # Ok(())
+    /// # }
+    ///
+    /// # try_inner().unwrap()
+    /// ```
+    ///
+    /// [`try_fill_bytes`]: RngCore::try_fill_bytes
+    /// [`fill`]: Rng::fill
+    fn try_fill<T: AsByteSliceMut + ?Sized>(&mut self, dest: &mut T) -> Result<(), Error> {
+        self.try_fill_bytes(dest.as_byte_slice_mut())?;
+        dest.to_le();
+        Ok(())
+    }
+
+    /// Return a bool with a probability `p` of being true.
+    ///
+    /// See also the [`Bernoulli`] distribution, which may be faster if
+    /// sampling from the same probability repeatedly.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use rand::{thread_rng, Rng};
+    ///
+    /// let mut rng = thread_rng();
+    /// println!("{}", rng.gen_bool(1.0 / 3.0));
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// If `p < 0` or `p > 1`.
+    ///
+    /// [`Bernoulli`]: distributions::bernoulli::Bernoulli
+    #[inline]
+    fn gen_bool(&mut self, p: f64) -> bool {
+        let d = distributions::Bernoulli::new(p).unwrap();
+        self.sample(d)
+    }
+
+    /// Return a bool with a probability of `numerator/denominator` of being
+    /// true. I.e. `gen_ratio(2, 3)` has chance of 2 in 3, or about 67%, of
+    /// returning true. If `numerator == denominator`, then the returned value
+    /// is guaranteed to be `true`. If `numerator == 0`, then the returned
+    /// value is guaranteed to be `false`.
+    ///
+    /// See also the [`Bernoulli`] distribution, which may be faster if
+    /// sampling from the same `numerator` and `denominator` repeatedly.
+    ///
+    /// # Panics
+    ///
+    /// If `denominator == 0` or `numerator > denominator`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use rand::{thread_rng, Rng};
+    ///
+    /// let mut rng = thread_rng();
+    /// println!("{}", rng.gen_ratio(2, 3));
+    /// ```
+    ///
+    /// [`Bernoulli`]: distributions::bernoulli::Bernoulli
+    #[inline]
+    fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool {
+        let d = distributions::Bernoulli::from_ratio(numerator, denominator).unwrap();
+        self.sample(d)
+    }
+}
+
+impl<R: RngCore + ?Sized> Rng for R {}
+
+/// Trait for casting types to byte slices
+///
+/// This is used by the [`Rng::fill`] and [`Rng::try_fill`] methods.
+pub trait AsByteSliceMut {
+    /// Return a mutable reference to self as a byte slice
+    fn as_byte_slice_mut(&mut self) -> &mut [u8];
+
+    /// Call `to_le` on each element (i.e. byte-swap on Big Endian platforms).
+    fn to_le(&mut self);
+}
+
+impl AsByteSliceMut for [u8] {
+    fn as_byte_slice_mut(&mut self) -> &mut [u8] {
+        self
+    }
+
+    fn to_le(&mut self) {}
+}
+
+macro_rules! impl_as_byte_slice {
+    () => {};
+    ($t:ty) => {
+        impl AsByteSliceMut for [$t] {
+            fn as_byte_slice_mut(&mut self) -> &mut [u8] {
+                if self.len() == 0 {
+                    unsafe {
+                        // must not use null pointer
+                        slice::from_raw_parts_mut(0x1 as *mut u8, 0)
+                    }
+                } else {
+                    unsafe {
+                        slice::from_raw_parts_mut(self.as_mut_ptr()
+                            as *mut u8,
+                            self.len() * mem::size_of::<$t>()
+                        )
+                    }
+                }
+            }
+
+            fn to_le(&mut self) {
+                for x in self {
+                    *x = x.to_le();
+                }
+            }
+        }
+        
+        impl AsByteSliceMut for [Wrapping<$t>] {
+            fn as_byte_slice_mut(&mut self) -> &mut [u8] {
+                if self.len() == 0 {
+                    unsafe {
+                        // must not use null pointer
+                        slice::from_raw_parts_mut(0x1 as *mut u8, 0)
+                    }
+                } else {
+                    unsafe {
+                        slice::from_raw_parts_mut(self.as_mut_ptr()
+                            as *mut u8,
+                            self.len() * mem::size_of::<$t>()
+                        )
+                    }
+                }
+            }
+
+            fn to_le(&mut self) {
+                for x in self {
+                    *x = Wrapping(x.0.to_le());
+                }
+            }
+        }
+    };
+    ($t:ty, $($tt:ty,)*) => {
+        impl_as_byte_slice!($t);
+        // TODO: this could replace above impl once Rust #32463 is fixed
+        // impl_as_byte_slice!(Wrapping<$t>);
+        impl_as_byte_slice!($($tt,)*);
+    }
+}
+
+impl_as_byte_slice!(u16, u32, u64, usize,);
+#[cfg(not(target_os = "emscripten"))] impl_as_byte_slice!(u128);
+impl_as_byte_slice!(i8, i16, i32, i64, isize,);
+#[cfg(not(target_os = "emscripten"))] impl_as_byte_slice!(i128);
+
+macro_rules! impl_as_byte_slice_arrays {
+    ($n:expr,) => {};
+    ($n:expr, $N:ident) => {
+        impl<T> AsByteSliceMut for [T; $n] where [T]: AsByteSliceMut {
+            fn as_byte_slice_mut(&mut self) -> &mut [u8] {
+                self[..].as_byte_slice_mut()
+            }
+
+            fn to_le(&mut self) {
+                self[..].to_le()
+            }
+        }
+    };
+    ($n:expr, $N:ident, $($NN:ident,)*) => {
+        impl_as_byte_slice_arrays!($n, $N);
+        impl_as_byte_slice_arrays!($n - 1, $($NN,)*);
+    };
+    (!div $n:expr,) => {};
+    (!div $n:expr, $N:ident, $($NN:ident,)*) => {
+        impl_as_byte_slice_arrays!($n, $N);
+        impl_as_byte_slice_arrays!(!div $n / 2, $($NN,)*);
+    };
+}
+impl_as_byte_slice_arrays!(32, N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,);
+impl_as_byte_slice_arrays!(!div 4096, N,N,N,N,N,N,N,);
+
+/// Generates a random value using the thread-local random number generator.
+///
+/// This is simply a shortcut for `thread_rng().gen()`. See [`thread_rng`] for
+/// documentation of the entropy source and [`Standard`] for documentation of
+/// distributions and type-specific generation.
+///
+/// # Examples
+///
+/// ```
+/// let x = rand::random::<u8>();
+/// println!("{}", x);
+///
+/// let y = rand::random::<f64>();
+/// println!("{}", y);
+///
+/// if rand::random() { // generates a boolean
+///     println!("Better lucky than good!");
+/// }
+/// ```
+///
+/// If you're calling `random()` in a loop, caching the generator as in the
+/// following example can increase performance.
+///
+/// ```
+/// use rand::Rng;
+///
+/// let mut v = vec![1, 2, 3];
+///
+/// for x in v.iter_mut() {
+///     *x = rand::random()
+/// }
+///
+/// // can be made faster by caching thread_rng
+///
+/// let mut rng = rand::thread_rng();
+///
+/// for x in v.iter_mut() {
+///     *x = rng.gen();
+/// }
+/// ```
+///
+/// [`Standard`]: distributions::Standard
+#[cfg(feature="std")]
+#[inline]
+pub fn random<T>() -> T
+where Standard: Distribution<T> {
+    thread_rng().gen()
+}
+
+#[cfg(test)]
+mod test {
+    use crate::rngs::mock::StepRng;
+    use super::*;
+    #[cfg(all(not(feature="std"), feature="alloc"))] use alloc::boxed::Box;
+
+    /// Construct a deterministic RNG with the given seed
+    pub fn rng(seed: u64) -> impl RngCore {
+        // For tests, we want a statistically good, fast, reproducible RNG.
+        // PCG32 will do fine, and will be easy to embed if we ever need to.
+        const INC: u64 = 11634580027462260723;
+        rand_pcg::Pcg32::new(seed, INC)
+    }
+
+    #[test]
+    fn test_fill_bytes_default() {
+        let mut r = StepRng::new(0x11_22_33_44_55_66_77_88, 0);
+
+        // check every remainder mod 8, both in small and big vectors.
+        let lengths = [0, 1, 2, 3, 4, 5, 6, 7,
+                       80, 81, 82, 83, 84, 85, 86, 87];
+        for &n in lengths.iter() {
+            let mut buffer = [0u8; 87];
+            let v = &mut buffer[0..n];
+            r.fill_bytes(v);
+
+            // use this to get nicer error messages.
+            for (i, &byte) in v.iter().enumerate() {
+                if byte == 0 {
+                    panic!("byte {} of {} is zero", i, n)
+                }
+            }
+        }
+    }
+
+    #[test]
+    fn test_fill() {
+        let x = 9041086907909331047;    // a random u64
+        let mut rng = StepRng::new(x, 0);
+
+        // Convert to byte sequence and back to u64; byte-swap twice if BE.
+        let mut array = [0u64; 2];
+        rng.fill(&mut array[..]);
+        assert_eq!(array, [x, x]);
+        assert_eq!(rng.next_u64(), x);
+
+        // Convert to bytes then u32 in LE order
+        let mut array = [0u32; 2];
+        rng.fill(&mut array[..]);
+        assert_eq!(array, [x as u32, (x >> 32) as u32]);
+        assert_eq!(rng.next_u32(), x as u32);
+        
+        // Check equivalence using wrapped arrays
+        let mut warray = [Wrapping(0u32); 2];
+        rng.fill(&mut warray[..]);
+        assert_eq!(array[0], warray[0].0);
+        assert_eq!(array[1], warray[1].0);
+    }
+
+    #[test]
+    fn test_fill_empty() {
+        let mut array = [0u32; 0];
+        let mut rng = StepRng::new(0, 1);
+        rng.fill(&mut array);
+        rng.fill(&mut array[..]);
+    }
+
+    #[test]
+    fn test_gen_range() {
+        let mut r = rng(101);
+        for _ in 0..1000 {
+            let a = r.gen_range(-4711, 17);
+            assert!(a >= -4711 && a < 17);
+            let a = r.gen_range(-3i8, 42);
+            assert!(a >= -3i8 && a < 42i8);
+            let a = r.gen_range(&10u16, 99);
+            assert!(a >= 10u16 && a < 99u16);
+            let a = r.gen_range(-100i32, &2000);
+            assert!(a >= -100i32 && a < 2000i32);
+            let a = r.gen_range(&12u32, &24u32);
+            assert!(a >= 12u32 && a < 24u32);
+
+            assert_eq!(r.gen_range(0u32, 1), 0u32);
+            assert_eq!(r.gen_range(-12i64, -11), -12i64);
+            assert_eq!(r.gen_range(3_000_000, 3_000_001), 3_000_000);
+        }
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_gen_range_panic_int() {
+        let mut r = rng(102);
+        r.gen_range(5, -2);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_gen_range_panic_usize() {
+        let mut r = rng(103);
+        r.gen_range(5, 2);
+    }
+
+    #[test]
+    fn test_gen_bool() {
+        let mut r = rng(105);
+        for _ in 0..5 {
+            assert_eq!(r.gen_bool(0.0), false);
+            assert_eq!(r.gen_bool(1.0), true);
+        }
+    }
+
+    #[test]
+    fn test_rng_trait_object() {
+        use crate::distributions::{Distribution, Standard};
+        let mut rng = rng(109);
+        let mut r = &mut rng as &mut dyn RngCore;
+        r.next_u32();
+        r.gen::<i32>();
+        assert_eq!(r.gen_range(0, 1), 0);
+        let _c: u8 = Standard.sample(&mut r);
+    }
+
+    #[test]
+    #[cfg(feature="alloc")]
+    fn test_rng_boxed_trait() {
+        use crate::distributions::{Distribution, Standard};
+        let rng = rng(110);
+        let mut r = Box::new(rng) as Box<dyn RngCore>;
+        r.next_u32();
+        r.gen::<i32>();
+        assert_eq!(r.gen_range(0, 1), 0);
+        let _c: u8 = Standard.sample(&mut r);
+    }
+
+    #[test]
+    #[cfg(feature="std")]
+    fn test_random() {
+        // not sure how to test this aside from just getting some values
+        let _n : usize = random();
+        let _f : f32 = random();
+        let _o : Option<Option<i8>> = random();
+        let _many : ((),
+                     (usize,
+                      isize,
+                      Option<(u32, (bool,))>),
+                     (u8, i8, u16, i16, u32, i32, u64, i64),
+                     (f32, (f64, (f64,)))) = random();
+    }
+
+    #[test]
+    #[cfg(not(miri))] // Miri is too slow
+    fn test_gen_ratio_average() {
+        const NUM: u32 = 3;
+        const DENOM: u32 = 10;
+        const N: u32 = 100_000;
+
+        let mut sum: u32 = 0;
+        let mut rng = rng(111);
+        for _ in 0..N {
+            if rng.gen_ratio(NUM, DENOM) {
+                sum += 1;
+            }
+        }
+        // Have Binomial(N, NUM/DENOM) distribution
+        let expected = (NUM * N) / DENOM;   // exact integer
+        assert!(((sum - expected) as i32).abs() < 500);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/prelude.rs.html b/target/doc/src/rand/prelude.rs.html new file mode 100644 index 0000000..6a27bc2 --- /dev/null +++ b/target/doc/src/rand/prelude.rs.html @@ -0,0 +1,59 @@ +prelude.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Convenience re-export of common members
+//!
+//! Like the standard library's prelude, this module simplifies importing of
+//! common items. Unlike the standard prelude, the contents of this module must
+//! be imported manually:
+//!
+//! ```
+//! use rand::prelude::*;
+//! # let mut r = StdRng::from_rng(thread_rng()).unwrap();
+//! # let _: f32 = r.gen();
+//! ```
+
+#[doc(no_inline)] pub use crate::distributions::Distribution;
+#[doc(no_inline)] pub use crate::rngs::StdRng;
+#[cfg(feature="small_rng")]
+#[doc(no_inline)] pub use crate::rngs::SmallRng;
+#[doc(no_inline)] #[cfg(feature="std")] pub use crate::rngs::ThreadRng;
+#[doc(no_inline)] pub use crate::{Rng, RngCore, CryptoRng, SeedableRng};
+#[doc(no_inline)] #[cfg(feature="std")] pub use crate::{random, thread_rng};
+#[doc(no_inline)] pub use crate::seq::{SliceRandom, IteratorRandom};
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/rngs/adapter/mod.rs.html b/target/doc/src/rand/rngs/adapter/mod.rs.html new file mode 100644 index 0000000..2fbef42 --- /dev/null +++ b/target/doc/src/rand/rngs/adapter/mod.rs.html @@ -0,0 +1,33 @@ +mod.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Wrappers / adapters forming RNGs
+
+#[cfg(feature="std")] mod read;
+mod reseeding;
+
+#[cfg(feature="std")] pub use self::read::{ReadRng, ReadError};
+pub use self::reseeding::ReseedingRng;
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/rngs/adapter/read.rs.html b/target/doc/src/rand/rngs/adapter/read.rs.html new file mode 100644 index 0000000..b37e397 --- /dev/null +++ b/target/doc/src/rand/rngs/adapter/read.rs.html @@ -0,0 +1,299 @@ +read.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+
+// Copyright 2018 Developers of the Rand project.
+// Copyright 2013 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! A wrapper around any Read to treat it as an RNG.
+
+use std::io::Read;
+use std::fmt;
+
+use rand_core::{RngCore, Error, impls};
+
+
+/// An RNG that reads random bytes straight from any type supporting
+/// [`std::io::Read`], for example files.
+///
+/// This will work best with an infinite reader, but that is not required.
+///
+/// This can be used with `/dev/urandom` on Unix but it is recommended to use
+/// [`OsRng`] instead.
+///
+/// # Panics
+///
+/// `ReadRng` uses [`std::io::Read::read_exact`], which retries on interrupts.
+/// All other errors from the underlying reader, including when it does not
+/// have enough data, will only be reported through [`try_fill_bytes`].
+/// The other [`RngCore`] methods will panic in case of an error.
+///
+/// # Example
+///
+/// ```
+/// use rand::Rng;
+/// use rand::rngs::adapter::ReadRng;
+///
+/// let data = vec![1, 2, 3, 4, 5, 6, 7, 8];
+/// let mut rng = ReadRng::new(&data[..]);
+/// println!("{:x}", rng.gen::<u32>());
+/// ```
+///
+/// [`OsRng`]: crate::rngs::OsRng
+/// [`try_fill_bytes`]: RngCore::try_fill_bytes
+#[derive(Debug)]
+pub struct ReadRng<R> {
+    reader: R
+}
+
+impl<R: Read> ReadRng<R> {
+    /// Create a new `ReadRng` from a `Read`.
+    pub fn new(r: R) -> ReadRng<R> {
+        ReadRng {
+            reader: r
+        }
+    }
+}
+
+impl<R: Read> RngCore for ReadRng<R> {
+    fn next_u32(&mut self) -> u32 {
+        impls::next_u32_via_fill(self)
+    }
+
+    fn next_u64(&mut self) -> u64 {
+        impls::next_u64_via_fill(self)
+    }
+
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        self.try_fill_bytes(dest).unwrap_or_else(|err|
+                panic!("reading random bytes from Read implementation failed; error: {}", err));
+    }
+
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        if dest.len() == 0 { return Ok(()); }
+        // Use `std::io::read_exact`, which retries on `ErrorKind::Interrupted`.
+        self.reader.read_exact(dest).map_err(|e| Error::new(ReadError(e)))
+    }
+}
+
+/// `ReadRng` error type
+#[derive(Debug)]
+pub struct ReadError(std::io::Error);
+
+impl fmt::Display for ReadError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "ReadError: {}", self.0)
+    }
+}
+
+impl std::error::Error for ReadError {
+    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+        Some(&self.0)
+    }
+}
+
+
+#[cfg(test)]
+mod test {
+    use super::ReadRng;
+    use crate::RngCore;
+
+    #[test]
+    fn test_reader_rng_u64() {
+        // transmute from the target to avoid endianness concerns.
+        let v = vec![0u8, 0, 0, 0, 0, 0, 0, 1,
+                     0  , 0, 0, 0, 0, 0, 0, 2,
+                     0,   0, 0, 0, 0, 0, 0, 3];
+        let mut rng = ReadRng::new(&v[..]);
+
+        assert_eq!(rng.next_u64(), 1_u64.to_be());
+        assert_eq!(rng.next_u64(), 2_u64.to_be());
+        assert_eq!(rng.next_u64(), 3_u64.to_be());
+    }
+
+    #[test]
+    fn test_reader_rng_u32() {
+        let v = vec![0u8, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3];
+        let mut rng = ReadRng::new(&v[..]);
+
+        assert_eq!(rng.next_u32(), 1_u32.to_be());
+        assert_eq!(rng.next_u32(), 2_u32.to_be());
+        assert_eq!(rng.next_u32(), 3_u32.to_be());
+    }
+
+    #[test]
+    fn test_reader_rng_fill_bytes() {
+        let v = [1u8, 2, 3, 4, 5, 6, 7, 8];
+        let mut w = [0u8; 8];
+
+        let mut rng = ReadRng::new(&v[..]);
+        rng.fill_bytes(&mut w);
+
+        assert!(v == w);
+    }
+
+    #[test]
+    fn test_reader_rng_insufficient_bytes() {
+        let v = [1u8, 2, 3, 4, 5, 6, 7, 8];
+        let mut w = [0u8; 9];
+
+        let mut rng = ReadRng::new(&v[..]);
+
+        let result = rng.try_fill_bytes(&mut w);
+        assert!(result.is_err());
+        println!("Error: {}", result.unwrap_err());
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/rngs/adapter/reseeding.rs.html b/target/doc/src/rand/rngs/adapter/reseeding.rs.html new file mode 100644 index 0000000..bcf5275 --- /dev/null +++ b/target/doc/src/rand/rngs/adapter/reseeding.rs.html @@ -0,0 +1,715 @@ +reseeding.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+
+// Copyright 2018 Developers of the Rand project.
+// Copyright 2013 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! A wrapper around another PRNG that reseeds it after it
+//! generates a certain number of random bytes.
+
+use core::mem::size_of;
+
+use rand_core::{RngCore, CryptoRng, SeedableRng, Error};
+use rand_core::block::{BlockRngCore, BlockRng};
+
+/// A wrapper around any PRNG that implements [`BlockRngCore`], that adds the
+/// ability to reseed it.
+///
+/// `ReseedingRng` reseeds the underlying PRNG in the following cases:
+///
+/// - On a manual call to [`reseed()`].
+/// - After `clone()`, the clone will be reseeded on first use.
+/// - After a process is forked, the RNG in the child process is reseeded within
+///   the next few generated values, depending on the block size of the
+///   underlying PRNG. For ChaCha and Hc128 this is a maximum of
+///   15 `u32` values before reseeding.
+/// - After the PRNG has generated a configurable number of random bytes.
+///
+/// # When should reseeding after a fixed number of generated bytes be used?
+///
+/// Reseeding after a fixed number of generated bytes is never strictly
+/// *necessary*. Cryptographic PRNGs don't have a limited number of bytes they
+/// can output, or at least not a limit reachable in any practical way. There is
+/// no such thing as 'running out of entropy'.
+///
+/// Occasionally reseeding can be seen as some form of 'security in depth'. Even
+/// if in the future a cryptographic weakness is found in the CSPRNG being used,
+/// or a flaw in the implementation, occasionally reseeding should make
+/// exploiting it much more difficult or even impossible.
+///
+/// Use [`ReseedingRng::new`] with a `threshold` of `0` to disable reseeding
+/// after a fixed number of generated bytes.
+///
+/// # Error handling
+///
+/// Although unlikely, reseeding the wrapped PRNG can fail. `ReseedingRng` will
+/// never panic but try to handle the error intelligently through some
+/// combination of retrying and delaying reseeding until later.
+/// If handling the source error fails `ReseedingRng` will continue generating
+/// data from the wrapped PRNG without reseeding.
+///
+/// Manually calling [`reseed()`] will not have this retry or delay logic, but
+/// reports the error.
+///
+/// # Example
+///
+/// ```
+/// use rand::prelude::*;
+/// use rand_chacha::ChaCha20Core; // Internal part of ChaChaRng that
+///                              // implements BlockRngCore
+/// use rand::rngs::OsRng;
+/// use rand::rngs::adapter::ReseedingRng;
+///
+/// let prng = ChaCha20Core::from_entropy();
+/// let mut reseeding_rng = ReseedingRng::new(prng, 0, OsRng);
+///
+/// println!("{}", reseeding_rng.gen::<u64>());
+///
+/// let mut cloned_rng = reseeding_rng.clone();
+/// assert!(reseeding_rng.gen::<u64>() != cloned_rng.gen::<u64>());
+/// ```
+///
+/// [`BlockRngCore`]: rand_core::block::BlockRngCore
+/// [`ReseedingRng::new`]: ReseedingRng::new
+/// [`reseed()`]: ReseedingRng::reseed
+#[derive(Debug)]
+pub struct ReseedingRng<R, Rsdr>(BlockRng<ReseedingCore<R, Rsdr>>)
+where R: BlockRngCore + SeedableRng,
+      Rsdr: RngCore;
+
+impl<R, Rsdr> ReseedingRng<R, Rsdr>
+where R: BlockRngCore + SeedableRng,
+      Rsdr: RngCore
+{
+    /// Create a new `ReseedingRng` from an existing PRNG, combined with a RNG
+    /// to use as reseeder.
+    ///
+    /// `threshold` sets the number of generated bytes after which to reseed the
+    /// PRNG. Set it to zero to never reseed based on the number of generated
+    /// values.
+    pub fn new(rng: R, threshold: u64, reseeder: Rsdr) -> Self {
+        ReseedingRng(BlockRng::new(ReseedingCore::new(rng, threshold, reseeder)))
+    }
+
+    /// Reseed the internal PRNG.
+    pub fn reseed(&mut self) -> Result<(), Error> {
+        self.0.core.reseed()
+    }
+}
+
+// TODO: this should be implemented for any type where the inner type
+// implements RngCore, but we can't specify that because ReseedingCore is private
+impl<R, Rsdr: RngCore> RngCore for ReseedingRng<R, Rsdr>
+where R: BlockRngCore<Item = u32> + SeedableRng,
+    <R as BlockRngCore>::Results: AsRef<[u32]> + AsMut<[u32]>
+{
+    #[inline(always)]
+    fn next_u32(&mut self) -> u32 {
+        self.0.next_u32()
+    }
+
+    #[inline(always)]
+    fn next_u64(&mut self) -> u64 {
+        self.0.next_u64()
+    }
+
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        self.0.fill_bytes(dest)
+    }
+
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        self.0.try_fill_bytes(dest)
+    }
+}
+
+impl<R, Rsdr> Clone for ReseedingRng<R, Rsdr>
+where R: BlockRngCore + SeedableRng + Clone,
+      Rsdr: RngCore + Clone
+{
+    fn clone(&self) -> ReseedingRng<R, Rsdr> {
+        // Recreating `BlockRng` seems easier than cloning it and resetting
+        // the index.
+        ReseedingRng(BlockRng::new(self.0.core.clone()))
+    }
+}
+
+impl<R, Rsdr> CryptoRng for ReseedingRng<R, Rsdr>
+where R: BlockRngCore + SeedableRng + CryptoRng,
+      Rsdr: RngCore + CryptoRng {}
+
+#[derive(Debug)]
+struct ReseedingCore<R, Rsdr> {
+    inner: R,
+    reseeder: Rsdr,
+    threshold: i64,
+    bytes_until_reseed: i64,
+    fork_counter: usize,
+}
+
+impl<R, Rsdr> BlockRngCore for ReseedingCore<R, Rsdr>
+where R: BlockRngCore + SeedableRng,
+      Rsdr: RngCore
+{
+    type Item = <R as BlockRngCore>::Item;
+    type Results = <R as BlockRngCore>::Results;
+
+    fn generate(&mut self, results: &mut Self::Results) {
+        let global_fork_counter = fork::get_fork_counter();
+        if self.bytes_until_reseed <= 0 ||
+           self.is_forked(global_fork_counter) {
+            // We get better performance by not calling only `reseed` here
+            // and continuing with the rest of the function, but by directly
+            // returning from a non-inlined function.
+            return self.reseed_and_generate(results, global_fork_counter);
+        }
+        let num_bytes = results.as_ref().len() * size_of::<Self::Item>();
+        self.bytes_until_reseed -= num_bytes as i64;
+        self.inner.generate(results);
+    }
+}
+
+impl<R, Rsdr> ReseedingCore<R, Rsdr>
+where R: BlockRngCore + SeedableRng,
+      Rsdr: RngCore
+{
+    /// Create a new `ReseedingCore`.
+    fn new(rng: R, threshold: u64, reseeder: Rsdr) -> Self {
+        use ::core::i64::MAX;
+        fork::register_fork_handler();
+
+        // Because generating more values than `i64::MAX` takes centuries on
+        // current hardware, we just clamp to that value.
+        // Also we set a threshold of 0, which indicates no limit, to that
+        // value.
+        let threshold =
+            if threshold == 0 { MAX }
+            else if threshold <= MAX as u64 { threshold as i64 }
+            else { MAX };
+
+        ReseedingCore {
+            inner: rng,
+            reseeder,
+            threshold: threshold as i64,
+            bytes_until_reseed: threshold as i64,
+            fork_counter: 0,
+        }
+    }
+
+    /// Reseed the internal PRNG.
+    fn reseed(&mut self) -> Result<(), Error> {
+        R::from_rng(&mut self.reseeder).map(|result| {
+            self.bytes_until_reseed = self.threshold;
+            self.inner = result
+        })
+    }
+
+    fn is_forked(&self, global_fork_counter: usize) -> bool {
+        // In theory, on 32-bit platforms, it is possible for
+        // `global_fork_counter` to wrap around after ~4e9 forks.
+        //
+        // This check will detect a fork in the normal case where
+        // `fork_counter < global_fork_counter`, and also when the difference
+        // between both is greater than `isize::MAX` (wrapped around).
+        //
+        // It will still fail to detect a fork if there have been more than
+        // `isize::MAX` forks, without any reseed in between. Seems unlikely
+        // enough.
+        (self.fork_counter.wrapping_sub(global_fork_counter) as isize) < 0
+    }
+
+    #[inline(never)]
+    fn reseed_and_generate(&mut self,
+                           results: &mut <Self as BlockRngCore>::Results,
+                           global_fork_counter: usize)
+    {
+        if self.is_forked(global_fork_counter) {
+            info!("Fork detected, reseeding RNG");
+        } else {
+            trace!("Reseeding RNG (periodic reseed)");
+        }
+
+        let num_bytes =
+            results.as_ref().len() * size_of::<<R as BlockRngCore>::Item>();
+
+        if let Err(e) = self.reseed() {
+            warn!("Reseeding RNG failed: {}", e);
+            let _ = e;
+        }
+        self.fork_counter = global_fork_counter;
+
+        self.bytes_until_reseed = self.threshold - num_bytes as i64;
+        self.inner.generate(results);
+    }
+}
+
+impl<R, Rsdr> Clone for ReseedingCore<R, Rsdr>
+where R: BlockRngCore + SeedableRng + Clone,
+      Rsdr: RngCore + Clone
+{
+    fn clone(&self) -> ReseedingCore<R, Rsdr> {
+        ReseedingCore {
+            inner: self.inner.clone(),
+            reseeder: self.reseeder.clone(),
+            threshold: self.threshold,
+            bytes_until_reseed: 0, // reseed clone on first use
+            fork_counter: self.fork_counter,
+        }
+    }
+}
+
+impl<R, Rsdr> CryptoRng for ReseedingCore<R, Rsdr>
+where R: BlockRngCore + SeedableRng + CryptoRng,
+      Rsdr: RngCore + CryptoRng {}
+
+
+#[cfg(all(unix, not(target_os="emscripten")))]
+mod fork {
+    use core::sync::atomic::{AtomicUsize, AtomicBool, Ordering};
+    #[allow(deprecated)]  // Required for compatibility with Rust < 1.24.
+    use core::sync::atomic::{ATOMIC_USIZE_INIT, ATOMIC_BOOL_INIT};
+
+    // Fork protection
+    //
+    // We implement fork protection on Unix using `pthread_atfork`.
+    // When the process is forked, we increment `RESEEDING_RNG_FORK_COUNTER`.
+    // Every `ReseedingRng` stores the last known value of the static in
+    // `fork_counter`. If the cached `fork_counter` is less than
+    // `RESEEDING_RNG_FORK_COUNTER`, it is time to reseed this RNG.
+    //
+    // If reseeding fails, we don't deal with this by setting a delay, but just
+    // don't update `fork_counter`, so a reseed is attempted as soon as
+    // possible.
+
+    #[allow(deprecated)]
+    static RESEEDING_RNG_FORK_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;
+
+    pub fn get_fork_counter() -> usize {
+        RESEEDING_RNG_FORK_COUNTER.load(Ordering::Relaxed)
+    }
+
+    #[allow(deprecated)]
+    static FORK_HANDLER_REGISTERED: AtomicBool = ATOMIC_BOOL_INIT;
+
+    extern fn fork_handler() {
+        // Note: fetch_add is defined to wrap on overflow
+        // (which is what we want).
+        RESEEDING_RNG_FORK_COUNTER.fetch_add(1, Ordering::Relaxed);
+    }
+
+    pub fn register_fork_handler() {
+        if FORK_HANDLER_REGISTERED.load(Ordering::Relaxed) == false {
+            unsafe { libc::pthread_atfork(None, None, Some(fork_handler)) };
+            FORK_HANDLER_REGISTERED.store(true, Ordering::Relaxed);
+        }
+    }
+}
+
+#[cfg(not(all(unix, not(target_os="emscripten"))))]
+mod fork {
+    pub fn get_fork_counter() -> usize { 0 }
+    pub fn register_fork_handler() {}
+}
+
+
+#[cfg(test)]
+mod test {
+    use crate::{Rng, SeedableRng};
+    use crate::rngs::std::Core;
+    use crate::rngs::mock::StepRng;
+    use super::ReseedingRng;
+
+    #[test]
+    fn test_reseeding() {
+        let mut zero = StepRng::new(0, 0);
+        let rng = Core::from_rng(&mut zero).unwrap();
+        let thresh = 1; // reseed every time the buffer is exhausted
+        let mut reseeding = ReseedingRng::new(rng, thresh, zero);
+
+        // RNG buffer size is [u32; 64]
+        // Debug is only implemented up to length 32 so use two arrays
+        let mut buf = ([0u32; 32], [0u32; 32]);
+        reseeding.fill(&mut buf.0);
+        reseeding.fill(&mut buf.1);
+        let seq = buf;
+        for _ in 0..10 {
+            reseeding.fill(&mut buf.0);
+            reseeding.fill(&mut buf.1);
+            assert_eq!(buf, seq);
+        }
+    }
+
+    #[test]
+    fn test_clone_reseeding() {
+        let mut zero = StepRng::new(0, 0);
+        let rng = Core::from_rng(&mut zero).unwrap();
+        let mut rng1 = ReseedingRng::new(rng, 32*4, zero);
+
+        let first: u32 = rng1.gen();
+        for _ in 0..10 { let _ = rng1.gen::<u32>(); }
+
+        let mut rng2 = rng1.clone();
+        assert_eq!(first, rng2.gen::<u32>());
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/rngs/entropy.rs.html b/target/doc/src/rand/rngs/entropy.rs.html new file mode 100644 index 0000000..2128d77 --- /dev/null +++ b/target/doc/src/rand/rngs/entropy.rs.html @@ -0,0 +1,157 @@ +entropy.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Entropy generator, or wrapper around external generators
+
+#![allow(deprecated)]   // whole module is deprecated
+
+use rand_core::{RngCore, CryptoRng, Error};
+#[allow(unused)]
+use crate::rngs::OsRng;
+
+/// An interface returning random data from external source(s), provided
+/// specifically for securely seeding algorithmic generators (PRNGs).
+///
+/// This is deprecated. It is suggested you use [`rngs::OsRng`] instead.
+/// 
+/// [`rngs::OsRng`]: crate::rngs::OsRng
+#[derive(Debug)]
+#[deprecated(since="0.7.0", note="use rngs::OsRng instead")]
+pub struct EntropyRng {
+    source: OsRng,
+}
+
+impl EntropyRng {
+    /// Create a new `EntropyRng`.
+    ///
+    /// This method will do no system calls or other initialization routines,
+    /// those are done on first use. This is done to make `new` infallible,
+    /// and `try_fill_bytes` the only place to report errors.
+    pub fn new() -> Self {
+        EntropyRng { source: OsRng }
+    }
+}
+
+impl Default for EntropyRng {
+    fn default() -> Self {
+        EntropyRng::new()
+    }
+}
+
+impl RngCore for EntropyRng {
+    fn next_u32(&mut self) -> u32 {
+        self.source.next_u32()
+    }
+
+    fn next_u64(&mut self) -> u64 {
+        self.source.next_u64()
+    }
+
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        self.source.fill_bytes(dest)
+    }
+
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        self.source.try_fill_bytes(dest)
+    }
+}
+
+impl CryptoRng for EntropyRng {}
+
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[test]
+    fn test_entropy() {
+        let mut rng = EntropyRng::new();
+        let n = (rng.next_u32() ^ rng.next_u32()).count_ones();
+        assert!(n >= 2);    // p(failure) approx 1e-7
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/rngs/mock.rs.html b/target/doc/src/rand/rngs/mock.rs.html new file mode 100644 index 0000000..c50cd12 --- /dev/null +++ b/target/doc/src/rand/rngs/mock.rs.html @@ -0,0 +1,129 @@ +mock.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Mock random number generator
+
+use rand_core::{RngCore, Error, impls};
+
+/// A simple implementation of `RngCore` for testing purposes.
+/// 
+/// This generates an arithmetic sequence (i.e. adds a constant each step)
+/// over a `u64` number, using wrapping arithmetic. If the increment is 0
+/// the generator yields a constant.
+/// 
+/// ```
+/// use rand::Rng;
+/// use rand::rngs::mock::StepRng;
+/// 
+/// let mut my_rng = StepRng::new(2, 1);
+/// let sample: [u64; 3] = my_rng.gen();
+/// assert_eq!(sample, [2, 3, 4]);
+/// ```
+#[derive(Debug, Clone)]
+pub struct StepRng {
+    v: u64,
+    a: u64,
+}
+
+impl StepRng {
+    /// Create a `StepRng`, yielding an arithmetic sequence starting with
+    /// `initial` and incremented by `increment` each time.
+    pub fn new(initial: u64, increment: u64) -> Self {
+        StepRng { v: initial, a: increment }
+    }
+}
+
+impl RngCore for StepRng {
+    #[inline]
+    fn next_u32(&mut self) -> u32 {
+        self.next_u64() as u32
+    }
+
+    #[inline]
+    fn next_u64(&mut self) -> u64 {
+        let result = self.v;
+        self.v = self.v.wrapping_add(self.a);
+        result
+    }
+
+    #[inline]
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        impls::fill_bytes_via_next(self, dest);
+    }
+
+    #[inline]
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        Ok(self.fill_bytes(dest))
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/rngs/mod.rs.html b/target/doc/src/rand/rngs/mod.rs.html new file mode 100644 index 0000000..b70ce76 --- /dev/null +++ b/target/doc/src/rand/rngs/mod.rs.html @@ -0,0 +1,243 @@ +mod.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Random number generators and adapters
+//!
+//! ## Background: Random number generators (RNGs)
+//!
+//! Computers cannot produce random numbers from nowhere. We classify
+//! random number generators as follows:
+//!
+//! -   "True" random number generators (TRNGs) use hard-to-predict data sources
+//!     (e.g. the high-resolution parts of event timings and sensor jitter) to
+//!     harvest random bit-sequences, apply algorithms to remove bias and
+//!     estimate available entropy, then combine these bits into a byte-sequence
+//!     or an entropy pool. This job is usually done by the operating system or
+//!     a hardware generator (HRNG).
+//! -   "Pseudo"-random number generators (PRNGs) use algorithms to transform a
+//!     seed into a sequence of pseudo-random numbers. These generators can be
+//!     fast and produce well-distributed unpredictable random numbers (or not).
+//!     They are usually deterministic: given algorithm and seed, the output
+//!     sequence can be reproduced. They have finite period and eventually loop;
+//!     with many algorithms this period is fixed and can be proven sufficiently
+//!     long, while others are chaotic and the period depends on the seed.
+//! -   "Cryptographically secure" pseudo-random number generators (CSPRNGs)
+//!     are the sub-set of PRNGs which are secure. Security of the generator
+//!     relies both on hiding the internal state and using a strong algorithm.
+//!
+//! ## Traits and functionality
+//!
+//! All RNGs implement the [`RngCore`] trait, as a consequence of which the
+//! [`Rng`] extension trait is automatically implemented. Secure RNGs may
+//! additionally implement the [`CryptoRng`] trait.
+//!
+//! All PRNGs require a seed to produce their random number sequence. The
+//! [`SeedableRng`] trait provides three ways of constructing PRNGs:
+//!
+//! -   `from_seed` accepts a type specific to the PRNG
+//! -   `from_rng` allows a PRNG to be seeded from any other RNG
+//! -   `seed_from_u64` allows any PRNG to be seeded from a `u64` insecurely
+//! -   `from_entropy` securely seeds a PRNG from fresh entropy
+//!
+//! Use the [`rand_core`] crate when implementing your own RNGs.
+//!
+//! ## Our generators
+//!
+//! This crate provides several random number generators:
+//!
+//! -   [`OsRng`] is an interface to the operating system's random number
+//!     source. Typically the operating system uses a CSPRNG with entropy
+//!     provided by a TRNG and some type of on-going re-seeding.
+//! -   [`ThreadRng`], provided by the [`thread_rng`] function, is a handle to a
+//!     thread-local CSPRNG with periodic seeding from [`OsRng`]. Because this
+//!     is local, it is typically much faster than [`OsRng`]. It should be
+//!     secure, though the paranoid may prefer [`OsRng`].
+//! -   [`StdRng`] is a CSPRNG chosen for good performance and trust of security
+//!     (based on reviews, maturity and usage). The current algorithm is ChaCha20,
+//!     which is well established and rigorously analysed.
+//!     [`StdRng`] provides the algorithm used by [`ThreadRng`] but without
+//!     periodic reseeding.
+//! -   [`SmallRng`] is an **insecure** PRNG designed to be fast, simple, require
+//!     little memory, and have good output quality.
+//!
+//! The algorithms selected for [`StdRng`] and [`SmallRng`] may change in any
+//! release and may be platform-dependent, therefore they should be considered
+//! **not reproducible**.
+//!
+//! ## Additional generators
+//!
+//! **TRNGs**: The [`rdrand`] crate provides an interface to the RDRAND and
+//! RDSEED instructions available in modern Intel and AMD CPUs.
+//! The [`rand_jitter`] crate provides a user-space implementation of
+//! entropy harvesting from CPU timer jitter, but is very slow and has
+//! [security issues](https://github.com/rust-random/rand/issues/699).
+//!
+//! **PRNGs**: Several companion crates are available, providing individual or
+//! families of PRNG algorithms. These provide the implementations behind
+//! [`StdRng`] and [`SmallRng`] but can also be used directly, indeed *should*
+//! be used directly when **reproducibility** matters.
+//! Some suggestions are: [`rand_chacha`], [`rand_pcg`], [`rand_xoshiro`].
+//! A full list can be found by searching for crates with the [`rng` tag].
+//!
+//! [`SmallRng`]: rngs::SmallRng
+//! [`StdRng`]: rngs::StdRng
+//! [`OsRng`]: rngs::OsRng
+//! [`ThreadRng`]: rngs::ThreadRng
+//! [`mock::StepRng`]: rngs::mock::StepRng
+//! [`adapter::ReadRng`]: rngs::adapter::ReadRng
+//! [`adapter::ReseedingRng`]: rngs::adapter::ReseedingRng
+//! [`rdrand`]: https://crates.io/crates/rdrand
+//! [`rand_jitter`]: https://crates.io/crates/rand_jitter
+//! [`rand_chacha`]: https://crates.io/crates/rand_chacha
+//! [`rand_pcg`]: https://crates.io/crates/rand_pcg
+//! [`rand_xoshiro`]: https://crates.io/crates/rand_xoshiro
+//! [`rng` tag]: https://crates.io/keywords/rng
+
+pub mod adapter;
+
+#[cfg(feature="std")] mod entropy;
+pub mod mock;   // Public so we don't export `StepRng` directly, making it a bit
+                // more clear it is intended for testing.
+#[cfg(feature="small_rng")]
+mod small;
+mod std;
+#[cfg(feature="std")] pub(crate) mod thread;
+
+#[allow(deprecated)]
+#[cfg(feature="std")] pub use self::entropy::EntropyRng;
+
+#[cfg(feature="small_rng")]
+pub use self::small::SmallRng;
+pub use self::std::StdRng;
+#[cfg(feature="std")] pub use self::thread::ThreadRng;
+
+#[cfg(feature="getrandom")] mod os;
+#[cfg(feature="getrandom")] pub use self::os::OsRng;
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/rngs/os.rs.html b/target/doc/src/rand/rngs/os.rs.html new file mode 100644 index 0000000..2acdd85 --- /dev/null +++ b/target/doc/src/rand/rngs/os.rs.html @@ -0,0 +1,193 @@ +os.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+
+// Copyright 2019 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Interface to the random number generator of the operating system.
+// Note: keep this code in sync with the rand_os crate!
+
+use crate::getrandom::getrandom;
+use rand_core::{CryptoRng, RngCore, Error, impls};
+
+/// A random number generator that retrieves randomness from from the
+/// operating system.
+///
+/// This is a zero-sized struct. It can be freely constructed with `OsRng`.
+///
+/// The implementation is provided by the [getrandom] crate. Refer to
+/// [getrandom] documentation for details.
+///
+/// # Blocking and error handling
+///
+/// It is possible that when used during early boot the first call to `OsRng`
+/// will block until the system's RNG is initialised. It is also possible
+/// (though highly unlikely) for `OsRng` to fail on some platforms, most
+/// likely due to system mis-configuration.
+///
+/// After the first successful call, it is highly unlikely that failures or
+/// significant delays will occur (although performance should be expected to
+/// be much slower than a user-space PRNG).
+///
+/// # Usage example
+/// ```
+/// use rand::rngs::{StdRng, OsRng};
+/// use rand::{RngCore, SeedableRng};
+///
+/// let mut key = [0u8; 16];
+/// OsRng.fill_bytes(&mut key);
+/// let random_u64 = OsRng.next_u64();
+/// 
+/// // OsRng is especially useful for seeding other RNGs (see also from_entropy)
+/// let mut rng = StdRng::from_rng(OsRng).unwrap();
+/// let _ = rng.next_u32();
+/// ```
+///
+/// [getrandom]: https://crates.io/crates/getrandom
+#[derive(Clone, Copy, Debug, Default)]
+pub struct OsRng;
+
+impl OsRng {
+    /// Create a new `OsRng`.
+    #[deprecated(since="0.7.0", note="replace OsRng::new().unwrap() with just OsRng")]
+    pub fn new() -> Result<OsRng, Error> {
+        Ok(OsRng)
+    }
+}
+
+impl CryptoRng for OsRng {}
+
+impl RngCore for OsRng {
+    fn next_u32(&mut self) -> u32 {
+        impls::next_u32_via_fill(self)
+    }
+
+    fn next_u64(&mut self) -> u64 {
+        impls::next_u64_via_fill(self)
+    }
+
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        if let Err(e) = self.try_fill_bytes(dest) {
+            panic!("Error: {}", e);
+        }
+    }
+
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        getrandom(dest)?;
+        Ok(())
+    }
+}
+
+#[test]
+fn test_os_rng() {
+    let x = OsRng.next_u64();
+    let y = OsRng.next_u64();
+    assert!(x != 0);
+    assert!(x != y);
+}
+
+#[test]
+fn test_construction() {
+    let mut rng = OsRng::default();
+    assert!(rng.next_u64() != 0);
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/rngs/std.rs.html b/target/doc/src/rand/rngs/std.rs.html new file mode 100644 index 0000000..cab4c93 --- /dev/null +++ b/target/doc/src/rand/rngs/std.rs.html @@ -0,0 +1,203 @@ +std.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The standard RNG
+
+use crate::{RngCore, CryptoRng, Error, SeedableRng};
+
+#[cfg(target_os = "emscripten")] pub(crate) use rand_hc::Hc128Core as Core;
+#[cfg(not(target_os = "emscripten"))] pub(crate) use rand_chacha::ChaCha20Core as Core;
+#[cfg(target_os = "emscripten")] use rand_hc::Hc128Rng as Rng;
+#[cfg(not(target_os = "emscripten"))] use rand_chacha::ChaCha20Rng as Rng;
+
+/// The standard RNG. The PRNG algorithm in `StdRng` is chosen to be efficient
+/// on the current platform, to be statistically strong and unpredictable
+/// (meaning a cryptographically secure PRNG).
+///
+/// The current algorithm used is the ChaCha block cipher with either 20 or 12
+/// rounds (see the `stdrng_*` feature flags, documented in the README).
+/// This may change as new evidence of cipher security and performance
+/// becomes available.
+///
+/// The algorithm is deterministic but should not be considered reproducible
+/// due to dependence on configuration and possible replacement in future
+/// library versions. For a secure reproducible generator, we recommend use of
+/// the [rand_chacha] crate directly.
+///
+/// [rand_chacha]: https://crates.io/crates/rand_chacha
+#[derive(Clone, Debug)]
+pub struct StdRng(Rng);
+
+impl RngCore for StdRng {
+    #[inline(always)]
+    fn next_u32(&mut self) -> u32 {
+        self.0.next_u32()
+    }
+
+    #[inline(always)]
+    fn next_u64(&mut self) -> u64 {
+        self.0.next_u64()
+    }
+
+    #[inline(always)]
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        self.0.fill_bytes(dest);
+    }
+
+    #[inline(always)]
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        self.0.try_fill_bytes(dest)
+    }
+}
+
+impl SeedableRng for StdRng {
+    type Seed = <Rng as SeedableRng>::Seed;
+
+    #[inline(always)]
+    fn from_seed(seed: Self::Seed) -> Self {
+        StdRng(Rng::from_seed(seed))
+    }
+
+    #[inline(always)]
+    fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error> {
+        Rng::from_rng(rng).map(StdRng)
+    }
+}
+
+impl CryptoRng for StdRng {}
+
+
+#[cfg(test)]
+mod test {
+    use crate::{RngCore, SeedableRng};
+    use crate::rngs::StdRng;
+
+    #[test]
+    fn test_stdrng_construction() {
+        // Test value-stability of StdRng. This is expected to break any time
+        // the algorithm is changed.
+        let seed = [1,0,0,0, 23,0,0,0, 200,1,0,0, 210,30,0,0,
+                    0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
+
+        #[cfg(any(feature="stdrng_strong", not(feature="stdrng_fast")))]
+        let target = [3950704604716924505, 5573172343717151650];
+        #[cfg(all(not(feature="stdrng_strong"), feature="stdrng_fast"))]
+        let target = [10719222850664546238, 14064965282130556830];
+        
+        let mut rng0 = StdRng::from_seed(seed);
+        let x0 = rng0.next_u64();
+
+        let mut rng1 = StdRng::from_rng(rng0).unwrap();
+        let x1 = rng1.next_u64();
+
+        assert_eq!([x0, x1], target);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/rngs/thread.rs.html b/target/doc/src/rand/rngs/thread.rs.html new file mode 100644 index 0000000..631368d --- /dev/null +++ b/target/doc/src/rand/rngs/thread.rs.html @@ -0,0 +1,251 @@ +thread.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Thread-local random number generator
+
+use std::cell::UnsafeCell;
+use std::ptr::NonNull;
+
+use crate::{RngCore, CryptoRng, SeedableRng, Error};
+use crate::rngs::adapter::ReseedingRng;
+use crate::rngs::OsRng;
+use super::std::Core;
+
+// Rationale for using `UnsafeCell` in `ThreadRng`:
+//
+// Previously we used a `RefCell`, with an overhead of ~15%. There will only
+// ever be one mutable reference to the interior of the `UnsafeCell`, because
+// we only have such a reference inside `next_u32`, `next_u64`, etc. Within a
+// single thread (which is the definition of `ThreadRng`), there will only ever
+// be one of these methods active at a time.
+//
+// A possible scenario where there could be multiple mutable references is if
+// `ThreadRng` is used inside `next_u32` and co. But the implementation is
+// completely under our control. We just have to ensure none of them use
+// `ThreadRng` internally, which is nonsensical anyway. We should also never run
+// `ThreadRng` in destructors of its implementation, which is also nonsensical.
+
+
+// Number of generated bytes after which to reseed `ThreadRng`.
+// According to benchmarks, reseeding has a noticable impact with thresholds
+// of 32 kB and less. We choose 64 kB to avoid significant overhead.
+const THREAD_RNG_RESEED_THRESHOLD: u64 = 1024 * 64;
+
+/// The type returned by [`thread_rng`], essentially just a reference to the
+/// PRNG in thread-local memory.
+///
+/// `ThreadRng` uses the same PRNG as [`StdRng`] for security and performance.
+/// As hinted by the name, the generator is thread-local. `ThreadRng` is a
+/// handle to this generator and thus supports `Copy`, but not `Send` or `Sync`.
+///
+/// Unlike `StdRng`, `ThreadRng` uses the  [`ReseedingRng`] wrapper to reseed
+/// the PRNG from fresh entropy every 64 kiB of random data.
+/// [`OsRng`] is used to provide seed data.
+///
+/// Note that the reseeding is done as an extra precaution against side-channel
+/// attacks and mis-use (e.g. if somehow weak entropy were supplied initially).
+/// The PRNG algorithms used are assumed to be secure.
+///
+/// [`ReseedingRng`]: crate::rngs::adapter::ReseedingRng
+/// [`StdRng`]: crate::rngs::StdRng
+#[derive(Copy, Clone, Debug)]
+pub struct ThreadRng {
+    // inner raw pointer implies type is neither Send nor Sync
+    rng: NonNull<ReseedingRng<Core, OsRng>>,
+}
+
+thread_local!(
+    static THREAD_RNG_KEY: UnsafeCell<ReseedingRng<Core, OsRng>> = {
+        let r = Core::from_rng(OsRng).unwrap_or_else(|err|
+                panic!("could not initialize thread_rng: {}", err));
+        let rng = ReseedingRng::new(r,
+                                    THREAD_RNG_RESEED_THRESHOLD,
+                                    OsRng);
+        UnsafeCell::new(rng)
+    }
+);
+
+/// Retrieve the lazily-initialized thread-local random number generator,
+/// seeded by the system. Intended to be used in method chaining style,
+/// e.g. `thread_rng().gen::<i32>()`, or cached locally, e.g.
+/// `let mut rng = thread_rng();`.  Invoked by the `Default` trait, making
+/// `ThreadRng::default()` equivalent.
+///
+/// For more information see [`ThreadRng`].
+pub fn thread_rng() -> ThreadRng {
+    let raw = THREAD_RNG_KEY.with(|t| t.get());
+    let nn = NonNull::new(raw).unwrap();
+    ThreadRng { rng: nn }
+}
+
+impl Default for ThreadRng {
+    fn default() -> ThreadRng {
+        crate::prelude::thread_rng()
+    }
+}
+
+impl RngCore for ThreadRng {
+    #[inline(always)]
+    fn next_u32(&mut self) -> u32 {
+        unsafe { self.rng.as_mut().next_u32() }
+    }
+
+    #[inline(always)]
+    fn next_u64(&mut self) -> u64 {
+        unsafe { self.rng.as_mut().next_u64() }
+    }
+
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        unsafe { self.rng.as_mut().fill_bytes(dest) }
+    }
+
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        unsafe { self.rng.as_mut().try_fill_bytes(dest) }
+    }
+}
+
+impl CryptoRng for ThreadRng {}
+
+
+#[cfg(test)]
+mod test {
+    #[test]
+    fn test_thread_rng() {
+        use crate::Rng;
+        let mut r = crate::thread_rng();
+        r.gen::<i32>();
+        assert_eq!(r.gen_range(0, 1), 0);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/seq/index.rs.html b/target/doc/src/rand/seq/index.rs.html new file mode 100644 index 0000000..3338b90 --- /dev/null +++ b/target/doc/src/rand/seq/index.rs.html @@ -0,0 +1,785 @@ +index.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Low-level API for sampling indices
+
+#[cfg(feature="alloc")] use core::slice;
+
+#[cfg(feature="std")] use std::vec;
+#[cfg(all(feature="alloc", not(feature="std")))] use crate::alloc::vec::{self, Vec};
+// BTreeMap is not as fast in tests, but better than nothing.
+#[cfg(feature="std")] use std::collections::{HashSet};
+#[cfg(all(feature="alloc", not(feature="std")))] use crate::alloc::collections::BTreeSet;
+
+#[cfg(feature="alloc")] use crate::distributions::{Distribution, Uniform, uniform::SampleUniform};
+use crate::Rng;
+
+/// A vector of indices.
+///
+/// Multiple internal representations are possible.
+#[derive(Clone, Debug)]
+pub enum IndexVec {
+    #[doc(hidden)] U32(Vec<u32>),
+    #[doc(hidden)] USize(Vec<usize>),
+}
+
+impl IndexVec {
+    /// Returns the number of indices
+    pub fn len(&self) -> usize {
+        match self {
+            &IndexVec::U32(ref v) => v.len(),
+            &IndexVec::USize(ref v) => v.len(),
+        }
+    }
+
+    /// Return the value at the given `index`.
+    ///
+    /// (Note: we cannot implement [`std::ops::Index`] because of lifetime
+    /// restrictions.)
+    pub fn index(&self, index: usize) -> usize {
+        match self {
+            &IndexVec::U32(ref v) => v[index] as usize,
+            &IndexVec::USize(ref v) => v[index],
+        }
+    }
+
+    /// Return result as a `Vec<usize>`. Conversion may or may not be trivial.
+    pub fn into_vec(self) -> Vec<usize> {
+        match self {
+            IndexVec::U32(v) => v.into_iter().map(|i| i as usize).collect(),
+            IndexVec::USize(v) => v,
+        }
+    }
+
+    /// Iterate over the indices as a sequence of `usize` values
+    pub fn iter<'a>(&'a self) -> IndexVecIter<'a> {
+        match self {
+            &IndexVec::U32(ref v) => IndexVecIter::U32(v.iter()),
+            &IndexVec::USize(ref v) => IndexVecIter::USize(v.iter()),
+        }
+    }
+
+    /// Convert into an iterator over the indices as a sequence of `usize` values
+    pub fn into_iter(self) -> IndexVecIntoIter {
+        match self {
+            IndexVec::U32(v) => IndexVecIntoIter::U32(v.into_iter()),
+            IndexVec::USize(v) => IndexVecIntoIter::USize(v.into_iter()),
+        }
+    }
+}
+
+impl PartialEq for IndexVec {
+    fn eq(&self, other: &IndexVec) -> bool {
+        use self::IndexVec::*;
+        match (self, other) {
+            (&U32(ref v1), &U32(ref v2)) => v1 == v2,
+            (&USize(ref v1), &USize(ref v2)) => v1 == v2,
+            (&U32(ref v1), &USize(ref v2)) => (v1.len() == v2.len())
+                && (v1.iter().zip(v2.iter()).all(|(x, y)| *x as usize == *y)),
+            (&USize(ref v1), &U32(ref v2)) => (v1.len() == v2.len())
+                && (v1.iter().zip(v2.iter()).all(|(x, y)| *x == *y as usize)),
+        }
+    }
+}
+
+impl From<Vec<u32>> for IndexVec {
+    fn from(v: Vec<u32>) -> Self {
+        IndexVec::U32(v)
+    }
+}
+
+impl From<Vec<usize>> for IndexVec {
+    fn from(v: Vec<usize>) -> Self {
+        IndexVec::USize(v)
+    }
+}
+
+/// Return type of `IndexVec::iter`.
+#[derive(Debug)]
+pub enum IndexVecIter<'a> {
+    #[doc(hidden)] U32(slice::Iter<'a, u32>),
+    #[doc(hidden)] USize(slice::Iter<'a, usize>),
+}
+
+impl<'a> Iterator for IndexVecIter<'a> {
+    type Item = usize;
+    fn next(&mut self) -> Option<usize> {
+        use self::IndexVecIter::*;
+        match self {
+            &mut U32(ref mut iter) => iter.next().map(|i| *i as usize),
+            &mut USize(ref mut iter) => iter.next().cloned(),
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        match self {
+            &IndexVecIter::U32(ref v) => v.size_hint(),
+            &IndexVecIter::USize(ref v) => v.size_hint(),
+        }
+    }
+}
+
+impl<'a> ExactSizeIterator for IndexVecIter<'a> {}
+
+/// Return type of `IndexVec::into_iter`.
+#[derive(Clone, Debug)]
+pub enum IndexVecIntoIter {
+    #[doc(hidden)] U32(vec::IntoIter<u32>),
+    #[doc(hidden)] USize(vec::IntoIter<usize>),
+}
+
+impl Iterator for IndexVecIntoIter {
+    type Item = usize;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        use self::IndexVecIntoIter::*;
+        match self {
+            &mut U32(ref mut v) => v.next().map(|i| i as usize),
+            &mut USize(ref mut v) => v.next(),
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        use self::IndexVecIntoIter::*;
+        match self {
+            &U32(ref v) => v.size_hint(),
+            &USize(ref v) => v.size_hint(),
+        }
+    }
+}
+
+impl ExactSizeIterator for IndexVecIntoIter {}
+
+
+/// Randomly sample exactly `amount` distinct indices from `0..length`, and
+/// return them in random order (fully shuffled).
+///
+/// This method is used internally by the slice sampling methods, but it can
+/// sometimes be useful to have the indices themselves so this is provided as
+/// an alternative.
+///
+/// The implementation used is not specified; we automatically select the
+/// fastest available algorithm for the `length` and `amount` parameters
+/// (based on detailed profiling on an Intel Haswell CPU). Roughly speaking,
+/// complexity is `O(amount)`, except that when `amount` is small, performance
+/// is closer to `O(amount^2)`, and when `length` is close to `amount` then
+/// `O(length)`.
+///
+/// Note that performance is significantly better over `u32` indices than over
+/// `u64` indices. Because of this we hide the underlying type behind an
+/// abstraction, `IndexVec`.
+///
+/// If an allocation-free `no_std` function is required, it is suggested
+/// to adapt the internal `sample_floyd` implementation.
+///
+/// Panics if `amount > length`.
+pub fn sample<R>(rng: &mut R, length: usize, amount: usize) -> IndexVec
+where R: Rng + ?Sized {
+    if amount > length {
+        panic!("`amount` of samples must be less than or equal to `length`");
+    }
+    if length > (::core::u32::MAX as usize) {
+        // We never want to use inplace here, but could use floyd's alg
+        // Lazy version: always use the cache alg.
+        return sample_rejection(rng, length, amount);
+    }
+    let amount = amount as u32;
+    let length = length as u32;
+
+    // Choice of algorithm here depends on both length and amount. See:
+    // https://github.com/rust-random/rand/pull/479
+    // We do some calculations with f32. Accuracy is not very important.
+
+    if amount < 163 {
+        const C: [[f32; 2]; 2] = [[1.6, 8.0/45.0], [10.0, 70.0/9.0]];
+        let j = if length < 500_000 { 0 } else { 1 };
+        let amount_fp = amount as f32;
+        let m4 = C[0][j] * amount_fp;
+        // Short-cut: when amount < 12, floyd's is always faster
+        if amount > 11 && (length as f32) < (C[1][j] + m4) * amount_fp {
+            sample_inplace(rng, length, amount)
+        } else {
+            sample_floyd(rng, length, amount)
+        }
+    } else {
+        const C: [f32; 2] = [270.0, 330.0/9.0];
+        let j = if length < 500_000 { 0 } else { 1 };
+        if (length as f32) < C[j] * (amount as f32) {
+            sample_inplace(rng, length, amount)
+        } else {
+            sample_rejection(rng, length, amount)
+        }
+    }
+}
+
+/// Randomly sample exactly `amount` indices from `0..length`, using Floyd's
+/// combination algorithm.
+///
+/// The output values are fully shuffled. (Overhead is under 50%.)
+///
+/// This implementation uses `O(amount)` memory and `O(amount^2)` time.
+fn sample_floyd<R>(rng: &mut R, length: u32, amount: u32) -> IndexVec
+where R: Rng + ?Sized {
+    // For small amount we use Floyd's fully-shuffled variant. For larger
+    // amounts this is slow due to Vec::insert performance, so we shuffle
+    // afterwards. Benchmarks show little overhead from extra logic.
+    let floyd_shuffle = amount < 50;
+
+    debug_assert!(amount <= length);
+    let mut indices = Vec::with_capacity(amount as usize);
+    for j in length - amount .. length {
+        let t = rng.gen_range(0, j + 1);
+        if floyd_shuffle {
+            if let Some(pos) = indices.iter().position(|&x| x == t) {
+                indices.insert(pos, j);
+                continue;
+            }
+        } else {
+            if indices.contains(&t) {
+                indices.push(j);
+                continue;
+            }
+        }
+        indices.push(t);
+    }
+    if !floyd_shuffle {
+        // Reimplement SliceRandom::shuffle with smaller indices
+        for i in (1..amount).rev() {
+            // invariant: elements with index > i have been locked in place.
+            indices.swap(i as usize, rng.gen_range(0, i + 1) as usize);
+        }
+    }
+    IndexVec::from(indices)
+}
+
+/// Randomly sample exactly `amount` indices from `0..length`, using an inplace
+/// partial Fisher-Yates method.
+/// Sample an amount of indices using an inplace partial fisher yates method.
+///
+/// This allocates the entire `length` of indices and randomizes only the first `amount`.
+/// It then truncates to `amount` and returns.
+///
+/// This method is not appropriate for large `length` and potentially uses a lot
+/// of memory; because of this we only implement for `u32` index (which improves
+/// performance in all cases).
+///
+/// Set-up is `O(length)` time and memory and shuffling is `O(amount)` time.
+fn sample_inplace<R>(rng: &mut R, length: u32, amount: u32) -> IndexVec
+where R: Rng + ?Sized {
+    debug_assert!(amount <= length);
+    let mut indices: Vec<u32> = Vec::with_capacity(length as usize);
+    indices.extend(0..length);
+    for i in 0..amount {
+        let j: u32 = rng.gen_range(i, length);
+        indices.swap(i as usize, j as usize);
+    }
+    indices.truncate(amount as usize);
+    debug_assert_eq!(indices.len(), amount as usize);
+    IndexVec::from(indices)
+}
+
+trait UInt: Copy + PartialOrd + Ord + PartialEq + Eq + SampleUniform + core::hash::Hash {
+    fn zero() -> Self;
+    fn as_usize(self) -> usize;
+}
+impl UInt for u32 {
+    #[inline] fn zero() -> Self { 0 }
+    #[inline] fn as_usize(self) -> usize { self as usize }
+}
+impl UInt for usize {
+    #[inline] fn zero() -> Self { 0 }
+    #[inline] fn as_usize(self) -> usize { self }
+}
+
+/// Randomly sample exactly `amount` indices from `0..length`, using rejection
+/// sampling.
+///
+/// Since `amount <<< length` there is a low chance of a random sample in
+/// `0..length` being a duplicate. We test for duplicates and resample where
+/// necessary. The algorithm is `O(amount)` time and memory.
+/// 
+/// This function  is generic over X primarily so that results are value-stable
+/// over 32-bit and 64-bit platforms.
+fn sample_rejection<X: UInt, R>(rng: &mut R, length: X, amount: X) -> IndexVec
+where R: Rng + ?Sized, IndexVec: From<Vec<X>> {
+    debug_assert!(amount < length);
+    #[cfg(feature="std")] let mut cache = HashSet::with_capacity(amount.as_usize());
+    #[cfg(not(feature="std"))] let mut cache = BTreeSet::new();
+    let distr = Uniform::new(X::zero(), length);
+    let mut indices = Vec::with_capacity(amount.as_usize());
+    for _ in 0..amount.as_usize() {
+        let mut pos = distr.sample(rng);
+        while !cache.insert(pos) {
+            pos = distr.sample(rng);
+        }
+        indices.push(pos);
+    }
+
+    debug_assert_eq!(indices.len(), amount.as_usize());
+    IndexVec::from(indices)
+}
+
+#[cfg(test)]
+mod test {
+    #[cfg(feature="std")] use std::vec;
+    #[cfg(all(feature="alloc", not(feature="std")))] use crate::alloc::vec;
+    use super::*;
+
+    #[test]
+    fn test_sample_boundaries() {
+        let mut r = crate::test::rng(404);
+
+        assert_eq!(sample_inplace(&mut r, 0, 0).len(), 0);
+        assert_eq!(sample_inplace(&mut r, 1, 0).len(), 0);
+        assert_eq!(sample_inplace(&mut r, 1, 1).into_vec(), vec![0]);
+
+        assert_eq!(sample_rejection(&mut r, 1u32, 0).len(), 0);
+
+        assert_eq!(sample_floyd(&mut r, 0, 0).len(), 0);
+        assert_eq!(sample_floyd(&mut r, 1, 0).len(), 0);
+        assert_eq!(sample_floyd(&mut r, 1, 1).into_vec(), vec![0]);
+
+        // These algorithms should be fast with big numbers. Test average.
+        let sum: usize = sample_rejection(&mut r, 1 << 25, 10u32)
+                .into_iter().sum();
+        assert!(1 << 25 < sum && sum < (1 << 25) * 25);
+
+        let sum: usize = sample_floyd(&mut r, 1 << 25, 10)
+                .into_iter().sum();
+        assert!(1 << 25 < sum && sum < (1 << 25) * 25);
+    }
+
+    #[test]
+    #[cfg(not(miri))] // Miri is too slow
+    fn test_sample_alg() {
+        let seed_rng = crate::test::rng;
+
+        // We can't test which algorithm is used directly, but Floyd's alg
+        // should produce different results from the others. (Also, `inplace`
+        // and `cached` currently use different sizes thus produce different results.)
+
+        // A small length and relatively large amount should use inplace
+        let (length, amount): (usize, usize) = (100, 50);
+        let v1 = sample(&mut seed_rng(420), length, amount);
+        let v2 = sample_inplace(&mut seed_rng(420), length as u32, amount as u32);
+        assert!(v1.iter().all(|e| e < length));
+        assert_eq!(v1, v2);
+
+        // Test Floyd's alg does produce different results
+        let v3 = sample_floyd(&mut seed_rng(420), length as u32, amount as u32);
+        assert!(v1 != v3);
+
+        // A large length and small amount should use Floyd
+        let (length, amount): (usize, usize) = (1<<20, 50);
+        let v1 = sample(&mut seed_rng(421), length, amount);
+        let v2 = sample_floyd(&mut seed_rng(421), length as u32, amount as u32);
+        assert!(v1.iter().all(|e| e < length));
+        assert_eq!(v1, v2);
+
+        // A large length and larger amount should use cache
+        let (length, amount): (usize, usize) = (1<<20, 600);
+        let v1 = sample(&mut seed_rng(422), length, amount);
+        let v2 = sample_rejection(&mut seed_rng(422), length as u32, amount as u32);
+        assert!(v1.iter().all(|e| e < length));
+        assert_eq!(v1, v2);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand/seq/mod.rs.html b/target/doc/src/rand/seq/mod.rs.html new file mode 100644 index 0000000..e41227f --- /dev/null +++ b/target/doc/src/rand/seq/mod.rs.html @@ -0,0 +1,1587 @@ +mod.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Sequence-related functionality
+//! 
+//! This module provides:
+//! 
+//! *   [`seq::SliceRandom`] slice sampling and mutation
+//! *   [`seq::IteratorRandom`] iterator sampling
+//! *   [`seq::index::sample`] low-level API to choose multiple indices from
+//!     `0..length`
+//! 
+//! Also see:
+//! 
+//! *   [`distributions::weighted`] module which provides implementations of
+//!     weighted index sampling.
+//! 
+//! In order to make results reproducible across 32-64 bit architectures, all
+//! `usize` indices are sampled as a `u32` where possible (also providing a
+//! small performance boost in some cases).
+
+
+#[cfg(feature="alloc")] pub mod index;
+
+#[cfg(feature="alloc")] use core::ops::Index;
+
+#[cfg(all(feature="alloc", not(feature="std")))] use crate::alloc::vec::Vec;
+
+use crate::Rng;
+#[cfg(feature="alloc")] use crate::distributions::WeightedError;
+#[cfg(feature="alloc")] use crate::distributions::uniform::{SampleUniform, SampleBorrow};
+
+/// Extension trait on slices, providing random mutation and sampling methods.
+/// 
+/// This trait is implemented on all `[T]` slice types, providing several
+/// methods for choosing and shuffling elements. You must `use` this trait:
+/// 
+/// ```
+/// use rand::seq::SliceRandom;
+/// 
+/// fn main() {
+///     let mut rng = rand::thread_rng();
+///     let mut bytes = "Hello, random!".to_string().into_bytes();
+///     bytes.shuffle(&mut rng);
+///     let str = String::from_utf8(bytes).unwrap();
+///     println!("{}", str);
+/// }
+/// ```
+/// Example output (non-deterministic):
+/// ```none
+/// l,nmroHado !le
+/// ```
+pub trait SliceRandom {
+    /// The element type.
+    type Item;
+
+    /// Returns a reference to one random element of the slice, or `None` if the
+    /// slice is empty.
+    /// 
+    /// For slices, complexity is `O(1)`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use rand::thread_rng;
+    /// use rand::seq::SliceRandom;
+    ///
+    /// let choices = [1, 2, 4, 8, 16, 32];
+    /// let mut rng = thread_rng();
+    /// println!("{:?}", choices.choose(&mut rng));
+    /// assert_eq!(choices[..0].choose(&mut rng), None);
+    /// ```
+    fn choose<R>(&self, rng: &mut R) -> Option<&Self::Item>
+    where R: Rng + ?Sized;
+
+    /// Returns a mutable reference to one random element of the slice, or
+    /// `None` if the slice is empty.
+    ///
+    /// For slices, complexity is `O(1)`.
+    fn choose_mut<R>(&mut self, rng: &mut R) -> Option<&mut Self::Item>
+    where R: Rng + ?Sized;
+
+    /// Chooses `amount` elements from the slice at random, without repetition,
+    /// and in random order. The returned iterator is appropriate both for
+    /// collection into a `Vec` and filling an existing buffer (see example).
+    ///
+    /// In case this API is not sufficiently flexible, use [`index::sample`].
+    ///
+    /// For slices, complexity is the same as [`index::sample`].
+    ///
+    /// # Example
+    /// ```
+    /// use rand::seq::SliceRandom;
+    ///
+    /// let mut rng = &mut rand::thread_rng();
+    /// let sample = "Hello, audience!".as_bytes();
+    ///
+    /// // collect the results into a vector:
+    /// let v: Vec<u8> = sample.choose_multiple(&mut rng, 3).cloned().collect();
+    ///
+    /// // store in a buffer:
+    /// let mut buf = [0u8; 5];
+    /// for (b, slot) in sample.choose_multiple(&mut rng, buf.len()).zip(buf.iter_mut()) {
+    ///     *slot = *b;
+    /// }
+    /// ```
+    #[cfg(feature = "alloc")]
+    fn choose_multiple<R>(&self, rng: &mut R, amount: usize) -> SliceChooseIter<Self, Self::Item>
+    where R: Rng + ?Sized;
+
+    /// Similar to [`choose`], but where the likelihood of each outcome may be
+    /// specified.
+    /// 
+    /// The specified function `weight` maps each item `x` to a relative
+    /// likelihood `weight(x)`. The probability of each item being selected is
+    /// therefore `weight(x) / s`, where `s` is the sum of all `weight(x)`.
+    ///
+    /// For slices of length `n`, complexity is `O(n)`.
+    /// See also [`choose_weighted_mut`], [`distributions::weighted`].
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use rand::prelude::*;
+    ///
+    /// let choices = [('a', 2), ('b', 1), ('c', 1)];
+    /// let mut rng = thread_rng();
+    /// // 50% chance to print 'a', 25% chance to print 'b', 25% chance to print 'c'
+    /// println!("{:?}", choices.choose_weighted(&mut rng, |item| item.1).unwrap().0);
+    /// ```
+    /// [`choose`]: SliceRandom::choose
+    /// [`choose_weighted_mut`]: SliceRandom::choose_weighted_mut
+    /// [`distributions::weighted`]: crate::distributions::weighted
+    #[cfg(feature = "alloc")]
+    fn choose_weighted<R, F, B, X>(
+        &self, rng: &mut R, weight: F,
+    ) -> Result<&Self::Item, WeightedError>
+    where
+        R: Rng + ?Sized,
+        F: Fn(&Self::Item) -> B,
+        B: SampleBorrow<X>,
+        X: SampleUniform
+            + for<'a> ::core::ops::AddAssign<&'a X>
+            + ::core::cmp::PartialOrd<X>
+            + Clone
+            + Default;
+
+    /// Similar to [`choose_mut`], but where the likelihood of each outcome may
+    /// be specified.
+    /// 
+    /// The specified function `weight` maps each item `x` to a relative
+    /// likelihood `weight(x)`. The probability of each item being selected is
+    /// therefore `weight(x) / s`, where `s` is the sum of all `weight(x)`.
+    ///
+    /// For slices of length `n`, complexity is `O(n)`.
+    /// See also [`choose_weighted`], [`distributions::weighted`].
+    ///
+    /// [`choose_mut`]: SliceRandom::choose_mut
+    /// [`choose_weighted`]: SliceRandom::choose_weighted
+    /// [`distributions::weighted`]: crate::distributions::weighted
+    #[cfg(feature = "alloc")]
+    fn choose_weighted_mut<R, F, B, X>(
+        &mut self, rng: &mut R, weight: F,
+    ) -> Result<&mut Self::Item, WeightedError>
+    where
+        R: Rng + ?Sized,
+        F: Fn(&Self::Item) -> B,
+        B: SampleBorrow<X>,
+        X: SampleUniform
+            + for<'a> ::core::ops::AddAssign<&'a X>
+            + ::core::cmp::PartialOrd<X>
+            + Clone
+            + Default;
+
+    /// Shuffle a mutable slice in place.
+    ///
+    /// For slices of length `n`, complexity is `O(n)`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use rand::seq::SliceRandom;
+    /// use rand::thread_rng;
+    ///
+    /// let mut rng = thread_rng();
+    /// let mut y = [1, 2, 3, 4, 5];
+    /// println!("Unshuffled: {:?}", y);
+    /// y.shuffle(&mut rng);
+    /// println!("Shuffled:   {:?}", y);
+    /// ```
+    fn shuffle<R>(&mut self, rng: &mut R)
+    where R: Rng + ?Sized;
+
+    /// Shuffle a slice in place, but exit early.
+    ///
+    /// Returns two mutable slices from the source slice. The first contains
+    /// `amount` elements randomly permuted. The second has the remaining
+    /// elements that are not fully shuffled.
+    ///
+    /// This is an efficient method to select `amount` elements at random from
+    /// the slice, provided the slice may be mutated.
+    ///
+    /// If you only need to choose elements randomly and `amount > self.len()/2`
+    /// then you may improve performance by taking
+    /// `amount = values.len() - amount` and using only the second slice.
+    ///
+    /// If `amount` is greater than the number of elements in the slice, this
+    /// will perform a full shuffle.
+    ///
+    /// For slices, complexity is `O(m)` where `m = amount`.
+    fn partial_shuffle<R>(
+        &mut self, rng: &mut R, amount: usize,
+    ) -> (&mut [Self::Item], &mut [Self::Item])
+    where R: Rng + ?Sized;
+}
+
+/// Extension trait on iterators, providing random sampling methods.
+/// 
+/// This trait is implemented on all sized iterators, providing methods for
+/// choosing one or more elements. You must `use` this trait:
+/// 
+/// ```
+/// use rand::seq::IteratorRandom;
+/// 
+/// fn main() {
+///     let mut rng = rand::thread_rng();
+///     
+///     let faces = "😀😎😐😕😠😢";
+///     println!("I am {}!", faces.chars().choose(&mut rng).unwrap());
+/// }
+/// ```
+/// Example output (non-deterministic):
+/// ```none
+/// I am 😀!
+/// ```
+pub trait IteratorRandom: Iterator + Sized {
+    /// Choose one element at random from the iterator.
+    /// 
+    /// Returns `None` if and only if the iterator is empty.
+    ///
+    /// This method uses [`Iterator::size_hint`] for optimisation. With an
+    /// accurate hint and where [`Iterator::nth`] is a constant-time operation
+    /// this method can offer `O(1)` performance. Where no size hint is
+    /// available, complexity is `O(n)` where `n` is the iterator length.
+    /// Partial hints (where `lower > 0`) also improve performance.
+    /// 
+    /// For slices, prefer [`SliceRandom::choose`] which guarantees `O(1)`
+    /// performance.
+    fn choose<R>(mut self, rng: &mut R) -> Option<Self::Item>
+    where R: Rng + ?Sized {
+        let (mut lower, mut upper) = self.size_hint();
+        let mut consumed = 0;
+        let mut result = None;
+
+        if upper == Some(lower) {
+            return if lower == 0 { None } else { self.nth(gen_index(rng, lower)) };
+        }
+
+        // Continue until the iterator is exhausted
+        loop {
+            if lower > 1 {
+                let ix = gen_index(rng, lower + consumed);
+                let skip;
+                if ix < lower {
+                    result = self.nth(ix);
+                    skip = lower - (ix + 1);
+                } else {
+                    skip = lower;
+                }
+                if upper == Some(lower) {
+                    return result;
+                }
+                consumed += lower;
+                if skip > 0 {
+                    self.nth(skip - 1);
+                }
+            } else {
+                let elem = self.next();
+                if elem.is_none() {
+                    return result;
+                }
+                consumed += 1;
+                let denom = consumed as f64; // accurate to 2^53 elements
+                if rng.gen_bool(1.0 / denom) {
+                    result = elem;
+                }
+            }
+
+            let hint = self.size_hint();
+            lower = hint.0;
+            upper = hint.1;
+        }
+    }
+
+    /// Collects values at random from the iterator into a supplied buffer
+    /// until that buffer is filled.
+    ///
+    /// Although the elements are selected randomly, the order of elements in
+    /// the buffer is neither stable nor fully random. If random ordering is
+    /// desired, shuffle the result.
+    ///
+    /// Returns the number of elements added to the buffer. This equals the length
+    /// of the buffer unless the iterator contains insufficient elements, in which
+    /// case this equals the number of elements available.
+    ///
+    /// Complexity is `O(n)` where `n` is the length of the iterator.
+    /// For slices, prefer [`SliceRandom::choose_multiple`].
+    fn choose_multiple_fill<R>(mut self, rng: &mut R, buf: &mut [Self::Item]) -> usize
+    where R: Rng + ?Sized {
+        let amount = buf.len();
+        let mut len = 0;
+        while len < amount {
+            if let Some(elem) = self.next() {
+                buf[len] = elem;
+                len += 1;
+            } else {
+                // Iterator exhausted; stop early
+                return len;
+            }
+        }
+
+        // Continue, since the iterator was not exhausted
+        for (i, elem) in self.enumerate() {
+            let k = gen_index(rng, i + 1 + amount);
+            if let Some(slot) = buf.get_mut(k) {
+                *slot = elem;
+            }
+        }
+        len
+    }
+
+    /// Collects `amount` values at random from the iterator into a vector.
+    ///
+    /// This is equivalent to `choose_multiple_fill` except for the result type.
+    ///
+    /// Although the elements are selected randomly, the order of elements in
+    /// the buffer is neither stable nor fully random. If random ordering is
+    /// desired, shuffle the result.
+    ///
+    /// The length of the returned vector equals `amount` unless the iterator
+    /// contains insufficient elements, in which case it equals the number of
+    /// elements available.
+    ///
+    /// Complexity is `O(n)` where `n` is the length of the iterator.
+    /// For slices, prefer [`SliceRandom::choose_multiple`].
+    #[cfg(feature = "alloc")]
+    fn choose_multiple<R>(mut self, rng: &mut R, amount: usize) -> Vec<Self::Item>
+    where R: Rng + ?Sized {
+        let mut reservoir = Vec::with_capacity(amount);
+        reservoir.extend(self.by_ref().take(amount));
+
+        // Continue unless the iterator was exhausted
+        //
+        // note: this prevents iterators that "restart" from causing problems.
+        // If the iterator stops once, then so do we.
+        if reservoir.len() == amount {
+            for (i, elem) in self.enumerate() {
+                let k = gen_index(rng, i + 1 + amount);
+                if let Some(slot) = reservoir.get_mut(k) {
+                    *slot = elem;
+                }
+            }
+        } else {
+            // Don't hang onto extra memory. There is a corner case where
+            // `amount` was much less than `self.len()`.
+            reservoir.shrink_to_fit();
+        }
+        reservoir
+    }
+}
+
+
+impl<T> SliceRandom for [T] {
+    type Item = T;
+
+    fn choose<R>(&self, rng: &mut R) -> Option<&Self::Item>
+    where R: Rng + ?Sized {
+        if self.is_empty() {
+            None
+        } else {
+            Some(&self[gen_index(rng, self.len())])
+        }
+    }
+
+    fn choose_mut<R>(&mut self, rng: &mut R) -> Option<&mut Self::Item>
+    where R: Rng + ?Sized {
+        if self.is_empty() {
+            None
+        } else {
+            let len = self.len();
+            Some(&mut self[gen_index(rng, len)])
+        }
+    }
+
+    #[cfg(feature = "alloc")]
+    fn choose_multiple<R>(&self, rng: &mut R, amount: usize) -> SliceChooseIter<Self, Self::Item>
+    where R: Rng + ?Sized {
+        let amount = ::core::cmp::min(amount, self.len());
+        SliceChooseIter {
+            slice: self,
+            _phantom: Default::default(),
+            indices: index::sample(rng, self.len(), amount).into_iter(),
+        }
+    }
+
+    #[cfg(feature = "alloc")]
+    fn choose_weighted<R, F, B, X>(
+        &self, rng: &mut R, weight: F,
+    ) -> Result<&Self::Item, WeightedError>
+    where
+        R: Rng + ?Sized,
+        F: Fn(&Self::Item) -> B,
+        B: SampleBorrow<X>,
+        X: SampleUniform
+            + for<'a> ::core::ops::AddAssign<&'a X>
+            + ::core::cmp::PartialOrd<X>
+            + Clone
+            + Default,
+    {
+        use crate::distributions::{Distribution, WeightedIndex};
+        let distr = WeightedIndex::new(self.iter().map(weight))?;
+        Ok(&self[distr.sample(rng)])
+    }
+
+    #[cfg(feature = "alloc")]
+    fn choose_weighted_mut<R, F, B, X>(
+        &mut self, rng: &mut R, weight: F,
+    ) -> Result<&mut Self::Item, WeightedError>
+    where
+        R: Rng + ?Sized,
+        F: Fn(&Self::Item) -> B,
+        B: SampleBorrow<X>,
+        X: SampleUniform
+            + for<'a> ::core::ops::AddAssign<&'a X>
+            + ::core::cmp::PartialOrd<X>
+            + Clone
+            + Default,
+    {
+        use crate::distributions::{Distribution, WeightedIndex};
+        let distr = WeightedIndex::new(self.iter().map(weight))?;
+        Ok(&mut self[distr.sample(rng)])
+    }
+
+    fn shuffle<R>(&mut self, rng: &mut R)
+    where R: Rng + ?Sized {
+        for i in (1..self.len()).rev() {
+            // invariant: elements with index > i have been locked in place.
+            self.swap(i, gen_index(rng, i + 1));
+        }
+    }
+
+    fn partial_shuffle<R>(
+        &mut self, rng: &mut R, amount: usize,
+    ) -> (&mut [Self::Item], &mut [Self::Item])
+    where R: Rng + ?Sized {
+        // This applies Durstenfeld's algorithm for the
+        // [Fisher–Yates shuffle](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm)
+        // for an unbiased permutation, but exits early after choosing `amount`
+        // elements.
+
+        let len = self.len();
+        let end = if amount >= len { 0 } else { len - amount };
+
+        for i in (end..len).rev() {
+            // invariant: elements with index > i have been locked in place.
+            self.swap(i, gen_index(rng, i + 1));
+        }
+        let r = self.split_at_mut(end);
+        (r.1, r.0)
+    }
+}
+
+impl<I> IteratorRandom for I where I: Iterator + Sized {}
+
+
+/// An iterator over multiple slice elements.
+/// 
+/// This struct is created by
+/// [`SliceRandom::choose_multiple`](trait.SliceRandom.html#tymethod.choose_multiple).
+#[cfg(feature = "alloc")]
+#[derive(Debug)]
+pub struct SliceChooseIter<'a, S: ?Sized + 'a, T: 'a> {
+    slice: &'a S,
+    _phantom: ::core::marker::PhantomData<T>,
+    indices: index::IndexVecIntoIter,
+}
+
+#[cfg(feature = "alloc")]
+impl<'a, S: Index<usize, Output = T> + ?Sized + 'a, T: 'a> Iterator for SliceChooseIter<'a, S, T> {
+    type Item = &'a T;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        // TODO: investigate using SliceIndex::get_unchecked when stable
+        self.indices.next().map(|i| &self.slice[i as usize])
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (self.indices.len(), Some(self.indices.len()))
+    }
+}
+
+#[cfg(feature = "alloc")]
+impl<'a, S: Index<usize, Output = T> + ?Sized + 'a, T: 'a> ExactSizeIterator
+    for SliceChooseIter<'a, S, T>
+{
+    fn len(&self) -> usize {
+        self.indices.len()
+    }
+}
+
+
+// Sample a number uniformly between 0 and `ubound`. Uses 32-bit sampling where
+// possible, primarily in order to produce the same output on 32-bit and 64-bit
+// platforms.
+#[inline]
+fn gen_index<R: Rng + ?Sized>(rng: &mut R, ubound: usize) -> usize {
+    if ubound <= (core::u32::MAX as usize) {
+        rng.gen_range(0, ubound as u32) as usize
+    } else {
+        rng.gen_range(0, ubound)
+    }
+}
+
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    #[cfg(feature = "alloc")] use crate::Rng;
+    #[cfg(all(feature="alloc", not(feature="std")))]
+    use alloc::vec::Vec;
+
+    #[test]
+    fn test_slice_choose() {
+        let mut r = crate::test::rng(107);
+        let chars = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'];
+        let mut chosen = [0i32; 14];
+        // The below all use a binomial distribution with n=1000, p=1/14.
+        // binocdf(40, 1000, 1/14) ~= 2e-5; 1-binocdf(106, ..) ~= 2e-5
+        for _ in 0..1000 {
+            let picked = *chars.choose(&mut r).unwrap();
+            chosen[(picked as usize) - ('a' as usize)] += 1;
+        }
+        for count in chosen.iter() {
+            assert!(40 < *count && *count < 106);
+        }
+
+        chosen.iter_mut().for_each(|x| *x = 0);
+        for _ in 0..1000 {
+            *chosen.choose_mut(&mut r).unwrap() += 1;
+        }
+        for count in chosen.iter() {
+            assert!(40 < *count && *count < 106);
+        }
+
+        let mut v: [isize; 0] = [];
+        assert_eq!(v.choose(&mut r), None);
+        assert_eq!(v.choose_mut(&mut r), None);
+    }
+
+    #[derive(Clone)]
+    struct UnhintedIterator<I: Iterator + Clone> {
+        iter: I,
+    }
+    impl<I: Iterator + Clone> Iterator for UnhintedIterator<I> {
+        type Item = I::Item;
+        fn next(&mut self) -> Option<Self::Item> {
+            self.iter.next()
+        }
+    }
+
+    #[derive(Clone)]
+    struct ChunkHintedIterator<I: ExactSizeIterator + Iterator + Clone> {
+        iter: I,
+        chunk_remaining: usize,
+        chunk_size: usize,
+        hint_total_size: bool,
+    }
+    impl<I: ExactSizeIterator + Iterator + Clone> Iterator for ChunkHintedIterator<I> {
+        type Item = I::Item;
+        fn next(&mut self) -> Option<Self::Item> {
+            if self.chunk_remaining == 0 {
+                self.chunk_remaining = ::core::cmp::min(self.chunk_size,
+                                                        self.iter.len());
+            }
+            self.chunk_remaining = self.chunk_remaining.saturating_sub(1);
+
+            self.iter.next()
+        }
+        fn size_hint(&self) -> (usize, Option<usize>) {
+            (self.chunk_remaining,
+             if self.hint_total_size { Some(self.iter.len()) } else { None })
+        }
+    }
+
+    #[derive(Clone)]
+    struct WindowHintedIterator<I: ExactSizeIterator + Iterator + Clone> {
+        iter: I,
+        window_size: usize,
+        hint_total_size: bool,
+    }
+    impl<I: ExactSizeIterator + Iterator + Clone> Iterator for WindowHintedIterator<I> {
+        type Item = I::Item;
+        fn next(&mut self) -> Option<Self::Item> {
+            self.iter.next()
+        }
+        fn size_hint(&self) -> (usize, Option<usize>) {
+            (::core::cmp::min(self.iter.len(), self.window_size),
+             if self.hint_total_size { Some(self.iter.len()) } else { None })
+        }
+    }
+
+    #[test]
+    #[cfg(not(miri))] // Miri is too slow
+    fn test_iterator_choose() {
+        let r = &mut crate::test::rng(109);
+        fn test_iter<R: Rng + ?Sized, Iter: Iterator<Item=usize> + Clone>(r: &mut R, iter: Iter) {
+            let mut chosen = [0i32; 9];
+            for _ in 0..1000 {
+                let picked = iter.clone().choose(r).unwrap();
+                chosen[picked] += 1;
+            }
+            for count in chosen.iter() {
+                // Samples should follow Binomial(1000, 1/9)
+                // Octave: binopdf(x, 1000, 1/9) gives the prob of *count == x
+                // Note: have seen 153, which is unlikely but not impossible.
+                assert!(72 < *count && *count < 154, "count not close to 1000/9: {}", count);
+            }
+        }
+
+        test_iter(r, 0..9);
+        test_iter(r, [0, 1, 2, 3, 4, 5, 6, 7, 8].iter().cloned());
+        #[cfg(feature = "alloc")]
+        test_iter(r, (0..9).collect::<Vec<_>>().into_iter());
+        test_iter(r, UnhintedIterator { iter: 0..9 });
+        test_iter(r, ChunkHintedIterator { iter: 0..9, chunk_size: 4, chunk_remaining: 4, hint_total_size: false });
+        test_iter(r, ChunkHintedIterator { iter: 0..9, chunk_size: 4, chunk_remaining: 4, hint_total_size: true });
+        test_iter(r, WindowHintedIterator { iter: 0..9, window_size: 2, hint_total_size: false });
+        test_iter(r, WindowHintedIterator { iter: 0..9, window_size: 2, hint_total_size: true });
+
+        assert_eq!((0..0).choose(r), None);
+        assert_eq!(UnhintedIterator{ iter: 0..0 }.choose(r), None);
+    }
+
+    #[test]
+    #[cfg(not(miri))] // Miri is too slow
+    fn test_shuffle() {
+        let mut r = crate::test::rng(108);
+        let empty: &mut [isize] = &mut [];
+        empty.shuffle(&mut r);
+        let mut one = [1];
+        one.shuffle(&mut r);
+        let b: &[_] = &[1];
+        assert_eq!(one, b);
+
+        let mut two = [1, 2];
+        two.shuffle(&mut r);
+        assert!(two == [1, 2] || two == [2, 1]);
+
+        fn move_last(slice: &mut [usize], pos: usize) {
+            // use slice[pos..].rotate_left(1); once we can use that
+            let last_val = slice[pos];
+            for i in pos..slice.len() - 1 {
+                slice[i] = slice[i + 1];
+            }
+            *slice.last_mut().unwrap() = last_val;
+        }
+        let mut counts = [0i32; 24];
+        for _ in 0..10000 {
+            let mut arr: [usize; 4] = [0, 1, 2, 3];
+            arr.shuffle(&mut r);
+            let mut permutation = 0usize;
+            let mut pos_value = counts.len();
+            for i in 0..4 {
+                pos_value /= 4 - i;
+                let pos = arr.iter().position(|&x| x == i).unwrap();
+                assert!(pos < (4 - i));
+                permutation += pos * pos_value;
+                move_last(&mut arr, pos);
+                assert_eq!(arr[3], i);
+            }
+            for i in 0..4 {
+                assert_eq!(arr[i], i);
+            }
+            counts[permutation] += 1;
+        }
+        for count in counts.iter() {
+            // Binomial(10000, 1/24) with average 416.667
+            // Octave: binocdf(n, 10000, 1/24)
+            // 99.9% chance samples lie within this range:
+            assert!(352 <= *count && *count <= 483, "count: {}", count);
+        }
+    }
+    
+    #[test]
+    fn test_partial_shuffle() {
+        let mut r = crate::test::rng(118);
+        
+        let mut empty: [u32; 0] = [];
+        let res = empty.partial_shuffle(&mut r, 10);
+        assert_eq!((res.0.len(), res.1.len()), (0, 0));
+        
+        let mut v = [1, 2, 3, 4, 5];
+        let res = v.partial_shuffle(&mut r, 2);
+        assert_eq!((res.0.len(), res.1.len()), (2, 3));
+        assert!(res.0[0] != res.0[1]);
+        // First elements are only modified if selected, so at least one isn't modified:
+        assert!(res.1[0] == 1 || res.1[1] == 2 || res.1[2] == 3);
+    }
+
+    #[test]
+    #[cfg(feature = "alloc")]
+    fn test_sample_iter() {
+        let min_val = 1;
+        let max_val = 100;
+
+        let mut r = crate::test::rng(401);
+        let vals = (min_val..max_val).collect::<Vec<i32>>();
+        let small_sample = vals.iter().choose_multiple(&mut r, 5);
+        let large_sample = vals.iter().choose_multiple(&mut r, vals.len() + 5);
+
+        assert_eq!(small_sample.len(), 5);
+        assert_eq!(large_sample.len(), vals.len());
+        // no randomization happens when amount >= len
+        assert_eq!(large_sample, vals.iter().collect::<Vec<_>>());
+
+        assert!(small_sample.iter().all(|e| {
+            **e >= min_val && **e <= max_val
+        }));
+    }
+    
+    #[test]
+    #[cfg(feature = "alloc")]
+    #[cfg(not(miri))] // Miri is too slow
+    fn test_weighted() {
+        let mut r = crate::test::rng(406);
+        const N_REPS: u32 = 3000;
+        let weights = [1u32, 2, 3, 0, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7];
+        let total_weight = weights.iter().sum::<u32>() as f32;
+
+        let verify = |result: [i32; 14]| {
+            for (i, count) in result.iter().enumerate() {
+                let exp = (weights[i] * N_REPS) as f32 / total_weight;
+                let mut err = (*count as f32 - exp).abs();
+                if err != 0.0 {
+                    err /= exp;
+                }
+                assert!(err <= 0.25);
+            }
+        };
+
+        // choose_weighted
+        fn get_weight<T>(item: &(u32, T)) -> u32 {
+            item.0
+        }
+        let mut chosen = [0i32; 14];
+        let mut items = [(0u32, 0usize); 14]; // (weight, index)
+        for (i, item) in items.iter_mut().enumerate() {
+            *item = (weights[i], i);
+        }
+        for _ in 0..N_REPS {
+            let item = items.choose_weighted(&mut r, get_weight).unwrap();
+            chosen[item.1] += 1;
+        }
+        verify(chosen);
+
+        // choose_weighted_mut
+        let mut items = [(0u32, 0i32); 14]; // (weight, count)
+        for (i, item) in items.iter_mut().enumerate() {
+            *item = (weights[i], 0);
+        }
+        for _ in 0..N_REPS {
+            items.choose_weighted_mut(&mut r, get_weight).unwrap().1 += 1;
+        }
+        for (ch, item) in chosen.iter_mut().zip(items.iter()) {
+            *ch = item.1;
+        }
+        verify(chosen);
+
+        // Check error cases
+        let empty_slice = &mut [10][0..0];
+        assert_eq!(empty_slice.choose_weighted(&mut r, |_| 1), Err(WeightedError::NoItem));
+        assert_eq!(empty_slice.choose_weighted_mut(&mut r, |_| 1), Err(WeightedError::NoItem));
+        assert_eq!(['x'].choose_weighted_mut(&mut r, |_| 0), Err(WeightedError::AllWeightsZero));
+        assert_eq!([0, -1].choose_weighted_mut(&mut r, |x| *x), Err(WeightedError::InvalidWeight));
+        assert_eq!([-1, 0].choose_weighted_mut(&mut r, |x| *x), Err(WeightedError::InvalidWeight));
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand_chacha/chacha.rs.html b/target/doc/src/rand_chacha/chacha.rs.html new file mode 100644 index 0000000..b1277b6 --- /dev/null +++ b/target/doc/src/rand_chacha/chacha.rs.html @@ -0,0 +1,907 @@ +chacha.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The ChaCha random number generator.
+
+#[cfg(feature = "std")]
+use std as core;
+#[cfg(not(feature = "std"))]
+use core;
+
+use c2_chacha::guts::ChaCha;
+use self::core::fmt;
+use rand_core::block::{BlockRng, BlockRngCore};
+use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
+
+const STREAM_PARAM_NONCE: u32 = 1;
+const STREAM_PARAM_BLOCK: u32 = 0;
+
+pub struct Array64<T>([T; 64]);
+impl<T> Default for Array64<T> where T: Default {
+    fn default() -> Self {
+        Self([T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
+              T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
+              T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
+              T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
+              T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
+              T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
+              T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
+              T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default()])
+    }
+}
+impl<T> AsRef<[T]> for Array64<T> {
+    fn as_ref(&self) -> &[T] {
+        &self.0
+    }
+}
+impl<T> AsMut<[T]> for Array64<T> {
+    fn as_mut(&mut self) -> &mut [T] {
+        &mut self.0
+    }
+}
+impl<T> Clone for Array64<T> where T: Copy + Default {
+    fn clone(&self) -> Self {
+        let mut new = Self::default();
+        new.0.copy_from_slice(&self.0);
+        new
+    }
+}
+impl<T> fmt::Debug for Array64<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "Array64 {{}}")
+    }
+}
+
+macro_rules! chacha_impl {
+    ($ChaChaXCore:ident, $ChaChaXRng:ident, $rounds:expr, $doc:expr) => {
+        #[doc=$doc]
+        #[derive(Clone)]
+        pub struct $ChaChaXCore {
+            state: ChaCha,
+        }
+
+        // Custom Debug implementation that does not expose the internal state
+        impl fmt::Debug for $ChaChaXCore {
+            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+                write!(f, "ChaChaXCore {{}}")
+            }
+        }
+
+        impl BlockRngCore for $ChaChaXCore {
+            type Item = u32;
+            type Results = Array64<u32>;
+            #[inline]
+            fn generate(&mut self, r: &mut Self::Results) {
+                // Fill slice of words by writing to equivalent slice of bytes, then fixing endianness.
+                self.state.refill4($rounds, unsafe {
+                    core::mem::transmute::<&mut Array64<u32>, &mut [u8; 256]>(&mut *r)
+                });
+                for x in r.as_mut() {
+                    *x = x.to_le();
+                }
+            }
+        }
+
+        impl SeedableRng for $ChaChaXCore {
+            type Seed = [u8; 32];
+            #[inline]
+            fn from_seed(seed: Self::Seed) -> Self {
+                $ChaChaXCore { state: ChaCha::new(&seed, &[0u8; 8]) }
+            }
+        }
+
+        /// A cryptographically secure random number generator that uses the ChaCha algorithm.
+        ///
+        /// ChaCha is a stream cipher designed by Daniel J. Bernstein[^1], that we use as an RNG. It is
+        /// an improved variant of the Salsa20 cipher family, which was selected as one of the "stream
+        /// ciphers suitable for widespread adoption" by eSTREAM[^2].
+        ///
+        /// ChaCha uses add-rotate-xor (ARX) operations as its basis. These are safe against timing
+        /// attacks, although that is mostly a concern for ciphers and not for RNGs. We provide a SIMD
+        /// implementation to support high throughput on a variety of common hardware platforms.
+        ///
+        /// With the ChaCha algorithm it is possible to choose the number of rounds the core algorithm
+        /// should run. The number of rounds is a tradeoff between performance and security, where 8
+        /// rounds is the minimum potentially secure configuration, and 20 rounds is widely used as a
+        /// conservative choice.
+        ///
+        /// We use a 64-bit counter and 64-bit stream identifier as in Bernstein's implementation[^1]
+        /// except that we use a stream identifier in place of a nonce. A 64-bit counter over 64-byte
+        /// (16 word) blocks allows 1 ZiB of output before cycling, and the stream identifier allows
+        /// 2<sup>64</sup> unique streams of output per seed. Both counter and stream are initialized
+        /// to zero but may be set via the `set_word_pos` and `set_stream` methods.
+        ///
+        /// The word layout is:
+        ///
+        /// ```text
+        /// constant  constant  constant  constant
+        /// seed      seed      seed      seed
+        /// seed      seed      seed      seed
+        /// counter   counter   stream_id stream_id
+        /// ```
+        ///
+        /// This implementation uses an output buffer of sixteen `u32` words, and uses
+        /// [`BlockRng`] to implement the [`RngCore`] methods.
+        ///
+        /// [^1]: D. J. Bernstein, [*ChaCha, a variant of Salsa20*](
+        ///       https://cr.yp.to/chacha.html)
+        ///
+        /// [^2]: [eSTREAM: the ECRYPT Stream Cipher Project](
+        ///       http://www.ecrypt.eu.org/stream/)
+        #[derive(Clone, Debug)]
+        pub struct $ChaChaXRng {
+            rng: BlockRng<$ChaChaXCore>,
+        }
+
+        impl SeedableRng for $ChaChaXRng {
+            type Seed = [u8; 32];
+            #[inline]
+            fn from_seed(seed: Self::Seed) -> Self {
+                let core = $ChaChaXCore::from_seed(seed);
+                Self {
+                    rng: BlockRng::new(core),
+                }
+            }
+        }
+
+        impl RngCore for $ChaChaXRng {
+            #[inline]
+            fn next_u32(&mut self) -> u32 {
+                self.rng.next_u32()
+            }
+            #[inline]
+            fn next_u64(&mut self) -> u64 {
+                self.rng.next_u64()
+            }
+            #[inline]
+            fn fill_bytes(&mut self, bytes: &mut [u8]) {
+                self.rng.fill_bytes(bytes)
+            }
+            #[inline]
+            fn try_fill_bytes(&mut self, bytes: &mut [u8]) -> Result<(), Error> {
+                self.rng.try_fill_bytes(bytes)
+            }
+        }
+
+        impl $ChaChaXRng {
+            // The buffer is a 4-block window, i.e. it is always at a block-aligned position in the
+            // stream but if the stream has been seeked it may not be self-aligned.
+
+            /// Get the offset from the start of the stream, in 32-bit words.
+            ///
+            /// Since the generated blocks are 16 words (2<sup>4</sup>) long and the
+            /// counter is 64-bits, the offset is a 68-bit number. Sub-word offsets are
+            /// not supported, hence the result can simply be multiplied by 4 to get a
+            /// byte-offset.
+            #[inline]
+            pub fn get_word_pos(&self) -> u128 {
+                let mut block = u128::from(self.rng.core.state.get_stream_param(STREAM_PARAM_BLOCK));
+                // counter is incremented *after* filling buffer
+                block -= 4;
+                (block << 4) + self.rng.index() as u128
+            }
+
+            /// Set the offset from the start of the stream, in 32-bit words.
+            ///
+            /// As with `get_word_pos`, we use a 68-bit number. Since the generator
+            /// simply cycles at the end of its period (1 ZiB), we ignore the upper
+            /// 60 bits.
+            #[inline]
+            pub fn set_word_pos(&mut self, word_offset: u128) {
+                let block = (word_offset >> 4) as u64;
+                self.rng
+                    .core
+                    .state
+                    .set_stream_param(STREAM_PARAM_BLOCK, block);
+                self.rng.generate_and_set((word_offset & 15) as usize);
+            }
+
+            /// Set the stream number.
+            ///
+            /// This is initialized to zero; 2<sup>64</sup> unique streams of output
+            /// are available per seed/key.
+            ///
+            /// Note that in order to reproduce ChaCha output with a specific 64-bit
+            /// nonce, one can convert that nonce to a `u64` in little-endian fashion
+            /// and pass to this function. In theory a 96-bit nonce can be used by
+            /// passing the last 64-bits to this function and using the first 32-bits as
+            /// the most significant half of the 64-bit counter (which may be set
+            /// indirectly via `set_word_pos`), but this is not directly supported.
+            #[inline]
+            pub fn set_stream(&mut self, stream: u64) {
+                self.rng
+                    .core
+                    .state
+                    .set_stream_param(STREAM_PARAM_NONCE, stream);
+                if self.rng.index() != 64 {
+                    let wp = self.get_word_pos();
+                    self.set_word_pos(wp);
+                }
+            }
+        }
+
+        impl CryptoRng for $ChaChaXRng {}
+
+        impl From<$ChaChaXCore> for $ChaChaXRng {
+            fn from(core: $ChaChaXCore) -> Self {
+                $ChaChaXRng {
+                    rng: BlockRng::new(core),
+                }
+            }
+        }
+    }
+}
+
+chacha_impl!(ChaCha20Core, ChaCha20Rng, 10, "ChaCha with 20 rounds");
+chacha_impl!(ChaCha12Core, ChaCha12Rng, 6, "ChaCha with 12 rounds");
+chacha_impl!(ChaCha8Core, ChaCha8Rng, 4, "ChaCha with 8 rounds");
+
+#[cfg(test)]
+mod test {
+    use rand_core::{RngCore, SeedableRng};
+
+    type ChaChaRng = super::ChaCha20Rng;
+
+    #[test]
+    fn test_chacha_construction() {
+        let seed = [
+            0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0,
+            0, 0, 0,
+        ];
+        let mut rng1 = ChaChaRng::from_seed(seed);
+        assert_eq!(rng1.next_u32(), 137206642);
+
+        let mut rng2 = ChaChaRng::from_rng(rng1).unwrap();
+        assert_eq!(rng2.next_u32(), 1325750369);
+    }
+
+    #[test]
+    fn test_chacha_true_values_a() {
+        // Test vectors 1 and 2 from
+        // https://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04
+        let seed = [0u8; 32];
+        let mut rng = ChaChaRng::from_seed(seed);
+
+        let mut results = [0u32; 16];
+        for i in results.iter_mut() {
+            *i = rng.next_u32();
+        }
+        let expected = [
+            0xade0b876, 0x903df1a0, 0xe56a5d40, 0x28bd8653, 0xb819d2bd, 0x1aed8da0, 0xccef36a8,
+            0xc70d778b, 0x7c5941da, 0x8d485751, 0x3fe02477, 0x374ad8b8, 0xf4b8436a, 0x1ca11815,
+            0x69b687c3, 0x8665eeb2,
+        ];
+        assert_eq!(results, expected);
+
+        for i in results.iter_mut() {
+            *i = rng.next_u32();
+        }
+        let expected = [
+            0xbee7079f, 0x7a385155, 0x7c97ba98, 0x0d082d73, 0xa0290fcb, 0x6965e348, 0x3e53c612,
+            0xed7aee32, 0x7621b729, 0x434ee69c, 0xb03371d5, 0xd539d874, 0x281fed31, 0x45fb0a51,
+            0x1f0ae1ac, 0x6f4d794b,
+        ];
+        assert_eq!(results, expected);
+    }
+
+    #[test]
+    fn test_chacha_true_values_b() {
+        // Test vector 3 from
+        // https://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04
+        let seed = [
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 1,
+        ];
+        let mut rng = ChaChaRng::from_seed(seed);
+
+        // Skip block 0
+        for _ in 0..16 {
+            rng.next_u32();
+        }
+
+        let mut results = [0u32; 16];
+        for i in results.iter_mut() {
+            *i = rng.next_u32();
+        }
+        let expected = [
+            0x2452eb3a, 0x9249f8ec, 0x8d829d9b, 0xddd4ceb1, 0xe8252083, 0x60818b01, 0xf38422b8,
+            0x5aaa49c9, 0xbb00ca8e, 0xda3ba7b4, 0xc4b592d1, 0xfdf2732f, 0x4436274e, 0x2561b3c8,
+            0xebdd4aa6, 0xa0136c00,
+        ];
+        assert_eq!(results, expected);
+    }
+
+    #[test]
+    fn test_chacha_true_values_c() {
+        // Test vector 4 from
+        // https://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04
+        let seed = [
+            0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0,
+        ];
+        let expected = [
+            0xfb4dd572, 0x4bc42ef1, 0xdf922636, 0x327f1394, 0xa78dea8f, 0x5e269039, 0xa1bebbc1,
+            0xcaf09aae, 0xa25ab213, 0x48a6b46c, 0x1b9d9bcb, 0x092c5be6, 0x546ca624, 0x1bec45d5,
+            0x87f47473, 0x96f0992e,
+        ];
+        let expected_end = 3 * 16;
+        let mut results = [0u32; 16];
+
+        // Test block 2 by skipping block 0 and 1
+        let mut rng1 = ChaChaRng::from_seed(seed);
+        for _ in 0..32 {
+            rng1.next_u32();
+        }
+        for i in results.iter_mut() {
+            *i = rng1.next_u32();
+        }
+        assert_eq!(results, expected);
+        assert_eq!(rng1.get_word_pos(), expected_end);
+
+        // Test block 2 by using `set_word_pos`
+        let mut rng2 = ChaChaRng::from_seed(seed);
+        rng2.set_word_pos(2 * 16);
+        for i in results.iter_mut() {
+            *i = rng2.next_u32();
+        }
+        assert_eq!(results, expected);
+        assert_eq!(rng2.get_word_pos(), expected_end);
+
+        // Test skipping behaviour with other types
+        let mut buf = [0u8; 32];
+        rng2.fill_bytes(&mut buf[..]);
+        assert_eq!(rng2.get_word_pos(), expected_end + 8);
+        rng2.fill_bytes(&mut buf[0..25]);
+        assert_eq!(rng2.get_word_pos(), expected_end + 15);
+        rng2.next_u64();
+        assert_eq!(rng2.get_word_pos(), expected_end + 17);
+        rng2.next_u32();
+        rng2.next_u64();
+        assert_eq!(rng2.get_word_pos(), expected_end + 20);
+        rng2.fill_bytes(&mut buf[0..1]);
+        assert_eq!(rng2.get_word_pos(), expected_end + 21);
+    }
+
+    #[test]
+    fn test_chacha_multiple_blocks() {
+        let seed = [
+            0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7,
+            0, 0, 0,
+        ];
+        let mut rng = ChaChaRng::from_seed(seed);
+
+        // Store the 17*i-th 32-bit word,
+        // i.e., the i-th word of the i-th 16-word block
+        let mut results = [0u32; 16];
+        for i in results.iter_mut() {
+            *i = rng.next_u32();
+            for _ in 0..16 {
+                rng.next_u32();
+            }
+        }
+        let expected = [
+            0xf225c81a, 0x6ab1be57, 0x04d42951, 0x70858036, 0x49884684, 0x64efec72, 0x4be2d186,
+            0x3615b384, 0x11cfa18e, 0xd3c50049, 0x75c775f6, 0x434c6530, 0x2c5bad8f, 0x898881dc,
+            0x5f1c86d9, 0xc1f8e7f4,
+        ];
+        assert_eq!(results, expected);
+    }
+
+    #[test]
+    fn test_chacha_true_bytes() {
+        let seed = [0u8; 32];
+        let mut rng = ChaChaRng::from_seed(seed);
+        let mut results = [0u8; 32];
+        rng.fill_bytes(&mut results);
+        let expected = [
+            118, 184, 224, 173, 160, 241, 61, 144, 64, 93, 106, 229, 83, 134, 189, 40, 189, 210,
+            25, 184, 160, 141, 237, 26, 168, 54, 239, 204, 139, 119, 13, 199,
+        ];
+        assert_eq!(results, expected);
+    }
+
+    #[test]
+    fn test_chacha_nonce() {
+        // Test vector 5 from
+        // https://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04
+        // Although we do not support setting a nonce, we try it here anyway so
+        // we can use this test vector.
+        let seed = [0u8; 32];
+        let mut rng = ChaChaRng::from_seed(seed);
+        // 96-bit nonce in LE order is: 0,0,0,0, 0,0,0,0, 0,0,0,2
+        rng.set_stream(2u64 << (24 + 32));
+
+        let mut results = [0u32; 16];
+        for i in results.iter_mut() {
+            *i = rng.next_u32();
+        }
+        let expected = [
+            0x374dc6c2, 0x3736d58c, 0xb904e24a, 0xcd3f93ef, 0x88228b1a, 0x96a4dfb3, 0x5b76ab72,
+            0xc727ee54, 0x0e0e978a, 0xf3145c95, 0x1b748ea8, 0xf786c297, 0x99c28f5f, 0x628314e8,
+            0x398a19fa, 0x6ded1b53,
+        ];
+        assert_eq!(results, expected);
+    }
+
+    #[test]
+    fn test_chacha_clone_streams() {
+        let seed = [
+            0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7,
+            0, 0, 0,
+        ];
+        let mut rng = ChaChaRng::from_seed(seed);
+        let mut clone = rng.clone();
+        for _ in 0..16 {
+            assert_eq!(rng.next_u64(), clone.next_u64());
+        }
+
+        rng.set_stream(51);
+        for _ in 0..7 {
+            assert!(rng.next_u32() != clone.next_u32());
+        }
+        clone.set_stream(51); // switch part way through block
+        for _ in 7..16 {
+            assert_eq!(rng.next_u32(), clone.next_u32());
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand_chacha/lib.rs.html b/target/doc/src/rand_chacha/lib.rs.html new file mode 100644 index 0000000..ca81707 --- /dev/null +++ b/target/doc/src/rand_chacha/lib.rs.html @@ -0,0 +1,63 @@ +lib.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The ChaCha random number generator.
+
+#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
+       html_favicon_url = "https://www.rust-lang.org/favicon.ico",
+       html_root_url = "https://rust-random.github.io/rand/")]
+
+#![deny(missing_docs)]
+#![deny(missing_debug_implementations)]
+#![doc(test(attr(allow(unused_variables), deny(warnings))))]
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+pub use rand_core;
+
+mod chacha;
+
+pub use crate::chacha::{ChaCha12Core, ChaCha12Rng, ChaCha20Core, ChaCha20Rng, ChaCha8Core, ChaCha8Rng};
+
+/// ChaCha with 20 rounds
+pub type ChaChaRng = ChaCha20Rng;
+/// ChaCha with 20 rounds, low-level interface
+pub type ChaChaCore = ChaCha20Core;
+
+
\ No newline at end of file diff --git a/target/doc/src/rand_core/block.rs.html b/target/doc/src/rand_core/block.rs.html new file mode 100644 index 0000000..ded2e3e --- /dev/null +++ b/target/doc/src/rand_core/block.rs.html @@ -0,0 +1,869 @@ +block.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The `BlockRngCore` trait and implementation helpers
+//!
+//! The [`BlockRngCore`] trait exists to assist in the implementation of RNGs
+//! which generate a block of data in a cache instead of returning generated
+//! values directly.
+//!
+//! Usage of this trait is optional, but provides two advantages:
+//! implementations only need to concern themselves with generation of the
+//! block, not the various [`RngCore`] methods (especially [`fill_bytes`], where
+//! the optimal implementations are not trivial), and this allows
+//! `ReseedingRng` (see [`rand`](https://docs.rs/rand) crate) perform periodic
+//! reseeding with very low overhead.
+//!
+//! # Example
+//!
+//! ```norun
+//! use rand_core::block::{BlockRngCore, BlockRng};
+//!
+//! struct MyRngCore;
+//!
+//! impl BlockRngCore for MyRngCore {
+//!     type Results = [u32; 16];
+//!
+//!     fn generate(&mut self, results: &mut Self::Results) {
+//!         unimplemented!()
+//!     }
+//! }
+//!
+//! impl SeedableRng for MyRngCore {
+//!     type Seed = unimplemented!();
+//!     fn from_seed(seed: Self::Seed) -> Self {
+//!         unimplemented!()
+//!     }
+//! }
+//!
+//! // optionally, also implement CryptoRng for MyRngCore
+//!
+//! // Final RNG.
+//! type MyRng = BlockRng<u32, MyRngCore>;
+//! ```
+//!
+//! [`BlockRngCore`]: crate::block::BlockRngCore
+//! [`fill_bytes`]: RngCore::fill_bytes
+
+use core::convert::AsRef;
+use core::{fmt, ptr};
+use {RngCore, CryptoRng, SeedableRng, Error};
+use impls::{fill_via_u32_chunks, fill_via_u64_chunks};
+
+/// A trait for RNGs which do not generate random numbers individually, but in
+/// blocks (typically `[u32; N]`). This technique is commonly used by
+/// cryptographic RNGs to improve performance.
+///
+/// See the [module][crate::block] documentation for details.
+pub trait BlockRngCore {
+    /// Results element type, e.g. `u32`.
+    type Item;
+
+    /// Results type. This is the 'block' an RNG implementing `BlockRngCore`
+    /// generates, which will usually be an array like `[u32; 16]`.
+    type Results: AsRef<[Self::Item]> + AsMut<[Self::Item]> + Default;
+
+    /// Generate a new block of results.
+    fn generate(&mut self, results: &mut Self::Results);
+}
+
+
+/// A wrapper type implementing [`RngCore`] for some type implementing
+/// [`BlockRngCore`] with `u32` array buffer; i.e. this can be used to implement
+/// a full RNG from just a `generate` function.
+///
+/// The `core` field may be accessed directly but the results buffer may not.
+/// PRNG implementations can simply use a type alias
+/// (`pub type MyRng = BlockRng<MyRngCore>;`) but might prefer to use a
+/// wrapper type (`pub struct MyRng(BlockRng<MyRngCore>);`); the latter must
+/// re-implement `RngCore` but hides the implementation details and allows
+/// extra functionality to be defined on the RNG
+/// (e.g. `impl MyRng { fn set_stream(...){...} }`).
+///
+/// `BlockRng` has heavily optimized implementations of the [`RngCore`] methods
+/// reading values from the results buffer, as well as
+/// calling [`BlockRngCore::generate`] directly on the output array when
+/// [`fill_bytes`] / [`try_fill_bytes`] is called on a large array. These methods
+/// also handle the bookkeeping of when to generate a new batch of values.
+///
+/// No whole generated `u32` values are thown away and all values are consumed
+/// in-order. [`next_u32`] simply takes the next available `u32` value.
+/// [`next_u64`] is implemented by combining two `u32` values, least
+/// significant first. [`fill_bytes`] and [`try_fill_bytes`] consume a whole
+/// number of `u32` values, converting each `u32` to a byte slice in
+/// little-endian order. If the requested byte length is not a multiple of 4,
+/// some bytes will be discarded.
+///
+/// See also [`BlockRng64`] which uses `u64` array buffers. Currently there is
+/// no direct support for other buffer types.
+///
+/// For easy initialization `BlockRng` also implements [`SeedableRng`].
+///
+/// [`next_u32`]: RngCore::next_u32
+/// [`next_u64`]: RngCore::next_u64
+/// [`fill_bytes`]: RngCore::fill_bytes
+/// [`try_fill_bytes`]: RngCore::try_fill_bytes
+#[derive(Clone)]
+#[cfg_attr(feature="serde1", derive(Serialize, Deserialize))]
+pub struct BlockRng<R: BlockRngCore + ?Sized> {
+    results: R::Results,
+    index: usize,
+    /// The *core* part of the RNG, implementing the `generate` function.
+    pub core: R,
+}
+
+// Custom Debug implementation that does not expose the contents of `results`.
+impl<R: BlockRngCore + fmt::Debug> fmt::Debug for BlockRng<R> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt.debug_struct("BlockRng")
+           .field("core", &self.core)
+           .field("result_len", &self.results.as_ref().len())
+           .field("index", &self.index)
+           .finish()
+    }
+}
+
+impl<R: BlockRngCore> BlockRng<R> {
+    /// Create a new `BlockRng` from an existing RNG implementing
+    /// `BlockRngCore`. Results will be generated on first use.
+    #[inline]
+    pub fn new(core: R) -> BlockRng<R>{
+        let results_empty = R::Results::default();
+        BlockRng {
+            core,
+            index: results_empty.as_ref().len(),
+            results: results_empty,
+        }
+    }
+
+    /// Get the index into the result buffer.
+    ///
+    /// If this is equal to or larger than the size of the result buffer then
+    /// the buffer is "empty" and `generate()` must be called to produce new
+    /// results.
+    #[inline(always)]
+    pub fn index(&self) -> usize {
+        self.index
+    }
+
+    /// Reset the number of available results.
+    /// This will force a new set of results to be generated on next use.
+    #[inline]
+    pub fn reset(&mut self) {
+        self.index = self.results.as_ref().len();
+    }
+
+    /// Generate a new set of results immediately, setting the index to the
+    /// given value.
+    #[inline]
+    pub fn generate_and_set(&mut self, index: usize) {
+        assert!(index < self.results.as_ref().len());
+        self.core.generate(&mut self.results);
+        self.index = index;
+    }
+}
+
+impl<R: BlockRngCore<Item=u32>> RngCore for BlockRng<R>
+where <R as BlockRngCore>::Results: AsRef<[u32]> + AsMut<[u32]>
+{
+    #[inline]
+    fn next_u32(&mut self) -> u32 {
+        if self.index >= self.results.as_ref().len() {
+            self.generate_and_set(0);
+        }
+
+        let value = self.results.as_ref()[self.index];
+        self.index += 1;
+        value
+    }
+
+    #[inline]
+    fn next_u64(&mut self) -> u64 {
+        let read_u64 = |results: &[u32], index| {
+            if cfg!(any(target_endian = "little")) {
+                // requires little-endian CPU
+                let ptr: *const u64 = results[index..=index+1].as_ptr() as *const u64;
+                unsafe { ptr::read_unaligned(ptr) }
+            } else {
+                let x = u64::from(results[index]);
+                let y = u64::from(results[index + 1]);
+                (y << 32) | x
+            }
+        };
+
+        let len = self.results.as_ref().len();
+
+        let index = self.index;
+        if index < len-1 {
+            self.index += 2;
+            // Read an u64 from the current index
+            read_u64(self.results.as_ref(), index)
+        } else if index >= len {
+            self.generate_and_set(2);
+            read_u64(self.results.as_ref(), 0)
+        } else {
+            let x = u64::from(self.results.as_ref()[len-1]);
+            self.generate_and_set(1);
+            let y = u64::from(self.results.as_ref()[0]);
+            (y << 32) | x
+        }
+    }
+
+    #[inline]
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        let mut read_len = 0;
+        while read_len < dest.len() {
+            if self.index >= self.results.as_ref().len() {
+                self.generate_and_set(0);
+            }
+            let (consumed_u32, filled_u8) =
+                fill_via_u32_chunks(&self.results.as_ref()[self.index..],
+                                    &mut dest[read_len..]);
+
+            self.index += consumed_u32;
+            read_len += filled_u8;
+        }
+    }
+
+    #[inline(always)]
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        Ok(self.fill_bytes(dest))
+    }
+}
+
+impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng<R> {
+    type Seed = R::Seed;
+
+    #[inline(always)]
+    fn from_seed(seed: Self::Seed) -> Self {
+        Self::new(R::from_seed(seed))
+    }
+
+    #[inline(always)]
+    fn seed_from_u64(seed: u64) -> Self {
+        Self::new(R::seed_from_u64(seed))
+    }
+
+    #[inline(always)]
+    fn from_rng<S: RngCore>(rng: S) -> Result<Self, Error> {
+        Ok(Self::new(R::from_rng(rng)?))
+    }
+}
+
+
+
+/// A wrapper type implementing [`RngCore`] for some type implementing
+/// [`BlockRngCore`] with `u64` array buffer; i.e. this can be used to implement
+/// a full RNG from just a `generate` function.
+///
+/// This is similar to [`BlockRng`], but specialized for algorithms that operate
+/// on `u64` values.
+///
+/// No whole generated `u64` values are thrown away and all values are consumed
+/// in-order. [`next_u64`] simply takes the next available `u64` value.
+/// [`next_u32`] is however a bit special: half of a `u64` is consumed, leaving
+/// the other half in the buffer. If the next function called is [`next_u32`]
+/// then the other half is then consumed, however both [`next_u64`] and
+/// [`fill_bytes`] discard the rest of any half-consumed `u64`s when called.
+///
+/// [`fill_bytes`] and [`try_fill_bytes`] consume a whole number of `u64`
+/// values. If the requested length is not a multiple of 8, some bytes will be
+/// discarded.
+///
+/// [`next_u32`]: RngCore::next_u32
+/// [`next_u64`]: RngCore::next_u64
+/// [`fill_bytes`]: RngCore::fill_bytes
+/// [`try_fill_bytes`]: RngCore::try_fill_bytes
+#[derive(Clone)]
+#[cfg_attr(feature="serde1", derive(Serialize, Deserialize))]
+pub struct BlockRng64<R: BlockRngCore + ?Sized> {
+    results: R::Results,
+    index: usize,
+    half_used: bool, // true if only half of the previous result is used
+    /// The *core* part of the RNG, implementing the `generate` function.
+    pub core: R,
+}
+
+// Custom Debug implementation that does not expose the contents of `results`.
+impl<R: BlockRngCore + fmt::Debug> fmt::Debug for BlockRng64<R> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt.debug_struct("BlockRng64")
+           .field("core", &self.core)
+           .field("result_len", &self.results.as_ref().len())
+           .field("index", &self.index)
+           .field("half_used", &self.half_used)
+           .finish()
+    }
+}
+
+impl<R: BlockRngCore> BlockRng64<R> {
+    /// Create a new `BlockRng` from an existing RNG implementing
+    /// `BlockRngCore`. Results will be generated on first use.
+    #[inline]
+    pub fn new(core: R) -> BlockRng64<R>{
+        let results_empty = R::Results::default();
+        BlockRng64 {
+            core,
+            index: results_empty.as_ref().len(),
+            half_used: false,
+            results: results_empty,
+        }
+    }
+
+    /// Get the index into the result buffer.
+    ///
+    /// If this is equal to or larger than the size of the result buffer then
+    /// the buffer is "empty" and `generate()` must be called to produce new
+    /// results.
+    #[inline(always)]
+    pub fn index(&self) -> usize {
+        self.index
+    }
+
+    /// Reset the number of available results.
+    /// This will force a new set of results to be generated on next use.
+    #[inline]
+    pub fn reset(&mut self) {
+        self.index = self.results.as_ref().len();
+        self.half_used = false;
+    }
+
+    /// Generate a new set of results immediately, setting the index to the
+    /// given value.
+    #[inline]
+    pub fn generate_and_set(&mut self, index: usize) {
+        assert!(index < self.results.as_ref().len());
+        self.core.generate(&mut self.results);
+        self.index = index;
+        self.half_used = false;
+    }
+}
+
+impl<R: BlockRngCore<Item=u64>> RngCore for BlockRng64<R>
+where <R as BlockRngCore>::Results: AsRef<[u64]> + AsMut<[u64]>
+{
+    #[inline]
+    fn next_u32(&mut self) -> u32 {
+        let mut index = self.index * 2 - self.half_used as usize;
+        if index >= self.results.as_ref().len() * 2 {
+            self.core.generate(&mut self.results);
+            self.index = 0;
+            // `self.half_used` is by definition `false`
+            self.half_used = false;
+            index = 0;
+        }
+
+        self.half_used = !self.half_used;
+        self.index += self.half_used as usize;
+
+        // Index as if this is a u32 slice.
+        unsafe {
+            let results =
+                &*(self.results.as_ref() as *const [u64] as *const [u32]);
+            if cfg!(target_endian = "little") {
+                *results.get_unchecked(index)
+            } else {
+                *results.get_unchecked(index ^ 1)
+            }
+        }
+    }
+
+    #[inline]
+    fn next_u64(&mut self) -> u64 {
+        if self.index >= self.results.as_ref().len() {
+            self.core.generate(&mut self.results);
+            self.index = 0;
+        }
+
+        let value = self.results.as_ref()[self.index];
+        self.index += 1;
+        self.half_used = false;
+        value
+    }
+
+    #[inline]
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        let mut read_len = 0;
+        self.half_used = false;
+        while read_len < dest.len() {
+            if self.index as usize >= self.results.as_ref().len() {
+                self.core.generate(&mut self.results);
+                self.index = 0;
+            }
+
+            let (consumed_u64, filled_u8) =
+                fill_via_u64_chunks(&self.results.as_ref()[self.index as usize..],
+                                    &mut dest[read_len..]);
+
+            self.index += consumed_u64;
+            read_len += filled_u8;
+        }
+    }
+
+    #[inline(always)]
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        Ok(self.fill_bytes(dest))
+    }
+}
+
+impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng64<R> {
+    type Seed = R::Seed;
+
+    #[inline(always)]
+    fn from_seed(seed: Self::Seed) -> Self {
+        Self::new(R::from_seed(seed))
+    }
+
+    #[inline(always)]
+    fn seed_from_u64(seed: u64) -> Self {
+        Self::new(R::seed_from_u64(seed))
+    }
+
+    #[inline(always)]
+    fn from_rng<S: RngCore>(rng: S) -> Result<Self, Error> {
+        Ok(Self::new(R::from_rng(rng)?))
+    }
+}
+
+impl<R: BlockRngCore + CryptoRng> CryptoRng for BlockRng<R> {}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand_core/error.rs.html b/target/doc/src/rand_core/error.rs.html new file mode 100644 index 0000000..0db2bf1 --- /dev/null +++ b/target/doc/src/rand_core/error.rs.html @@ -0,0 +1,271 @@ +error.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Error types
+
+use core::fmt;
+use core::num::NonZeroU32;
+
+
+/// Error type of random number generators
+///
+/// In order to be compatible with `std` and `no_std`, this type has two
+/// possible implementations: with `std` a boxed `Error` trait object is stored,
+/// while with `no_std` we merely store an error code.
+#[derive(Debug)]
+pub struct Error {
+    #[cfg(feature="std")]
+    inner: Box<dyn std::error::Error + Send + Sync + 'static>,
+    #[cfg(not(feature="std"))]
+    code: NonZeroU32,
+}
+
+impl Error {
+    /// Construct from any type supporting `std::error::Error`
+    /// 
+    /// Available only when configured with `std`.
+    /// 
+    /// See also `From<NonZeroU32>`, which is available with and without `std`.
+    #[cfg(feature="std")]
+    pub fn new<E>(err: E) -> Self
+    where E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>
+    {
+        Error { inner: err.into() }
+    }
+    
+    /// Reference the inner error (`std` only)
+    /// 
+    /// When configured with `std`, this is a trivial operation and never
+    /// panics. Without `std`, this method is simply unavailable.
+    #[cfg(feature="std")]
+    pub fn inner(&self) -> &(dyn std::error::Error + Send + Sync + 'static) {
+        &*self.inner
+    }
+    
+    /// Unwrap the inner error (`std` only)
+    /// 
+    /// When configured with `std`, this is a trivial operation and never
+    /// panics. Without `std`, this method is simply unavailable.
+    #[cfg(feature="std")]
+    pub fn take_inner(self) -> Box<dyn std::error::Error + Send + Sync + 'static> {
+        self.inner
+    }
+    
+    /// Retrieve the error code, if any.
+    /// 
+    /// If this `Error` was constructed via `From<NonZeroU32>`, then this method
+    /// will return this `NonZeroU32` code (for `no_std` this is always the
+    /// case). Otherwise, this method will return `None`.
+    pub fn code(&self) -> Option<NonZeroU32> {
+        #[cfg(feature="std")] {
+            self.inner.downcast_ref::<ErrorCode>().map(|c| c.0)
+        }
+        #[cfg(not(feature="std"))] {
+            Some(self.code)
+        }
+    }
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        #[cfg(feature="std")] {
+            write!(f, "{}", self.inner)
+        }
+        #[cfg(not(feature="std"))] {
+            write!(f, "error code {}", self.code)
+        }
+    }
+}
+
+impl From<NonZeroU32> for Error {
+    fn from(code: NonZeroU32) -> Self {
+        #[cfg(feature="std")] {
+            Error { inner: Box::new(ErrorCode(code)) }
+        }
+        #[cfg(not(feature="std"))] {
+            Error { code }
+        }
+    }
+}
+
+#[cfg(feature="getrandom")]
+impl From<getrandom::Error> for Error {
+    fn from(error: getrandom::Error) -> Self {
+        #[cfg(feature="std")] {
+            Error { inner: Box::new(error) }
+        }
+        #[cfg(not(feature="std"))] {
+            Error { code: error.code() }
+        }
+    }
+}
+
+#[cfg(feature="std")]
+impl std::error::Error for Error {
+    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+        self.inner.source()
+    }
+}
+
+#[cfg(feature="std")]
+impl From<Error> for std::io::Error {
+    fn from(error: Error) -> Self {
+        std::io::Error::new(std::io::ErrorKind::Other, error)
+    }
+}
+
+#[cfg(feature="std")]
+#[derive(Debug, Copy, Clone)]
+struct ErrorCode(NonZeroU32);
+
+#[cfg(feature="std")]
+impl fmt::Display for ErrorCode {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "error code {}", self.0)
+    }
+}
+
+#[cfg(feature="std")]
+impl std::error::Error for ErrorCode {}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand_core/impls.rs.html b/target/doc/src/rand_core/impls.rs.html new file mode 100644 index 0000000..30dcf42 --- /dev/null +++ b/target/doc/src/rand_core/impls.rs.html @@ -0,0 +1,333 @@ +impls.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Helper functions for implementing `RngCore` functions.
+//!
+//! For cross-platform reproducibility, these functions all use Little Endian:
+//! least-significant part first. For example, `next_u64_via_u32` takes `u32`
+//! values `x, y`, then outputs `(y << 32) | x`. To implement `next_u32`
+//! from `next_u64` in little-endian order, one should use `next_u64() as u32`.
+//!
+//! Byte-swapping (like the std `to_le` functions) is only needed to convert
+//! to/from byte sequences, and since its purpose is reproducibility,
+//! non-reproducible sources (e.g. `OsRng`) need not bother with it.
+
+use core::intrinsics::transmute;
+use core::ptr::copy_nonoverlapping;
+use core::slice;
+use core::cmp::min;
+use core::mem::size_of;
+use RngCore;
+
+
+/// Implement `next_u64` via `next_u32`, little-endian order.
+pub fn next_u64_via_u32<R: RngCore + ?Sized>(rng: &mut R) -> u64 {
+    // Use LE; we explicitly generate one value before the next.
+    let x = u64::from(rng.next_u32());
+    let y = u64::from(rng.next_u32());
+    (y << 32) | x
+}
+
+/// Implement `fill_bytes` via `next_u64` and `next_u32`, little-endian order.
+///
+/// The fastest way to fill a slice is usually to work as long as possible with
+/// integers. That is why this method mostly uses `next_u64`, and only when
+/// there are 4 or less bytes remaining at the end of the slice it uses
+/// `next_u32` once.
+pub fn fill_bytes_via_next<R: RngCore + ?Sized>(rng: &mut R, dest: &mut [u8]) {
+    let mut left = dest;
+    while left.len() >= 8 {
+        let (l, r) = {left}.split_at_mut(8);
+        left = r;
+        let chunk: [u8; 8] = unsafe {
+            transmute(rng.next_u64().to_le())
+        };
+        l.copy_from_slice(&chunk);
+    }
+    let n = left.len();
+    if n > 4 {
+        let chunk: [u8; 8] = unsafe {
+            transmute(rng.next_u64().to_le())
+        };
+        left.copy_from_slice(&chunk[..n]);
+    } else if n > 0 {
+        let chunk: [u8; 4] = unsafe {
+            transmute(rng.next_u32().to_le())
+        };
+        left.copy_from_slice(&chunk[..n]);
+    }
+}
+
+macro_rules! impl_uint_from_fill {
+    ($rng:expr, $ty:ty, $N:expr) => ({
+        debug_assert!($N == size_of::<$ty>());
+
+        let mut int: $ty = 0;
+        unsafe {
+            let ptr = &mut int as *mut $ty as *mut u8;
+            let slice = slice::from_raw_parts_mut(ptr, $N);
+            $rng.fill_bytes(slice);
+        }
+        int
+    });
+}
+
+macro_rules! fill_via_chunks {
+    ($src:expr, $dst:expr, $ty:ty, $size:expr) => ({
+        let chunk_size_u8 = min($src.len() * $size, $dst.len());
+        let chunk_size = (chunk_size_u8 + $size - 1) / $size;
+        if cfg!(target_endian="little") {
+            unsafe {
+                copy_nonoverlapping(
+                    $src.as_ptr() as *const u8,
+                    $dst.as_mut_ptr(),
+                    chunk_size_u8);
+            }
+        } else {
+            for (&n, chunk) in $src.iter().zip($dst.chunks_mut($size)) {
+                let tmp = n.to_le();
+                let src_ptr = &tmp as *const $ty as *const u8;
+                unsafe {
+                    copy_nonoverlapping(src_ptr,
+                                        chunk.as_mut_ptr(),
+                                        chunk.len());
+                }
+            }
+        }
+
+        (chunk_size, chunk_size_u8)
+    });
+}
+
+/// Implement `fill_bytes` by reading chunks from the output buffer of a block
+/// based RNG.
+///
+/// The return values are `(consumed_u32, filled_u8)`.
+///
+/// `filled_u8` is the number of filled bytes in `dest`, which may be less than
+/// the length of `dest`.
+/// `consumed_u32` is the number of words consumed from `src`, which is the same
+/// as `filled_u8 / 4` rounded up.
+///
+/// # Example
+/// (from `IsaacRng`)
+///
+/// ```ignore
+/// fn fill_bytes(&mut self, dest: &mut [u8]) {
+///     let mut read_len = 0;
+///     while read_len < dest.len() {
+///         if self.index >= self.rsl.len() {
+///             self.isaac();
+///         }
+///
+///         let (consumed_u32, filled_u8) =
+///             impls::fill_via_u32_chunks(&mut self.rsl[self.index..],
+///                                        &mut dest[read_len..]);
+///
+///         self.index += consumed_u32;
+///         read_len += filled_u8;
+///     }
+/// }
+/// ```
+pub fn fill_via_u32_chunks(src: &[u32], dest: &mut [u8]) -> (usize, usize) {
+    fill_via_chunks!(src, dest, u32, 4)
+}
+
+/// Implement `fill_bytes` by reading chunks from the output buffer of a block
+/// based RNG.
+///
+/// The return values are `(consumed_u64, filled_u8)`.
+/// `filled_u8` is the number of filled bytes in `dest`, which may be less than
+/// the length of `dest`.
+/// `consumed_u64` is the number of words consumed from `src`, which is the same
+/// as `filled_u8 / 8` rounded up.
+///
+/// See `fill_via_u32_chunks` for an example.
+pub fn fill_via_u64_chunks(src: &[u64], dest: &mut [u8]) -> (usize, usize) {
+    fill_via_chunks!(src, dest, u64, 8)
+}
+
+/// Implement `next_u32` via `fill_bytes`, little-endian order.
+pub fn next_u32_via_fill<R: RngCore + ?Sized>(rng: &mut R) -> u32 {
+    impl_uint_from_fill!(rng, u32, 4)
+}
+
+/// Implement `next_u64` via `fill_bytes`, little-endian order.
+pub fn next_u64_via_fill<R: RngCore + ?Sized>(rng: &mut R) -> u64 {
+    impl_uint_from_fill!(rng, u64, 8)
+}
+
+// TODO: implement tests for the above
+
+
\ No newline at end of file diff --git a/target/doc/src/rand_core/le.rs.html b/target/doc/src/rand_core/le.rs.html new file mode 100644 index 0000000..cb8c16c --- /dev/null +++ b/target/doc/src/rand_core/le.rs.html @@ -0,0 +1,139 @@ +le.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+
+// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Little-Endian utilities
+//! 
+//! Little-Endian order has been chosen for internal usage; this makes some
+//! useful functions available.
+
+use core::ptr;
+
+macro_rules! read_slice {
+    ($src:expr, $dst:expr, $size:expr, $which:ident) => {{
+        assert_eq!($src.len(), $size * $dst.len());
+
+        unsafe {
+            ptr::copy_nonoverlapping(
+                $src.as_ptr(),
+                $dst.as_mut_ptr() as *mut u8,
+                $src.len());
+        }
+        for v in $dst.iter_mut() {
+            *v = v.$which();
+        }
+    }};
+}
+
+/// Reads unsigned 32 bit integers from `src` into `dst`.
+/// Borrowed from the `byteorder` crate.
+#[inline]
+pub fn read_u32_into(src: &[u8], dst: &mut [u32]) {
+    read_slice!(src, dst, 4, to_le);
+}
+
+/// Reads unsigned 64 bit integers from `src` into `dst`.
+/// Borrowed from the `byteorder` crate.
+#[inline]
+pub fn read_u64_into(src: &[u8], dst: &mut [u64]) {
+    read_slice!(src, dst, 8, to_le);
+}
+
+#[test]
+fn test_read() {
+    let bytes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
+    
+    let mut buf = [0u32; 4];
+    read_u32_into(&bytes, &mut buf);
+    assert_eq!(buf[0], 0x04030201);
+    assert_eq!(buf[3], 0x100F0E0D);
+    
+    let mut buf = [0u32; 3];
+    read_u32_into(&bytes[1..13], &mut buf);  // unaligned
+    assert_eq!(buf[0], 0x05040302);
+    assert_eq!(buf[2], 0x0D0C0B0A);
+    
+    let mut buf = [0u64; 2];
+    read_u64_into(&bytes, &mut buf);
+    assert_eq!(buf[0], 0x0807060504030201);
+    assert_eq!(buf[1], 0x100F0E0D0C0B0A09);
+    
+    let mut buf = [0u64; 1];
+    read_u64_into(&bytes[7..15], &mut buf); // unaligned
+    assert_eq!(buf[0], 0x0F0E0D0C0B0A0908);
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/rand_core/lib.rs.html b/target/doc/src/rand_core/lib.rs.html new file mode 100644 index 0000000..497fdab --- /dev/null +++ b/target/doc/src/rand_core/lib.rs.html @@ -0,0 +1,989 @@ +lib.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+
+// Copyright 2018 Developers of the Rand project.
+// Copyright 2017-2018 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Random number generation traits
+//!
+//! This crate is mainly of interest to crates publishing implementations of
+//! [`RngCore`]. Other users are encouraged to use the [`rand`] crate instead
+//! which re-exports the main traits and error types.
+//!
+//! [`RngCore`] is the core trait implemented by algorithmic pseudo-random number
+//! generators and external random-number sources.
+//!
+//! [`SeedableRng`] is an extension trait for construction from fixed seeds and
+//! other random number generators.
+//!
+//! [`Error`] is provided for error-handling. It is safe to use in `no_std`
+//! environments.
+//!
+//! The [`impls`] and [`le`] sub-modules include a few small functions to assist
+//! implementation of [`RngCore`].
+//!
+//! [`rand`]: https://docs.rs/rand
+
+#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
+       html_favicon_url = "https://www.rust-lang.org/favicon.ico",
+       html_root_url = "https://rust-random.github.io/rand/")]
+
+#![deny(missing_docs)]
+#![deny(missing_debug_implementations)]
+#![doc(test(attr(allow(unused_variables), deny(warnings))))]
+
+#![cfg_attr(not(feature="std"), no_std)]
+#![cfg_attr(all(feature="alloc", not(feature="std")), feature(alloc))]
+
+#[cfg(feature="std")] extern crate core;
+#[cfg(all(feature = "alloc", not(feature="std")))] extern crate alloc;
+#[cfg(feature="serde1")] extern crate serde;
+#[cfg(feature="serde1")] #[macro_use] extern crate serde_derive;
+
+
+use core::default::Default;
+use core::convert::AsMut;
+use core::ptr::copy_nonoverlapping;
+
+#[cfg(all(feature="alloc", not(feature="std")))] use alloc::boxed::Box;
+
+pub use error::Error;
+
+
+mod error;
+pub mod block;
+pub mod impls;
+pub mod le;
+
+
+/// The core of a random number generator.
+///
+/// This trait encapsulates the low-level functionality common to all
+/// generators, and is the "back end", to be implemented by generators.
+/// End users should normally use the `Rng` trait from the [`rand`] crate,
+/// which is automatically implemented for every type implementing `RngCore`.
+///
+/// Three different methods for generating random data are provided since the
+/// optimal implementation of each is dependent on the type of generator. There
+/// is no required relationship between the output of each; e.g. many
+/// implementations of [`fill_bytes`] consume a whole number of `u32` or `u64`
+/// values and drop any remaining unused bytes.
+///
+/// The [`try_fill_bytes`] method is a variant of [`fill_bytes`] allowing error
+/// handling; it is not deemed sufficiently useful to add equivalents for
+/// [`next_u32`] or [`next_u64`] since the latter methods are almost always used
+/// with algorithmic generators (PRNGs), which are normally infallible.
+///
+/// Algorithmic generators implementing [`SeedableRng`] should normally have
+/// *portable, reproducible* output, i.e. fix Endianness when converting values
+/// to avoid platform differences, and avoid making any changes which affect
+/// output (except by communicating that the release has breaking changes).
+///
+/// Typically implementators will implement only one of the methods available
+/// in this trait directly, then use the helper functions from the
+/// [`impls`] module to implement the other methods.
+///
+/// It is recommended that implementations also implement:
+///
+/// - `Debug` with a custom implementation which *does not* print any internal
+///   state (at least, [`CryptoRng`]s should not risk leaking state through
+///   `Debug`).
+/// - `Serialize` and `Deserialize` (from Serde), preferably making Serde
+///   support optional at the crate level in PRNG libs.
+/// - `Clone`, if possible.
+/// - *never* implement `Copy` (accidental copies may cause repeated values).
+/// - *do not* implement `Default` for pseudorandom generators, but instead
+///   implement [`SeedableRng`], to guide users towards proper seeding.
+///   External / hardware RNGs can choose to implement `Default`.
+/// - `Eq` and `PartialEq` could be implemented, but are probably not useful.
+///
+/// # Example
+///
+/// A simple example, obviously not generating very *random* output:
+///
+/// ```
+/// #![allow(dead_code)]
+/// use rand_core::{RngCore, Error, impls};
+///
+/// struct CountingRng(u64);
+///
+/// impl RngCore for CountingRng {
+///     fn next_u32(&mut self) -> u32 {
+///         self.next_u64() as u32
+///     }
+///
+///     fn next_u64(&mut self) -> u64 {
+///         self.0 += 1;
+///         self.0
+///     }
+///
+///     fn fill_bytes(&mut self, dest: &mut [u8]) {
+///         impls::fill_bytes_via_next(self, dest)
+///     }
+///
+///     fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+///         Ok(self.fill_bytes(dest))
+///     }
+/// }
+/// ```
+///
+/// [`rand`]: https://docs.rs/rand
+/// [`try_fill_bytes`]: RngCore::try_fill_bytes
+/// [`fill_bytes`]: RngCore::fill_bytes
+/// [`next_u32`]: RngCore::next_u32
+/// [`next_u64`]: RngCore::next_u64
+pub trait RngCore {
+    /// Return the next random `u32`.
+    ///
+    /// RNGs must implement at least one method from this trait directly. In
+    /// the case this method is not implemented directly, it can be implemented
+    /// using `self.next_u64() as u32` or via
+    /// [`fill_bytes`][impls::next_u32_via_fill].
+    fn next_u32(&mut self) -> u32;
+
+    /// Return the next random `u64`.
+    ///
+    /// RNGs must implement at least one method from this trait directly. In
+    /// the case this method is not implemented directly, it can be implemented
+    /// via [`next_u32`][impls::next_u64_via_u32] or via
+    /// [`fill_bytes`][impls::next_u64_via_fill].
+    fn next_u64(&mut self) -> u64;
+
+    /// Fill `dest` with random data.
+    ///
+    /// RNGs must implement at least one method from this trait directly. In
+    /// the case this method is not implemented directly, it can be implemented
+    /// via [`next_u*`][impls::fill_bytes_via_next] or
+    /// via [`try_fill_bytes`][RngCore::try_fill_bytes]; if this generator can
+    /// fail the implementation must choose how best to handle errors here
+    /// (e.g. panic with a descriptive message or log a warning and retry a few
+    /// times).
+    ///
+    /// This method should guarantee that `dest` is entirely filled
+    /// with new data, and may panic if this is impossible
+    /// (e.g. reading past the end of a file that is being used as the
+    /// source of randomness).
+    fn fill_bytes(&mut self, dest: &mut [u8]);
+
+    /// Fill `dest` entirely with random data.
+    ///
+    /// This is the only method which allows an RNG to report errors while
+    /// generating random data thus making this the primary method implemented
+    /// by external (true) RNGs (e.g. `OsRng`) which can fail. It may be used
+    /// directly to generate keys and to seed (infallible) PRNGs.
+    ///
+    /// Other than error handling, this method is identical to [`fill_bytes`];
+    /// thus this may be implemented using `Ok(self.fill_bytes(dest))` or
+    /// `fill_bytes` may be implemented with
+    /// `self.try_fill_bytes(dest).unwrap()` or more specific error handling.
+    ///
+    /// [`fill_bytes`]: RngCore::fill_bytes
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error>;
+}
+
+/// A marker trait used to indicate that an [`RngCore`] or [`BlockRngCore`]
+/// implementation is supposed to be cryptographically secure.
+///
+/// *Cryptographically secure generators*, also known as *CSPRNGs*, should
+/// satisfy an additional properties over other generators: given the first
+/// *k* bits of an algorithm's output
+/// sequence, it should not be possible using polynomial-time algorithms to
+/// predict the next bit with probability significantly greater than 50%.
+///
+/// Some generators may satisfy an additional property, however this is not
+/// required by this trait: if the CSPRNG's state is revealed, it should not be
+/// computationally-feasible to reconstruct output prior to this. Some other
+/// generators allow backwards-computation and are consided *reversible*.
+///
+/// Note that this trait is provided for guidance only and cannot guarantee
+/// suitability for cryptographic applications. In general it should only be
+/// implemented for well-reviewed code implementing well-regarded algorithms.
+///
+/// Note also that use of a `CryptoRng` does not protect against other
+/// weaknesses such as seeding from a weak entropy source or leaking state.
+///
+/// [`BlockRngCore`]: block::BlockRngCore
+pub trait CryptoRng {}
+
+/// A random number generator that can be explicitly seeded.
+///
+/// This trait encapsulates the low-level functionality common to all
+/// pseudo-random number generators (PRNGs, or algorithmic generators).
+///
+/// [`rand`]: https://docs.rs/rand
+pub trait SeedableRng: Sized {
+    /// Seed type, which is restricted to types mutably-dereferencable as `u8`
+    /// arrays (we recommend `[u8; N]` for some `N`).
+    ///
+    /// It is recommended to seed PRNGs with a seed of at least circa 100 bits,
+    /// which means an array of `[u8; 12]` or greater to avoid picking RNGs with
+    /// partially overlapping periods.
+    ///
+    /// For cryptographic RNG's a seed of 256 bits is recommended, `[u8; 32]`.
+    ///
+    ///
+    /// # Implementing `SeedableRng` for RNGs with large seeds
+    ///
+    /// Note that the required traits `core::default::Default` and
+    /// `core::convert::AsMut<u8>` are not implemented for large arrays
+    /// `[u8; N]` with `N` > 32. To be able to implement the traits required by
+    /// `SeedableRng` for RNGs with such large seeds, the newtype pattern can be
+    /// used:
+    ///
+    /// ```
+    /// use rand_core::SeedableRng;
+    ///
+    /// const N: usize = 64;
+    /// pub struct MyRngSeed(pub [u8; N]);
+    /// pub struct MyRng(MyRngSeed);
+    ///
+    /// impl Default for MyRngSeed {
+    ///     fn default() -> MyRngSeed {
+    ///         MyRngSeed([0; N])
+    ///     }
+    /// }
+    ///
+    /// impl AsMut<[u8]> for MyRngSeed {
+    ///     fn as_mut(&mut self) -> &mut [u8] {
+    ///         &mut self.0
+    ///     }
+    /// }
+    ///
+    /// impl SeedableRng for MyRng {
+    ///     type Seed = MyRngSeed;
+    ///
+    ///     fn from_seed(seed: MyRngSeed) -> MyRng {
+    ///         MyRng(seed)
+    ///     }
+    /// }
+    /// ```
+    type Seed: Sized + Default + AsMut<[u8]>;
+
+    /// Create a new PRNG using the given seed.
+    ///
+    /// PRNG implementations are allowed to assume that bits in the seed are
+    /// well distributed. That means usually that the number of one and zero
+    /// bits are roughly equal, and values like 0, 1 and (size - 1) are unlikely.
+    /// Note that many non-cryptographic PRNGs will show poor quality output
+    /// if this is not adhered to. If you wish to seed from simple numbers, use
+    /// `seed_from_u64` instead.
+    ///
+    /// All PRNG implementations should be reproducible unless otherwise noted:
+    /// given a fixed `seed`, the same sequence of output should be produced
+    /// on all runs, library versions and architectures (e.g. check endianness).
+    /// Any "value-breaking" changes to the generator should require bumping at
+    /// least the minor version and documentation of the change.
+    ///
+    /// It is not required that this function yield the same state as a
+    /// reference implementation of the PRNG given equivalent seed; if necessary
+    /// another constructor replicating behaviour from a reference
+    /// implementation can be added.
+    ///
+    /// PRNG implementations should make sure `from_seed` never panics. In the
+    /// case that some special values (like an all zero seed) are not viable
+    /// seeds it is preferable to map these to alternative constant value(s),
+    /// for example `0xBAD5EEDu32` or `0x0DDB1A5E5BAD5EEDu64` ("odd biases? bad
+    /// seed"). This is assuming only a small number of values must be rejected.
+    fn from_seed(seed: Self::Seed) -> Self;
+
+    /// Create a new PRNG using a `u64` seed.
+    ///
+    /// This is a convenience-wrapper around `from_seed` to allow construction
+    /// of any `SeedableRng` from a simple `u64` value. It is designed such that
+    /// low Hamming Weight numbers like 0 and 1 can be used and should still
+    /// result in good, independent seeds to the PRNG which is returned.
+    ///
+    /// This **is not suitable for cryptography**, as should be clear given that
+    /// the input size is only 64 bits.
+    ///
+    /// Implementations for PRNGs *may* provide their own implementations of
+    /// this function, but the default implementation should be good enough for
+    /// all purposes. *Changing* the implementation of this function should be
+    /// considered a value-breaking change.
+    fn seed_from_u64(mut state: u64) -> Self {
+        // We use PCG32 to generate a u32 sequence, and copy to the seed
+        const MUL: u64 = 6364136223846793005;
+        const INC: u64 = 11634580027462260723;
+
+        let mut seed = Self::Seed::default();
+        for chunk in seed.as_mut().chunks_mut(4) {
+            // We advance the state first (to get away from the input value,
+            // in case it has low Hamming Weight).
+            state = state.wrapping_mul(MUL).wrapping_add(INC);
+
+            // Use PCG output function with to_le to generate x:
+            let xorshifted = (((state >> 18) ^ state) >> 27) as u32;
+            let rot = (state >> 59) as u32;
+            let x = xorshifted.rotate_right(rot).to_le();
+
+            unsafe {
+                let p = &x as *const u32 as *const u8;
+                copy_nonoverlapping(p, chunk.as_mut_ptr(), chunk.len());
+            }
+        }
+
+        Self::from_seed(seed)
+    }
+
+    /// Create a new PRNG seeded from another `Rng`.
+    ///
+    /// This may be useful when needing to rapidly seed many PRNGs from a master
+    /// PRNG, and to allow forking of PRNGs. It may be considered deterministic.
+    ///
+    /// The master PRNG should be at least as high quality as the child PRNGs.
+    /// When seeding non-cryptographic child PRNGs, we recommend using a
+    /// different algorithm for the master PRNG (ideally a CSPRNG) to avoid
+    /// correlations between the child PRNGs. If this is not possible (e.g.
+    /// forking using small non-crypto PRNGs) ensure that your PRNG has a good
+    /// mixing function on the output or consider use of a hash function with
+    /// `from_seed`.
+    ///
+    /// Note that seeding `XorShiftRng` from another `XorShiftRng` provides an
+    /// extreme example of what can go wrong: the new PRNG will be a clone
+    /// of the parent.
+    ///
+    /// PRNG implementations are allowed to assume that a good RNG is provided
+    /// for seeding, and that it is cryptographically secure when appropriate.
+    /// As of `rand` 0.7 / `rand_core` 0.5, implementations overriding this
+    /// method should ensure the implementation satisfies reproducibility
+    /// (in prior versions this was not required).
+    ///
+    /// [`rand`]: https://docs.rs/rand
+    /// [`rand_os`]: https://docs.rs/rand_os
+    fn from_rng<R: RngCore>(mut rng: R) -> Result<Self, Error> {
+        let mut seed = Self::Seed::default();
+        rng.try_fill_bytes(seed.as_mut())?;
+        Ok(Self::from_seed(seed))
+    }
+
+    /// Creates a new instance of the RNG seeded via [`getrandom`].
+    ///
+    /// This method is the recommended way to construct non-deterministic PRNGs
+    /// since it is convenient and secure.
+    ///
+    /// In case the overhead of using [`getrandom`] to seed *many* PRNGs is an
+    /// issue, one may prefer to seed from a local PRNG, e.g.
+    /// `from_rng(thread_rng()).unwrap()`.
+    ///
+    /// # Panics
+    ///
+    /// If [`getrandom`] is unable to provide secure entropy this method will panic.
+    ///
+    /// [`getrandom`]: https://docs.rs/getrandom
+    #[cfg(feature="getrandom")]
+    fn from_entropy() -> Self {
+        let mut seed = Self::Seed::default();
+        if let Err(err) = getrandom::getrandom(seed.as_mut()) {
+            panic!("from_entropy failed: {}", err);
+        }
+        Self::from_seed(seed)
+    }
+}
+
+// Implement `RngCore` for references to an `RngCore`.
+// Force inlining all functions, so that it is up to the `RngCore`
+// implementation and the optimizer to decide on inlining.
+impl<'a, R: RngCore + ?Sized> RngCore for &'a mut R {
+    #[inline(always)]
+    fn next_u32(&mut self) -> u32 {
+        (**self).next_u32()
+    }
+
+    #[inline(always)]
+    fn next_u64(&mut self) -> u64 {
+        (**self).next_u64()
+    }
+
+    #[inline(always)]
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        (**self).fill_bytes(dest)
+    }
+
+    #[inline(always)]
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        (**self).try_fill_bytes(dest)
+    }
+}
+
+// Implement `RngCore` for boxed references to an `RngCore`.
+// Force inlining all functions, so that it is up to the `RngCore`
+// implementation and the optimizer to decide on inlining.
+#[cfg(feature="alloc")]
+impl<R: RngCore + ?Sized> RngCore for Box<R> {
+    #[inline(always)]
+    fn next_u32(&mut self) -> u32 {
+        (**self).next_u32()
+    }
+
+    #[inline(always)]
+    fn next_u64(&mut self) -> u64 {
+        (**self).next_u64()
+    }
+
+    #[inline(always)]
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        (**self).fill_bytes(dest)
+    }
+
+    #[inline(always)]
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        (**self).try_fill_bytes(dest)
+    }
+}
+
+#[cfg(feature="std")]
+impl std::io::Read for RngCore {
+    fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
+        self.try_fill_bytes(buf)?;
+        Ok(buf.len())
+    }
+}
+
+// Implement `CryptoRng` for references to an `CryptoRng`.
+impl<'a, R: CryptoRng + ?Sized> CryptoRng for &'a mut R {}
+
+// Implement `CryptoRng` for boxed references to an `CryptoRng`.
+#[cfg(feature="alloc")]
+impl<R: CryptoRng + ?Sized> CryptoRng for Box<R> {}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[test]
+    fn test_seed_from_u64() {
+        struct SeedableNum(u64);
+        impl SeedableRng for SeedableNum {
+            type Seed = [u8; 8];
+            fn from_seed(seed: Self::Seed) -> Self {
+                let mut x = [0u64; 1];
+                le::read_u64_into(&seed, &mut x);
+                SeedableNum(x[0])
+            }
+        }
+
+        const N: usize = 8;
+        const SEEDS: [u64; N] = [0u64, 1, 2, 3, 4, 8, 16, -1i64 as u64];
+        let mut results = [0u64; N];
+        for (i, seed) in SEEDS.iter().enumerate() {
+            let SeedableNum(x) = SeedableNum::seed_from_u64(*seed);
+            results[i] = x;
+        }
+
+        for (i1, r1) in results.iter().enumerate() {
+            let weight = r1.count_ones();
+            // This is the binomial distribution B(64, 0.5), so chance of
+            // weight < 20 is binocdf(19, 64, 0.5) = 7.8e-4, and same for
+            // weight > 44.
+            assert!(weight >= 20 && weight <= 44);
+
+            for (i2, r2) in results.iter().enumerate() {
+                if i1 == i2 { continue; }
+                let diff_weight = (r1 ^ r2).count_ones();
+                assert!(diff_weight >= 20);
+            }
+        }
+
+        // value-breakage test:
+        assert_eq!(results[0], 5029875928683246316);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/backtrack.rs.html b/target/doc/src/regex/backtrack.rs.html new file mode 100644 index 0000000..bc2173c --- /dev/null +++ b/target/doc/src/regex/backtrack.rs.html @@ -0,0 +1,609 @@ +backtrack.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This is the backtracking matching engine. It has the same exact capability
+// as the full NFA simulation, except it is artificially restricted to small
+// regexes on small inputs because of its memory requirements.
+//
+// In particular, this is a *bounded* backtracking engine. It retains worst
+// case linear time by keeping track of the states that it has visited (using a
+// bitmap). Namely, once a state is visited, it is never visited again. Since a
+// state is keyed by `(instruction index, input index)`, we have that its time
+// complexity is `O(mn)` (i.e., linear in the size of the search text).
+//
+// The backtracking engine can beat out the NFA simulation on small
+// regexes/inputs because it doesn't have to keep track of multiple copies of
+// the capture groups. In benchmarks, the backtracking engine is roughly twice
+// as fast as the full NFA simulation. Note though that its performance doesn't
+// scale, even if you're willing to live with the memory requirements. Namely,
+// the bitset has to be zeroed on each execution, which becomes quite expensive
+// on large bitsets.
+
+use exec::ProgramCache;
+use input::{Input, InputAt};
+use prog::{Program, InstPtr};
+use re_trait::Slot;
+
+type Bits = u32;
+
+const BIT_SIZE: usize = 32;
+const MAX_SIZE_BYTES: usize = 256 * (1 << 10); // 256 KB
+
+/// Returns true iff the given regex and input should be executed by this
+/// engine with reasonable memory usage.
+pub fn should_exec(num_insts: usize, text_len: usize) -> bool {
+    // Total memory usage in bytes is determined by:
+    //
+    //   ((len(insts) * (len(input) + 1) + bits - 1) / bits) * (size_of(u32))
+    //
+    // The actual limit picked is pretty much a heuristic.
+    // See: https://github.com/rust-lang/regex/issues/215
+    let size = ((num_insts * (text_len + 1) + BIT_SIZE - 1) / BIT_SIZE) * 4;
+    size <= MAX_SIZE_BYTES
+}
+
+/// A backtracking matching engine.
+#[derive(Debug)]
+pub struct Bounded<'a, 'm, 'r, 's, I> {
+    prog: &'r Program,
+    input: I,
+    matches: &'m mut [bool],
+    slots: &'s mut [Slot],
+    m: &'a mut Cache,
+}
+
+/// Shared cached state between multiple invocations of a backtracking engine
+/// in the same thread.
+#[derive(Clone, Debug)]
+pub struct Cache {
+    jobs: Vec<Job>,
+    visited: Vec<Bits>,
+}
+
+impl Cache {
+    /// Create new empty cache for the backtracking engine.
+    pub fn new(_prog: &Program) -> Self {
+        Cache { jobs: vec![], visited: vec![] }
+    }
+}
+
+/// A job is an explicit unit of stack space in the backtracking engine.
+///
+/// The "normal" representation is a single state transition, which corresponds
+/// to an NFA state and a character in the input. However, the backtracking
+/// engine must keep track of old capture group values. We use the explicit
+/// stack to do it.
+#[derive(Clone, Copy, Debug)]
+enum Job {
+    Inst { ip: InstPtr, at: InputAt },
+    SaveRestore { slot: usize, old_pos: Option<usize> },
+}
+
+impl<'a, 'm, 'r, 's, I: Input> Bounded<'a, 'm, 'r, 's, I> {
+    /// Execute the backtracking matching engine.
+    ///
+    /// If there's a match, `exec` returns `true` and populates the given
+    /// captures accordingly.
+    pub fn exec(
+        prog: &'r Program,
+        cache: &ProgramCache,
+        matches: &'m mut [bool],
+        slots: &'s mut [Slot],
+        input: I,
+        start: usize,
+        end: usize,
+    ) -> bool {
+        let mut cache = cache.borrow_mut();
+        let cache = &mut cache.backtrack;
+        let start = input.at(start);
+        let mut b = Bounded {
+            prog: prog,
+            input: input,
+            matches: matches,
+            slots: slots,
+            m: cache,
+        };
+        b.exec_(start, end)
+    }
+
+    /// Clears the cache such that the backtracking engine can be executed
+    /// on some input of fixed length.
+    fn clear(&mut self) {
+        // Reset the job memory so that we start fresh.
+        self.m.jobs.clear();
+
+        // Now we need to clear the bit state set.
+        // We do this by figuring out how much space we need to keep track
+        // of the states we've visited.
+        // Then we reset all existing allocated space to 0.
+        // Finally, we request more space if we need it.
+        //
+        // This is all a little circuitous, but doing this unsafely
+        // doesn't seem to have a measurable impact on performance.
+        // (Probably because backtracking is limited to such small
+        // inputs/regexes in the first place.)
+        let visited_len =
+            (self.prog.len() * (self.input.len() + 1) + BIT_SIZE - 1)
+            /
+            BIT_SIZE;
+        self.m.visited.truncate(visited_len);
+        for v in &mut self.m.visited {
+            *v = 0;
+        }
+        if visited_len > self.m.visited.len() {
+            let len = self.m.visited.len();
+            self.m.visited.reserve_exact(visited_len - len);
+            for _ in 0..(visited_len - len) {
+                self.m.visited.push(0);
+            }
+        }
+    }
+
+    /// Start backtracking at the given position in the input, but also look
+    /// for literal prefixes.
+    fn exec_(&mut self, mut at: InputAt, end: usize) -> bool {
+        self.clear();
+        // If this is an anchored regex at the beginning of the input, then
+        // we're either already done or we only need to try backtracking once.
+        if self.prog.is_anchored_start {
+            return if !at.is_start() {
+                false
+            } else {
+                self.backtrack(at)
+            };
+        }
+        let mut matched = false;
+        loop {
+            if !self.prog.prefixes.is_empty() {
+                at = match self.input.prefix_at(&self.prog.prefixes, at) {
+                    None => break,
+                    Some(at) => at,
+                };
+            }
+            matched = self.backtrack(at) || matched;
+            if matched && self.prog.matches.len() == 1 {
+                return true;
+            }
+            if at.pos() == end || at.is_end() {
+                break;
+            }
+            at = self.input.at(at.next_pos());
+        }
+        matched
+    }
+
+    /// The main backtracking loop starting at the given input position.
+    fn backtrack(&mut self, start: InputAt) -> bool {
+        // N.B. We use an explicit stack to avoid recursion.
+        // To avoid excessive pushing and popping, most transitions are handled
+        // in the `step` helper function, which only pushes to the stack when
+        // there's a capture or a branch.
+        let mut matched = false;
+        self.m.jobs.push(Job::Inst { ip: 0, at: start });
+        while let Some(job) = self.m.jobs.pop() {
+            match job {
+                Job::Inst { ip, at } => {
+                    if self.step(ip, at) {
+                        // Only quit if we're matching one regex.
+                        // If we're matching a regex set, then mush on and
+                        // try to find other matches (if we want them).
+                        if self.prog.matches.len() == 1 {
+                            return true;
+                        }
+                        matched = true;
+                    }
+                }
+                Job::SaveRestore { slot, old_pos } => {
+                    if slot < self.slots.len() {
+                        self.slots[slot] = old_pos;
+                    }
+                }
+            }
+        }
+        matched
+    }
+
+    fn step(&mut self, mut ip: InstPtr, mut at: InputAt) -> bool {
+        use prog::Inst::*;
+        loop {
+            // This loop is an optimization to avoid constantly pushing/popping
+            // from the stack. Namely, if we're pushing a job only to run it
+            // next, avoid the push and just mutate `ip` (and possibly `at`)
+            // in place.
+            if self.has_visited(ip, at) {
+                return false;
+            }
+            match self.prog[ip] {
+                Match(slot) => {
+                    if slot < self.matches.len() {
+                        self.matches[slot] = true;
+                    }
+                    return true;
+                }
+                Save(ref inst) => {
+                    if let Some(&old_pos) = self.slots.get(inst.slot) {
+                        // If this path doesn't work out, then we save the old
+                        // capture index (if one exists) in an alternate
+                        // job. If the next path fails, then the alternate
+                        // job is popped and the old capture index is restored.
+                        self.m.jobs.push(Job::SaveRestore {
+                            slot: inst.slot,
+                            old_pos: old_pos,
+                        });
+                        self.slots[inst.slot] = Some(at.pos());
+                    }
+                    ip = inst.goto;
+                }
+                Split(ref inst) => {
+                    self.m.jobs.push(Job::Inst { ip: inst.goto2, at: at });
+                    ip = inst.goto1;
+                }
+                EmptyLook(ref inst) => {
+                    if self.input.is_empty_match(at, inst) {
+                        ip = inst.goto;
+                    } else {
+                        return false;
+                    }
+                }
+                Char(ref inst) => {
+                    if inst.c == at.char() {
+                        ip = inst.goto;
+                        at = self.input.at(at.next_pos());
+                    } else {
+                        return false;
+                    }
+                }
+                Ranges(ref inst) => {
+                    if inst.matches(at.char()) {
+                        ip = inst.goto;
+                        at = self.input.at(at.next_pos());
+                    } else {
+                        return false;
+                    }
+                }
+                Bytes(ref inst) => {
+                    if let Some(b) = at.byte() {
+                        if inst.matches(b) {
+                            ip = inst.goto;
+                            at = self.input.at(at.next_pos());
+                            continue;
+                        }
+                    }
+                    return false;
+                }
+            }
+        }
+    }
+
+    fn has_visited(&mut self, ip: InstPtr, at: InputAt) -> bool {
+        let k = ip * (self.input.len() + 1) + at.pos();
+        let k1 = k / BIT_SIZE;
+        let k2 = usize_to_u32(1 << (k & (BIT_SIZE - 1)));
+        if self.m.visited[k1] & k2 == 0 {
+            self.m.visited[k1] |= k2;
+            false
+        } else {
+            true
+        }
+    }
+}
+
+fn usize_to_u32(n: usize) -> u32 {
+    if (n as u64) > (::std::u32::MAX as u64) {
+        panic!("BUG: {} is too big to fit into u32", n)
+    }
+    n as u32
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/compile.rs.html b/target/doc/src/regex/compile.rs.html new file mode 100644 index 0000000..9520e90 --- /dev/null +++ b/target/doc/src/regex/compile.rs.html @@ -0,0 +1,2233 @@ +compile.rs.html -- source
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+
+// Copyright 2014-2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::collections::HashMap;
+use std::iter;
+use std::result;
+use std::sync::Arc;
+
+use syntax::is_word_byte;
+use syntax::hir::{self, Hir};
+use utf8_ranges::{Utf8Range, Utf8Sequence, Utf8Sequences};
+
+use prog::{
+    Program, Inst, InstPtr, EmptyLook,
+    InstSave, InstSplit, InstEmptyLook, InstChar, InstRanges, InstBytes,
+};
+
+use Error;
+
+type Result = result::Result<Patch, Error>;
+
+#[derive(Debug)]
+struct Patch {
+    hole: Hole,
+    entry: InstPtr,
+}
+
+/// A compiler translates a regular expression AST to a sequence of
+/// instructions. The sequence of instructions represents an NFA.
+pub struct Compiler {
+    insts: Vec<MaybeInst>,
+    compiled: Program,
+    capture_name_idx: HashMap<String, usize>,
+    num_exprs: usize,
+    size_limit: usize,
+    suffix_cache: SuffixCache,
+    utf8_seqs: Option<Utf8Sequences>,
+    byte_classes: ByteClassSet,
+}
+
+impl Compiler {
+    /// Create a new regular expression compiler.
+    ///
+    /// Various options can be set before calling `compile` on an expression.
+    pub fn new() -> Self {
+        Compiler {
+            insts: vec![],
+            compiled: Program::new(),
+            capture_name_idx: HashMap::new(),
+            num_exprs: 0,
+            size_limit: 10 * (1 << 20),
+            suffix_cache: SuffixCache::new(1000),
+            utf8_seqs: Some(Utf8Sequences::new('\x00', '\x00')),
+            byte_classes: ByteClassSet::new(),
+        }
+    }
+
+    /// The size of the resulting program is limited by size_limit. If
+    /// the program approximately exceeds the given size (in bytes), then
+    /// compilation will stop and return an error.
+    pub fn size_limit(mut self, size_limit: usize) -> Self {
+        self.size_limit = size_limit;
+        self
+    }
+
+    /// If bytes is true, then the program is compiled as a byte based
+    /// automaton, which incorporates UTF-8 decoding into the machine. If it's
+    /// false, then the automaton is Unicode scalar value based, e.g., an
+    /// engine utilizing such an automaton is responsible for UTF-8 decoding.
+    ///
+    /// The specific invariant is that when returning a byte based machine,
+    /// the neither the `Char` nor `Ranges` instructions are produced.
+    /// Conversely, when producing a Unicode scalar value machine, the `Bytes`
+    /// instruction is never produced.
+    ///
+    /// Note that `dfa(true)` implies `bytes(true)`.
+    pub fn bytes(mut self, yes: bool) -> Self {
+        self.compiled.is_bytes = yes;
+        self
+    }
+
+    /// When disabled, the program compiled may match arbitrary bytes.
+    ///
+    /// When enabled (the default), all compiled programs exclusively match
+    /// valid UTF-8 bytes.
+    pub fn only_utf8(mut self, yes: bool) -> Self {
+        self.compiled.only_utf8 = yes;
+        self
+    }
+
+    /// When set, the machine returned is suitable for use in the DFA matching
+    /// engine.
+    ///
+    /// In particular, this ensures that if the regex is not anchored in the
+    /// beginning, then a preceding `.*?` is included in the program. (The NFA
+    /// based engines handle the preceding `.*?` explicitly, which is difficult
+    /// or impossible in the DFA engine.)
+    pub fn dfa(mut self, yes: bool) -> Self {
+        self.compiled.is_dfa = yes;
+        self
+    }
+
+    /// When set, the machine returned is suitable for matching text in
+    /// reverse. In particular, all concatenations are flipped.
+    pub fn reverse(mut self, yes: bool) -> Self {
+        self.compiled.is_reverse = yes;
+        self
+    }
+
+    /// Compile a regular expression given its AST.
+    ///
+    /// The compiler is guaranteed to succeed unless the program exceeds the
+    /// specified size limit. If the size limit is exceeded, then compilation
+    /// stops and returns an error.
+    pub fn compile(
+        mut self,
+        exprs: &[Hir],
+    ) -> result::Result<Program, Error> {
+        debug_assert!(exprs.len() >= 1);
+        self.num_exprs = exprs.len();
+        if exprs.len() == 1 {
+            self.compile_one(&exprs[0])
+        } else {
+            self.compile_many(exprs)
+        }
+    }
+
+    fn compile_one(mut self, expr: &Hir) -> result::Result<Program, Error> {
+        // If we're compiling a forward DFA and we aren't anchored, then
+        // add a `.*?` before the first capture group.
+        // Other matching engines handle this by baking the logic into the
+        // matching engine itself.
+        let mut dotstar_patch = Patch { hole: Hole::None, entry: 0 };
+        self.compiled.is_anchored_start = expr.is_anchored_start();
+        self.compiled.is_anchored_end = expr.is_anchored_end();
+        if self.compiled.needs_dotstar() {
+            dotstar_patch = self.c_dotstar()?;
+            self.compiled.start = dotstar_patch.entry;
+        }
+        self.compiled.captures = vec![None];
+        let patch = self.c_capture(0, expr)?;
+        if self.compiled.needs_dotstar() {
+            self.fill(dotstar_patch.hole, patch.entry);
+        } else {
+            self.compiled.start = patch.entry;
+        }
+        self.fill_to_next(patch.hole);
+        self.compiled.matches = vec![self.insts.len()];
+        self.push_compiled(Inst::Match(0));
+        self.compile_finish()
+    }
+
+    fn compile_many(
+        mut self,
+        exprs: &[Hir],
+    ) -> result::Result<Program, Error> {
+        debug_assert!(exprs.len() > 1);
+
+        self.compiled.is_anchored_start =
+            exprs.iter().all(|e| e.is_anchored_start());
+        self.compiled.is_anchored_end =
+            exprs.iter().all(|e| e.is_anchored_end());
+        let mut dotstar_patch = Patch { hole: Hole::None, entry: 0 };
+        if self.compiled.needs_dotstar() {
+            dotstar_patch = self.c_dotstar()?;
+            self.compiled.start = dotstar_patch.entry;
+        } else {
+            self.compiled.start = 0; // first instruction is always split
+        }
+        self.fill_to_next(dotstar_patch.hole);
+
+        let mut prev_hole = Hole::None;
+        for (i, expr) in exprs[0..exprs.len() - 1].iter().enumerate() {
+            self.fill_to_next(prev_hole);
+            let split = self.push_split_hole();
+            let Patch { hole, entry } = self.c_capture(0, expr)?;
+            self.fill_to_next(hole);
+            self.compiled.matches.push(self.insts.len());
+            self.push_compiled(Inst::Match(i));
+            prev_hole = self.fill_split(split, Some(entry), None);
+        }
+        let i = exprs.len() - 1;
+        let Patch { hole, entry } = self.c_capture(0, &exprs[i])?;
+        self.fill(prev_hole, entry);
+        self.fill_to_next(hole);
+        self.compiled.matches.push(self.insts.len());
+        self.push_compiled(Inst::Match(i));
+        self.compile_finish()
+    }
+
+    fn compile_finish(mut self) -> result::Result<Program, Error> {
+        self.compiled.insts =
+            self.insts.into_iter().map(|inst| inst.unwrap()).collect();
+        self.compiled.byte_classes = self.byte_classes.byte_classes();
+        self.compiled.capture_name_idx = Arc::new(self.capture_name_idx);
+        Ok(self.compiled)
+    }
+
+    /// Compile expr into self.insts, returning a patch on success,
+    /// or an error if we run out of memory.
+    ///
+    /// All of the c_* methods of the compiler share the contract outlined
+    /// here.
+    ///
+    /// The main thing that a c_* method does is mutate `self.insts`
+    /// to add a list of mostly compiled instructions required to execute
+    /// the given expression. `self.insts` contains MaybeInsts rather than
+    /// Insts because there is some backpatching required.
+    ///
+    /// The `Patch` value returned by each c_* method provides metadata
+    /// about the compiled instructions emitted to `self.insts`. The
+    /// `entry` member of the patch refers to the first instruction
+    /// (the entry point), while the `hole` member contains zero or
+    /// more offsets to partial instructions that need to be backpatched.
+    /// The c_* routine can't know where its list of instructions are going to
+    /// jump to after execution, so it is up to the caller to patch
+    /// these jumps to point to the right place. So compiling some
+    /// expression, e, we would end up with a situation that looked like:
+    ///
+    /// ```text
+    /// self.insts = [ ..., i1, i2, ..., iexit1, ..., iexitn, ...]
+    ///                     ^              ^             ^
+    ///                     |                \         /
+    ///                   entry                \     /
+    ///                                         hole
+    /// ```
+    ///
+    /// To compile two expressions, e1 and e2, concatinated together we
+    /// would do:
+    ///
+    /// ```ignore
+    /// let patch1 = self.c(e1);
+    /// let patch2 = self.c(e2);
+    /// ```
+    ///
+    /// while leaves us with a situation that looks like
+    ///
+    /// ```text
+    /// self.insts = [ ..., i1, ..., iexit1, ..., i2, ..., iexit2 ]
+    ///                     ^        ^            ^        ^
+    ///                     |        |            |        |
+    ///                entry1        hole1   entry2        hole2
+    /// ```
+    ///
+    /// Then to merge the two patches together into one we would backpatch
+    /// hole1 with entry2 and return a new patch that enters at entry1
+    /// and has hole2 for a hole. In fact, if you look at the c_concat
+    /// method you will see that it does exactly this, though it handles
+    /// a list of expressions rather than just the two that we use for
+    /// an example.
+    fn c(&mut self, expr: &Hir) -> Result {
+        use prog;
+        use syntax::hir::HirKind::*;
+
+        self.check_size()?;
+        match *expr.kind() {
+            Empty => Ok(Patch { hole: Hole::None, entry: self.insts.len() }),
+            Literal(hir::Literal::Unicode(c)) => {
+                self.c_char(c)
+            }
+            Literal(hir::Literal::Byte(b)) => {
+                assert!(self.compiled.uses_bytes());
+                self.c_byte(b)
+            }
+            Class(hir::Class::Unicode(ref cls)) => {
+                self.c_class(cls.ranges())
+            }
+            Class(hir::Class::Bytes(ref cls)) => {
+                if self.compiled.uses_bytes() {
+                    self.c_class_bytes(cls.ranges())
+                } else {
+                    assert!(cls.is_all_ascii());
+                    let mut char_ranges = vec![];
+                    for r in cls.iter() {
+                        let (s, e) = (r.start() as char, r.end() as char);
+                        char_ranges.push(hir::ClassUnicodeRange::new(s, e));
+                    }
+                    self.c_class(&char_ranges)
+                }
+            }
+            Anchor(hir::Anchor::StartLine) if self.compiled.is_reverse => {
+                self.byte_classes.set_range(b'\n', b'\n');
+                self.c_empty_look(prog::EmptyLook::EndLine)
+            }
+            Anchor(hir::Anchor::StartLine) => {
+                self.byte_classes.set_range(b'\n', b'\n');
+                self.c_empty_look(prog::EmptyLook::StartLine)
+            }
+            Anchor(hir::Anchor::EndLine) if self.compiled.is_reverse => {
+                self.byte_classes.set_range(b'\n', b'\n');
+                self.c_empty_look(prog::EmptyLook::StartLine)
+            }
+            Anchor(hir::Anchor::EndLine) => {
+                self.byte_classes.set_range(b'\n', b'\n');
+                self.c_empty_look(prog::EmptyLook::EndLine)
+            }
+            Anchor(hir::Anchor::StartText) if self.compiled.is_reverse => {
+                self.c_empty_look(prog::EmptyLook::EndText)
+            }
+            Anchor(hir::Anchor::StartText) => {
+                self.c_empty_look(prog::EmptyLook::StartText)
+            }
+            Anchor(hir::Anchor::EndText) if self.compiled.is_reverse => {
+                self.c_empty_look(prog::EmptyLook::StartText)
+            }
+            Anchor(hir::Anchor::EndText) => {
+                self.c_empty_look(prog::EmptyLook::EndText)
+            }
+            WordBoundary(hir::WordBoundary::Unicode) => {
+                self.compiled.has_unicode_word_boundary = true;
+                self.byte_classes.set_word_boundary();
+                self.c_empty_look(prog::EmptyLook::WordBoundary)
+            }
+            WordBoundary(hir::WordBoundary::UnicodeNegate) => {
+                self.compiled.has_unicode_word_boundary = true;
+                self.byte_classes.set_word_boundary();
+                self.c_empty_look(prog::EmptyLook::NotWordBoundary)
+            }
+            WordBoundary(hir::WordBoundary::Ascii) => {
+                self.byte_classes.set_word_boundary();
+                self.c_empty_look(prog::EmptyLook::WordBoundaryAscii)
+            }
+            WordBoundary(hir::WordBoundary::AsciiNegate) => {
+                self.byte_classes.set_word_boundary();
+                self.c_empty_look(prog::EmptyLook::NotWordBoundaryAscii)
+            }
+            Group(ref g) => {
+                match g.kind {
+                    hir::GroupKind::NonCapturing => self.c(&g.hir),
+                    hir::GroupKind::CaptureIndex(index) => {
+                        if index as usize >= self.compiled.captures.len() {
+                            self.compiled.captures.push(None);
+                        }
+                        self.c_capture(2 * index as usize, &g.hir)
+                    }
+                    hir::GroupKind::CaptureName { index, ref name } => {
+                        if index as usize >= self.compiled.captures.len() {
+                            let n = name.to_string();
+                            self.compiled.captures.push(Some(n.clone()));
+                            self.capture_name_idx.insert(n, index as usize);
+                        }
+                        self.c_capture(2 * index as usize, &g.hir)
+                    }
+                }
+            }
+            Concat(ref es) => {
+                if self.compiled.is_reverse {
+                    self.c_concat(es.iter().rev())
+                } else {
+                    self.c_concat(es)
+                }
+            }
+            Alternation(ref es) => self.c_alternate(&**es),
+            Repetition(ref rep) => self.c_repeat(rep),
+        }
+    }
+
+    fn c_capture(&mut self, first_slot: usize, expr: &Hir) -> Result {
+        if self.num_exprs > 1 || self.compiled.is_dfa {
+            // Don't ever compile Save instructions for regex sets because
+            // they are never used. They are also never used in DFA programs
+            // because DFAs can't handle captures.
+            self.c(expr)
+        } else {
+            let entry = self.insts.len();
+            let hole = self.push_hole(InstHole::Save { slot: first_slot });
+            let patch = self.c(expr)?;
+            self.fill(hole, patch.entry);
+            self.fill_to_next(patch.hole);
+            let hole = self.push_hole(InstHole::Save { slot: first_slot + 1 });
+            Ok(Patch { hole: hole, entry: entry })
+        }
+    }
+
+    fn c_dotstar(&mut self) -> Result {
+        Ok(if !self.compiled.only_utf8() {
+            self.c(&Hir::repetition(hir::Repetition {
+                kind: hir::RepetitionKind::ZeroOrMore,
+                greedy: false,
+                hir: Box::new(Hir::any(true)),
+            }))?
+        } else {
+            self.c(&Hir::repetition(hir::Repetition {
+                kind: hir::RepetitionKind::ZeroOrMore,
+                greedy: false,
+                hir: Box::new(Hir::any(false)),
+            }))?
+        })
+    }
+
+    fn c_char(&mut self, c: char) -> Result {
+        self.c_class(&[hir::ClassUnicodeRange::new(c, c)])
+    }
+
+    fn c_class(&mut self, ranges: &[hir::ClassUnicodeRange]) -> Result {
+        assert!(!ranges.is_empty());
+        if self.compiled.uses_bytes() {
+            CompileClass {
+                c: self,
+                ranges: ranges,
+            }.compile()
+        } else {
+            let ranges: Vec<(char, char)> =
+                ranges.iter().map(|r| (r.start(), r.end())).collect();
+            let hole = if ranges.len() == 1 && ranges[0].0 == ranges[0].1 {
+                self.push_hole(InstHole::Char { c: ranges[0].0 })
+            } else {
+                self.push_hole(InstHole::Ranges { ranges: ranges })
+            };
+            Ok(Patch { hole: hole, entry: self.insts.len() - 1 })
+        }
+    }
+
+    fn c_byte(&mut self, b: u8) -> Result {
+        self.c_class_bytes(&[hir::ClassBytesRange::new(b, b)])
+    }
+
+    fn c_class_bytes(&mut self, ranges: &[hir::ClassBytesRange]) -> Result {
+        debug_assert!(!ranges.is_empty());
+
+        let first_split_entry = self.insts.len();
+        let mut holes = vec![];
+        let mut prev_hole = Hole::None;
+        for r in &ranges[0..ranges.len() - 1] {
+            self.fill_to_next(prev_hole);
+            let split = self.push_split_hole();
+            let next = self.insts.len();
+            self.byte_classes.set_range(r.start(), r.end());
+            holes.push(self.push_hole(InstHole::Bytes {
+                start: r.start(), end: r.end(),
+            }));
+            prev_hole = self.fill_split(split, Some(next), None);
+        }
+        let next = self.insts.len();
+        let r = &ranges[ranges.len() - 1];
+        self.byte_classes.set_range(r.start(), r.end());
+        holes.push(self.push_hole(InstHole::Bytes {
+            start: r.start(), end: r.end(),
+        }));
+        self.fill(prev_hole, next);
+        Ok(Patch { hole: Hole::Many(holes), entry: first_split_entry })
+    }
+
+    fn c_empty_look(&mut self, look: EmptyLook) -> Result {
+        let hole = self.push_hole(InstHole::EmptyLook { look: look });
+        Ok(Patch { hole: hole, entry: self.insts.len() - 1 })
+    }
+
+    fn c_concat<'a, I>(&mut self, exprs: I) -> Result
+            where I: IntoIterator<Item=&'a Hir> {
+        let mut exprs = exprs.into_iter();
+        let first = match exprs.next() {
+            Some(expr) => expr,
+            None => {
+                return Ok(Patch { hole: Hole::None, entry: self.insts.len() })
+            }
+        };
+        let Patch { mut hole, entry } = self.c(first)?;
+        for e in exprs {
+            let p = self.c(e)?;
+            self.fill(hole, p.entry);
+            hole = p.hole;
+        }
+        Ok(Patch { hole: hole, entry: entry })
+    }
+
+    fn c_alternate(&mut self, exprs: &[Hir]) -> Result {
+        debug_assert!(
+            exprs.len() >= 2, "alternates must have at least 2 exprs");
+
+        // Initial entry point is always the first split.
+        let first_split_entry = self.insts.len();
+
+        // Save up all of the holes from each alternate. They will all get
+        // patched to point to the same location.
+        let mut holes = vec![];
+
+        let mut prev_hole = Hole::None;
+        for e in &exprs[0..exprs.len() - 1] {
+            self.fill_to_next(prev_hole);
+            let split = self.push_split_hole();
+            let prev_entry = self.insts.len();
+            let Patch { hole, entry } = self.c(e)?;
+            if prev_entry == self.insts.len() {
+                // TODO(burntsushi): It is kind of silly that we don't support
+                // empty-subexpressions in alternates, but it is supremely
+                // awkward to support them in the existing compiler
+                // infrastructure. This entire compiler needs to be thrown out
+                // anyway, so don't feel too bad.
+                return Err(Error::Syntax(
+                    "alternations cannot currently contain \
+                     empty sub-expressions".to_string()));
+            }
+            holes.push(hole);
+            prev_hole = self.fill_split(split, Some(entry), None);
+        }
+        let prev_entry = self.insts.len();
+        let Patch { hole, entry } = self.c(&exprs[exprs.len() - 1])?;
+        if prev_entry == self.insts.len() {
+            // TODO(burntsushi): See TODO above.
+            return Err(Error::Syntax(
+                "alternations cannot currently contain \
+                 empty sub-expressions".to_string()));
+        }
+        holes.push(hole);
+        self.fill(prev_hole, entry);
+        Ok(Patch { hole: Hole::Many(holes), entry: first_split_entry })
+    }
+
+    fn c_repeat(&mut self, rep: &hir::Repetition) -> Result {
+        use syntax::hir::RepetitionKind::*;
+        match rep.kind {
+            ZeroOrOne => self.c_repeat_zero_or_one(&rep.hir, rep.greedy),
+            ZeroOrMore => self.c_repeat_zero_or_more(&rep.hir, rep.greedy),
+            OneOrMore => self.c_repeat_one_or_more(&rep.hir, rep.greedy),
+            Range(hir::RepetitionRange::Exactly(min_max)) => {
+                self.c_repeat_range(&rep.hir, rep.greedy, min_max, min_max)
+            }
+            Range(hir::RepetitionRange::AtLeast(min)) => {
+                self.c_repeat_range_min_or_more(&rep.hir, rep.greedy, min)
+            }
+            Range(hir::RepetitionRange::Bounded(min, max)) => {
+                self.c_repeat_range(&rep.hir, rep.greedy, min, max)
+            }
+        }
+    }
+
+    fn c_repeat_zero_or_one(&mut self, expr: &Hir, greedy: bool) -> Result {
+        let split_entry = self.insts.len();
+        let split = self.push_split_hole();
+        let Patch { hole: hole_rep, entry: entry_rep } = self.c(expr)?;
+
+        let split_hole = if greedy {
+            self.fill_split(split, Some(entry_rep), None)
+        } else {
+            self.fill_split(split, None, Some(entry_rep))
+        };
+        let holes = vec![hole_rep, split_hole];
+        Ok(Patch { hole: Hole::Many(holes), entry: split_entry })
+    }
+
+    fn c_repeat_zero_or_more(&mut self, expr: &Hir, greedy: bool) -> Result {
+        let split_entry = self.insts.len();
+        let split = self.push_split_hole();
+        let Patch { hole: hole_rep, entry: entry_rep } = self.c(expr)?;
+
+        self.fill(hole_rep, split_entry);
+        let split_hole = if greedy {
+            self.fill_split(split, Some(entry_rep), None)
+        } else {
+            self.fill_split(split, None, Some(entry_rep))
+        };
+        Ok(Patch { hole: split_hole, entry: split_entry })
+    }
+
+    fn c_repeat_one_or_more(&mut self, expr: &Hir, greedy: bool) -> Result {
+        let Patch { hole: hole_rep, entry: entry_rep } = self.c(expr)?;
+        self.fill_to_next(hole_rep);
+        let split = self.push_split_hole();
+
+        let split_hole = if greedy {
+            self.fill_split(split, Some(entry_rep), None)
+        } else {
+            self.fill_split(split, None, Some(entry_rep))
+        };
+        Ok(Patch { hole: split_hole, entry: entry_rep })
+    }
+
+    fn c_repeat_range_min_or_more(
+        &mut self,
+        expr: &Hir,
+        greedy: bool,
+        min: u32,
+    ) -> Result {
+        let min = u32_to_usize(min);
+        let patch_concat = self.c_concat(iter::repeat(expr).take(min))?;
+        let patch_rep = self.c_repeat_zero_or_more(expr, greedy)?;
+        self.fill(patch_concat.hole, patch_rep.entry);
+        Ok(Patch { hole: patch_rep.hole, entry: patch_concat.entry })
+    }
+
+    fn c_repeat_range(
+        &mut self,
+        expr: &Hir,
+        greedy: bool,
+        min: u32,
+        max: u32,
+    ) -> Result {
+        let (min, max) = (u32_to_usize(min), u32_to_usize(max));
+        let patch_concat = self.c_concat(iter::repeat(expr).take(min))?;
+        let initial_entry = patch_concat.entry;
+        if min == max {
+            return Ok(patch_concat);
+        }
+        // It is much simpler to compile, e.g., `a{2,5}` as:
+        //
+        //     aaa?a?a?
+        //
+        // But you end up with a sequence of instructions like this:
+        //
+        //     0: 'a'
+        //     1: 'a',
+        //     2: split(3, 4)
+        //     3: 'a'
+        //     4: split(5, 6)
+        //     5: 'a'
+        //     6: split(7, 8)
+        //     7: 'a'
+        //     8: MATCH
+        //
+        // This is *incredibly* inefficient because the splits end
+        // up forming a chain, which has to be resolved everything a
+        // transition is followed.
+        let mut holes = vec![];
+        let mut prev_hole = patch_concat.hole;
+        for _ in min..max {
+            self.fill_to_next(prev_hole);
+            let split = self.push_split_hole();
+            let Patch { hole, entry } = self.c(expr)?;
+            prev_hole = hole;
+            if greedy {
+                holes.push(self.fill_split(split, Some(entry), None));
+            } else {
+                holes.push(self.fill_split(split, None, Some(entry)));
+            }
+        }
+        holes.push(prev_hole);
+        Ok(Patch { hole: Hole::Many(holes), entry: initial_entry })
+    }
+
+    fn fill(&mut self, hole: Hole, goto: InstPtr) {
+        match hole {
+            Hole::None => {}
+            Hole::One(pc) => {
+                self.insts[pc].fill(goto);
+            }
+            Hole::Many(holes) => {
+                for hole in holes {
+                    self.fill(hole, goto);
+                }
+            }
+        }
+    }
+
+    fn fill_to_next(&mut self, hole: Hole) {
+        let next = self.insts.len();
+        self.fill(hole, next);
+    }
+
+    fn fill_split(
+        &mut self,
+        hole: Hole,
+        goto1: Option<InstPtr>,
+        goto2: Option<InstPtr>,
+    ) -> Hole {
+        match hole {
+            Hole::None => Hole::None,
+            Hole::One(pc) => {
+                match (goto1, goto2) {
+                    (Some(goto1), Some(goto2)) => {
+                        self.insts[pc].fill_split(goto1, goto2);
+                        Hole::None
+                    }
+                    (Some(goto1), None) => {
+                        self.insts[pc].half_fill_split_goto1(goto1);
+                        Hole::One(pc)
+                    }
+                    (None, Some(goto2)) => {
+                        self.insts[pc].half_fill_split_goto2(goto2);
+                        Hole::One(pc)
+                    }
+                    (None, None) => unreachable!("at least one of the split \
+                                                  holes must be filled"),
+                }
+            }
+            Hole::Many(holes) => {
+                let mut new_holes = vec![];
+                for hole in holes {
+                    new_holes.push(self.fill_split(hole, goto1, goto2));
+                }
+                if new_holes.is_empty() {
+                    Hole::None
+                } else if new_holes.len() == 1 {
+                    new_holes.pop().unwrap()
+                } else {
+                    Hole::Many(new_holes)
+                }
+            }
+        }
+    }
+
+    fn push_compiled(&mut self, inst: Inst) {
+        self.insts.push(MaybeInst::Compiled(inst));
+    }
+
+    fn push_hole(&mut self, inst: InstHole) -> Hole {
+        let hole = self.insts.len();
+        self.insts.push(MaybeInst::Uncompiled(inst));
+        Hole::One(hole)
+    }
+
+    fn push_split_hole(&mut self) -> Hole {
+        let hole = self.insts.len();
+        self.insts.push(MaybeInst::Split);
+        Hole::One(hole)
+    }
+
+    fn check_size(&self) -> result::Result<(), Error> {
+        use std::mem::size_of;
+
+        if self.insts.len() * size_of::<Inst>() > self.size_limit {
+            Err(Error::CompiledTooBig(self.size_limit))
+        } else {
+            Ok(())
+        }
+    }
+}
+
+#[derive(Debug)]
+enum Hole {
+    None,
+    One(InstPtr),
+    Many(Vec<Hole>),
+}
+
+#[derive(Clone, Debug)]
+enum MaybeInst {
+    Compiled(Inst),
+    Uncompiled(InstHole),
+    Split,
+    Split1(InstPtr),
+    Split2(InstPtr),
+}
+
+impl MaybeInst {
+    fn fill(&mut self, goto: InstPtr) {
+        let filled = match *self {
+            MaybeInst::Uncompiled(ref inst) => inst.fill(goto),
+            MaybeInst::Split1(goto1) => {
+                Inst::Split(InstSplit { goto1: goto1, goto2: goto })
+            }
+            MaybeInst::Split2(goto2) => {
+                Inst::Split(InstSplit { goto1: goto, goto2: goto2 })
+            }
+            _ => unreachable!("not all instructions were compiled! \
+                               found uncompiled instruction: {:?}", self),
+        };
+        *self = MaybeInst::Compiled(filled);
+    }
+
+    fn fill_split(&mut self, goto1: InstPtr, goto2: InstPtr) {
+        let filled = match *self {
+            MaybeInst::Split => {
+                Inst::Split(InstSplit { goto1: goto1, goto2: goto2 })
+            }
+            _ => unreachable!("must be called on Split instruction, \
+                               instead it was called on: {:?}", self),
+        };
+        *self = MaybeInst::Compiled(filled);
+    }
+
+    fn half_fill_split_goto1(&mut self, goto1: InstPtr) {
+        let half_filled = match *self {
+            MaybeInst::Split => goto1,
+            _ => unreachable!("must be called on Split instruction, \
+                               instead it was called on: {:?}", self),
+        };
+        *self = MaybeInst::Split1(half_filled);
+    }
+
+    fn half_fill_split_goto2(&mut self, goto2: InstPtr) {
+        let half_filled = match *self {
+            MaybeInst::Split => goto2,
+            _ => unreachable!("must be called on Split instruction, \
+                               instead it was called on: {:?}", self),
+        };
+        *self = MaybeInst::Split2(half_filled);
+    }
+
+    fn unwrap(self) -> Inst {
+        match self {
+            MaybeInst::Compiled(inst) => inst,
+            _ => unreachable!("must be called on a compiled instruction, \
+                               instead it was called on: {:?}", self),
+        }
+    }
+}
+
+#[derive(Clone, Debug)]
+enum InstHole {
+    Save { slot: usize },
+    EmptyLook { look: EmptyLook },
+    Char { c: char },
+    Ranges { ranges: Vec<(char, char)> },
+    Bytes { start: u8, end: u8 },
+}
+
+impl InstHole {
+    fn fill(&self, goto: InstPtr) -> Inst {
+        match *self {
+            InstHole::Save { slot } => Inst::Save(InstSave {
+                goto: goto,
+                slot: slot,
+            }),
+            InstHole::EmptyLook { look } => Inst::EmptyLook(InstEmptyLook {
+                goto: goto,
+                look: look,
+            }),
+            InstHole::Char { c } => Inst::Char(InstChar {
+                goto: goto,
+                c: c,
+            }),
+            InstHole::Ranges { ref ranges } => Inst::Ranges(InstRanges {
+                goto: goto,
+                ranges: ranges.clone(),
+            }),
+            InstHole::Bytes { start, end } => Inst::Bytes(InstBytes {
+                goto: goto,
+                start: start,
+                end: end,
+            }),
+        }
+    }
+}
+
+struct CompileClass<'a, 'b> {
+    c: &'a mut Compiler,
+    ranges: &'b [hir::ClassUnicodeRange],
+}
+
+impl<'a, 'b> CompileClass<'a, 'b> {
+    fn compile(mut self) -> Result {
+        let mut holes = vec![];
+        let mut initial_entry = None;
+        let mut last_split = Hole::None;
+        let mut utf8_seqs = self.c.utf8_seqs.take().unwrap();
+        self.c.suffix_cache.clear();
+
+        for (i, range) in self.ranges.iter().enumerate() {
+            let is_last_range = i + 1 == self.ranges.len();
+            utf8_seqs.reset(range.start(), range.end());
+            let mut it = (&mut utf8_seqs).peekable();
+            loop {
+                let utf8_seq = match it.next() {
+                    None => break,
+                    Some(utf8_seq) => utf8_seq,
+                };
+                if is_last_range && it.peek().is_none() {
+                    let Patch { hole, entry } = self.c_utf8_seq(&utf8_seq)?;
+                    holes.push(hole);
+                    self.c.fill(last_split, entry);
+                    last_split = Hole::None;
+                    if initial_entry.is_none() {
+                        initial_entry = Some(entry);
+                    }
+                } else {
+                    if initial_entry.is_none() {
+                        initial_entry = Some(self.c.insts.len());
+                    }
+                    self.c.fill_to_next(last_split);
+                    last_split = self.c.push_split_hole();
+                    let Patch { hole, entry } = self.c_utf8_seq(&utf8_seq)?;
+                    holes.push(hole);
+                    last_split = self.c.fill_split(last_split, Some(entry), None);
+                }
+            }
+        }
+        self.c.utf8_seqs = Some(utf8_seqs);
+        Ok(Patch {
+            hole: Hole::Many(holes),
+            entry: initial_entry.unwrap(),
+        })
+    }
+
+    fn c_utf8_seq(&mut self, seq: &Utf8Sequence) -> Result {
+        if self.c.compiled.is_reverse {
+            self.c_utf8_seq_(seq)
+        } else {
+            self.c_utf8_seq_(seq.into_iter().rev())
+        }
+    }
+
+    fn c_utf8_seq_<'r, I>(&mut self, seq: I) -> Result
+            where I: IntoIterator<Item=&'r Utf8Range> {
+        // The initial instruction for each UTF-8 sequence should be the same.
+        let mut from_inst = ::std::usize::MAX;
+        let mut last_hole = Hole::None;
+        for byte_range in seq {
+            let key = SuffixCacheKey {
+                from_inst: from_inst,
+                start: byte_range.start,
+                end: byte_range.end,
+            };
+            {
+                let pc = self.c.insts.len();
+                if let Some(cached_pc) = self.c.suffix_cache.get(key, pc) {
+                    from_inst = cached_pc;
+                    continue;
+                }
+            }
+            self.c.byte_classes.set_range(byte_range.start, byte_range.end);
+            if from_inst == ::std::usize::MAX {
+                last_hole = self.c.push_hole(InstHole::Bytes {
+                    start: byte_range.start,
+                    end: byte_range.end,
+                });
+            } else {
+                self.c.push_compiled(Inst::Bytes(InstBytes {
+                    goto: from_inst,
+                    start: byte_range.start,
+                    end: byte_range.end,
+                }));
+            }
+            from_inst = self.c.insts.len().checked_sub(1).unwrap();
+            debug_assert!(from_inst < ::std::usize::MAX);
+        }
+        debug_assert!(from_inst < ::std::usize::MAX);
+        Ok(Patch { hole: last_hole, entry: from_inst })
+    }
+}
+
+/// `SuffixCache` is a simple bounded hash map for caching suffix entries in
+/// UTF-8 automata. For example, consider the Unicode range \u{0}-\u{FFFF}.
+/// The set of byte ranges looks like this:
+///
+/// [0-7F]
+/// [C2-DF][80-BF]
+/// [E0][A0-BF][80-BF]
+/// [E1-EC][80-BF][80-BF]
+/// [ED][80-9F][80-BF]
+/// [EE-EF][80-BF][80-BF]
+///
+/// Each line above translates to one alternate in the compiled regex program.
+/// However, all but one of the alternates end in the same suffix, which is
+/// a waste of an instruction. The suffix cache facilitates reusing them across
+/// alternates.
+///
+/// Note that a HashMap could be trivially used for this, but we don't need its
+/// overhead. Some small bounded space (LRU style) is more than enough.
+///
+/// This uses similar idea to [`SparseSet`](../sparse/struct.SparseSet.html),
+/// except it uses hashes as original indices and then compares full keys for
+/// validation against `dense` array.
+struct SuffixCache {
+    sparse: Box<[usize]>,
+    dense: Vec<SuffixCacheEntry>,
+}
+
+#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
+struct SuffixCacheEntry {
+    key: SuffixCacheKey,
+    pc: InstPtr,
+}
+
+#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
+struct SuffixCacheKey {
+    from_inst: InstPtr,
+    start: u8,
+    end: u8,
+}
+
+impl SuffixCache {
+    fn new(size: usize) -> Self {
+        SuffixCache {
+            sparse: vec![0usize; size].into(),
+            dense: Vec::with_capacity(size),
+        }
+    }
+
+    fn get(&mut self, key: SuffixCacheKey, pc: InstPtr) -> Option<InstPtr> {
+        let hash = self.hash(&key);
+        let pos = &mut self.sparse[hash];
+        if let Some(entry) = self.dense.get(*pos) {
+            if entry.key == key {
+                return Some(entry.pc);
+            }
+        }
+        *pos = self.dense.len();
+        self.dense.push(SuffixCacheEntry {
+            key: key,
+            pc: pc,
+        });
+        None
+    }
+
+    fn clear(&mut self) {
+        self.dense.clear();
+    }
+
+    fn hash(&self, suffix: &SuffixCacheKey) -> usize {
+        // Basic FNV-1a hash as described:
+        // https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
+        const FNV_PRIME: u64 = 1099511628211;
+        let mut h = 14695981039346656037;
+        h = (h ^ (suffix.from_inst as u64)).wrapping_mul(FNV_PRIME);
+        h = (h ^ (suffix.start as u64)).wrapping_mul(FNV_PRIME);
+        h = (h ^ (suffix.end as u64)).wrapping_mul(FNV_PRIME);
+        (h as usize) % self.sparse.len()
+    }
+}
+
+struct ByteClassSet([bool; 256]);
+
+impl ByteClassSet {
+    fn new() -> Self {
+        ByteClassSet([false; 256])
+    }
+
+    fn set_range(&mut self, start: u8, end: u8) {
+        debug_assert!(start <= end);
+        if start > 0 {
+            self.0[start as usize - 1] = true;
+        }
+        self.0[end as usize] = true;
+    }
+
+    fn set_word_boundary(&mut self) {
+        // We need to mark all ranges of bytes whose pairs result in
+        // evaluating \b differently.
+        let iswb = is_word_byte;
+        let mut b1: u16 = 0;
+        let mut b2: u16;
+        while b1 <= 255 {
+            b2 = b1 + 1;
+            while b2 <= 255 && iswb(b1 as u8) == iswb(b2 as u8) {
+                b2 += 1;
+            }
+            self.set_range(b1 as u8, (b2 - 1) as u8);
+            b1 = b2;
+        }
+    }
+
+    fn byte_classes(&self) -> Vec<u8> {
+        // N.B. If you're debugging the DFA, it's useful to simply return
+        // `(0..256).collect()`, which effectively removes the byte classes
+        // and makes the transitions easier to read.
+        // (0usize..256).map(|x| x as u8).collect()
+        let mut byte_classes = vec![0; 256];
+        let mut class = 0u8;
+        let mut i = 0;
+        loop {
+            byte_classes[i] = class as u8;
+            if i >= 255 {
+                break;
+            }
+            if self.0[i] {
+                class = class.checked_add(1).unwrap();
+            }
+            i += 1;
+        }
+        byte_classes
+    }
+}
+
+fn u32_to_usize(n: u32) -> usize {
+    // In case usize is less than 32 bits, we need to guard against overflow.
+    // On most platforms this compiles to nothing.
+    // TODO Use `std::convert::TryFrom` once it's stable.
+    if (n as u64) > (::std::usize::MAX as u64) {
+        panic!("BUG: {} is too big to be pointer sized", n)
+    }
+    n as usize
+}
+
+#[cfg(test)]
+mod tests {
+    use super::ByteClassSet;
+
+    #[test]
+    fn byte_classes() {
+        let mut set = ByteClassSet::new();
+        set.set_range(b'a', b'z');
+        let classes = set.byte_classes();
+        assert_eq!(classes[0], 0);
+        assert_eq!(classes[1], 0);
+        assert_eq!(classes[2], 0);
+        assert_eq!(classes[b'a' as usize - 1], 0);
+        assert_eq!(classes[b'a' as usize], 1);
+        assert_eq!(classes[b'm' as usize], 1);
+        assert_eq!(classes[b'z' as usize], 1);
+        assert_eq!(classes[b'z' as usize + 1], 2);
+        assert_eq!(classes[254], 2);
+        assert_eq!(classes[255], 2);
+
+        let mut set = ByteClassSet::new();
+        set.set_range(0, 2);
+        set.set_range(4, 6);
+        let classes = set.byte_classes();
+        assert_eq!(classes[0], 0);
+        assert_eq!(classes[1], 0);
+        assert_eq!(classes[2], 0);
+        assert_eq!(classes[3], 1);
+        assert_eq!(classes[4], 2);
+        assert_eq!(classes[5], 2);
+        assert_eq!(classes[6], 2);
+        assert_eq!(classes[7], 3);
+        assert_eq!(classes[255], 3);
+    }
+
+    #[test]
+    fn full_byte_classes() {
+        let mut set = ByteClassSet::new();
+        for i in 0..256u16 {
+            set.set_range(i as u8, i as u8);
+        }
+        assert_eq!(set.byte_classes().len(), 256);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/dfa.rs.html b/target/doc/src/regex/dfa.rs.html new file mode 100644 index 0000000..2a7aeef --- /dev/null +++ b/target/doc/src/regex/dfa.rs.html @@ -0,0 +1,3933 @@ +dfa.rs.html -- source
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+
+// Copyright 2014-2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+The DFA matching engine.
+
+A DFA provides faster matching because the engine is in exactly one state at
+any point in time. In the NFA, there may be multiple active states, and
+considerable CPU cycles are spent shuffling them around. In finite automata
+speak, the DFA follows epsilon transitions in the regex far less than the NFA.
+
+A DFA is a classic trade off between time and space. The NFA is slower, but
+its memory requirements are typically small and predictable. The DFA is faster,
+but given the right regex and the right input, the number of states in the
+DFA can grow exponentially. To mitigate this space problem, we do two things:
+
+1. We implement an *online* DFA. That is, the DFA is constructed from the NFA
+   during a search. When a new state is computed, it is stored in a cache so
+   that it may be reused. An important consequence of this implementation
+   is that states that are never reached for a particular input are never
+   computed. (This is impossible in an "offline" DFA which needs to compute
+   all possible states up front.)
+2. If the cache gets too big, we wipe it and continue matching.
+
+In pathological cases, a new state can be created for every byte of input.
+(e.g., The regex `(a|b)*a(a|b){20}` on a long sequence of a's and b's.)
+In this case, performance regresses to slightly slower than the full NFA
+simulation, in large part because the cache becomes useless. If the cache
+is wiped too frequently, the DFA quits and control falls back to one of the
+NFA simulations.
+
+Because of the "lazy" nature of this DFA, the inner matching loop is
+considerably more complex than one might expect out of a DFA. A number of
+tricks are employed to make it fast. Tread carefully.
+
+N.B. While this implementation is heavily commented, Russ Cox's series of
+articles on regexes is strongly recommended: https://swtch.com/~rsc/regexp/
+(As is the DFA implementation in RE2, which heavily influenced this
+implementation.)
+*/
+
+use std::collections::HashMap;
+use std::fmt;
+use std::iter::repeat;
+use std::mem;
+use std::sync::Arc;
+
+use exec::ProgramCache;
+use prog::{Inst, Program};
+use sparse::SparseSet;
+
+/// Return true if and only if the given program can be executed by a DFA.
+///
+/// Generally, a DFA is always possible. A pathological case where it is not
+/// possible is if the number of NFA states exceeds `u32::MAX`, in which case,
+/// this function will return false.
+///
+/// This function will also return false if the given program has any Unicode
+/// instructions (Char or Ranges) since the DFA operates on bytes only.
+pub fn can_exec(insts: &Program) -> bool {
+    use prog::Inst::*;
+    // If for some reason we manage to allocate a regex program with more
+    // than i32::MAX instructions, then we can't execute the DFA because we
+    // use 32 bit instruction pointer deltas for memory savings.
+    // If i32::MAX is the largest positive delta,
+    // then -i32::MAX == i32::MIN + 1 is the largest negative delta,
+    // and we are OK to use 32 bits.
+    if insts.dfa_size_limit == 0 || insts.len() > ::std::i32::MAX as usize {
+        return false;
+    }
+    for inst in insts {
+        match *inst {
+            Char(_) | Ranges(_) => return false,
+            EmptyLook(_) | Match(_) | Save(_) | Split(_) | Bytes(_) => {}
+        }
+    }
+    true
+}
+
+/// A reusable cache of DFA states.
+///
+/// This cache is reused between multiple invocations of the same regex
+/// program. (It is not shared simultaneously between threads. If there is
+/// contention, then new caches are created.)
+#[derive(Debug)]
+pub struct Cache {
+    /// Group persistent DFA related cache state together. The sparse sets
+    /// listed below are used as scratch space while computing uncached states.
+    inner: CacheInner,
+    /// qcur and qnext are ordered sets with constant time
+    /// addition/membership/clearing-whole-set and linear time iteration. They
+    /// are used to manage the sets of NFA states in DFA states when computing
+    /// cached DFA states. In particular, the order of the NFA states matters
+    /// for leftmost-first style matching. Namely, when computing a cached
+    /// state, the set of NFA states stops growing as soon as the first Match
+    /// instruction is observed.
+    qcur: SparseSet,
+    qnext: SparseSet,
+}
+
+/// `CacheInner` is logically just a part of Cache, but groups together fields
+/// that aren't passed as function parameters throughout search. (This split
+/// is mostly an artifact of the borrow checker. It is happily paid.)
+#[derive(Debug)]
+struct CacheInner {
+    /// A cache of pre-compiled DFA states, keyed by the set of NFA states
+    /// and the set of empty-width flags set at the byte in the input when the
+    /// state was observed.
+    ///
+    /// A StatePtr is effectively a `*State`, but to avoid various inconvenient
+    /// things, we just pass indexes around manually. The performance impact of
+    /// this is probably an instruction or two in the inner loop. However, on
+    /// 64 bit, each StatePtr is half the size of a *State.
+    compiled: StateMap,
+    /// The transition table.
+    ///
+    /// The transition table is laid out in row-major order, where states are
+    /// rows and the transitions for each state are columns. At a high level,
+    /// given state `s` and byte `b`, the next state can be found at index
+    /// `s * 256 + b`.
+    ///
+    /// This is, of course, a lie. A StatePtr is actually a pointer to the
+    /// *start* of a row in this table. When indexing in the DFA's inner loop,
+    /// this removes the need to multiply the StatePtr by the stride. Yes, it
+    /// matters. This reduces the number of states we can store, but: the
+    /// stride is rarely 256 since we define transitions in terms of
+    /// *equivalence classes* of bytes. Each class corresponds to a set of
+    /// bytes that never discriminate a distinct path through the DFA from each
+    /// other.
+    trans: Transitions,
+    /// A set of cached start states, which are limited to the number of
+    /// permutations of flags set just before the initial byte of input. (The
+    /// index into this vec is a `EmptyFlags`.)
+    ///
+    /// N.B. A start state can be "dead" (i.e., no possible match), so we
+    /// represent it with a StatePtr.
+    start_states: Vec<StatePtr>,
+    /// Stack scratch space used to follow epsilon transitions in the NFA.
+    /// (This permits us to avoid recursion.)
+    ///
+    /// The maximum stack size is the number of NFA states.
+    stack: Vec<InstPtr>,
+    /// The total number of times this cache has been flushed by the DFA
+    /// because of space constraints.
+    flush_count: u64,
+    /// The total heap size of the DFA's cache. We use this to determine when
+    /// we should flush the cache.
+    size: usize,
+    /// Scratch space used when building instruction pointer lists for new
+    /// states. This helps amortize allocation.
+    insts_scratch_space: Vec<u8>,
+}
+
+/// The transition table.
+///
+/// It is laid out in row-major order, with states as rows and byte class
+/// transitions as columns.
+///
+/// The transition table is responsible for producing valid `StatePtrs`. A
+/// `StatePtr` points to the start of a particular row in this table. When
+/// indexing to find the next state this allows us to avoid a multiplication
+/// when computing an index into the table.
+#[derive(Clone)]
+struct Transitions {
+    /// The table.
+    table: Vec<StatePtr>,
+    /// The stride.
+    num_byte_classes: usize,
+}
+
+/// Fsm encapsulates the actual execution of the DFA.
+#[derive(Debug)]
+pub struct Fsm<'a> {
+    /// prog contains the NFA instruction opcodes. DFA execution uses either
+    /// the `dfa` instructions or the `dfa_reverse` instructions from
+    /// `exec::ExecReadOnly`. (It never uses `ExecReadOnly.nfa`, which may have
+    /// Unicode opcodes that cannot be executed by the DFA.)
+    prog: &'a Program,
+    /// The start state. We record it here because the pointer may change
+    /// when the cache is wiped.
+    start: StatePtr,
+    /// The current position in the input.
+    at: usize,
+    /// Should we quit after seeing the first match? e.g., When the caller
+    /// uses `is_match` or `shortest_match`.
+    quit_after_match: bool,
+    /// The last state that matched.
+    ///
+    /// When no match has occurred, this is set to STATE_UNKNOWN.
+    ///
+    /// This is only useful when matching regex sets. The last match state
+    /// is useful because it contains all of the match instructions seen,
+    /// thereby allowing us to enumerate which regexes in the set matched.
+    last_match_si: StatePtr,
+    /// The input position of the last cache flush. We use this to determine
+    /// if we're thrashing in the cache too often. If so, the DFA quits so
+    /// that we can fall back to the NFA algorithm.
+    last_cache_flush: usize,
+    /// All cached DFA information that is persisted between searches.
+    cache: &'a mut CacheInner,
+}
+
+/// The result of running the DFA.
+///
+/// Generally, the result is either a match or not a match, but sometimes the
+/// DFA runs too slowly because the cache size is too small. In that case, it
+/// gives up with the intent of falling back to the NFA algorithm.
+///
+/// The DFA can also give up if it runs out of room to create new states, or if
+/// it sees non-ASCII bytes in the presence of a Unicode word boundary.
+#[derive(Clone, Debug)]
+pub enum Result<T> {
+    Match(T),
+    NoMatch(usize),
+    Quit,
+}
+
+impl<T> Result<T> {
+    /// Returns true if this result corresponds to a match.
+    pub fn is_match(&self) -> bool {
+        match *self {
+            Result::Match(_) => true,
+            Result::NoMatch(_) | Result::Quit => false,
+        }
+    }
+
+    /// Maps the given function onto T and returns the result.
+    ///
+    /// If this isn't a match, then this is a no-op.
+    pub fn map<U, F: FnMut(T) -> U>(self, mut f: F) -> Result<U> {
+        match self {
+            Result::Match(t) => Result::Match(f(t)),
+            Result::NoMatch(x) => Result::NoMatch(x),
+            Result::Quit => Result::Quit,
+        }
+    }
+
+    /// Sets the non-match position.
+    ///
+    /// If this isn't a non-match, then this is a no-op.
+    fn set_non_match(self, at: usize) -> Result<T> {
+        match self {
+            Result::NoMatch(_) => Result::NoMatch(at),
+            r => r,
+        }
+    }
+}
+
+/// `State` is a DFA state. It contains an ordered set of NFA states (not
+/// necessarily complete) and a smattering of flags.
+///
+/// The flags are packed into the first byte of data.
+///
+/// States don't carry their transitions. Instead, transitions are stored in
+/// a single row-major table.
+///
+/// Delta encoding is used to store the instruction pointers.
+/// The first instruction pointer is stored directly starting
+/// at data[1], and each following pointer is stored as an offset
+/// to the previous one. If a delta is in the range -127..127,
+/// it is packed into a single byte; Otherwise the byte 128 (-128 as an i8)
+/// is coded as a flag, followed by 4 bytes encoding the delta.
+#[derive(Clone, Eq, Hash, PartialEq)]
+struct State {
+    data: Arc<[u8]>,
+}
+
+/// `InstPtr` is a 32 bit pointer into a sequence of opcodes (i.e., it indexes
+/// an NFA state).
+///
+/// Throughout this library, this is usually set to `usize`, but we force a
+/// `u32` here for the DFA to save on space.
+type InstPtr = u32;
+
+/// Adds ip to data using delta encoding with respect to prev.
+///
+/// After completion, `data` will contain `ip` and `prev` will be set to `ip`.
+fn push_inst_ptr(data: &mut Vec<u8>, prev: &mut InstPtr, ip: InstPtr) {
+    let delta = (ip as i32) - (*prev as i32);
+    write_vari32(data, delta);
+    *prev = ip;
+}
+
+struct InstPtrs<'a> {
+    base: usize,
+    data: &'a [u8],
+}
+
+impl <'a>Iterator for InstPtrs<'a> {
+    type Item = usize;
+
+    fn next(&mut self) -> Option<usize> {
+        if self.data.is_empty() {
+            return None;
+        }
+        let (delta, nread) = read_vari32(self.data);
+        let base = self.base as i32 + delta;
+        debug_assert!(base >= 0);
+        debug_assert!(nread > 0);
+        self.data = &self.data[nread..];
+        self.base = base as usize;
+        Some(self.base)
+    }
+}
+
+impl State {
+    fn flags(&self) -> StateFlags {
+        StateFlags(self.data[0])
+    }
+
+    fn inst_ptrs(&self) -> InstPtrs {
+        InstPtrs {
+            base: 0,
+            data: &self.data[1..],
+        }
+    }
+}
+
+/// `StatePtr` is a 32 bit pointer to the start of a row in the transition
+/// table.
+///
+/// It has many special values. There are two types of special values:
+/// sentinels and flags.
+///
+/// Sentinels corresponds to special states that carry some kind of
+/// significance. There are three such states: unknown, dead and quit states.
+///
+/// Unknown states are states that haven't been computed yet. They indicate
+/// that a transition should be filled in that points to either an existing
+/// cached state or a new state altogether. In general, an unknown state means
+/// "follow the NFA's epsilon transitions."
+///
+/// Dead states are states that can never lead to a match, no matter what
+/// subsequent input is observed. This means that the DFA should quit
+/// immediately and return the longest match it has found thus far.
+///
+/// Quit states are states that imply the DFA is not capable of matching the
+/// regex correctly. Currently, this is only used when a Unicode word boundary
+/// exists in the regex *and* a non-ASCII byte is observed.
+///
+/// The other type of state pointer is a state pointer with special flag bits.
+/// There are two flags: a start flag and a match flag. The lower bits of both
+/// kinds always contain a "valid" `StatePtr` (indicated by the `STATE_MAX`
+/// mask).
+///
+/// The start flag means that the state is a start state, and therefore may be
+/// subject to special prefix scanning optimizations.
+///
+/// The match flag means that the state is a match state, and therefore the
+/// current position in the input (while searching) should be recorded.
+///
+/// The above exists mostly in the service of making the inner loop fast.
+/// In particular, the inner *inner* loop looks something like this:
+///
+/// ```ignore
+/// while state <= STATE_MAX and i < len(text):
+///     state = state.next[i]
+/// ```
+///
+/// This is nice because it lets us execute a lazy DFA as if it were an
+/// entirely offline DFA (i.e., with very few instructions). The loop will
+/// quit only when we need to examine a case that needs special attention.
+type StatePtr = u32;
+
+/// An unknown state means that the state has not been computed yet, and that
+/// the only way to progress is to compute it.
+const STATE_UNKNOWN: StatePtr = 1<<31;
+
+/// A dead state means that the state has been computed and it is known that
+/// once it is entered, no future match can ever occur.
+const STATE_DEAD: StatePtr = STATE_UNKNOWN + 1;
+
+/// A quit state means that the DFA came across some input that it doesn't
+/// know how to process correctly. The DFA should quit and another matching
+/// engine should be run in its place.
+const STATE_QUIT: StatePtr = STATE_DEAD + 1;
+
+/// A start state is a state that the DFA can start in.
+///
+/// Note that start states have their lower bits set to a state pointer.
+const STATE_START: StatePtr = 1<<30;
+
+/// A match state means that the regex has successfully matched.
+///
+/// Note that match states have their lower bits set to a state pointer.
+const STATE_MATCH: StatePtr = 1<<29;
+
+/// The maximum state pointer. This is useful to mask out the "valid" state
+/// pointer from a state with the "start" or "match" bits set.
+///
+/// It doesn't make sense to use this with unknown, dead or quit state
+/// pointers, since those pointers are sentinels and never have their lower
+/// bits set to anything meaningful.
+const STATE_MAX: StatePtr = STATE_MATCH - 1;
+
+/// Byte is a u8 in spirit, but a u16 in practice so that we can represent the
+/// special EOF sentinel value.
+#[derive(Copy, Clone, Debug)]
+struct Byte(u16);
+
+/// A set of flags for zero-width assertions.
+#[derive(Clone, Copy, Eq, Debug, Default, Hash, PartialEq)]
+struct EmptyFlags {
+    start: bool,
+    end: bool,
+    start_line: bool,
+    end_line: bool,
+    word_boundary: bool,
+    not_word_boundary: bool,
+}
+
+/// A set of flags describing various configurations of a DFA state. This is
+/// represented by a `u8` so that it is compact.
+#[derive(Clone, Copy, Eq, Default, Hash, PartialEq)]
+struct StateFlags(u8);
+
+impl Cache {
+    /// Create new empty cache for the DFA engine.
+    pub fn new(prog: &Program) -> Self {
+        // We add 1 to account for the special EOF byte.
+        let num_byte_classes = (prog.byte_classes[255] as usize + 1) + 1;
+        let starts = vec![STATE_UNKNOWN; 256];
+        let mut cache = Cache {
+            inner: CacheInner {
+                compiled: StateMap::new(num_byte_classes),
+                trans: Transitions::new(num_byte_classes),
+                start_states: starts,
+                stack: vec![],
+                flush_count: 0,
+                size: 0,
+                insts_scratch_space: vec![],
+            },
+            qcur: SparseSet::new(prog.insts.len()),
+            qnext: SparseSet::new(prog.insts.len()),
+        };
+        cache.inner.reset_size();
+        cache
+    }
+}
+
+impl CacheInner {
+    /// Resets the cache size to account for fixed costs, such as the program
+    /// and stack sizes.
+    fn reset_size(&mut self) {
+        self.size =
+            (self.start_states.len() * mem::size_of::<StatePtr>())
+            + (self.stack.len() * mem::size_of::<InstPtr>());
+    }
+}
+
+impl<'a> Fsm<'a> {
+    #[inline(always)] // reduces constant overhead
+    pub fn forward(
+        prog: &'a Program,
+        cache: &ProgramCache,
+        quit_after_match: bool,
+        text: &[u8],
+        at: usize,
+    ) -> Result<usize> {
+        let mut cache = cache.borrow_mut();
+        let cache = &mut cache.dfa;
+        let mut dfa = Fsm {
+            prog: prog,
+            start: 0, // filled in below
+            at: at,
+            quit_after_match: quit_after_match,
+            last_match_si: STATE_UNKNOWN,
+            last_cache_flush: at,
+            cache: &mut cache.inner,
+        };
+        let (empty_flags, state_flags) = dfa.start_flags(text, at);
+        dfa.start = match dfa.start_state(
+            &mut cache.qcur,
+            empty_flags,
+            state_flags,
+        ) {
+            None => return Result::Quit,
+            Some(STATE_DEAD) => return Result::NoMatch(at),
+            Some(si) => si,
+        };
+        debug_assert!(dfa.start != STATE_UNKNOWN);
+        dfa.exec_at(&mut cache.qcur, &mut cache.qnext, text)
+    }
+
+    #[inline(always)] // reduces constant overhead
+    pub fn reverse(
+        prog: &'a Program,
+        cache: &ProgramCache,
+        quit_after_match: bool,
+        text: &[u8],
+        at: usize,
+    ) -> Result<usize> {
+        let mut cache = cache.borrow_mut();
+        let cache = &mut cache.dfa_reverse;
+        let mut dfa = Fsm {
+            prog: prog,
+            start: 0, // filled in below
+            at: at,
+            quit_after_match: quit_after_match,
+            last_match_si: STATE_UNKNOWN,
+            last_cache_flush: at,
+            cache: &mut cache.inner,
+        };
+        let (empty_flags, state_flags) = dfa.start_flags_reverse(text, at);
+        dfa.start = match dfa.start_state(
+            &mut cache.qcur,
+            empty_flags,
+            state_flags,
+        ) {
+            None => return Result::Quit,
+            Some(STATE_DEAD) => return Result::NoMatch(at),
+            Some(si) => si,
+        };
+        debug_assert!(dfa.start != STATE_UNKNOWN);
+        dfa.exec_at_reverse(&mut cache.qcur, &mut cache.qnext, text)
+    }
+
+    #[inline(always)] // reduces constant overhead
+    pub fn forward_many(
+        prog: &'a Program,
+        cache: &ProgramCache,
+        matches: &mut [bool],
+        text: &[u8],
+        at: usize,
+    ) -> Result<usize> {
+        debug_assert!(matches.len() == prog.matches.len());
+        let mut cache = cache.borrow_mut();
+        let cache = &mut cache.dfa;
+        let mut dfa = Fsm {
+            prog: prog,
+            start: 0, // filled in below
+            at: at,
+            quit_after_match: false,
+            last_match_si: STATE_UNKNOWN,
+            last_cache_flush: at,
+            cache: &mut cache.inner,
+        };
+        let (empty_flags, state_flags) = dfa.start_flags(text, at);
+        dfa.start = match dfa.start_state(
+            &mut cache.qcur,
+            empty_flags,
+            state_flags,
+        ) {
+            None => return Result::Quit,
+            Some(STATE_DEAD) => return Result::NoMatch(at),
+            Some(si) => si,
+        };
+        debug_assert!(dfa.start != STATE_UNKNOWN);
+        let result = dfa.exec_at(&mut cache.qcur, &mut cache.qnext, text);
+        if result.is_match() {
+            if matches.len() == 1 {
+                matches[0] = true;
+            } else {
+                debug_assert!(dfa.last_match_si != STATE_UNKNOWN);
+                debug_assert!(dfa.last_match_si != STATE_DEAD);
+                for ip in dfa.state(dfa.last_match_si).inst_ptrs() {
+                    if let Inst::Match(slot) = dfa.prog[ip] {
+                        matches[slot] = true;
+                    }
+                }
+            }
+        }
+        result
+    }
+
+    /// Executes the DFA on a forward NFA.
+    ///
+    /// {qcur,qnext} are scratch ordered sets which may be non-empty.
+    #[inline(always)] // reduces constant overhead
+    fn exec_at(
+        &mut self,
+        qcur: &mut SparseSet,
+        qnext: &mut SparseSet,
+        text: &[u8],
+    ) -> Result<usize> {
+        // For the most part, the DFA is basically:
+        //
+        //   last_match = null
+        //   while current_byte != EOF:
+        //     si = current_state.next[current_byte]
+        //     if si is match
+        //       last_match = si
+        //   return last_match
+        //
+        // However, we need to deal with a few things:
+        //
+        //   1. This is an *online* DFA, so the current state's next list
+        //      may not point to anywhere yet, so we must go out and compute
+        //      them. (They are then cached into the current state's next list
+        //      to avoid re-computation.)
+        //   2. If we come across a state that is known to be dead (i.e., never
+        //      leads to a match), then we can quit early.
+        //   3. If the caller just wants to know if a match occurs, then we
+        //      can quit as soon as we know we have a match. (Full leftmost
+        //      first semantics require continuing on.)
+        //   4. If we're in the start state, then we can use a pre-computed set
+        //      of prefix literals to skip quickly along the input.
+        //   5. After the input is exhausted, we run the DFA on one symbol
+        //      that stands for EOF. This is useful for handling empty width
+        //      assertions.
+        //   6. We can't actually do state.next[byte]. Instead, we have to do
+        //      state.next[byte_classes[byte]], which permits us to keep the
+        //      'next' list very small.
+        //
+        // Since there's a bunch of extra stuff we need to consider, we do some
+        // pretty hairy tricks to get the inner loop to run as fast as
+        // possible.
+        debug_assert!(!self.prog.is_reverse);
+
+        // The last match is the currently known ending match position. It is
+        // reported as an index to the most recent byte that resulted in a
+        // transition to a match state and is always stored in capture slot `1`
+        // when searching forwards. Its maximum value is `text.len()`.
+        let mut result = Result::NoMatch(self.at);
+        let (mut prev_si, mut next_si) = (self.start, self.start);
+        let mut at = self.at;
+        while at < text.len() {
+            // This is the real inner loop. We take advantage of special bits
+            // set in the state pointer to determine whether a state is in the
+            // "common" case or not. Specifically, the common case is a
+            // non-match non-start non-dead state that has already been
+            // computed. So long as we remain in the common case, this inner
+            // loop will chew through the input.
+            //
+            // We also unroll the loop 4 times to amortize the cost of checking
+            // whether we've consumed the entire input. We are also careful
+            // to make sure that `prev_si` always represents the previous state
+            // and `next_si` always represents the next state after the loop
+            // exits, even if it isn't always true inside the loop.
+            while next_si <= STATE_MAX && at < text.len() {
+                // Argument for safety is in the definition of next_si.
+                prev_si = unsafe { self.next_si(next_si, text, at) };
+                at += 1;
+                if prev_si > STATE_MAX || at + 2 >= text.len() {
+                    mem::swap(&mut prev_si, &mut next_si);
+                    break;
+                }
+                next_si = unsafe { self.next_si(prev_si, text, at) };
+                at += 1;
+                if next_si > STATE_MAX {
+                    break;
+                }
+                prev_si = unsafe { self.next_si(next_si, text, at) };
+                at += 1;
+                if prev_si > STATE_MAX {
+                    mem::swap(&mut prev_si, &mut next_si);
+                    break;
+                }
+                next_si = unsafe { self.next_si(prev_si, text, at) };
+                at += 1;
+            }
+            if next_si & STATE_MATCH > 0 {
+                // A match state is outside of the common case because it needs
+                // special case analysis. In particular, we need to record the
+                // last position as having matched and possibly quit the DFA if
+                // we don't need to keep matching.
+                next_si &= !STATE_MATCH;
+                result = Result::Match(at - 1);
+                if self.quit_after_match {
+                    return result;
+                }
+                self.last_match_si = next_si;
+                prev_si = next_si;
+
+                // This permits short-circuiting when matching a regex set.
+                // In particular, if this DFA state contains only match states,
+                // then it's impossible to extend the set of matches since
+                // match states are final. Therefore, we can quit.
+                if self.prog.matches.len() > 1 {
+                    let state = self.state(next_si);
+                    let just_matches = state.inst_ptrs()
+                         .all(|ip| self.prog[ip].is_match());
+                    if just_matches {
+                        return result;
+                    }
+                }
+
+                // Another inner loop! If the DFA stays in this particular
+                // match state, then we can rip through all of the input
+                // very quickly, and only recording the match location once
+                // we've left this particular state.
+                let cur = at;
+                while (next_si & !STATE_MATCH) == prev_si
+                    && at + 2 < text.len() {
+                    // Argument for safety is in the definition of next_si.
+                    next_si = unsafe {
+                        self.next_si(next_si & !STATE_MATCH, text, at)
+                    };
+                    at += 1;
+                }
+                if at > cur {
+                    result = Result::Match(at - 2);
+                }
+            } else if next_si & STATE_START > 0 {
+                // A start state isn't in the common case because we may
+                // what to do quick prefix scanning. If the program doesn't
+                // have a detected prefix, then start states are actually
+                // considered common and this case is never reached.
+                debug_assert!(self.has_prefix());
+                next_si &= !STATE_START;
+                prev_si = next_si;
+                at = match self.prefix_at(text, at) {
+                    None => return Result::NoMatch(text.len()),
+                    Some(i) => i,
+                };
+            } else if next_si >= STATE_UNKNOWN {
+                if next_si == STATE_QUIT {
+                    return Result::Quit;
+                }
+                // Finally, this corresponds to the case where the transition
+                // entered a state that can never lead to a match or a state
+                // that hasn't been computed yet. The latter being the "slow"
+                // path.
+                let byte = Byte::byte(text[at - 1]);
+                // We no longer care about the special bits in the state
+                // pointer.
+                prev_si &= STATE_MAX;
+                // Record where we are. This is used to track progress for
+                // determining whether we should quit if we've flushed the
+                // cache too much.
+                self.at = at;
+                next_si = match self.next_state(qcur, qnext, prev_si, byte) {
+                    None => return Result::Quit,
+                    Some(STATE_DEAD) => return result.set_non_match(at),
+                    Some(si) => si,
+                };
+                debug_assert!(next_si != STATE_UNKNOWN);
+                if next_si & STATE_MATCH > 0 {
+                    next_si &= !STATE_MATCH;
+                    result = Result::Match(at - 1);
+                    if self.quit_after_match {
+                        return result;
+                    }
+                    self.last_match_si = next_si;
+                }
+                prev_si = next_si;
+            } else {
+                prev_si = next_si;
+            }
+        }
+
+        // Run the DFA once more on the special EOF senitnel value.
+        // We don't care about the special bits in the state pointer any more,
+        // so get rid of them.
+        prev_si &= STATE_MAX;
+        prev_si = match self.next_state(qcur, qnext, prev_si, Byte::eof()) {
+            None => return Result::Quit,
+            Some(STATE_DEAD) => return result.set_non_match(text.len()),
+            Some(si) => si & !STATE_START,
+        };
+        debug_assert!(prev_si != STATE_UNKNOWN);
+        if prev_si & STATE_MATCH > 0 {
+            prev_si &= !STATE_MATCH;
+            self.last_match_si = prev_si;
+            result = Result::Match(text.len());
+        }
+        result
+    }
+
+    /// Executes the DFA on a reverse NFA.
+    #[inline(always)] // reduces constant overhead
+    fn exec_at_reverse(
+        &mut self,
+        qcur: &mut SparseSet,
+        qnext: &mut SparseSet,
+        text: &[u8],
+    ) -> Result<usize> {
+        // The comments in `exec_at` above mostly apply here too. The main
+        // difference is that we move backwards over the input and we look for
+        // the longest possible match instead of the leftmost-first match.
+        //
+        // N.B. The code duplication here is regrettable. Efforts to improve
+        // it without sacrificing performance are welcome. ---AG
+        debug_assert!(self.prog.is_reverse);
+        let mut result = Result::NoMatch(self.at);
+        let (mut prev_si, mut next_si) = (self.start, self.start);
+        let mut at = self.at;
+        while at > 0 {
+            while next_si <= STATE_MAX && at > 0 {
+                // Argument for safety is in the definition of next_si.
+                at -= 1;
+                prev_si = unsafe { self.next_si(next_si, text, at) };
+                if prev_si > STATE_MAX || at <= 4 {
+                    mem::swap(&mut prev_si, &mut next_si);
+                    break;
+                }
+                at -= 1;
+                next_si = unsafe { self.next_si(prev_si, text, at) };
+                if next_si > STATE_MAX {
+                    break;
+                }
+                at -= 1;
+                prev_si = unsafe { self.next_si(next_si, text, at) };
+                if prev_si > STATE_MAX {
+                    mem::swap(&mut prev_si, &mut next_si);
+                    break;
+                }
+                at -= 1;
+                next_si = unsafe { self.next_si(prev_si, text, at) };
+            }
+            if next_si & STATE_MATCH > 0 {
+                next_si &= !STATE_MATCH;
+                result = Result::Match(at + 1);
+                if self.quit_after_match {
+                    return result
+                }
+                self.last_match_si = next_si;
+                prev_si = next_si;
+                let cur = at;
+                while (next_si & !STATE_MATCH) == prev_si && at >= 2 {
+                    // Argument for safety is in the definition of next_si.
+                    at -= 1;
+                    next_si = unsafe {
+                        self.next_si(next_si & !STATE_MATCH, text, at)
+                    };
+                }
+                if at < cur {
+                    result = Result::Match(at + 2);
+                }
+            } else if next_si >= STATE_UNKNOWN {
+                if next_si == STATE_QUIT {
+                    return Result::Quit;
+                }
+                let byte = Byte::byte(text[at]);
+                prev_si &= STATE_MAX;
+                self.at = at;
+                next_si = match self.next_state(qcur, qnext, prev_si, byte) {
+                    None => return Result::Quit,
+                    Some(STATE_DEAD) => return result.set_non_match(at),
+                    Some(si) => si,
+                };
+                debug_assert!(next_si != STATE_UNKNOWN);
+                if next_si & STATE_MATCH > 0 {
+                    next_si &= !STATE_MATCH;
+                    result = Result::Match(at + 1);
+                    if self.quit_after_match {
+                        return result;
+                    }
+                    self.last_match_si = next_si;
+                }
+                prev_si = next_si;
+            } else {
+                prev_si = next_si;
+            }
+        }
+
+        // Run the DFA once more on the special EOF senitnel value.
+        prev_si = match self.next_state(qcur, qnext, prev_si, Byte::eof()) {
+            None => return Result::Quit,
+            Some(STATE_DEAD) => return result.set_non_match(0),
+            Some(si) => si,
+        };
+        debug_assert!(prev_si != STATE_UNKNOWN);
+        if prev_si & STATE_MATCH > 0 {
+            prev_si &= !STATE_MATCH;
+            self.last_match_si = prev_si;
+            result = Result::Match(0);
+        }
+        result
+    }
+
+    /// next_si transitions to the next state, where the transition input
+    /// corresponds to text[i].
+    ///
+    /// This elides bounds checks, and is therefore unsafe.
+    #[inline(always)]
+    unsafe fn next_si(&self, si: StatePtr, text: &[u8], i: usize) -> StatePtr {
+        // What is the argument for safety here?
+        // We have three unchecked accesses that could possibly violate safety:
+        //
+        //   1. The given byte of input (`text[i]`).
+        //   2. The class of the byte of input (`classes[text[i]]`).
+        //   3. The transition for the class (`trans[si + cls]`).
+        //
+        // (1) is only safe when calling next_si is guarded by
+        // `i < text.len()`.
+        //
+        // (2) is the easiest case to guarantee since `text[i]` is always a
+        // `u8` and `self.prog.byte_classes` always has length `u8::MAX`.
+        // (See `ByteClassSet.byte_classes` in `compile.rs`.)
+        //
+        // (3) is only safe if (1)+(2) are safe. Namely, the transitions
+        // of every state are defined to have length equal to the number of
+        // byte classes in the program. Therefore, a valid class leads to a
+        // valid transition. (All possible transitions are valid lookups, even
+        // if it points to a state that hasn't been computed yet.) (3) also
+        // relies on `si` being correct, but StatePtrs should only ever be
+        // retrieved from the transition table, which ensures they are correct.
+        debug_assert!(i < text.len());
+        let b = *text.get_unchecked(i);
+        debug_assert!((b as usize) < self.prog.byte_classes.len());
+        let cls = *self.prog.byte_classes.get_unchecked(b as usize);
+        self.cache.trans.next_unchecked(si, cls as usize)
+    }
+
+    /// Computes the next state given the current state and the current input
+    /// byte (which may be EOF).
+    ///
+    /// If STATE_DEAD is returned, then there is no valid state transition.
+    /// This implies that no permutation of future input can lead to a match
+    /// state.
+    ///
+    /// STATE_UNKNOWN can never be returned.
+    fn exec_byte(
+        &mut self,
+        qcur: &mut SparseSet,
+        qnext: &mut SparseSet,
+        mut si: StatePtr,
+        b: Byte,
+    ) -> Option<StatePtr> {
+        use prog::Inst::*;
+
+        // Initialize a queue with the current DFA state's NFA states.
+        qcur.clear();
+        for ip in self.state(si).inst_ptrs() {
+            qcur.insert(ip);
+        }
+
+        // Before inspecting the current byte, we may need to also inspect
+        // whether the position immediately preceding the current byte
+        // satisfies the empty assertions found in the current state.
+        //
+        // We only need to do this step if there are any empty assertions in
+        // the current state.
+        let is_word_last = self.state(si).flags().is_word();
+        let is_word = b.is_ascii_word();
+        if self.state(si).flags().has_empty() {
+            // Compute the flags immediately preceding the current byte.
+            // This means we only care about the "end" or "end line" flags.
+            // (The "start" flags are computed immediately proceding the
+            // current byte and is handled below.)
+            let mut flags = EmptyFlags::default();
+            if b.is_eof() {
+                flags.end = true;
+                flags.end_line = true;
+            } else if b.as_byte().map_or(false, |b| b == b'\n') {
+                flags.end_line = true;
+            }
+            if is_word_last == is_word {
+                flags.not_word_boundary = true;
+            } else {
+                flags.word_boundary = true;
+            }
+            // Now follow epsilon transitions from every NFA state, but make
+            // sure we only follow transitions that satisfy our flags.
+            qnext.clear();
+            for &ip in &*qcur {
+                self.follow_epsilons(usize_to_u32(ip), qnext, flags);
+            }
+            mem::swap(qcur, qnext);
+        }
+
+        // Now we set flags for immediately after the current byte. Since start
+        // states are processed separately, and are the only states that can
+        // have the StartText flag set, we therefore only need to worry about
+        // the StartLine flag here.
+        //
+        // We do also keep track of whether this DFA state contains a NFA state
+        // that is a matching state. This is precisely how we delay the DFA
+        // matching by one byte in order to process the special EOF sentinel
+        // byte. Namely, if this DFA state containing a matching NFA state,
+        // then it is the *next* DFA state that is marked as a match.
+        let mut empty_flags = EmptyFlags::default();
+        let mut state_flags = StateFlags::default();
+        empty_flags.start_line = b.as_byte().map_or(false, |b| b == b'\n');
+        if b.is_ascii_word() {
+            state_flags.set_word();
+        }
+        // Now follow all epsilon transitions again, but only after consuming
+        // the current byte.
+        qnext.clear();
+        for &ip in &*qcur {
+            match self.prog[ip as usize] {
+                // These states never happen in a byte-based program.
+                Char(_) | Ranges(_) => unreachable!(),
+                // These states are handled when following epsilon transitions.
+                Save(_) | Split(_) | EmptyLook(_) => {}
+                Match(_) => {
+                    state_flags.set_match();
+                    if !self.continue_past_first_match() {
+                        break;
+                    } else if self.prog.matches.len() > 1
+                            && !qnext.contains(ip as usize) {
+                        // If we are continuing on to find other matches,
+                        // then keep a record of the match states we've seen.
+                        qnext.insert(ip);
+                    }
+                }
+                Bytes(ref inst) => {
+                    if b.as_byte().map_or(false, |b| inst.matches(b)) {
+                        self.follow_epsilons(
+                            inst.goto as InstPtr, qnext, empty_flags);
+                    }
+                }
+            }
+        }
+
+        let cache =
+            if b.is_eof() && self.prog.matches.len() > 1 {
+                // If we're processing the last byte of the input and we're
+                // matching a regex set, then make the next state contain the
+                // previous states transitions. We do this so that the main
+                // matching loop can extract all of the match instructions.
+                mem::swap(qcur, qnext);
+                // And don't cache this state because it's totally bunk.
+                false
+            } else {
+                true
+            };
+
+        // We've now built up the set of NFA states that ought to comprise the
+        // next DFA state, so try to find it in the cache, and if it doesn't
+        // exist, cache it.
+        //
+        // N.B. We pass `&mut si` here because the cache may clear itself if
+        // it has gotten too full. When that happens, the location of the
+        // current state may change.
+        let mut next = match self.cached_state(
+            qnext,
+            state_flags,
+            Some(&mut si),
+        ) {
+            None => return None,
+            Some(next) => next,
+        };
+        if (self.start & !STATE_START) == next {
+            // Start states can never be match states since all matches are
+            // delayed by one byte.
+            debug_assert!(!self.state(next).flags().is_match());
+            next = self.start_ptr(next);
+        }
+        if next <= STATE_MAX && self.state(next).flags().is_match() {
+            next |= STATE_MATCH;
+        }
+        debug_assert!(next != STATE_UNKNOWN);
+        // And now store our state in the current state's next list.
+        if cache {
+            let cls = self.byte_class(b);
+            self.cache.trans.set_next(si, cls, next);
+        }
+        Some(next)
+    }
+
+    /// Follows the epsilon transitions starting at (and including) `ip`. The
+    /// resulting states are inserted into the ordered set `q`.
+    ///
+    /// Conditional epsilon transitions (i.e., empty width assertions) are only
+    /// followed if they are satisfied by the given flags, which should
+    /// represent the flags set at the current location in the input.
+    ///
+    /// If the current location corresponds to the empty string, then only the
+    /// end line and/or end text flags may be set. If the current location
+    /// corresponds to a real byte in the input, then only the start line
+    /// and/or start text flags may be set.
+    ///
+    /// As an exception to the above, when finding the initial state, any of
+    /// the above flags may be set:
+    ///
+    /// If matching starts at the beginning of the input, then start text and
+    /// start line should be set. If the input is empty, then end text and end
+    /// line should also be set.
+    ///
+    /// If matching starts after the beginning of the input, then only start
+    /// line should be set if the preceding byte is `\n`. End line should never
+    /// be set in this case. (Even if the proceding byte is a `\n`, it will
+    /// be handled in a subsequent DFA state.)
+    fn follow_epsilons(
+        &mut self,
+        ip: InstPtr,
+        q: &mut SparseSet,
+        flags: EmptyFlags,
+    ) {
+        use prog::Inst::*;
+        use prog::EmptyLook::*;
+
+        // We need to traverse the NFA to follow epsilon transitions, so avoid
+        // recursion with an explicit stack.
+        self.cache.stack.push(ip);
+        while let Some(mut ip) = self.cache.stack.pop() {
+            // Try to munch through as many states as possible without
+            // pushes/pops to the stack.
+            loop {
+                // Don't visit states we've already added.
+                if q.contains(ip as usize) {
+                    break;
+                }
+                q.insert(ip as usize);
+                match self.prog[ip as usize] {
+                    Char(_) | Ranges(_) => unreachable!(),
+                    Match(_) | Bytes(_) => {
+                        break;
+                    }
+                    EmptyLook(ref inst) => {
+                        // Only follow empty assertion states if our flags
+                        // satisfy the assertion.
+                        match inst.look {
+                            StartLine if flags.start_line => {
+                                ip = inst.goto as InstPtr;
+                            }
+                            EndLine if flags.end_line => {
+                                ip = inst.goto as InstPtr;
+                            }
+                            StartText if flags.start => {
+                                ip = inst.goto as InstPtr;
+                            }
+                            EndText if flags.end => {
+                                ip = inst.goto as InstPtr;
+                            }
+                            WordBoundaryAscii if flags.word_boundary => {
+                                ip = inst.goto as InstPtr;
+                            }
+                            NotWordBoundaryAscii if flags.not_word_boundary => {
+                                ip = inst.goto as InstPtr;
+                            }
+                            WordBoundary if flags.word_boundary => {
+                                ip = inst.goto as InstPtr;
+                            }
+                            NotWordBoundary if flags.not_word_boundary => {
+                                ip = inst.goto as InstPtr;
+                            }
+                            StartLine | EndLine | StartText | EndText
+                            | WordBoundaryAscii | NotWordBoundaryAscii
+                            | WordBoundary | NotWordBoundary => {
+                                break;
+                            }
+                        }
+                    }
+                    Save(ref inst) => {
+                        ip = inst.goto as InstPtr;
+                    }
+                    Split(ref inst) => {
+                        self.cache.stack.push(inst.goto2 as InstPtr);
+                        ip = inst.goto1 as InstPtr;
+                    }
+                }
+            }
+        }
+    }
+
+    /// Find a previously computed state matching the given set of instructions
+    /// and is_match bool.
+    ///
+    /// The given set of instructions should represent a single state in the
+    /// NFA along with all states reachable without consuming any input.
+    ///
+    /// The is_match bool should be true if and only if the preceding DFA state
+    /// contains an NFA matching state. The cached state produced here will
+    /// then signify a match. (This enables us to delay a match by one byte,
+    /// in order to account for the EOF sentinel byte.)
+    ///
+    /// If the cache is full, then it is wiped before caching a new state.
+    ///
+    /// The current state should be specified if it exists, since it will need
+    /// to be preserved if the cache clears itself. (Start states are
+    /// always saved, so they should not be passed here.) It takes a mutable
+    /// pointer to the index because if the cache is cleared, the state's
+    /// location may change.
+    fn cached_state(
+        &mut self,
+        q: &SparseSet,
+        mut state_flags: StateFlags,
+        current_state: Option<&mut StatePtr>,
+    ) -> Option<StatePtr> {
+        // If we couldn't come up with a non-empty key to represent this state,
+        // then it is dead and can never lead to a match.
+        //
+        // Note that inst_flags represent the set of empty width assertions
+        // in q. We use this as an optimization in exec_byte to determine when
+        // we should follow epsilon transitions at the empty string preceding
+        // the current byte.
+        let key = match self.cached_state_key(q, &mut state_flags) {
+            None => return Some(STATE_DEAD),
+            Some(v) => v,
+        };
+        // In the cache? Cool. Done.
+        if let Some(si) = self
+            .cache
+            .compiled
+            .get_ptr(&key)
+        {
+            return Some(si);
+        }
+        // If the cache has gotten too big, wipe it.
+        if self.approximate_size() > self.prog.dfa_size_limit
+            && !self.clear_cache_and_save(current_state)
+            {
+                // Ooops. DFA is giving up.
+                return None;
+            }
+        // Allocate room for our state and add it.
+        self.add_state(key)
+    }
+
+    /// Produces a key suitable for describing a state in the DFA cache.
+    ///
+    /// The key invariant here is that equivalent keys are produced for any two
+    /// sets of ordered NFA states (and toggling of whether the previous NFA
+    /// states contain a match state) that do not discriminate a match for any
+    /// input.
+    ///
+    /// Specifically, q should be an ordered set of NFA states and is_match
+    /// should be true if and only if the previous NFA states contained a match
+    /// state.
+    fn cached_state_key(
+        &mut self,
+        q: &SparseSet,
+        state_flags: &mut StateFlags,
+    ) -> Option<State> {
+        use prog::Inst::*;
+
+        // We need to build up enough information to recognize pre-built states
+        // in the DFA. Generally speaking, this includes every instruction
+        // except for those which are purely epsilon transitions, e.g., the
+        // Save and Split instructions.
+        //
+        // Empty width assertions are also epsilon transitions, but since they
+        // are conditional, we need to make them part of a state's key in the
+        // cache.
+
+        let mut insts = mem::replace(
+            &mut self.cache.insts_scratch_space,
+            vec![],
+        );
+        insts.clear();
+        // Reserve 1 byte for flags.
+        insts.push(0);
+
+        let mut prev = 0;
+        for &ip in q {
+            let ip = usize_to_u32(ip);
+            match self.prog[ip as usize] {
+                Char(_) | Ranges(_) => unreachable!(),
+                Save(_) | Split(_) => {}
+                Bytes(_) => push_inst_ptr(&mut insts, &mut prev, ip),
+                EmptyLook(_) => {
+                    state_flags.set_empty();
+                    push_inst_ptr(&mut insts, &mut prev, ip)
+                }
+                Match(_) => {
+                    push_inst_ptr(&mut insts, &mut prev, ip);
+                    if !self.continue_past_first_match() {
+                        break;
+                    }
+                }
+            }
+        }
+        // If we couldn't transition to any other instructions and we didn't
+        // see a match when expanding NFA states previously, then this is a
+        // dead state and no amount of additional input can transition out
+        // of this state.
+        let opt_state =
+            if insts.len() == 1 && !state_flags.is_match() {
+                None
+            } else {
+                let StateFlags(f) = *state_flags;
+                insts[0] = f;
+                Some(State { data: Arc::from(&*insts) })
+            };
+        self.cache.insts_scratch_space = insts;
+        opt_state
+    }
+
+    /// Clears the cache, but saves and restores current_state if it is not
+    /// none.
+    ///
+    /// The current state must be provided here in case its location in the
+    /// cache changes.
+    ///
+    /// This returns false if the cache is not cleared and the DFA should
+    /// give up.
+    fn clear_cache_and_save(
+        &mut self,
+        current_state: Option<&mut StatePtr>,
+    ) -> bool {
+        if self.cache.compiled.is_empty() {
+            // Nothing to clear...
+            return true;
+        }
+        match current_state {
+            None => self.clear_cache(),
+            Some(si) => {
+                let cur = self.state(*si).clone();
+                if !self.clear_cache() {
+                    return false;
+                }
+                // The unwrap is OK because we just cleared the cache and
+                // therefore know that the next state pointer won't exceed
+                // STATE_MAX.
+                *si = self.restore_state(cur).unwrap();
+                true
+            }
+        }
+    }
+
+    /// Wipes the state cache, but saves and restores the current start state.
+    ///
+    /// This returns false if the cache is not cleared and the DFA should
+    /// give up.
+    fn clear_cache(&mut self) -> bool {
+        // Bail out of the DFA if we're moving too "slowly."
+        // A heuristic from RE2: assume the DFA is too slow if it is processing
+        // 10 or fewer bytes per state.
+        // Additionally, we permit the cache to be flushed a few times before
+        // caling it quits.
+        let nstates = self.cache.compiled.len();
+        if self.cache.flush_count >= 3
+            && self.at >= self.last_cache_flush
+            && (self.at - self.last_cache_flush) <= 10 * nstates {
+            return false;
+        }
+        // Update statistics tracking cache flushes.
+        self.last_cache_flush = self.at;
+        self.cache.flush_count += 1;
+
+        // OK, actually flush the cache.
+        let start = self.state(self.start & !STATE_START).clone();
+        let last_match = if self.last_match_si <= STATE_MAX {
+            Some(self.state(self.last_match_si).clone())
+        } else {
+            None
+        };
+        self.cache.reset_size();
+        self.cache.trans.clear();
+        self.cache.compiled.clear();
+        for s in &mut self.cache.start_states {
+            *s = STATE_UNKNOWN;
+        }
+        // The unwraps are OK because we just cleared the cache and therefore
+        // know that the next state pointer won't exceed STATE_MAX.
+        let start_ptr = self.restore_state(start).unwrap();
+        self.start = self.start_ptr(start_ptr);
+        if let Some(last_match) = last_match {
+            self.last_match_si = self.restore_state(last_match).unwrap();
+        }
+        true
+    }
+
+    /// Restores the given state back into the cache, and returns a pointer
+    /// to it.
+    fn restore_state(&mut self, state: State) -> Option<StatePtr> {
+        // If we've already stored this state, just return a pointer to it.
+        // None will be the wiser.
+        if let Some(si) = self.cache.compiled.get_ptr(&state) {
+            return Some(si);
+        }
+        self.add_state(state)
+    }
+
+    /// Returns the next state given the current state si and current byte
+    /// b. {qcur,qnext} are used as scratch space for storing ordered NFA
+    /// states.
+    ///
+    /// This tries to fetch the next state from the cache, but if that fails,
+    /// it computes the next state, caches it and returns a pointer to it.
+    ///
+    /// The pointer can be to a real state, or it can be STATE_DEAD.
+    /// STATE_UNKNOWN cannot be returned.
+    ///
+    /// None is returned if a new state could not be allocated (i.e., the DFA
+    /// ran out of space and thinks it's running too slowly).
+    fn next_state(
+        &mut self,
+        qcur: &mut SparseSet,
+        qnext: &mut SparseSet,
+        si: StatePtr,
+        b: Byte,
+    ) -> Option<StatePtr> {
+        if si == STATE_DEAD {
+            return Some(STATE_DEAD);
+        }
+        match self.cache.trans.next(si, self.byte_class(b)) {
+            STATE_UNKNOWN => self.exec_byte(qcur, qnext, si, b),
+            STATE_QUIT => None,
+            STATE_DEAD => Some(STATE_DEAD),
+            nsi => Some(nsi),
+        }
+    }
+
+    /// Computes and returns the start state, where searching begins at
+    /// position `at` in `text`. If the state has already been computed,
+    /// then it is pulled from the cache. If the state hasn't been cached,
+    /// then it is computed, cached and a pointer to it is returned.
+    ///
+    /// This may return STATE_DEAD but never STATE_UNKNOWN.
+    #[inline(always)] // reduces constant overhead
+    fn start_state(
+        &mut self,
+        q: &mut SparseSet,
+        empty_flags: EmptyFlags,
+        state_flags: StateFlags,
+    ) -> Option<StatePtr> {
+        // Compute an index into our cache of start states based on the set
+        // of empty/state flags set at the current position in the input. We
+        // don't use every flag since not all flags matter. For example, since
+        // matches are delayed by one byte, start states can never be match
+        // states.
+        let flagi = {
+            (((empty_flags.start as u8) << 0) |
+             ((empty_flags.end as u8) << 1) |
+             ((empty_flags.start_line as u8) << 2) |
+             ((empty_flags.end_line as u8) << 3) |
+             ((empty_flags.word_boundary as u8) << 4) |
+             ((empty_flags.not_word_boundary as u8) << 5) |
+             ((state_flags.is_word() as u8) << 6))
+            as usize
+        };
+        match self.cache.start_states[flagi] {
+            STATE_UNKNOWN => {}
+            STATE_DEAD => return Some(STATE_DEAD),
+            si => return Some(si),
+        }
+        q.clear();
+        let start = usize_to_u32(self.prog.start);
+        self.follow_epsilons(start, q, empty_flags);
+        // Start states can never be match states because we delay every match
+        // by one byte. Given an empty string and an empty match, the match
+        // won't actually occur until the DFA processes the special EOF
+        // sentinel byte.
+        let sp = match self.cached_state(q, state_flags, None) {
+            None => return None,
+            Some(sp) => self.start_ptr(sp),
+        };
+        self.cache.start_states[flagi] = sp;
+        Some(sp)
+    }
+
+    /// Computes the set of starting flags for the given position in text.
+    ///
+    /// This should only be used when executing the DFA forwards over the
+    /// input.
+    fn start_flags(&self, text: &[u8], at: usize) -> (EmptyFlags, StateFlags) {
+        let mut empty_flags = EmptyFlags::default();
+        let mut state_flags = StateFlags::default();
+        empty_flags.start = at == 0;
+        empty_flags.end = text.is_empty();
+        empty_flags.start_line = at == 0 || text[at - 1] == b'\n';
+        empty_flags.end_line = text.is_empty();
+
+        let is_word_last = at > 0 && Byte::byte(text[at - 1]).is_ascii_word();
+        let is_word = at < text.len() && Byte::byte(text[at]).is_ascii_word();
+        if is_word_last {
+            state_flags.set_word();
+        }
+        if is_word == is_word_last {
+            empty_flags.not_word_boundary = true;
+        } else {
+            empty_flags.word_boundary = true;
+        }
+        (empty_flags, state_flags)
+    }
+
+    /// Computes the set of starting flags for the given position in text.
+    ///
+    /// This should only be used when executing the DFA in reverse over the
+    /// input.
+    fn start_flags_reverse(
+        &self,
+        text: &[u8],
+        at: usize,
+    ) -> (EmptyFlags, StateFlags) {
+        let mut empty_flags = EmptyFlags::default();
+        let mut state_flags = StateFlags::default();
+        empty_flags.start = at == text.len();
+        empty_flags.end = text.is_empty();
+        empty_flags.start_line = at == text.len() || text[at] == b'\n';
+        empty_flags.end_line = text.is_empty();
+
+        let is_word_last =
+            at < text.len() && Byte::byte(text[at]).is_ascii_word();
+        let is_word = at > 0 && Byte::byte(text[at - 1]).is_ascii_word();
+        if is_word_last {
+            state_flags.set_word();
+        }
+        if is_word == is_word_last {
+            empty_flags.not_word_boundary = true;
+        } else {
+            empty_flags.word_boundary = true;
+        }
+        (empty_flags, state_flags)
+    }
+
+    /// Returns a reference to a State given a pointer to it.
+    fn state(&self, si: StatePtr) -> &State {
+        self.cache.compiled.get_state(si).unwrap()
+    }
+
+    /// Adds the given state to the DFA.
+    ///
+    /// This allocates room for transitions out of this state in
+    /// self.cache.trans. The transitions can be set with the returned
+    /// StatePtr.
+    ///
+    /// If None is returned, then the state limit was reached and the DFA
+    /// should quit.
+    fn add_state(&mut self, state: State) -> Option<StatePtr> {
+        // This will fail if the next state pointer exceeds STATE_PTR. In
+        // practice, the cache limit will prevent us from ever getting here,
+        // but maybe callers will set the cache size to something ridiculous...
+        let si = match self.cache.trans.add() {
+            None => return None,
+            Some(si) => si,
+        };
+        // If the program has a Unicode word boundary, then set any transitions
+        // for non-ASCII bytes to STATE_QUIT. If the DFA stumbles over such a
+        // transition, then it will quit and an alternative matching engine
+        // will take over.
+        if self.prog.has_unicode_word_boundary {
+            for b in 128..256 {
+                let cls = self.byte_class(Byte::byte(b as u8));
+                self.cache.trans.set_next(si, cls, STATE_QUIT);
+            }
+        }
+        // Finally, put our actual state on to our heap of states and index it
+        // so we can find it later.
+        self.cache.size +=
+            self.cache.trans.state_heap_size()
+            + state.data.len()
+            + (2 * mem::size_of::<State>())
+            + mem::size_of::<StatePtr>();
+        self.cache.compiled.insert(state, si);
+        // Transition table and set of states and map should all be in sync.
+        debug_assert!(self.cache.compiled.len()
+                      == self.cache.trans.num_states());
+        Some(si)
+    }
+
+    /// Quickly finds the next occurrence of any literal prefixes in the regex.
+    /// If there are no literal prefixes, then the current position is
+    /// returned. If there are literal prefixes and one could not be found,
+    /// then None is returned.
+    ///
+    /// This should only be called when the DFA is in a start state.
+    fn prefix_at(&self, text: &[u8], at: usize) -> Option<usize> {
+        self.prog.prefixes.find(&text[at..]).map(|(s, _)| at + s)
+    }
+
+    /// Returns the number of byte classes required to discriminate transitions
+    /// in each state.
+    ///
+    /// invariant: num_byte_classes() == len(State.next)
+    fn num_byte_classes(&self) -> usize {
+        // We add 1 to account for the special EOF byte.
+        (self.prog.byte_classes[255] as usize + 1) + 1
+    }
+
+    /// Given an input byte or the special EOF sentinel, return its
+    /// corresponding byte class.
+    #[inline(always)]
+    fn byte_class(&self, b: Byte) -> usize {
+        match b.as_byte() {
+            None => self.num_byte_classes() - 1,
+            Some(b) => self.u8_class(b),
+        }
+    }
+
+    /// Like byte_class, but explicitly for u8s.
+    #[inline(always)]
+    fn u8_class(&self, b: u8) -> usize {
+        self.prog.byte_classes[b as usize] as usize
+    }
+
+    /// Returns true if the DFA should continue searching past the first match.
+    ///
+    /// Leftmost first semantics in the DFA are preserved by not following NFA
+    /// transitions after the first match is seen.
+    ///
+    /// On occasion, we want to avoid leftmost first semantics to find either
+    /// the longest match (for reverse search) or all possible matches (for
+    /// regex sets).
+    fn continue_past_first_match(&self) -> bool {
+        self.prog.is_reverse || self.prog.matches.len() > 1
+    }
+
+    /// Returns true if there is a prefix we can quickly search for.
+    fn has_prefix(&self) -> bool {
+        !self.prog.is_reverse
+        && !self.prog.prefixes.is_empty()
+        && !self.prog.is_anchored_start
+    }
+
+    /// Sets the STATE_START bit in the given state pointer if and only if
+    /// we have a prefix to scan for.
+    ///
+    /// If there's no prefix, then it's a waste to treat the start state
+    /// specially.
+    fn start_ptr(&self, si: StatePtr) -> StatePtr {
+        if self.has_prefix() {
+            si | STATE_START
+        } else {
+            si
+        }
+    }
+
+    /// Approximate size returns the approximate heap space currently used by
+    /// the DFA. It is used to determine whether the DFA's state cache needs to
+    /// be wiped. Namely, it is possible that for certain regexes on certain
+    /// inputs, a new state could be created for every byte of input. (This is
+    /// bad for memory use, so we bound it with a cache.)
+    fn approximate_size(&self) -> usize {
+        self.cache.size + self.prog.approximate_size()
+    }
+}
+
+/// An abstraction for representing a map of states. The map supports two
+/// different ways of state lookup. One is fast constant time access via a
+/// state pointer. The other is a hashmap lookup based on the DFA's
+/// constituent NFA states.
+///
+/// A DFA state internally uses an Arc such that we only need to store the
+/// set of NFA states on the heap once, even though we support looking up
+/// states by two different means. A more natural way to express this might
+/// use raw pointers, but an Arc is safe and effectively achieves the same
+/// thing.
+#[derive(Debug)]
+struct StateMap {
+    /// The keys are not actually static but rely on always pointing to a
+    /// buffer in `states` which will never be moved except when clearing
+    /// the map or on drop, in which case the keys of this map will be
+    /// removed before
+    map: HashMap<State, StatePtr>,
+    /// Our set of states. Note that `StatePtr / num_byte_classes` indexes
+    /// this Vec rather than just a `StatePtr`.
+    states: Vec<State>,
+    /// The number of byte classes in the DFA. Used to index `states`.
+    num_byte_classes: usize,
+}
+
+impl StateMap {
+    fn new(num_byte_classes: usize) -> StateMap {
+        StateMap {
+            map: HashMap::new(),
+            states: vec![],
+            num_byte_classes: num_byte_classes,
+        }
+    }
+
+    fn len(&self) -> usize {
+        self.states.len()
+    }
+
+    fn is_empty(&self) -> bool {
+        self.states.is_empty()
+    }
+
+    fn get_ptr(&self, state: &State) -> Option<StatePtr> {
+        self.map.get(state).cloned()
+    }
+
+    fn get_state(&self, si: StatePtr) -> Option<&State> {
+        self.states.get(si as usize / self.num_byte_classes)
+    }
+
+    fn insert(&mut self, state: State, si: StatePtr) {
+        self.map.insert(state.clone(), si);
+        self.states.push(state);
+    }
+
+    fn clear(&mut self) {
+        self.map.clear();
+        self.states.clear();
+    }
+}
+
+impl Transitions {
+    /// Create a new transition table.
+    ///
+    /// The number of byte classes corresponds to the stride. Every state will
+    /// have `num_byte_classes` slots for transitions.
+    fn new(num_byte_classes: usize) -> Transitions {
+        Transitions {
+            table: vec![],
+            num_byte_classes: num_byte_classes,
+        }
+    }
+
+    /// Returns the total number of states currently in this table.
+    fn num_states(&self) -> usize {
+        self.table.len() / self.num_byte_classes
+    }
+
+    /// Allocates room for one additional state and returns a pointer to it.
+    ///
+    /// If there's no more room, None is returned.
+    fn add(&mut self) -> Option<StatePtr> {
+        let si = self.table.len();
+        if si > STATE_MAX as usize {
+            return None;
+        }
+        self.table.extend(repeat(STATE_UNKNOWN).take(self.num_byte_classes));
+        Some(usize_to_u32(si))
+    }
+
+    /// Clears the table of all states.
+    fn clear(&mut self) {
+        self.table.clear();
+    }
+
+    /// Sets the transition from (si, cls) to next.
+    fn set_next(&mut self, si: StatePtr, cls: usize, next: StatePtr) {
+        self.table[si as usize + cls] = next;
+    }
+
+    /// Returns the transition corresponding to (si, cls).
+    fn next(&self, si: StatePtr, cls: usize) -> StatePtr {
+        self.table[si as usize + cls]
+    }
+
+    /// The heap size, in bytes, of a single state in the transition table.
+    fn state_heap_size(&self) -> usize {
+        self.num_byte_classes * mem::size_of::<StatePtr>()
+    }
+
+    /// Like `next`, but uses unchecked access and is therefore unsafe.
+    unsafe fn next_unchecked(&self, si: StatePtr, cls: usize) -> StatePtr {
+        debug_assert!((si as usize) < self.table.len());
+        debug_assert!(cls < self.num_byte_classes);
+        *self.table.get_unchecked(si as usize + cls)
+    }
+}
+
+impl StateFlags {
+    fn is_match(&self) -> bool {
+        self.0 & 0b0000000_1 > 0
+    }
+
+    fn set_match(&mut self) {
+        self.0 |= 0b0000000_1;
+    }
+
+    fn is_word(&self) -> bool {
+        self.0 & 0b000000_1_0 > 0
+    }
+
+    fn set_word(&mut self) {
+        self.0 |= 0b000000_1_0;
+    }
+
+    fn has_empty(&self) -> bool {
+        self.0 & 0b00000_1_00 > 0
+    }
+
+    fn set_empty(&mut self) {
+        self.0 |= 0b00000_1_00;
+    }
+}
+
+impl Byte {
+    fn byte(b: u8) -> Self { Byte(b as u16) }
+    fn eof() -> Self { Byte(256) }
+    fn is_eof(&self) -> bool { self.0 == 256 }
+
+    fn is_ascii_word(&self) -> bool {
+        let b = match self.as_byte() {
+            None => return false,
+            Some(b) => b,
+        };
+        match b {
+            b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'_' => true,
+            _ => false,
+        }
+    }
+
+    fn as_byte(&self) -> Option<u8> {
+        if self.is_eof() {
+            None
+        } else {
+            Some(self.0 as u8)
+        }
+    }
+}
+
+impl fmt::Debug for State {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let ips: Vec<usize> = self.inst_ptrs().collect();
+        f.debug_struct("State")
+         .field("flags", &self.flags())
+         .field("insts", &ips)
+         .finish()
+    }
+}
+
+impl fmt::Debug for Transitions {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let mut fmtd = f.debug_map();
+        for si in 0..self.num_states() {
+            let s = si * self.num_byte_classes;
+            let e = s + self.num_byte_classes;
+            fmtd.entry(&si.to_string(), &TransitionsRow(&self.table[s..e]));
+        }
+        fmtd.finish()
+    }
+}
+
+struct TransitionsRow<'a>(&'a [StatePtr]);
+
+impl<'a> fmt::Debug for TransitionsRow<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let mut fmtd = f.debug_map();
+        for (b, si) in self.0.iter().enumerate() {
+            match *si {
+                STATE_UNKNOWN => {}
+                STATE_DEAD => {
+                    fmtd.entry(&vb(b as usize), &"DEAD");
+                }
+                si => {
+                    fmtd.entry(&vb(b as usize), &si.to_string());
+                }
+            }
+        }
+        fmtd.finish()
+    }
+}
+
+impl fmt::Debug for StateFlags {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("StateFlags")
+         .field("is_match", &self.is_match())
+         .field("is_word", &self.is_word())
+         .field("has_empty", &self.has_empty())
+         .finish()
+    }
+}
+
+/// Helper function for formatting a byte as a nice-to-read escaped string.
+fn vb(b: usize) -> String {
+    use std::ascii::escape_default;
+
+    if b > ::std::u8::MAX as usize {
+        "EOF".to_owned()
+    } else {
+        let escaped = escape_default(b as u8).collect::<Vec<u8>>();
+        String::from_utf8_lossy(&escaped).into_owned()
+    }
+}
+
+fn usize_to_u32(n: usize) -> u32 {
+    if (n as u64) > (::std::u32::MAX as u64) {
+        panic!("BUG: {} is too big to fit into u32", n)
+    }
+    n as u32
+}
+
+#[allow(dead_code)] // useful for debugging
+fn show_state_ptr(si: StatePtr) -> String {
+    let mut s = format!("{:?}", si & STATE_MAX);
+    if si == STATE_UNKNOWN {
+        s = format!("{} (unknown)", s);
+    }
+    if si == STATE_DEAD {
+        s = format!("{} (dead)", s);
+    }
+    if si == STATE_QUIT {
+        s = format!("{} (quit)", s);
+    }
+    if si & STATE_START > 0 {
+        s = format!("{} (start)", s);
+    }
+    if si & STATE_MATCH > 0 {
+        s = format!("{} (match)", s);
+    }
+    s
+}
+
+/// https://developers.google.com/protocol-buffers/docs/encoding#varints
+fn write_vari32(data: &mut Vec<u8>, n: i32) {
+    let mut un = (n as u32) << 1;
+    if n < 0 {
+        un = !un;
+    }
+    write_varu32(data, un)
+}
+
+/// https://developers.google.com/protocol-buffers/docs/encoding#varints
+fn read_vari32(data: &[u8]) -> (i32, usize) {
+    let (un, i) = read_varu32(data);
+    let mut n = (un >> 1) as i32;
+    if un & 1 != 0 {
+        n = !n;
+    }
+    (n, i)
+}
+
+/// https://developers.google.com/protocol-buffers/docs/encoding#varints
+fn write_varu32(data: &mut Vec<u8>, mut n: u32) {
+    while n >= 0b1000_0000 {
+        data.push((n as u8) | 0b1000_0000);
+        n >>= 7;
+    }
+    data.push(n as u8);
+}
+
+/// https://developers.google.com/protocol-buffers/docs/encoding#varints
+fn read_varu32(data: &[u8]) -> (u32, usize) {
+    let mut n: u32 = 0;
+    let mut shift: u32 = 0;
+    for (i, &b) in data.iter().enumerate() {
+        if b < 0b1000_0000 {
+            return (n | ((b as u32) << shift), i + 1);
+        }
+        n |= ((b as u32) & 0b0111_1111) << shift;
+        shift += 7;
+    }
+    (0, 0)
+}
+
+#[cfg(test)]
+mod tests {
+    extern crate rand;
+
+    use std::sync::Arc;
+    use quickcheck::{QuickCheck, StdGen, quickcheck};
+    use super::{
+        StateFlags, State, push_inst_ptr,
+        write_varu32, read_varu32, write_vari32, read_vari32,
+    };
+
+    #[test]
+    fn prop_state_encode_decode() {
+        fn p(ips: Vec<u32>, flags: u8) -> bool {
+            let mut data = vec![flags];
+            let mut prev = 0;
+            for &ip in ips.iter() {
+                push_inst_ptr(&mut data, &mut prev, ip);
+            }
+            let state = State { data: Arc::from(&data[..]) };
+
+            let expected: Vec<usize> =
+                ips.into_iter().map(|ip| ip as usize).collect();
+            let got: Vec<usize> = state.inst_ptrs().collect();
+            expected == got && state.flags() == StateFlags(flags)
+        }
+        QuickCheck::new()
+            .gen(StdGen::new(self::rand::thread_rng(), 10_000))
+            .quickcheck(p as fn(Vec<u32>, u8) -> bool);
+    }
+
+    #[test]
+    fn prop_read_write_u32() {
+        fn p(n: u32) -> bool {
+            let mut buf = vec![];
+            write_varu32(&mut buf, n);
+            let (got, nread) = read_varu32(&buf);
+            nread == buf.len() && got == n
+        }
+        quickcheck(p as fn(u32) -> bool);
+    }
+
+    #[test]
+    fn prop_read_write_i32() {
+        fn p(n: i32) -> bool {
+            let mut buf = vec![];
+            write_vari32(&mut buf, n);
+            let (got, nread) = read_vari32(&buf);
+            nread == buf.len() && got == n
+        }
+        quickcheck(p as fn(i32) -> bool);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/error.rs.html b/target/doc/src/regex/error.rs.html new file mode 100644 index 0000000..432120f --- /dev/null +++ b/target/doc/src/regex/error.rs.html @@ -0,0 +1,163 @@ +error.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::fmt;
+use std::iter::repeat;
+
+/// An error that occurred during parsing or compiling a regular expression.
+#[derive(Clone, PartialEq)]
+pub enum Error {
+    /// A syntax error.
+    Syntax(String),
+    /// The compiled program exceeded the set size limit.
+    /// The argument is the size limit imposed.
+    CompiledTooBig(usize),
+    /// Hints that destructuring should not be exhaustive.
+    ///
+    /// This enum may grow additional variants, so this makes sure clients
+    /// don't count on exhaustive matching. (Otherwise, adding a new variant
+    /// could break existing code.)
+    #[doc(hidden)]
+    __Nonexhaustive,
+}
+
+impl ::std::error::Error for Error {
+    fn description(&self) -> &str {
+        match *self {
+            Error::Syntax(ref err) => err,
+            Error::CompiledTooBig(_) => "compiled program too big",
+            Error::__Nonexhaustive => unreachable!(),
+        }
+    }
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            Error::Syntax(ref err) => err.fmt(f),
+            Error::CompiledTooBig(limit) => {
+                write!(f, "Compiled regex exceeds size limit of {} bytes.",
+                       limit)
+            }
+            Error::__Nonexhaustive => unreachable!(),
+        }
+    }
+}
+
+// We implement our own Debug implementation so that we show nicer syntax
+// errors when people use `Regex::new(...).unwrap()`. It's a little weird,
+// but the `Syntax` variant is already storing a `String` anyway, so we might
+// as well format it nicely.
+impl fmt::Debug for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            Error::Syntax(ref err) => {
+                let hr: String = repeat('~').take(79).collect();
+                writeln!(f, "Syntax(")?;
+                writeln!(f, "{}", hr)?;
+                writeln!(f, "{}", err)?;
+                writeln!(f, "{}", hr)?;
+                write!(f, ")")?;
+                Ok(())
+            }
+            Error::CompiledTooBig(limit) => {
+                f.debug_tuple("CompiledTooBig")
+                    .field(&limit)
+                    .finish()
+            }
+            Error::__Nonexhaustive => {
+                f.debug_tuple("__Nonexhaustive").finish()
+            }
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/exec.rs.html b/target/doc/src/regex/exec.rs.html new file mode 100644 index 0000000..ac33d46 --- /dev/null +++ b/target/doc/src/regex/exec.rs.html @@ -0,0 +1,2933 @@ +exec.rs.html -- source
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::cell::RefCell;
+use std::collections::HashMap;
+use std::sync::Arc;
+
+use aho_corasick::{AhoCorasick, AhoCorasickBuilder, MatchKind};
+use thread_local::CachedThreadLocal;
+use syntax::ParserBuilder;
+use syntax::hir::Hir;
+use syntax::hir::literal::Literals;
+
+use backtrack;
+use compile::Compiler;
+use dfa;
+use error::Error;
+use input::{ByteInput, CharInput};
+use literal::LiteralSearcher;
+use pikevm;
+use prog::Program;
+use re_builder::RegexOptions;
+use re_bytes;
+use re_set;
+use re_trait::{RegularExpression, Slot, Locations};
+use re_unicode;
+use utf8::next_utf8;
+
+/// `Exec` manages the execution of a regular expression.
+///
+/// In particular, this manages the various compiled forms of a single regular
+/// expression and the choice of which matching engine to use to execute a
+/// regular expression.
+pub struct Exec {
+    /// All read only state.
+    ro: Arc<ExecReadOnly>,
+    /// Caches for the various matching engines.
+    cache: CachedThreadLocal<ProgramCache>,
+}
+
+/// `ExecNoSync` is like `Exec`, except it embeds a reference to a cache. This
+/// means it is no longer Sync, but we can now avoid the overhead of
+/// synchronization to fetch the cache.
+#[derive(Debug)]
+pub struct ExecNoSync<'c> {
+    /// All read only state.
+    ro: &'c Arc<ExecReadOnly>,
+    /// Caches for the various matching engines.
+    cache: &'c ProgramCache,
+}
+
+/// `ExecNoSyncStr` is like `ExecNoSync`, but matches on &str instead of &[u8].
+pub struct ExecNoSyncStr<'c>(ExecNoSync<'c>);
+
+/// `ExecReadOnly` comprises all read only state for a regex. Namely, all such
+/// state is determined at compile time and never changes during search.
+#[derive(Debug)]
+struct ExecReadOnly {
+    /// The original regular expressions given by the caller to compile.
+    res: Vec<String>,
+    /// A compiled program that is used in the NFA simulation and backtracking.
+    /// It can be byte-based or Unicode codepoint based.
+    ///
+    /// N.B. It is not possibly to make this byte-based from the public API.
+    /// It is only used for testing byte based programs in the NFA simulations.
+    nfa: Program,
+    /// A compiled byte based program for DFA execution. This is only used
+    /// if a DFA can be executed. (Currently, only word boundary assertions are
+    /// not supported.) Note that this program contains an embedded `.*?`
+    /// preceding the first capture group, unless the regex is anchored at the
+    /// beginning.
+    dfa: Program,
+    /// The same as above, except the program is reversed (and there is no
+    /// preceding `.*?`). This is used by the DFA to find the starting location
+    /// of matches.
+    dfa_reverse: Program,
+    /// A set of suffix literals extracted from the regex.
+    ///
+    /// Prefix literals are stored on the `Program`, since they are used inside
+    /// the matching engines.
+    suffixes: LiteralSearcher,
+    /// An Aho-Corasick automaton with leftmost-first match semantics.
+    ///
+    /// This is only set when the entire regex is a simple unanchored
+    /// alternation of literals. We could probably use it more circumstances,
+    /// but this is already hacky enough in this architecture.
+    ///
+    /// N.B. We use u32 as a state ID representation under the assumption that
+    /// if we were to exhaust the ID space, we probably would have long
+    /// surpassed the compilation size limit.
+    ac: Option<AhoCorasick<u32>>,
+    /// match_type encodes as much upfront knowledge about how we're going to
+    /// execute a search as possible.
+    match_type: MatchType,
+}
+
+/// Facilitates the construction of an executor by exposing various knobs
+/// to control how a regex is executed and what kinds of resources it's
+/// permitted to use.
+pub struct ExecBuilder {
+    options: RegexOptions,
+    match_type: Option<MatchType>,
+    bytes: bool,
+    only_utf8: bool,
+}
+
+/// Parsed represents a set of parsed regular expressions and their detected
+/// literals.
+struct Parsed {
+    exprs: Vec<Hir>,
+    prefixes: Literals,
+    suffixes: Literals,
+    bytes: bool,
+}
+
+impl ExecBuilder {
+    /// Create a regex execution builder.
+    ///
+    /// This uses default settings for everything except the regex itself,
+    /// which must be provided. Further knobs can be set by calling methods,
+    /// and then finally, `build` to actually create the executor.
+    pub fn new(re: &str) -> Self {
+        Self::new_many(&[re])
+    }
+
+    /// Like new, but compiles the union of the given regular expressions.
+    ///
+    /// Note that when compiling 2 or more regular expressions, capture groups
+    /// are completely unsupported. (This means both `find` and `captures`
+    /// wont work.)
+    pub fn new_many<I, S>(res: I) -> Self
+            where S: AsRef<str>, I: IntoIterator<Item=S> {
+        let mut opts = RegexOptions::default();
+        opts.pats = res.into_iter().map(|s| s.as_ref().to_owned()).collect();
+        Self::new_options(opts)
+    }
+
+    /// Create a regex execution builder.
+    pub fn new_options(opts: RegexOptions) -> Self {
+        ExecBuilder {
+            options: opts,
+            match_type: None,
+            bytes: false,
+            only_utf8: true,
+        }
+    }
+
+    /// Set the matching engine to be automatically determined.
+    ///
+    /// This is the default state and will apply whatever optimizations are
+    /// possible, such as running a DFA.
+    ///
+    /// This overrides whatever was previously set via the `nfa` or
+    /// `bounded_backtracking` methods.
+    pub fn automatic(mut self) -> Self {
+        self.match_type = None;
+        self
+    }
+
+    /// Sets the matching engine to use the NFA algorithm no matter what
+    /// optimizations are possible.
+    ///
+    /// This overrides whatever was previously set via the `automatic` or
+    /// `bounded_backtracking` methods.
+    pub fn nfa(mut self) -> Self {
+        self.match_type = Some(MatchType::Nfa(MatchNfaType::PikeVM));
+        self
+    }
+
+    /// Sets the matching engine to use a bounded backtracking engine no
+    /// matter what optimizations are possible.
+    ///
+    /// One must use this with care, since the bounded backtracking engine
+    /// uses memory proportion to `len(regex) * len(text)`.
+    ///
+    /// This overrides whatever was previously set via the `automatic` or
+    /// `nfa` methods.
+    pub fn bounded_backtracking(mut self) -> Self {
+        self.match_type = Some(MatchType::Nfa(MatchNfaType::Backtrack));
+        self
+    }
+
+    /// Compiles byte based programs for use with the NFA matching engines.
+    ///
+    /// By default, the NFA engines match on Unicode scalar values. They can
+    /// be made to use byte based programs instead. In general, the byte based
+    /// programs are slower because of a less efficient encoding of character
+    /// classes.
+    ///
+    /// Note that this does not impact DFA matching engines, which always
+    /// execute on bytes.
+    pub fn bytes(mut self, yes: bool) -> Self {
+        self.bytes = yes;
+        self
+    }
+
+    /// When disabled, the program compiled may match arbitrary bytes.
+    ///
+    /// When enabled (the default), all compiled programs exclusively match
+    /// valid UTF-8 bytes.
+    pub fn only_utf8(mut self, yes: bool) -> Self {
+        self.only_utf8 = yes;
+        self
+    }
+
+    /// Set the Unicode flag.
+    pub fn unicode(mut self, yes: bool) -> Self {
+        self.options.unicode = yes;
+        self
+    }
+
+    /// Parse the current set of patterns into their AST and extract literals.
+    fn parse(&self) -> Result<Parsed, Error> {
+        let mut exprs = Vec::with_capacity(self.options.pats.len());
+        let mut prefixes = Some(Literals::empty());
+        let mut suffixes = Some(Literals::empty());
+        let mut bytes = false;
+        let is_set = self.options.pats.len() > 1;
+        // If we're compiling a regex set and that set has any anchored
+        // expressions, then disable all literal optimizations.
+        for pat in &self.options.pats {
+            let mut parser =
+                ParserBuilder::new()
+                    .octal(self.options.octal)
+                    .case_insensitive(self.options.case_insensitive)
+                    .multi_line(self.options.multi_line)
+                    .dot_matches_new_line(self.options.dot_matches_new_line)
+                    .swap_greed(self.options.swap_greed)
+                    .ignore_whitespace(self.options.ignore_whitespace)
+                    .unicode(self.options.unicode)
+                    .allow_invalid_utf8(!self.only_utf8)
+                    .nest_limit(self.options.nest_limit)
+                    .build();
+            let expr = parser
+                .parse(pat)
+                .map_err(|e| Error::Syntax(e.to_string()))?;
+            bytes = bytes || !expr.is_always_utf8();
+
+            if !expr.is_anchored_start() && expr.is_any_anchored_start() {
+                // Partial anchors unfortunately make it hard to use prefixes,
+                // so disable them.
+                prefixes = None;
+            } else if is_set && expr.is_anchored_start() {
+                // Regex sets with anchors do not go well with literal
+                // optimizations.
+                prefixes = None;
+            }
+            prefixes = prefixes.and_then(|mut prefixes| {
+                if !prefixes.union_prefixes(&expr) {
+                    None
+                } else {
+                    Some(prefixes)
+                }
+            });
+
+            if !expr.is_anchored_end() && expr.is_any_anchored_end() {
+                // Partial anchors unfortunately make it hard to use suffixes,
+                // so disable them.
+                suffixes = None;
+            } else if is_set && expr.is_anchored_end() {
+                // Regex sets with anchors do not go well with literal
+                // optimizations.
+                suffixes = None;
+            }
+            suffixes = suffixes.and_then(|mut suffixes| {
+                if !suffixes.union_suffixes(&expr) {
+                    None
+                } else {
+                    Some(suffixes)
+                }
+            });
+            exprs.push(expr);
+        }
+        Ok(Parsed {
+            exprs: exprs,
+            prefixes: prefixes.unwrap_or_else(Literals::empty),
+            suffixes: suffixes.unwrap_or_else(Literals::empty),
+            bytes: bytes,
+        })
+    }
+
+    /// Build an executor that can run a regular expression.
+    pub fn build(self) -> Result<Exec, Error> {
+        // Special case when we have no patterns to compile.
+        // This can happen when compiling a regex set.
+        if self.options.pats.is_empty() {
+            let ro = Arc::new(ExecReadOnly {
+                res: vec![],
+                nfa: Program::new(),
+                dfa: Program::new(),
+                dfa_reverse: Program::new(),
+                suffixes: LiteralSearcher::empty(),
+                ac: None,
+                match_type: MatchType::Nothing,
+            });
+            return Ok(Exec { ro: ro, cache: CachedThreadLocal::new() });
+        }
+        let parsed = self.parse()?;
+        let mut nfa =
+            Compiler::new()
+                     .size_limit(self.options.size_limit)
+                     .bytes(self.bytes || parsed.bytes)
+                     .only_utf8(self.only_utf8)
+                     .compile(&parsed.exprs)?;
+        let mut dfa =
+            Compiler::new()
+                     .size_limit(self.options.size_limit)
+                     .dfa(true)
+                     .only_utf8(self.only_utf8)
+                     .compile(&parsed.exprs)?;
+        let mut dfa_reverse =
+            Compiler::new()
+                     .size_limit(self.options.size_limit)
+                     .dfa(true)
+                     .only_utf8(self.only_utf8)
+                     .reverse(true)
+                     .compile(&parsed.exprs)?;
+
+        nfa.prefixes = LiteralSearcher::prefixes(parsed.prefixes);
+        dfa.prefixes = nfa.prefixes.clone();
+        dfa.dfa_size_limit = self.options.dfa_size_limit;
+        dfa_reverse.dfa_size_limit = self.options.dfa_size_limit;
+
+        let mut ac = None;
+        if parsed.exprs.len() == 1 {
+            if let Some(lits) = alternation_literals(&parsed.exprs[0]) {
+                // If we have a small number of literals, then let Teddy
+                // handle things (see literal/mod.rs).
+                if lits.len() > 32 {
+                    let fsm = AhoCorasickBuilder::new()
+                        .match_kind(MatchKind::LeftmostFirst)
+                        .auto_configure(&lits)
+                        // We always want this to reduce size, regardless of
+                        // what auto-configure does.
+                        .byte_classes(true)
+                        .build_with_size::<u32, _, _>(&lits)
+                        .expect("AC automaton too big");
+                    ac = Some(fsm);
+                }
+            }
+        }
+
+        let mut ro = ExecReadOnly {
+            res: self.options.pats,
+            nfa: nfa,
+            dfa: dfa,
+            dfa_reverse: dfa_reverse,
+            suffixes: LiteralSearcher::suffixes(parsed.suffixes),
+            ac: ac,
+            match_type: MatchType::Nothing,
+        };
+        ro.match_type = ro.choose_match_type(self.match_type);
+
+        let ro = Arc::new(ro);
+        Ok(Exec { ro: ro, cache: CachedThreadLocal::new() })
+    }
+}
+
+impl<'c> RegularExpression for ExecNoSyncStr<'c> {
+    type Text = str;
+
+    fn slots_len(&self) -> usize { self.0.slots_len() }
+
+    fn next_after_empty(&self, text: &str, i: usize) -> usize {
+        next_utf8(text.as_bytes(), i)
+    }
+
+    #[inline(always)] // reduces constant overhead
+    fn shortest_match_at(&self, text: &str, start: usize) -> Option<usize> {
+        self.0.shortest_match_at(text.as_bytes(), start)
+    }
+
+    #[inline(always)] // reduces constant overhead
+    fn is_match_at(&self, text: &str, start: usize) -> bool {
+        self.0.is_match_at(text.as_bytes(), start)
+    }
+
+    #[inline(always)] // reduces constant overhead
+    fn find_at(&self, text: &str, start: usize) -> Option<(usize, usize)> {
+        self.0.find_at(text.as_bytes(), start)
+    }
+
+    #[inline(always)] // reduces constant overhead
+    fn captures_read_at(
+        &self,
+        locs: &mut Locations,
+        text: &str,
+        start: usize,
+    ) -> Option<(usize, usize)> {
+        self.0.captures_read_at(locs, text.as_bytes(), start)
+    }
+}
+
+impl<'c> RegularExpression for ExecNoSync<'c> {
+    type Text = [u8];
+
+    /// Returns the number of capture slots in the regular expression. (There
+    /// are two slots for every capture group, corresponding to possibly empty
+    /// start and end locations of the capture.)
+    fn slots_len(&self) -> usize {
+        self.ro.nfa.captures.len() * 2
+    }
+
+    fn next_after_empty(&self, _text: &[u8], i: usize) -> usize {
+        i + 1
+    }
+
+    /// Returns the end of a match location, possibly occurring before the
+    /// end location of the correct leftmost-first match.
+    #[inline(always)] // reduces constant overhead
+    fn shortest_match_at(&self, text: &[u8], start: usize) -> Option<usize> {
+        if !self.is_anchor_end_match(text) {
+            return None;
+        }
+        match self.ro.match_type {
+            MatchType::Literal(ty) => {
+                self.find_literals(ty, text, start).map(|(_, e)| e)
+            }
+            MatchType::Dfa | MatchType::DfaMany => {
+                match self.shortest_dfa(text, start) {
+                    dfa::Result::Match(end) => Some(end),
+                    dfa::Result::NoMatch(_) => None,
+                    dfa::Result::Quit => self.shortest_nfa(text, start),
+                }
+            }
+            MatchType::DfaAnchoredReverse => {
+                match dfa::Fsm::reverse(
+                    &self.ro.dfa_reverse,
+                    self.cache,
+                    true,
+                    &text[start..],
+                    text.len(),
+                ) {
+                    dfa::Result::Match(_) => Some(text.len()),
+                    dfa::Result::NoMatch(_) => None,
+                    dfa::Result::Quit => self.shortest_nfa(text, start),
+                }
+            }
+            MatchType::DfaSuffix => {
+                match self.shortest_dfa_reverse_suffix(text, start) {
+                    dfa::Result::Match(e) => Some(e),
+                    dfa::Result::NoMatch(_) => None,
+                    dfa::Result::Quit => self.shortest_nfa(text, start),
+                }
+            }
+            MatchType::Nfa(ty) => self.shortest_nfa_type(ty, text, start),
+            MatchType::Nothing => None,
+        }
+    }
+
+    /// Returns true if and only if the regex matches text.
+    ///
+    /// For single regular expressions, this is equivalent to calling
+    /// shortest_match(...).is_some().
+    #[inline(always)] // reduces constant overhead
+    fn is_match_at(&self, text: &[u8], start: usize) -> bool {
+        if !self.is_anchor_end_match(text) {
+            return false;
+        }
+        // We need to do this dance because shortest_match relies on the NFA
+        // filling in captures[1], but a RegexSet has no captures. In other
+        // words, a RegexSet can't (currently) use shortest_match. ---AG
+        match self.ro.match_type {
+            MatchType::Literal(ty) => {
+                self.find_literals(ty, text, start).is_some()
+            }
+            MatchType::Dfa | MatchType::DfaMany => {
+                match self.shortest_dfa(text, start) {
+                    dfa::Result::Match(_) => true,
+                    dfa::Result::NoMatch(_) => false,
+                    dfa::Result::Quit => self.match_nfa(text, start),
+                }
+            }
+            MatchType::DfaAnchoredReverse => {
+                match dfa::Fsm::reverse(
+                    &self.ro.dfa_reverse,
+                    self.cache,
+                    true,
+                    &text[start..],
+                    text.len(),
+                ) {
+                    dfa::Result::Match(_) => true,
+                    dfa::Result::NoMatch(_) => false,
+                    dfa::Result::Quit => self.match_nfa(text, start),
+                }
+            }
+            MatchType::DfaSuffix => {
+                match self.shortest_dfa_reverse_suffix(text, start) {
+                    dfa::Result::Match(_) => true,
+                    dfa::Result::NoMatch(_) => false,
+                    dfa::Result::Quit => self.match_nfa(text, start),
+                }
+            }
+            MatchType::Nfa(ty) => self.match_nfa_type(ty, text, start),
+            MatchType::Nothing => false,
+        }
+    }
+
+    /// Finds the start and end location of the leftmost-first match, starting
+    /// at the given location.
+    #[inline(always)] // reduces constant overhead
+    fn find_at(&self, text: &[u8], start: usize) -> Option<(usize, usize)> {
+        if !self.is_anchor_end_match(text) {
+            return None;
+        }
+        match self.ro.match_type {
+            MatchType::Literal(ty) => {
+                self.find_literals(ty, text, start)
+            }
+            MatchType::Dfa => {
+                match self.find_dfa_forward(text, start) {
+                    dfa::Result::Match((s, e)) => Some((s, e)),
+                    dfa::Result::NoMatch(_) => None,
+                    dfa::Result::Quit => {
+                        self.find_nfa(MatchNfaType::Auto, text, start)
+                    }
+                }
+            }
+            MatchType::DfaAnchoredReverse => {
+                match self.find_dfa_anchored_reverse(text, start) {
+                    dfa::Result::Match((s, e)) => Some((s, e)),
+                    dfa::Result::NoMatch(_) => None,
+                    dfa::Result::Quit => {
+                        self.find_nfa(MatchNfaType::Auto, text, start)
+                    }
+                }
+            }
+            MatchType::DfaSuffix => {
+                match self.find_dfa_reverse_suffix(text, start) {
+                    dfa::Result::Match((s, e)) => Some((s, e)),
+                    dfa::Result::NoMatch(_) => None,
+                    dfa::Result::Quit => {
+                        self.find_nfa(MatchNfaType::Auto, text, start)
+                    }
+                }
+            }
+            MatchType::Nfa(ty) => self.find_nfa(ty, text, start),
+            MatchType::Nothing => None,
+            MatchType::DfaMany => {
+                unreachable!("BUG: RegexSet cannot be used with find")
+            }
+        }
+    }
+
+    /// Finds the start and end location of the leftmost-first match and also
+    /// fills in all matching capture groups.
+    ///
+    /// The number of capture slots given should be equal to the total number
+    /// of capture slots in the compiled program.
+    ///
+    /// Note that the first two slots always correspond to the start and end
+    /// locations of the overall match.
+    fn captures_read_at(
+        &self,
+        locs: &mut Locations,
+        text: &[u8],
+        start: usize,
+    ) -> Option<(usize, usize)> {
+        let slots = locs.as_slots();
+        for slot in slots.iter_mut() {
+            *slot = None;
+        }
+        // If the caller unnecessarily uses this, then we try to save them
+        // from themselves.
+        match slots.len() {
+            0 => return self.find_at(text, start),
+            2 => {
+                return self.find_at(text, start).map(|(s, e)| {
+                    slots[0] = Some(s);
+                    slots[1] = Some(e);
+                    (s, e)
+                });
+            }
+            _ => {} // fallthrough
+        }
+        if !self.is_anchor_end_match(text) {
+            return None;
+        }
+        match self.ro.match_type {
+            MatchType::Literal(ty) => {
+                self.find_literals(ty, text, start).and_then(|(s, e)| {
+                    self.captures_nfa_type(
+                        MatchNfaType::Auto, slots, text, s, e)
+                })
+            }
+            MatchType::Dfa => {
+                if self.ro.nfa.is_anchored_start {
+                    self.captures_nfa(slots, text, start)
+                } else {
+                    match self.find_dfa_forward(text, start) {
+                        dfa::Result::Match((s, e)) => {
+                            self.captures_nfa_type(
+                                MatchNfaType::Auto, slots, text, s, e)
+                        }
+                        dfa::Result::NoMatch(_) => None,
+                        dfa::Result::Quit => {
+                            self.captures_nfa(slots, text, start)
+                        }
+                    }
+                }
+            }
+            MatchType::DfaAnchoredReverse => {
+                match self.find_dfa_anchored_reverse(text, start) {
+                    dfa::Result::Match((s, e)) => {
+                        self.captures_nfa_type(
+                            MatchNfaType::Auto, slots, text, s, e)
+                    }
+                    dfa::Result::NoMatch(_) => None,
+                    dfa::Result::Quit => self.captures_nfa(slots, text, start),
+                }
+            }
+            MatchType::DfaSuffix => {
+                match self.find_dfa_reverse_suffix(text, start) {
+                    dfa::Result::Match((s, e)) => {
+                        self.captures_nfa_type(
+                            MatchNfaType::Auto, slots, text, s, e)
+                    }
+                    dfa::Result::NoMatch(_) => None,
+                    dfa::Result::Quit => self.captures_nfa(slots, text, start),
+                }
+            }
+            MatchType::Nfa(ty) => {
+                self.captures_nfa_type(ty, slots, text, start, text.len())
+            }
+            MatchType::Nothing => None,
+            MatchType::DfaMany => {
+                unreachable!("BUG: RegexSet cannot be used with captures")
+            }
+        }
+    }
+}
+
+impl<'c> ExecNoSync<'c> {
+    /// Finds the leftmost-first match using only literal search.
+    #[inline(always)] // reduces constant overhead
+    fn find_literals(
+        &self,
+        ty: MatchLiteralType,
+        text: &[u8],
+        start: usize,
+    ) -> Option<(usize, usize)> {
+        use self::MatchLiteralType::*;
+        match ty {
+            Unanchored => {
+                let lits = &self.ro.nfa.prefixes;
+                lits.find(&text[start..])
+                    .map(|(s, e)| (start + s, start + e))
+            }
+            AnchoredStart => {
+                let lits = &self.ro.nfa.prefixes;
+                if !self.ro.nfa.is_anchored_start
+                    || (self.ro.nfa.is_anchored_start && start == 0) {
+                    lits.find_start(&text[start..])
+                        .map(|(s, e)| (start + s, start + e))
+                } else {
+                    None
+                }
+            }
+            AnchoredEnd => {
+                let lits = &self.ro.suffixes;
+                lits.find_end(&text[start..])
+                    .map(|(s, e)| (start + s, start + e))
+            }
+            AhoCorasick => {
+                self.ro.ac.as_ref().unwrap()
+                    .find(&text[start..])
+                    .map(|m| (start + m.start(), start + m.end()))
+            }
+        }
+    }
+
+    /// Finds the leftmost-first match (start and end) using only the DFA.
+    ///
+    /// If the result returned indicates that the DFA quit, then another
+    /// matching engine should be used.
+    #[inline(always)] // reduces constant overhead
+    fn find_dfa_forward(
+        &self,
+        text: &[u8],
+        start: usize,
+    ) -> dfa::Result<(usize, usize)> {
+        use dfa::Result::*;
+        let end = match dfa::Fsm::forward(
+            &self.ro.dfa,
+            self.cache,
+            false,
+            text,
+            start,
+        ) {
+            NoMatch(i) => return NoMatch(i),
+            Quit => return Quit,
+            Match(end) if start == end => return Match((start, start)),
+            Match(end) => end,
+        };
+        // Now run the DFA in reverse to find the start of the match.
+        match dfa::Fsm::reverse(
+            &self.ro.dfa_reverse,
+            self.cache,
+            false,
+            &text[start..],
+            end - start,
+        ) {
+            Match(s) => Match((start + s, end)),
+            NoMatch(i) => NoMatch(i),
+            Quit => Quit,
+        }
+    }
+
+    /// Finds the leftmost-first match (start and end) using only the DFA,
+    /// but assumes the regex is anchored at the end and therefore starts at
+    /// the end of the regex and matches in reverse.
+    ///
+    /// If the result returned indicates that the DFA quit, then another
+    /// matching engine should be used.
+    #[inline(always)] // reduces constant overhead
+    fn find_dfa_anchored_reverse(
+        &self,
+        text: &[u8],
+        start: usize,
+    ) -> dfa::Result<(usize, usize)> {
+        use dfa::Result::*;
+        match dfa::Fsm::reverse(
+            &self.ro.dfa_reverse,
+            self.cache,
+            false,
+            &text[start..],
+            text.len() - start,
+        ) {
+            Match(s) => Match((start + s, text.len())),
+            NoMatch(i) => NoMatch(i),
+            Quit => Quit,
+        }
+    }
+
+    /// Finds the end of the shortest match using only the DFA.
+    #[inline(always)] // reduces constant overhead
+    fn shortest_dfa(&self, text: &[u8], start: usize) -> dfa::Result<usize> {
+        dfa::Fsm::forward(&self.ro.dfa, self.cache, true, text, start)
+    }
+
+    /// Finds the end of the shortest match using only the DFA by scanning for
+    /// suffix literals.
+    ///
+    #[inline(always)] // reduces constant overhead
+    fn shortest_dfa_reverse_suffix(
+        &self,
+        text: &[u8],
+        start: usize,
+    ) -> dfa::Result<usize> {
+        match self.exec_dfa_reverse_suffix(text, start) {
+            None => self.shortest_dfa(text, start),
+            Some(r) => r.map(|(_, end)| end),
+        }
+    }
+
+    /// Finds the end of the shortest match using only the DFA by scanning for
+    /// suffix literals. It also reports the start of the match.
+    ///
+    /// Note that if None is returned, then the optimization gave up to avoid
+    /// worst case quadratic behavior. A forward scanning DFA should be tried
+    /// next.
+    ///
+    /// If a match is returned and the full leftmost-first match is desired,
+    /// then a forward scan starting from the beginning of the match must be
+    /// done.
+    ///
+    /// If the result returned indicates that the DFA quit, then another
+    /// matching engine should be used.
+    #[inline(always)] // reduces constant overhead
+    fn exec_dfa_reverse_suffix(
+        &self,
+        text: &[u8],
+        original_start: usize,
+    ) -> Option<dfa::Result<(usize, usize)>> {
+        use dfa::Result::*;
+
+        let lcs = self.ro.suffixes.lcs();
+        debug_assert!(lcs.len() >= 1);
+        let mut start = original_start;
+        let mut end = start;
+        let mut last_literal = start;
+        while end <= text.len() {
+            last_literal += match lcs.find(&text[last_literal..]) {
+                None => return Some(NoMatch(text.len())),
+                Some(i) => i,
+            };
+            end = last_literal + lcs.len();
+            match dfa::Fsm::reverse(
+                &self.ro.dfa_reverse,
+                self.cache,
+                false,
+                &text[start..end],
+                end - start,
+            ) {
+                Match(0) | NoMatch(0) => return None,
+                Match(i) => return Some(Match((start + i, end))),
+                NoMatch(i) => {
+                    start += i;
+                    last_literal += 1;
+                    continue;
+                }
+                Quit => return Some(Quit),
+            };
+        }
+        Some(NoMatch(text.len()))
+    }
+
+    /// Finds the leftmost-first match (start and end) using only the DFA
+    /// by scanning for suffix literals.
+    ///
+    /// If the result returned indicates that the DFA quit, then another
+    /// matching engine should be used.
+    #[inline(always)] // reduces constant overhead
+    fn find_dfa_reverse_suffix(
+        &self,
+        text: &[u8],
+        start: usize,
+    ) -> dfa::Result<(usize, usize)> {
+        use dfa::Result::*;
+
+        let match_start = match self.exec_dfa_reverse_suffix(text, start) {
+            None => return self.find_dfa_forward(text, start),
+            Some(Match((start, _))) => start,
+            Some(r) => return r,
+        };
+        // At this point, we've found a match. The only way to quit now
+        // without a match is if the DFA gives up (seems unlikely).
+        //
+        // Now run the DFA forwards to find the proper end of the match.
+        // (The suffix literal match can only indicate the earliest
+        // possible end location, which may appear before the end of the
+        // leftmost-first match.)
+        match dfa::Fsm::forward(
+            &self.ro.dfa,
+            self.cache,
+            false,
+            text,
+            match_start,
+        ) {
+            NoMatch(_) => panic!("BUG: reverse match implies forward match"),
+            Quit => Quit,
+            Match(e) => Match((match_start, e)),
+        }
+    }
+
+    /// Executes the NFA engine to return whether there is a match or not.
+    ///
+    /// Ideally, we could use shortest_nfa(...).is_some() and get the same
+    /// performance characteristics, but regex sets don't have captures, which
+    /// shortest_nfa depends on.
+    fn match_nfa(
+        &self,
+        text: &[u8],
+        start: usize,
+    ) -> bool {
+        self.match_nfa_type(MatchNfaType::Auto, text, start)
+    }
+
+    /// Like match_nfa, but allows specification of the type of NFA engine.
+    fn match_nfa_type(
+        &self,
+        ty: MatchNfaType,
+        text: &[u8],
+        start: usize,
+    ) -> bool {
+        self.exec_nfa(ty, &mut [false], &mut [], true, text, start, text.len())
+    }
+
+    /// Finds the shortest match using an NFA.
+    fn shortest_nfa(&self, text: &[u8], start: usize) -> Option<usize> {
+        self.shortest_nfa_type(MatchNfaType::Auto, text, start)
+    }
+
+    /// Like shortest_nfa, but allows specification of the type of NFA engine.
+    fn shortest_nfa_type(
+        &self,
+        ty: MatchNfaType,
+        text: &[u8],
+        start: usize,
+    ) -> Option<usize> {
+        let mut slots = [None, None];
+        if self.exec_nfa(
+            ty,
+            &mut [false],
+            &mut slots,
+            true,
+            text,
+            start,
+            text.len()
+        ) {
+            slots[1]
+        } else {
+            None
+        }
+    }
+
+    /// Like find, but executes an NFA engine.
+    fn find_nfa(
+        &self,
+        ty: MatchNfaType,
+        text: &[u8],
+        start: usize,
+    ) -> Option<(usize, usize)> {
+        let mut slots = [None, None];
+        if self.exec_nfa(
+            ty,
+            &mut [false],
+            &mut slots,
+            false,
+            text,
+            start,
+            text.len()
+        ) {
+            match (slots[0], slots[1]) {
+                (Some(s), Some(e)) => Some((s, e)),
+                _ => None,
+            }
+        } else {
+            None
+        }
+    }
+
+    /// Like find_nfa, but fills in captures.
+    ///
+    /// `slots` should have length equal to `2 * nfa.captures.len()`.
+    fn captures_nfa(
+        &self,
+        slots: &mut [Slot],
+        text: &[u8],
+        start: usize,
+    ) -> Option<(usize, usize)> {
+        self.captures_nfa_type(
+            MatchNfaType::Auto, slots, text, start, text.len())
+    }
+
+    /// Like captures_nfa, but allows specification of type of NFA engine.
+    fn captures_nfa_type(
+        &self,
+        ty: MatchNfaType,
+        slots: &mut [Slot],
+        text: &[u8],
+        start: usize,
+        end: usize,
+    ) -> Option<(usize, usize)> {
+        if self.exec_nfa(ty, &mut [false], slots, false, text, start, end) {
+            match (slots[0], slots[1]) {
+                (Some(s), Some(e)) => Some((s, e)),
+                _ => None,
+            }
+        } else {
+            None
+        }
+    }
+
+    fn exec_nfa(
+        &self,
+        mut ty: MatchNfaType,
+        matches: &mut [bool],
+        slots: &mut [Slot],
+        quit_after_match: bool,
+        text: &[u8],
+        start: usize,
+        end: usize,
+    ) -> bool {
+        use self::MatchNfaType::*;
+        if let Auto = ty {
+            if backtrack::should_exec(self.ro.nfa.len(), text.len()) {
+                ty = Backtrack;
+            } else {
+                ty = PikeVM;
+            }
+        }
+        match ty {
+            Auto => unreachable!(),
+            Backtrack => self.exec_backtrack(matches, slots, text, start, end),
+            PikeVM => {
+                self.exec_pikevm(
+                    matches, slots, quit_after_match, text, start, end)
+            }
+        }
+    }
+
+    /// Always run the NFA algorithm.
+    fn exec_pikevm(
+        &self,
+        matches: &mut [bool],
+        slots: &mut [Slot],
+        quit_after_match: bool,
+        text: &[u8],
+        start: usize,
+        end: usize,
+    ) -> bool {
+        if self.ro.nfa.uses_bytes() {
+            pikevm::Fsm::exec(
+                &self.ro.nfa,
+                self.cache,
+                matches,
+                slots,
+                quit_after_match,
+                ByteInput::new(text, self.ro.nfa.only_utf8),
+                start,
+                end)
+        } else {
+            pikevm::Fsm::exec(
+                &self.ro.nfa,
+                self.cache,
+                matches,
+                slots,
+                quit_after_match,
+                CharInput::new(text),
+                start,
+                end)
+        }
+    }
+
+    /// Always runs the NFA using bounded backtracking.
+    fn exec_backtrack(
+        &self,
+        matches: &mut [bool],
+        slots: &mut [Slot],
+        text: &[u8],
+        start: usize,
+        end: usize,
+    ) -> bool {
+        if self.ro.nfa.uses_bytes() {
+            backtrack::Bounded::exec(
+                &self.ro.nfa,
+                self.cache,
+                matches,
+                slots,
+                ByteInput::new(text, self.ro.nfa.only_utf8),
+                start,
+                end)
+        } else {
+            backtrack::Bounded::exec(
+                &self.ro.nfa,
+                self.cache,
+                matches,
+                slots,
+                CharInput::new(text),
+                start,
+                end)
+        }
+    }
+
+    /// Finds which regular expressions match the given text.
+    ///
+    /// `matches` should have length equal to the number of regexes being
+    /// searched.
+    ///
+    /// This is only useful when one wants to know which regexes in a set
+    /// match some text.
+    pub fn many_matches_at(
+        &self,
+        matches: &mut [bool],
+        text: &[u8],
+        start: usize,
+    ) -> bool {
+        use self::MatchType::*;
+        if !self.is_anchor_end_match(text) {
+            return false;
+        }
+        match self.ro.match_type {
+            Literal(ty) => {
+                debug_assert_eq!(matches.len(), 1);
+                matches[0] = self.find_literals(ty, text, start).is_some();
+                matches[0]
+            }
+            Dfa | DfaAnchoredReverse | DfaSuffix | DfaMany => {
+                match dfa::Fsm::forward_many(
+                    &self.ro.dfa,
+                    self.cache,
+                    matches,
+                    text,
+                    start,
+                ) {
+                    dfa::Result::Match(_) => true,
+                    dfa::Result::NoMatch(_) => false,
+                    dfa::Result::Quit => {
+                        self.exec_nfa(
+                            MatchNfaType::Auto,
+                            matches,
+                            &mut [],
+                            false,
+                            text,
+                            start,
+                            text.len())
+                    }
+                }
+            }
+            Nfa(ty) => {
+                self.exec_nfa(
+                    ty, matches, &mut [], false, text, start, text.len())
+            }
+            Nothing => false,
+        }
+    }
+
+    #[inline(always)] // reduces constant overhead
+    fn is_anchor_end_match(&self, text: &[u8]) -> bool {
+        // Only do this check if the haystack is big (>1MB).
+        if text.len() > (1<<20) && self.ro.nfa.is_anchored_end {
+            let lcs = self.ro.suffixes.lcs();
+            if lcs.len() >= 1 && !lcs.is_suffix(text) {
+                return false;
+            }
+        }
+        true
+    }
+
+    pub fn capture_name_idx(&self) -> &Arc<HashMap<String, usize>> {
+        &self.ro.nfa.capture_name_idx
+    }
+}
+
+impl<'c> ExecNoSyncStr<'c> {
+    pub fn capture_name_idx(&self) -> &Arc<HashMap<String, usize>> {
+        self.0.capture_name_idx()
+    }
+}
+
+impl Exec {
+    /// Get a searcher that isn't Sync.
+    #[inline(always)] // reduces constant overhead
+    pub fn searcher(&self) -> ExecNoSync {
+        let create = || {
+            Box::new(RefCell::new(ProgramCacheInner::new(&self.ro)))
+        };
+        ExecNoSync {
+            ro: &self.ro, // a clone is too expensive here! (and not needed)
+            cache: self.cache.get_or(create),
+        }
+    }
+
+    /// Get a searcher that isn't Sync and can match on &str.
+    #[inline(always)] // reduces constant overhead
+    pub fn searcher_str(&self) -> ExecNoSyncStr {
+        ExecNoSyncStr(self.searcher())
+    }
+
+    /// Build a Regex from this executor.
+    pub fn into_regex(self) -> re_unicode::Regex {
+        re_unicode::Regex::from(self)
+    }
+
+    /// Build a RegexSet from this executor.
+    pub fn into_regex_set(self) -> re_set::unicode::RegexSet {
+        re_set::unicode::RegexSet::from(self)
+    }
+
+    /// Build a Regex from this executor that can match arbitrary bytes.
+    pub fn into_byte_regex(self) -> re_bytes::Regex {
+        re_bytes::Regex::from(self)
+    }
+
+    /// Build a RegexSet from this executor that can match arbitrary bytes.
+    pub fn into_byte_regex_set(self) -> re_set::bytes::RegexSet {
+        re_set::bytes::RegexSet::from(self)
+    }
+
+    /// The original regular expressions given by the caller that were
+    /// compiled.
+    pub fn regex_strings(&self) -> &[String] {
+        &self.ro.res
+    }
+
+    /// Return a slice of capture names.
+    ///
+    /// Any capture that isn't named is None.
+    pub fn capture_names(&self) -> &[Option<String>] {
+        &self.ro.nfa.captures
+    }
+
+    /// Return a reference to named groups mapping (from group name to
+    /// group position).
+    pub fn capture_name_idx(&self) -> &Arc<HashMap<String, usize>> {
+        &self.ro.nfa.capture_name_idx
+    }
+}
+
+impl Clone for Exec {
+    fn clone(&self) -> Exec {
+        Exec {
+            ro: self.ro.clone(),
+            cache: CachedThreadLocal::new(),
+        }
+    }
+}
+
+impl ExecReadOnly {
+    fn choose_match_type(&self, hint: Option<MatchType>) -> MatchType {
+        use self::MatchType::*;
+        if let Some(Nfa(_)) = hint {
+            return hint.unwrap();
+        }
+        // If the NFA is empty, then we'll never match anything.
+        if self.nfa.insts.is_empty() {
+            return Nothing;
+        }
+        // If our set of prefixes is complete, then we can use it to find
+        // a match in lieu of a regex engine. This doesn't quite work well in
+        // the presence of multiple regexes, so only do it when there's one.
+        //
+        // TODO(burntsushi): Also, don't try to match literals if the regex is
+        // partially anchored. We could technically do it, but we'd need to
+        // create two sets of literals: all of them and then the subset that
+        // aren't anchored. We would then only search for all of them when at
+        // the beginning of the input and use the subset in all other cases.
+        if self.res.len() == 1 {
+            if self.ac.is_some() {
+                return Literal(MatchLiteralType::AhoCorasick);
+            }
+            if self.nfa.prefixes.complete() {
+                return if self.nfa.is_anchored_start {
+                    Literal(MatchLiteralType::AnchoredStart)
+                } else {
+                    Literal(MatchLiteralType::Unanchored)
+                };
+            }
+            if self.suffixes.complete() {
+                return if self.nfa.is_anchored_end {
+                    Literal(MatchLiteralType::AnchoredEnd)
+                } else {
+                    // This case shouldn't happen. When the regex isn't
+                    // anchored, then complete prefixes should imply complete
+                    // suffixes.
+                    Literal(MatchLiteralType::Unanchored)
+                };
+            }
+        }
+        // If we can execute the DFA, then we totally should.
+        if dfa::can_exec(&self.dfa) {
+            // Regex sets require a slightly specialized path.
+            if self.res.len() >= 2 {
+                return DfaMany;
+            }
+            // If the regex is anchored at the end but not the start, then
+            // just match in reverse from the end of the haystack.
+            if !self.nfa.is_anchored_start && self.nfa.is_anchored_end {
+                return DfaAnchoredReverse;
+            }
+            // If there's a longish suffix literal, then it might be faster
+            // to look for that first.
+            if self.should_suffix_scan() {
+                return DfaSuffix;
+            }
+            // Fall back to your garden variety forward searching lazy DFA.
+            return Dfa;
+        }
+        // We're so totally hosed.
+        Nfa(MatchNfaType::Auto)
+    }
+
+    /// Returns true if the program is amenable to suffix scanning.
+    ///
+    /// When this is true, as a heuristic, we assume it is OK to quickly scan
+    /// for suffix literals and then do a *reverse* DFA match from any matches
+    /// produced by the literal scan. (And then followed by a forward DFA
+    /// search, since the previously found suffix literal maybe not actually be
+    /// the end of a match.)
+    ///
+    /// This is a bit of a specialized optimization, but can result in pretty
+    /// big performance wins if 1) there are no prefix literals and 2) the
+    /// suffix literals are pretty rare in the text. (1) is obviously easy to
+    /// account for but (2) is harder. As a proxy, we assume that longer
+    /// strings are generally rarer, so we only enable this optimization when
+    /// we have a meaty suffix.
+    fn should_suffix_scan(&self) -> bool {
+        if self.suffixes.is_empty() {
+            return false;
+        }
+        let lcs_len = self.suffixes.lcs().char_len();
+        lcs_len >= 3 && lcs_len > self.dfa.prefixes.lcp().char_len()
+    }
+}
+
+#[derive(Clone, Copy, Debug)]
+enum MatchType {
+    /// A single or multiple literal search. This is only used when the regex
+    /// can be decomposed into a literal search.
+    Literal(MatchLiteralType),
+    /// A normal DFA search.
+    Dfa,
+    /// A reverse DFA search starting from the end of a haystack.
+    DfaAnchoredReverse,
+    /// A reverse DFA search with suffix literal scanning.
+    DfaSuffix,
+    /// Use the DFA on two or more regular expressions.
+    DfaMany,
+    /// An NFA variant.
+    Nfa(MatchNfaType),
+    /// No match is ever possible, so don't ever try to search.
+    Nothing,
+}
+
+#[derive(Clone, Copy, Debug)]
+enum MatchLiteralType {
+    /// Match literals anywhere in text.
+    Unanchored,
+    /// Match literals only at the start of text.
+    AnchoredStart,
+    /// Match literals only at the end of text.
+    AnchoredEnd,
+    /// Use an Aho-Corasick automaton. This requires `ac` to be Some on
+    /// ExecReadOnly.
+    AhoCorasick,
+}
+
+#[derive(Clone, Copy, Debug)]
+enum MatchNfaType {
+    /// Choose between Backtrack and PikeVM.
+    Auto,
+    /// NFA bounded backtracking.
+    ///
+    /// (This is only set by tests, since it never makes sense to always want
+    /// backtracking.)
+    Backtrack,
+    /// The Pike VM.
+    ///
+    /// (This is only set by tests, since it never makes sense to always want
+    /// the Pike VM.)
+    PikeVM,
+}
+
+/// `ProgramCache` maintains reusable allocations for each matching engine
+/// available to a particular program.
+pub type ProgramCache = RefCell<ProgramCacheInner>;
+
+#[derive(Debug)]
+pub struct ProgramCacheInner {
+    pub pikevm: pikevm::Cache,
+    pub backtrack: backtrack::Cache,
+    pub dfa: dfa::Cache,
+    pub dfa_reverse: dfa::Cache,
+}
+
+impl ProgramCacheInner {
+    fn new(ro: &ExecReadOnly) -> Self {
+        ProgramCacheInner {
+            pikevm: pikevm::Cache::new(&ro.nfa),
+            backtrack: backtrack::Cache::new(&ro.nfa),
+            dfa: dfa::Cache::new(&ro.dfa),
+            dfa_reverse: dfa::Cache::new(&ro.dfa_reverse),
+        }
+    }
+}
+
+/// Alternation literals checks if the given HIR is a simple alternation of
+/// literals, and if so, returns them. Otherwise, this returns None.
+fn alternation_literals(expr: &Hir) -> Option<Vec<Vec<u8>>> {
+    use syntax::hir::{HirKind, Literal};
+
+    // This is pretty hacky, but basically, if `is_alternation_literal` is
+    // true, then we can make several assumptions about the structure of our
+    // HIR. This is what justifies the `unreachable!` statements below.
+    //
+    // This code should be refactored once we overhaul this crate's
+    // optimization pipeline, because this is a terribly inflexible way to go
+    // about things.
+
+    if !expr.is_alternation_literal() {
+        return None;
+    }
+    let alts = match *expr.kind() {
+        HirKind::Alternation(ref alts) => alts,
+        _ => return None, // one literal isn't worth it
+    };
+
+    let extendlit = |lit: &Literal, dst: &mut Vec<u8>| {
+        match *lit {
+            Literal::Unicode(c) => {
+                let mut buf = [0; 4];
+                dst.extend_from_slice(c.encode_utf8(&mut buf).as_bytes());
+            }
+            Literal::Byte(b) => {
+                dst.push(b);
+            }
+        }
+    };
+
+    let mut lits = vec![];
+    for alt in alts {
+        let mut lit = vec![];
+        match *alt.kind() {
+            HirKind::Literal(ref x) => extendlit(x, &mut lit),
+            HirKind::Concat(ref exprs) => {
+                for e in exprs {
+                    match *e.kind() {
+                        HirKind::Literal(ref x) => extendlit(x, &mut lit),
+                        _ => unreachable!("expected literal, got {:?}", e),
+                    }
+                }
+            }
+            _ => unreachable!("expected literal or concat, got {:?}", alt),
+        }
+        lits.push(lit);
+    }
+    Some(lits)
+}
+
+#[cfg(test)]
+mod test {
+    #[test]
+    fn uppercut_s_backtracking_bytes_default_bytes_mismatch() {
+        use internal::ExecBuilder;
+
+        let backtrack_bytes_re = ExecBuilder::new("^S")
+            .bounded_backtracking()
+            .only_utf8(false)
+            .build()
+            .map(|exec| exec.into_byte_regex())
+            .map_err(|err| format!("{}", err))
+            .unwrap();
+
+        let default_bytes_re = ExecBuilder::new("^S")
+            .only_utf8(false)
+            .build()
+            .map(|exec| exec.into_byte_regex())
+            .map_err(|err| format!("{}", err))
+            .unwrap();
+
+        let input = vec![83, 83];
+
+        let s1 = backtrack_bytes_re.split(&input);
+        let s2 = default_bytes_re.split(&input);
+        for (chunk1, chunk2) in s1.zip(s2) {
+            assert_eq!(chunk1, chunk2);
+        }
+    }
+
+    #[test]
+    fn unicode_lit_star_backtracking_utf8bytes_default_utf8bytes_mismatch() {
+        use internal::ExecBuilder;
+
+        let backtrack_bytes_re = ExecBuilder::new(r"^(?u:\*)")
+            .bounded_backtracking()
+            .bytes(true)
+            .build()
+            .map(|exec| exec.into_regex())
+            .map_err(|err| format!("{}", err))
+            .unwrap();
+
+        let default_bytes_re = ExecBuilder::new(r"^(?u:\*)")
+            .bytes(true)
+            .build()
+            .map(|exec| exec.into_regex())
+            .map_err(|err| format!("{}", err))
+            .unwrap();
+
+        let input = "**";
+
+        let s1 = backtrack_bytes_re.split(input);
+        let s2 = default_bytes_re.split(input);
+        for (chunk1, chunk2) in s1.zip(s2) {
+            assert_eq!(chunk1, chunk2);
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/expand.rs.html b/target/doc/src/regex/expand.rs.html new file mode 100644 index 0000000..43b4388 --- /dev/null +++ b/target/doc/src/regex/expand.rs.html @@ -0,0 +1,443 @@ +expand.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+
+use std::str;
+
+use memchr::memchr;
+
+use re_bytes;
+use re_unicode;
+
+pub fn expand_str(
+    caps: &re_unicode::Captures,
+    mut replacement: &str,
+    dst: &mut String,
+) {
+    while !replacement.is_empty() {
+        match memchr(b'$', replacement.as_bytes()) {
+            None => break,
+            Some(i) => {
+                dst.push_str(&replacement[..i]);
+                replacement = &replacement[i..];
+            }
+        }
+        if replacement.as_bytes().get(1).map_or(false, |&b| b == b'$') {
+            dst.push_str("$");
+            replacement = &replacement[2..];
+            continue;
+        }
+        debug_assert!(!replacement.is_empty());
+        let cap_ref = match find_cap_ref(replacement) {
+            Some(cap_ref) => cap_ref,
+            None => {
+                dst.push_str("$");
+                replacement = &replacement[1..];
+                continue;
+            }
+        };
+        replacement = &replacement[cap_ref.end..];
+        match cap_ref.cap {
+            Ref::Number(i) => {
+                dst.push_str(
+                    caps.get(i).map(|m| m.as_str()).unwrap_or(""));
+            }
+            Ref::Named(name) => {
+                dst.push_str(
+                    caps.name(name).map(|m| m.as_str()).unwrap_or(""));
+            }
+        }
+    }
+    dst.push_str(replacement);
+}
+
+pub fn expand_bytes(
+    caps: &re_bytes::Captures,
+    mut replacement: &[u8],
+    dst: &mut Vec<u8>,
+) {
+    while !replacement.is_empty() {
+        match memchr(b'$', replacement) {
+            None => break,
+            Some(i) => {
+                dst.extend(&replacement[..i]);
+                replacement = &replacement[i..];
+            }
+        }
+        if replacement.get(1).map_or(false, |&b| b == b'$') {
+            dst.push(b'$');
+            replacement = &replacement[2..];
+            continue;
+        }
+        debug_assert!(!replacement.is_empty());
+        let cap_ref = match find_cap_ref(replacement) {
+            Some(cap_ref) => cap_ref,
+            None => {
+                dst.push(b'$');
+                replacement = &replacement[1..];
+                continue;
+            }
+        };
+        replacement = &replacement[cap_ref.end..];
+        match cap_ref.cap {
+            Ref::Number(i) => {
+                dst.extend(
+                    caps.get(i).map(|m| m.as_bytes()).unwrap_or(b""));
+            }
+            Ref::Named(name) => {
+                dst.extend(
+                    caps.name(name).map(|m| m.as_bytes()).unwrap_or(b""));
+            }
+        }
+    }
+    dst.extend(replacement);
+}
+
+/// `CaptureRef` represents a reference to a capture group inside some text.
+/// The reference is either a capture group name or a number.
+///
+/// It is also tagged with the position in the text following the
+/// capture reference.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+struct CaptureRef<'a> {
+    cap: Ref<'a>,
+    end: usize,
+}
+
+/// A reference to a capture group in some text.
+///
+/// e.g., `$2`, `$foo`, `${foo}`.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+enum Ref<'a> {
+    Named(&'a str),
+    Number(usize),
+}
+
+impl<'a> From<&'a str> for Ref<'a> {
+    fn from(x: &'a str) -> Ref<'a> {
+        Ref::Named(x)
+    }
+}
+
+impl From<usize> for Ref<'static> {
+    fn from(x: usize) -> Ref<'static> {
+        Ref::Number(x)
+    }
+}
+
+/// Parses a possible reference to a capture group name in the given text,
+/// starting at the beginning of `replacement`.
+///
+/// If no such valid reference could be found, None is returned.
+fn find_cap_ref<T: ?Sized + AsRef<[u8]>>(
+    replacement: &T,
+) -> Option<CaptureRef> {
+    let mut i = 0;
+    let rep: &[u8] = replacement.as_ref();
+    if rep.len() <= 1 || rep[0] != b'$' {
+        return None;
+    }
+    let mut brace = false;
+    i += 1;
+    if rep[i] == b'{' {
+        brace = true;
+        i += 1;
+    }
+    let mut cap_end = i;
+    while rep.get(cap_end).map_or(false, is_valid_cap_letter) {
+        cap_end += 1;
+    }
+    if cap_end == i {
+        return None;
+    }
+    // We just verified that the range 0..cap_end is valid ASCII, so it must
+    // therefore be valid UTF-8. If we really cared, we could avoid this UTF-8
+    // check with either unsafe or by parsing the number straight from &[u8].
+    let cap = str::from_utf8(&rep[i..cap_end])
+                  .expect("valid UTF-8 capture name");
+    if brace {
+        if !rep.get(cap_end).map_or(false, |&b| b == b'}') {
+            return None;
+        }
+        cap_end += 1;
+    }
+    Some(CaptureRef {
+        cap: match cap.parse::<u32>() {
+            Ok(i) => Ref::Number(i as usize),
+            Err(_) => Ref::Named(cap),
+        },
+        end: cap_end,
+    })
+}
+
+/// Returns true if and only if the given byte is allowed in a capture name.
+fn is_valid_cap_letter(b: &u8) -> bool {
+    match *b {
+        b'0' ..= b'9' | b'a' ..= b'z' | b'A' ..= b'Z' | b'_' => true,
+        _ => false,
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::{CaptureRef, find_cap_ref};
+
+    macro_rules! find {
+        ($name:ident, $text:expr) => {
+            #[test]
+            fn $name() {
+                assert_eq!(None, find_cap_ref($text));
+            }
+        };
+        ($name:ident, $text:expr, $capref:expr) => {
+            #[test]
+            fn $name() {
+                assert_eq!(Some($capref), find_cap_ref($text));
+            }
+        };
+    }
+
+    macro_rules! c {
+        ($name_or_number:expr, $pos:expr) => {
+            CaptureRef { cap: $name_or_number.into(), end: $pos }
+        };
+    }
+
+    find!(find_cap_ref1, "$foo", c!("foo", 4));
+    find!(find_cap_ref2, "${foo}", c!("foo", 6));
+    find!(find_cap_ref3, "$0", c!(0, 2));
+    find!(find_cap_ref4, "$5", c!(5, 2));
+    find!(find_cap_ref5, "$10", c!(10, 3));
+    // see https://github.com/rust-lang/regex/pull/585 for more on characters following numbers
+    find!(find_cap_ref6, "$42a", c!("42a", 4));
+    find!(find_cap_ref7, "${42}a", c!(42, 5));
+    find!(find_cap_ref8, "${42");
+    find!(find_cap_ref9, "${42 ");
+    find!(find_cap_ref10, " $0 ");
+    find!(find_cap_ref11, "$");
+    find!(find_cap_ref12, " ");
+    find!(find_cap_ref13, "");
+    find!(find_cap_ref14, "$1-$2", c!(1,2));
+    find!(find_cap_ref15, "$1_$2", c!("1_",3));
+    find!(find_cap_ref16, "$x-$y", c!("x",2));
+    find!(find_cap_ref17, "$x_$y", c!("x_",3));
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/freqs.rs.html b/target/doc/src/regex/freqs.rs.html new file mode 100644 index 0000000..0fe449e --- /dev/null +++ b/target/doc/src/regex/freqs.rs.html @@ -0,0 +1,545 @@ +freqs.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// NOTE: The following code was generated by "scripts/frequencies.py", do not
+// edit directly
+
+pub const BYTE_FREQUENCIES: [u8; 256] = [
+     55, // '\x00'
+     52, // '\x01'
+     51, // '\x02'
+     50, // '\x03'
+     49, // '\x04'
+     48, // '\x05'
+     47, // '\x06'
+     46, // '\x07'
+     45, // '\x08'
+    103, // '\t'
+    242, // '\n'
+     66, // '\x0b'
+     67, // '\x0c'
+    229, // '\r'
+     44, // '\x0e'
+     43, // '\x0f'
+     42, // '\x10'
+     41, // '\x11'
+     40, // '\x12'
+     39, // '\x13'
+     38, // '\x14'
+     37, // '\x15'
+     36, // '\x16'
+     35, // '\x17'
+     34, // '\x18'
+     33, // '\x19'
+     56, // '\x1a'
+     32, // '\x1b'
+     31, // '\x1c'
+     30, // '\x1d'
+     29, // '\x1e'
+     28, // '\x1f'
+    255, // ' '
+    148, // '!'
+    164, // '"'
+    149, // '#'
+    136, // '$'
+    160, // '%'
+    155, // '&'
+    173, // "'"
+    221, // '('
+    222, // ')'
+    134, // '*'
+    122, // '+'
+    232, // ','
+    202, // '-'
+    215, // '.'
+    224, // '/'
+    208, // '0'
+    220, // '1'
+    204, // '2'
+    187, // '3'
+    183, // '4'
+    179, // '5'
+    177, // '6'
+    168, // '7'
+    178, // '8'
+    200, // '9'
+    226, // ':'
+    195, // ';'
+    154, // '<'
+    184, // '='
+    174, // '>'
+    126, // '?'
+    120, // '@'
+    191, // 'A'
+    157, // 'B'
+    194, // 'C'
+    170, // 'D'
+    189, // 'E'
+    162, // 'F'
+    161, // 'G'
+    150, // 'H'
+    193, // 'I'
+    142, // 'J'
+    137, // 'K'
+    171, // 'L'
+    176, // 'M'
+    185, // 'N'
+    167, // 'O'
+    186, // 'P'
+    112, // 'Q'
+    175, // 'R'
+    192, // 'S'
+    188, // 'T'
+    156, // 'U'
+    140, // 'V'
+    143, // 'W'
+    123, // 'X'
+    133, // 'Y'
+    128, // 'Z'
+    147, // '['
+    138, // '\\'
+    146, // ']'
+    114, // '^'
+    223, // '_'
+    151, // '`'
+    249, // 'a'
+    216, // 'b'
+    238, // 'c'
+    236, // 'd'
+    253, // 'e'
+    227, // 'f'
+    218, // 'g'
+    230, // 'h'
+    247, // 'i'
+    135, // 'j'
+    180, // 'k'
+    241, // 'l'
+    233, // 'm'
+    246, // 'n'
+    244, // 'o'
+    231, // 'p'
+    139, // 'q'
+    245, // 'r'
+    243, // 's'
+    251, // 't'
+    235, // 'u'
+    201, // 'v'
+    196, // 'w'
+    240, // 'x'
+    214, // 'y'
+    152, // 'z'
+    182, // '{'
+    205, // '|'
+    181, // '}'
+    127, // '~'
+     27, // '\x7f'
+    212, // '\x80'
+    211, // '\x81'
+    210, // '\x82'
+    213, // '\x83'
+    228, // '\x84'
+    197, // '\x85'
+    169, // '\x86'
+    159, // '\x87'
+    131, // '\x88'
+    172, // '\x89'
+    105, // '\x8a'
+     80, // '\x8b'
+     98, // '\x8c'
+     96, // '\x8d'
+     97, // '\x8e'
+     81, // '\x8f'
+    207, // '\x90'
+    145, // '\x91'
+    116, // '\x92'
+    115, // '\x93'
+    144, // '\x94'
+    130, // '\x95'
+    153, // '\x96'
+    121, // '\x97'
+    107, // '\x98'
+    132, // '\x99'
+    109, // '\x9a'
+    110, // '\x9b'
+    124, // '\x9c'
+    111, // '\x9d'
+     82, // '\x9e'
+    108, // '\x9f'
+    118, // '\xa0'
+    141, // '¡'
+    113, // '¢'
+    129, // '£'
+    119, // '¤'
+    125, // '¥'
+    165, // '¦'
+    117, // '§'
+     92, // '¨'
+    106, // '©'
+     83, // 'ª'
+     72, // '«'
+     99, // '¬'
+     93, // '\xad'
+     65, // '®'
+     79, // '¯'
+    166, // '°'
+    237, // '±'
+    163, // '²'
+    199, // '³'
+    190, // '´'
+    225, // 'µ'
+    209, // '¶'
+    203, // '·'
+    198, // '¸'
+    217, // '¹'
+    219, // 'º'
+    206, // '»'
+    234, // '¼'
+    248, // '½'
+    158, // '¾'
+    239, // '¿'
+    255, // 'À'
+    255, // 'Á'
+    255, // 'Â'
+    255, // 'Ã'
+    255, // 'Ä'
+    255, // 'Å'
+    255, // 'Æ'
+    255, // 'Ç'
+    255, // 'È'
+    255, // 'É'
+    255, // 'Ê'
+    255, // 'Ë'
+    255, // 'Ì'
+    255, // 'Í'
+    255, // 'Î'
+    255, // 'Ï'
+    255, // 'Ð'
+    255, // 'Ñ'
+    255, // 'Ò'
+    255, // 'Ó'
+    255, // 'Ô'
+    255, // 'Õ'
+    255, // 'Ö'
+    255, // '×'
+    255, // 'Ø'
+    255, // 'Ù'
+    255, // 'Ú'
+    255, // 'Û'
+    255, // 'Ü'
+    255, // 'Ý'
+    255, // 'Þ'
+    255, // 'ß'
+    255, // 'à'
+    255, // 'á'
+    255, // 'â'
+    255, // 'ã'
+    255, // 'ä'
+    255, // 'å'
+    255, // 'æ'
+    255, // 'ç'
+    255, // 'è'
+    255, // 'é'
+    255, // 'ê'
+    255, // 'ë'
+    255, // 'ì'
+    255, // 'í'
+    255, // 'î'
+    255, // 'ï'
+    255, // 'ð'
+    255, // 'ñ'
+    255, // 'ò'
+    255, // 'ó'
+    255, // 'ô'
+    255, // 'õ'
+    255, // 'ö'
+    255, // '÷'
+    255, // 'ø'
+    255, // 'ù'
+    255, // 'ú'
+    255, // 'û'
+    255, // 'ü'
+    255, // 'ý'
+    255, // 'þ'
+    255, // 'ÿ'
+];
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/input.rs.html b/target/doc/src/regex/input.rs.html new file mode 100644 index 0000000..38db4e8 --- /dev/null +++ b/target/doc/src/regex/input.rs.html @@ -0,0 +1,843 @@ +input.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::char;
+use std::cmp::Ordering;
+use std::fmt;
+use std::ops;
+use std::u32;
+
+use syntax;
+
+use literal::LiteralSearcher;
+use prog::InstEmptyLook;
+use utf8::{decode_utf8, decode_last_utf8};
+
+/// Represents a location in the input.
+#[derive(Clone, Copy, Debug)]
+pub struct InputAt {
+    pos: usize,
+    c: Char,
+    byte: Option<u8>,
+    len: usize,
+}
+
+impl InputAt {
+    /// Returns true iff this position is at the beginning of the input.
+    pub fn is_start(&self) -> bool {
+        self.pos == 0
+    }
+
+    /// Returns true iff this position is past the end of the input.
+    pub fn is_end(&self) -> bool {
+        self.c.is_none() && self.byte.is_none()
+    }
+
+    /// Returns the character at this position.
+    ///
+    /// If this position is just before or after the input, then an absent
+    /// character is returned.
+    pub fn char(&self) -> Char {
+        self.c
+    }
+
+    /// Returns the byte at this position.
+    pub fn byte(&self) -> Option<u8> {
+        self.byte
+    }
+
+    /// Returns the UTF-8 width of the character at this position.
+    pub fn len(&self) -> usize {
+        self.len
+    }
+
+    /// Returns whether the UTF-8 width of the character at this position
+    /// is zero.
+    pub fn is_empty(&self) -> bool {
+        self.len == 0
+    }
+
+    /// Returns the byte offset of this position.
+    pub fn pos(&self) -> usize {
+        self.pos
+    }
+
+    /// Returns the byte offset of the next position in the input.
+    pub fn next_pos(&self) -> usize {
+        self.pos + self.len
+    }
+}
+
+/// An abstraction over input used in the matching engines.
+pub trait Input {
+    /// Return an encoding of the position at byte offset `i`.
+    fn at(&self, i: usize) -> InputAt;
+
+    /// Return the Unicode character occurring next to `at`.
+    ///
+    /// If no such character could be decoded, then `Char` is absent.
+    fn next_char(&self, at: InputAt) -> Char;
+
+    /// Return the Unicode character occurring previous to `at`.
+    ///
+    /// If no such character could be decoded, then `Char` is absent.
+    fn previous_char(&self, at: InputAt) -> Char;
+
+    /// Return true if the given empty width instruction matches at the
+    /// input position given.
+    fn is_empty_match(&self, at: InputAt, empty: &InstEmptyLook) -> bool;
+
+    /// Scan the input for a matching prefix.
+    fn prefix_at(
+        &self,
+        prefixes: &LiteralSearcher,
+        at: InputAt,
+    ) -> Option<InputAt>;
+
+    /// The number of bytes in the input.
+    fn len(&self) -> usize;
+
+    /// Whether the input is empty.
+    fn is_empty(&self) -> bool { self.len() == 0 }
+
+    /// Return the given input as a sequence of bytes.
+    fn as_bytes(&self) -> &[u8];
+}
+
+impl<'a, T: Input> Input for &'a T {
+    fn at(&self, i: usize) -> InputAt { (**self).at(i) }
+
+    fn next_char(&self, at: InputAt) -> Char { (**self).next_char(at) }
+
+    fn previous_char(&self, at: InputAt) -> Char { (**self).previous_char(at) }
+
+    fn is_empty_match(&self, at: InputAt, empty: &InstEmptyLook) -> bool {
+        (**self).is_empty_match(at, empty)
+    }
+
+    fn prefix_at(
+        &self,
+        prefixes: &LiteralSearcher,
+        at: InputAt,
+    ) -> Option<InputAt> {
+        (**self).prefix_at(prefixes, at)
+    }
+
+    fn len(&self) -> usize { (**self).len() }
+
+    fn as_bytes(&self) -> &[u8] { (**self).as_bytes() }
+}
+
+/// An input reader over characters.
+#[derive(Clone, Copy, Debug)]
+pub struct CharInput<'t>(&'t [u8]);
+
+impl<'t> CharInput<'t> {
+    /// Return a new character input reader for the given string.
+    pub fn new(s: &'t [u8]) -> CharInput<'t> {
+        CharInput(s)
+    }
+}
+
+impl<'t> ops::Deref for CharInput<'t> {
+    type Target = [u8];
+
+    fn deref(&self) -> &[u8] {
+        self.0
+    }
+}
+
+impl<'t> Input for CharInput<'t> {
+    fn at(&self, i: usize) -> InputAt {
+        let c = decode_utf8(&self[i..]).map(|(c, _)| c).into();
+        InputAt {
+            pos: i,
+            c: c,
+            byte: None,
+            len: c.len_utf8(),
+        }
+    }
+
+    fn next_char(&self, at: InputAt) -> Char {
+        at.char()
+    }
+
+    fn previous_char(&self, at: InputAt) -> Char {
+        decode_last_utf8(&self[..at.pos()]).map(|(c, _)| c).into()
+    }
+
+    fn is_empty_match(&self, at: InputAt, empty: &InstEmptyLook) -> bool {
+        use prog::EmptyLook::*;
+        match empty.look {
+            StartLine => {
+                let c = self.previous_char(at);
+                at.pos() == 0 || c == '\n'
+            }
+            EndLine => {
+                let c = self.next_char(at);
+                at.pos() == self.len() || c == '\n'
+            }
+            StartText => at.pos() == 0,
+            EndText => at.pos() == self.len(),
+            WordBoundary => {
+                let (c1, c2) = (self.previous_char(at), self.next_char(at));
+                c1.is_word_char() != c2.is_word_char()
+            }
+            NotWordBoundary => {
+                let (c1, c2) = (self.previous_char(at), self.next_char(at));
+                c1.is_word_char() == c2.is_word_char()
+            }
+            WordBoundaryAscii => {
+                let (c1, c2) = (self.previous_char(at), self.next_char(at));
+                c1.is_word_byte() != c2.is_word_byte()
+            }
+            NotWordBoundaryAscii => {
+                let (c1, c2) = (self.previous_char(at), self.next_char(at));
+                c1.is_word_byte() == c2.is_word_byte()
+            }
+        }
+    }
+
+    fn prefix_at(
+        &self,
+        prefixes: &LiteralSearcher,
+        at: InputAt,
+    ) -> Option<InputAt> {
+        prefixes.find(&self[at.pos()..]).map(|(s, _)| self.at(at.pos() + s))
+    }
+
+    fn len(&self) -> usize {
+        self.0.len()
+    }
+
+    fn as_bytes(&self) -> &[u8] {
+        self.0
+    }
+}
+
+/// An input reader over bytes.
+#[derive(Clone, Copy, Debug)]
+pub struct ByteInput<'t> {
+    text: &'t [u8],
+    only_utf8: bool,
+}
+
+impl<'t> ByteInput<'t> {
+    /// Return a new byte-based input reader for the given string.
+    pub fn new(text: &'t [u8], only_utf8: bool) -> ByteInput<'t> {
+        ByteInput {
+            text: text,
+            only_utf8: only_utf8,
+        }
+    }
+}
+
+impl<'t> ops::Deref for ByteInput<'t> {
+    type Target = [u8];
+
+    fn deref(&self) -> &[u8] {
+        self.text
+    }
+}
+
+impl<'t> Input for ByteInput<'t> {
+    fn at(&self, i: usize) -> InputAt {
+        InputAt {
+            pos: i,
+            c: None.into(),
+            byte: self.get(i).cloned(),
+            len: 1,
+        }
+    }
+
+    fn next_char(&self, at: InputAt) -> Char {
+        decode_utf8(&self[at.pos()..]).map(|(c, _)| c).into()
+    }
+
+    fn previous_char(&self, at: InputAt) -> Char {
+        decode_last_utf8(&self[..at.pos()]).map(|(c, _)| c).into()
+    }
+
+    fn is_empty_match(&self, at: InputAt, empty: &InstEmptyLook) -> bool {
+        use prog::EmptyLook::*;
+        match empty.look {
+            StartLine => {
+                let c = self.previous_char(at);
+                at.pos() == 0 || c == '\n'
+            }
+            EndLine => {
+                let c = self.next_char(at);
+                at.pos() == self.len() || c == '\n'
+            }
+            StartText => at.pos() == 0,
+            EndText => at.pos() == self.len(),
+            WordBoundary => {
+                let (c1, c2) = (self.previous_char(at), self.next_char(at));
+                c1.is_word_char() != c2.is_word_char()
+            }
+            NotWordBoundary => {
+                let (c1, c2) = (self.previous_char(at), self.next_char(at));
+                c1.is_word_char() == c2.is_word_char()
+            }
+            WordBoundaryAscii => {
+                let (c1, c2) = (self.previous_char(at), self.next_char(at));
+                if self.only_utf8 {
+                    // If we must match UTF-8, then we can't match word
+                    // boundaries at invalid UTF-8.
+                    if c1.is_none() && !at.is_start() {
+                        return false;
+                    }
+                    if c2.is_none() && !at.is_end() {
+                        return false;
+                    }
+                }
+                c1.is_word_byte() != c2.is_word_byte()
+            }
+            NotWordBoundaryAscii => {
+                let (c1, c2) = (self.previous_char(at), self.next_char(at));
+                if self.only_utf8 {
+                    // If we must match UTF-8, then we can't match word
+                    // boundaries at invalid UTF-8.
+                    if c1.is_none() && !at.is_start() {
+                        return false;
+                    }
+                    if c2.is_none() && !at.is_end() {
+                        return false;
+                    }
+                }
+                c1.is_word_byte() == c2.is_word_byte()
+            }
+        }
+    }
+
+    fn prefix_at(
+        &self,
+        prefixes: &LiteralSearcher,
+        at: InputAt,
+    ) -> Option<InputAt> {
+        prefixes.find(&self[at.pos()..]).map(|(s, _)| self.at(at.pos() + s))
+    }
+
+    fn len(&self) -> usize {
+        self.text.len()
+    }
+
+    fn as_bytes(&self) -> &[u8] {
+        self.text
+    }
+}
+
+/// An inline representation of `Option<char>`.
+///
+/// This eliminates the need to do case analysis on `Option<char>` to determine
+/// ordinality with other characters.
+///
+/// (The `Option<char>` is not related to encoding. Instead, it is used in the
+/// matching engines to represent the beginning and ending boundaries of the
+/// search text.)
+#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Char(u32);
+
+impl fmt::Debug for Char {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match char::from_u32(self.0) {
+            None => write!(f, "Empty"),
+            Some(c) => write!(f, "{:?}", c),
+        }
+    }
+}
+
+impl Char {
+    /// Returns true iff the character is absent.
+    #[inline]
+    pub fn is_none(self) -> bool { self.0 == u32::MAX }
+
+    /// Returns the length of the character's UTF-8 encoding.
+    ///
+    /// If the character is absent, then `0` is returned.
+    #[inline]
+    pub fn len_utf8(self) -> usize {
+        char::from_u32(self.0).map_or(0, |c| c.len_utf8())
+    }
+
+    /// Returns true iff the character is a word character.
+    ///
+    /// If the character is absent, then false is returned.
+    pub fn is_word_char(self) -> bool {
+        char::from_u32(self.0).map_or(false, syntax::is_word_character)
+    }
+
+    /// Returns true iff the byte is a word byte.
+    ///
+    /// If the byte is absent, then false is returned.
+    pub fn is_word_byte(self) -> bool {
+        match char::from_u32(self.0) {
+            Some(c) if c <= '\u{7F}' => syntax::is_word_byte(c as u8),
+            None | Some(_) => false,
+        }
+    }
+}
+
+impl From<char> for Char {
+    fn from(c: char) -> Char { Char(c as u32) }
+}
+
+impl From<Option<char>> for Char {
+    fn from(c: Option<char>) -> Char {
+        c.map_or(Char(u32::MAX), |c| c.into())
+    }
+}
+
+impl PartialEq<char> for Char {
+    #[inline]
+    fn eq(&self, other: &char) -> bool { self.0 == *other as u32 }
+}
+
+impl PartialEq<Char> for char {
+    #[inline]
+    fn eq(&self, other: &Char) -> bool { *self as u32 == other.0 }
+}
+
+impl PartialOrd<char> for Char {
+    #[inline]
+    fn partial_cmp(&self, other: &char) -> Option<Ordering> {
+        self.0.partial_cmp(&(*other as u32))
+    }
+}
+
+impl PartialOrd<Char> for char {
+    #[inline]
+    fn partial_cmp(&self, other: &Char) -> Option<Ordering> {
+        (*self as u32).partial_cmp(&other.0)
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/lib.rs.html b/target/doc/src/regex/lib.rs.html new file mode 100644 index 0000000..dcfb2e3 --- /dev/null +++ b/target/doc/src/regex/lib.rs.html @@ -0,0 +1,1377 @@ +lib.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+This crate provides a library for parsing, compiling, and executing regular
+expressions. Its syntax is similar to Perl-style regular expressions, but lacks
+a few features like look around and backreferences. In exchange, all searches
+execute in linear time with respect to the size of the regular expression and
+search text.
+
+This crate's documentation provides some simple examples, describes
+[Unicode support](#unicode) and exhaustively lists the
+[supported syntax](#syntax).
+
+For more specific details on the API for regular expressions, please see the
+documentation for the [`Regex`](struct.Regex.html) type.
+
+# Usage
+
+This crate is [on crates.io](https://crates.io/crates/regex) and can be
+used by adding `regex` to your dependencies in your project's `Cargo.toml`.
+
+```toml
+[dependencies]
+regex = "1"
+```
+
+and this to your crate root:
+
+```rust
+extern crate regex;
+```
+
+# Example: find a date
+
+General use of regular expressions in this package involves compiling an
+expression and then using it to search, split or replace text. For example,
+to confirm that some text resembles a date:
+
+```rust
+use regex::Regex;
+let re = Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();
+assert!(re.is_match("2014-01-01"));
+```
+
+Notice the use of the `^` and `$` anchors. In this crate, every expression
+is executed with an implicit `.*?` at the beginning and end, which allows
+it to match anywhere in the text. Anchors can be used to ensure that the
+full text matches an expression.
+
+This example also demonstrates the utility of
+[raw strings](https://doc.rust-lang.org/stable/reference/tokens.html#raw-string-literals)
+in Rust, which
+are just like regular strings except they are prefixed with an `r` and do
+not process any escape sequences. For example, `"\\d"` is the same
+expression as `r"\d"`.
+
+# Example: Avoid compiling the same regex in a loop
+
+It is an anti-pattern to compile the same regular expression in a loop
+since compilation is typically expensive. (It takes anywhere from a few
+microseconds to a few **milliseconds** depending on the size of the
+regex.) Not only is compilation itself expensive, but this also prevents
+optimizations that reuse allocations internally to the matching engines.
+
+In Rust, it can sometimes be a pain to pass regular expressions around if
+they're used from inside a helper function. Instead, we recommend using the
+[`lazy_static`](https://crates.io/crates/lazy_static) crate to ensure that
+regular expressions are compiled exactly once.
+
+For example:
+
+```rust
+#[macro_use] extern crate lazy_static;
+extern crate regex;
+
+use regex::Regex;
+
+fn some_helper_function(text: &str) -> bool {
+    lazy_static! {
+        static ref RE: Regex = Regex::new("...").unwrap();
+    }
+    RE.is_match(text)
+}
+
+fn main() {}
+```
+
+Specifically, in this example, the regex will be compiled when it is used for
+the first time. On subsequent uses, it will reuse the previous compilation.
+
+# Example: iterating over capture groups
+
+This crate provides convenient iterators for matching an expression
+repeatedly against a search string to find successive non-overlapping
+matches. For example, to find all dates in a string and be able to access
+them by their component pieces:
+
+```rust
+# extern crate regex; use regex::Regex;
+# fn main() {
+let re = Regex::new(r"(\d{4})-(\d{2})-(\d{2})").unwrap();
+let text = "2012-03-14, 2013-01-01 and 2014-07-05";
+for cap in re.captures_iter(text) {
+    println!("Month: {} Day: {} Year: {}", &cap[2], &cap[3], &cap[1]);
+}
+// Output:
+// Month: 03 Day: 14 Year: 2012
+// Month: 01 Day: 01 Year: 2013
+// Month: 07 Day: 05 Year: 2014
+# }
+```
+
+Notice that the year is in the capture group indexed at `1`. This is
+because the *entire match* is stored in the capture group at index `0`.
+
+# Example: replacement with named capture groups
+
+Building on the previous example, perhaps we'd like to rearrange the date
+formats. This can be done with text replacement. But to make the code
+clearer, we can *name*  our capture groups and use those names as variables
+in our replacement text:
+
+```rust
+# extern crate regex; use regex::Regex;
+# fn main() {
+let re = Regex::new(r"(?P<y>\d{4})-(?P<m>\d{2})-(?P<d>\d{2})").unwrap();
+let before = "2012-03-14, 2013-01-01 and 2014-07-05";
+let after = re.replace_all(before, "$m/$d/$y");
+assert_eq!(after, "03/14/2012, 01/01/2013 and 07/05/2014");
+# }
+```
+
+The `replace` methods are actually polymorphic in the replacement, which
+provides more flexibility than is seen here. (See the documentation for
+`Regex::replace` for more details.)
+
+Note that if your regex gets complicated, you can use the `x` flag to
+enable insignificant whitespace mode, which also lets you write comments:
+
+```rust
+# extern crate regex; use regex::Regex;
+# fn main() {
+let re = Regex::new(r"(?x)
+  (?P<y>\d{4}) # the year
+  -
+  (?P<m>\d{2}) # the month
+  -
+  (?P<d>\d{2}) # the day
+").unwrap();
+let before = "2012-03-14, 2013-01-01 and 2014-07-05";
+let after = re.replace_all(before, "$m/$d/$y");
+assert_eq!(after, "03/14/2012, 01/01/2013 and 07/05/2014");
+# }
+```
+
+If you wish to match against whitespace in this mode, you can still use `\s`,
+`\n`, `\t`, etc. For escaping a single space character, you can use its hex
+character code `\x20` or temporarily disable the `x` flag, e.g., `(?-x: )`.
+
+# Example: match multiple regular expressions simultaneously
+
+This demonstrates how to use a `RegexSet` to match multiple (possibly
+overlapping) regular expressions in a single scan of the search text:
+
+```rust
+use regex::RegexSet;
+
+let set = RegexSet::new(&[
+    r"\w+",
+    r"\d+",
+    r"\pL+",
+    r"foo",
+    r"bar",
+    r"barfoo",
+    r"foobar",
+]).unwrap();
+
+// Iterate over and collect all of the matches.
+let matches: Vec<_> = set.matches("foobar").into_iter().collect();
+assert_eq!(matches, vec![0, 2, 3, 4, 6]);
+
+// You can also test whether a particular regex matched:
+let matches = set.matches("foobar");
+assert!(!matches.matched(5));
+assert!(matches.matched(6));
+```
+
+# Pay for what you use
+
+With respect to searching text with a regular expression, there are three
+questions that can be asked:
+
+1. Does the text match this expression?
+2. If so, where does it match?
+3. Where did the capturing groups match?
+
+Generally speaking, this crate could provide a function to answer only #3,
+which would subsume #1 and #2 automatically. However, it can be significantly
+more expensive to compute the location of capturing group matches, so it's best
+not to do it if you don't need to.
+
+Therefore, only use what you need. For example, don't use `find` if you
+only need to test if an expression matches a string. (Use `is_match`
+instead.)
+
+# Unicode
+
+This implementation executes regular expressions **only** on valid UTF-8
+while exposing match locations as byte indices into the search string.
+
+Only simple case folding is supported. Namely, when matching
+case-insensitively, the characters are first mapped using the "simple" case
+folding rules defined by Unicode.
+
+Regular expressions themselves are **only** interpreted as a sequence of
+Unicode scalar values. This means you can use Unicode characters directly
+in your expression:
+
+```rust
+# extern crate regex; use regex::Regex;
+# fn main() {
+let re = Regex::new(r"(?i)Δ+").unwrap();
+let mat = re.find("ΔδΔ").unwrap();
+assert_eq!((mat.start(), mat.end()), (0, 6));
+# }
+```
+
+Most features of the regular expressions in this crate are Unicode aware. Here
+are some examples:
+
+* `.` will match any valid UTF-8 encoded Unicode scalar value except for `\n`.
+  (To also match `\n`, enable the `s` flag, e.g., `(?s:.)`.)
+* `\w`, `\d` and `\s` are Unicode aware. For example, `\s` will match all forms
+  of whitespace categorized by Unicode.
+* `\b` matches a Unicode word boundary.
+* Negated character classes like `[^a]` match all Unicode scalar values except
+  for `a`.
+* `^` and `$` are **not** Unicode aware in multi-line mode. Namely, they only
+  recognize `\n` and not any of the other forms of line terminators defined
+  by Unicode.
+
+Unicode general categories, scripts, script extensions, ages and a smattering
+of boolean properties are available as character classes. For example, you can
+match a sequence of numerals, Greek or Cherokee letters:
+
+```rust
+# extern crate regex; use regex::Regex;
+# fn main() {
+let re = Regex::new(r"[\pN\p{Greek}\p{Cherokee}]+").unwrap();
+let mat = re.find("abcΔᎠβⅠᏴγδⅡxyz").unwrap();
+assert_eq!((mat.start(), mat.end()), (3, 23));
+# }
+```
+
+For a more detailed breakdown of Unicode support with respect to
+[UTS#18](http://unicode.org/reports/tr18/),
+please see the
+[UNICODE](https://github.com/rust-lang/regex/blob/master/UNICODE.md)
+document in the root of the regex repository.
+
+# Opt out of Unicode support
+
+The `bytes` sub-module provides a `Regex` type that can be used to match
+on `&[u8]`. By default, text is interpreted as UTF-8 just like it is with
+the main `Regex` type. However, this behavior can be disabled by turning
+off the `u` flag, even if doing so could result in matching invalid UTF-8.
+For example, when the `u` flag is disabled, `.` will match any byte instead
+of any Unicode scalar value.
+
+Disabling the `u` flag is also possible with the standard `&str`-based `Regex`
+type, but it is only allowed where the UTF-8 invariant is maintained. For
+example, `(?-u:\w)` is an ASCII-only `\w` character class and is legal in an
+`&str`-based `Regex`, but `(?-u:\xFF)` will attempt to match the raw byte
+`\xFF`, which is invalid UTF-8 and therefore is illegal in `&str`-based
+regexes.
+
+# Syntax
+
+The syntax supported in this crate is documented below.
+
+Note that the regular expression parser and abstract syntax are exposed in
+a separate crate, [`regex-syntax`](https://docs.rs/regex-syntax).
+
+## Matching one character
+
+<pre class="rust">
+.             any character except new line (includes new line with s flag)
+\d            digit (\p{Nd})
+\D            not digit
+\pN           One-letter name Unicode character class
+\p{Greek}     Unicode character class (general category or script)
+\PN           Negated one-letter name Unicode character class
+\P{Greek}     negated Unicode character class (general category or script)
+</pre>
+
+### Character classes
+
+<pre class="rust">
+[xyz]         A character class matching either x, y or z (union).
+[^xyz]        A character class matching any character except x, y and z.
+[a-z]         A character class matching any character in range a-z.
+[[:alpha:]]   ASCII character class ([A-Za-z])
+[[:^alpha:]]  Negated ASCII character class ([^A-Za-z])
+[x[^xyz]]     Nested/grouping character class (matching any character except y and z)
+[a-y&&xyz]    Intersection (matching x or y)
+[0-9&&[^4]]   Subtraction using intersection and negation (matching 0-9 except 4)
+[0-9--4]      Direct subtraction (matching 0-9 except 4)
+[a-g~~b-h]    Symmetric difference (matching `a` and `h` only)
+[\[\]]        Escaping in character classes (matching [ or ])
+</pre>
+
+Any named character class may appear inside a bracketed `[...]` character
+class. For example, `[\p{Greek}[:digit:]]` matches any Greek or ASCII
+digit. `[\p{Greek}&&\pL]` matches Greek letters.
+
+Precedence in character classes, from most binding to least:
+
+1. Ranges: `a-cd` == `[a-c]d`
+2. Union: `ab&&bc` == `[ab]&&[bc]`
+3. Intersection: `^a-z&&b` == `^[a-z&&b]`
+4. Negation
+
+## Composites
+
+<pre class="rust">
+xy    concatenation (x followed by y)
+x|y   alternation (x or y, prefer x)
+</pre>
+
+## Repetitions
+
+<pre class="rust">
+x*        zero or more of x (greedy)
+x+        one or more of x (greedy)
+x?        zero or one of x (greedy)
+x*?       zero or more of x (ungreedy/lazy)
+x+?       one or more of x (ungreedy/lazy)
+x??       zero or one of x (ungreedy/lazy)
+x{n,m}    at least n x and at most m x (greedy)
+x{n,}     at least n x (greedy)
+x{n}      exactly n x
+x{n,m}?   at least n x and at most m x (ungreedy/lazy)
+x{n,}?    at least n x (ungreedy/lazy)
+x{n}?     exactly n x
+</pre>
+
+## Empty matches
+
+<pre class="rust">
+^     the beginning of text (or start-of-line with multi-line mode)
+$     the end of text (or end-of-line with multi-line mode)
+\A    only the beginning of text (even with multi-line mode enabled)
+\z    only the end of text (even with multi-line mode enabled)
+\b    a Unicode word boundary (\w on one side and \W, \A, or \z on other)
+\B    not a Unicode word boundary
+</pre>
+
+## Grouping and flags
+
+<pre class="rust">
+(exp)          numbered capture group (indexed by opening parenthesis)
+(?P&lt;name&gt;exp)  named (also numbered) capture group (allowed chars: [_0-9a-zA-Z])
+(?:exp)        non-capturing group
+(?flags)       set flags within current group
+(?flags:exp)   set flags for exp (non-capturing)
+</pre>
+
+Flags are each a single character. For example, `(?x)` sets the flag `x`
+and `(?-x)` clears the flag `x`. Multiple flags can be set or cleared at
+the same time: `(?xy)` sets both the `x` and `y` flags and `(?x-y)` sets
+the `x` flag and clears the `y` flag.
+
+All flags are by default disabled unless stated otherwise. They are:
+
+<pre class="rust">
+i     case-insensitive: letters match both upper and lower case
+m     multi-line mode: ^ and $ match begin/end of line
+s     allow . to match \n
+U     swap the meaning of x* and x*?
+u     Unicode support (enabled by default)
+x     ignore whitespace and allow line comments (starting with `#`)
+</pre>
+
+Flags can be toggled within a pattern. Here's an example that matches
+case-insensitively for the first part but case-sensitively for the second part:
+
+```rust
+# extern crate regex; use regex::Regex;
+# fn main() {
+let re = Regex::new(r"(?i)a+(?-i)b+").unwrap();
+let cap = re.captures("AaAaAbbBBBb").unwrap();
+assert_eq!(&cap[0], "AaAaAbb");
+# }
+```
+
+Notice that the `a+` matches either `a` or `A`, but the `b+` only matches
+`b`.
+
+Multi-line mode means `^` and `$` no longer match just at the beginning/end of
+the input, but at the beginning/end of lines:
+
+```
+# use regex::Regex;
+let re = Regex::new(r"(?m)^line \d+").unwrap();
+let m = re.find("line one\nline 2\n").unwrap();
+assert_eq!(m.as_str(), "line 2");
+```
+
+Note that `^` matches after new lines, even at the end of input:
+
+```
+# use regex::Regex;
+let re = Regex::new(r"(?m)^").unwrap();
+let m = re.find_iter("test\n").last().unwrap();
+assert_eq!((m.start(), m.end()), (5, 5));
+```
+
+Here is an example that uses an ASCII word boundary instead of a Unicode
+word boundary:
+
+```rust
+# extern crate regex; use regex::Regex;
+# fn main() {
+let re = Regex::new(r"(?-u:\b).+(?-u:\b)").unwrap();
+let cap = re.captures("$$abc$$").unwrap();
+assert_eq!(&cap[0], "abc");
+# }
+```
+
+## Escape sequences
+
+<pre class="rust">
+\*          literal *, works for any punctuation character: \.+*?()|[]{}^$
+\a          bell (\x07)
+\f          form feed (\x0C)
+\t          horizontal tab
+\n          new line
+\r          carriage return
+\v          vertical tab (\x0B)
+\123        octal character code (up to three digits) (when enabled)
+\x7F        hex character code (exactly two digits)
+\x{10FFFF}  any hex character code corresponding to a Unicode code point
+\u007F      hex character code (exactly four digits)
+\u{7F}      any hex character code corresponding to a Unicode code point
+\U0000007F  hex character code (exactly eight digits)
+\U{7F}      any hex character code corresponding to a Unicode code point
+</pre>
+
+## Perl character classes (Unicode friendly)
+
+These classes are based on the definitions provided in
+[UTS#18](http://www.unicode.org/reports/tr18/#Compatibility_Properties):
+
+<pre class="rust">
+\d     digit (\p{Nd})
+\D     not digit
+\s     whitespace (\p{White_Space})
+\S     not whitespace
+\w     word character (\p{Alphabetic} + \p{M} + \d + \p{Pc} + \p{Join_Control})
+\W     not word character
+</pre>
+
+## ASCII character classes
+
+<pre class="rust">
+[[:alnum:]]    alphanumeric ([0-9A-Za-z])
+[[:alpha:]]    alphabetic ([A-Za-z])
+[[:ascii:]]    ASCII ([\x00-\x7F])
+[[:blank:]]    blank ([\t ])
+[[:cntrl:]]    control ([\x00-\x1F\x7F])
+[[:digit:]]    digits ([0-9])
+[[:graph:]]    graphical ([!-~])
+[[:lower:]]    lower case ([a-z])
+[[:print:]]    printable ([ -~])
+[[:punct:]]    punctuation ([!-/:-@\[-`{-~])
+[[:space:]]    whitespace ([\t\n\v\f\r ])
+[[:upper:]]    upper case ([A-Z])
+[[:word:]]     word characters ([0-9A-Za-z_])
+[[:xdigit:]]   hex digit ([0-9A-Fa-f])
+</pre>
+
+# Untrusted input
+
+This crate can handle both untrusted regular expressions and untrusted
+search text.
+
+Untrusted regular expressions are handled by capping the size of a compiled
+regular expression.
+(See [`RegexBuilder::size_limit`](struct.RegexBuilder.html#method.size_limit).)
+Without this, it would be trivial for an attacker to exhaust your system's
+memory with expressions like `a{100}{100}{100}`.
+
+Untrusted search text is allowed because the matching engine(s) in this
+crate have time complexity `O(mn)` (with `m ~ regex` and `n ~ search
+text`), which means there's no way to cause exponential blow-up like with
+some other regular expression engines. (We pay for this by disallowing
+features like arbitrary look-ahead and backreferences.)
+
+When a DFA is used, pathological cases with exponential state blow-up are
+avoided by constructing the DFA lazily or in an "online" manner. Therefore,
+at most one new state can be created for each byte of input. This satisfies
+our time complexity guarantees, but can lead to memory growth
+proportional to the size of the input. As a stopgap, the DFA is only
+allowed to store a fixed number of states. When the limit is reached, its
+states are wiped and continues on, possibly duplicating previous work. If
+the limit is reached too frequently, it gives up and hands control off to
+another matching engine with fixed memory requirements.
+(The DFA size limit can also be tweaked. See
+[`RegexBuilder::dfa_size_limit`](struct.RegexBuilder.html#method.dfa_size_limit).)
+*/
+
+#![deny(missing_docs)]
+#![cfg_attr(test, deny(warnings))]
+#![cfg_attr(feature = "pattern", feature(pattern))]
+
+#[cfg(not(feature = "use_std"))]
+compile_error!("`use_std` feature is currently required to build this crate");
+
+extern crate aho_corasick;
+extern crate memchr;
+extern crate thread_local;
+#[cfg(test)]
+#[macro_use]
+extern crate quickcheck;
+extern crate regex_syntax as syntax;
+extern crate utf8_ranges;
+#[cfg(test)]
+extern crate doc_comment;
+
+#[cfg(test)]
+doc_comment::doctest!("../README.md");
+
+#[cfg(feature = "use_std")]
+pub use error::Error;
+#[cfg(feature = "use_std")]
+pub use re_builder::unicode::*;
+#[cfg(feature = "use_std")]
+pub use re_builder::set_unicode::*;
+#[cfg(feature = "use_std")]
+pub use re_set::unicode::*;
+#[cfg(feature = "use_std")]
+#[cfg(feature = "use_std")]
+pub use re_unicode::{
+    Regex, Match, Captures,
+    CaptureNames, Matches, CaptureMatches, SubCaptureMatches,
+    CaptureLocations, Locations,
+    Replacer, ReplacerRef, NoExpand, Split, SplitN,
+    escape,
+};
+
+/**
+Match regular expressions on arbitrary bytes.
+
+This module provides a nearly identical API to the one found in the
+top-level of this crate. There are two important differences:
+
+1. Matching is done on `&[u8]` instead of `&str`. Additionally, `Vec<u8>`
+is used where `String` would have been used.
+2. Unicode support can be disabled even when disabling it would result in
+matching invalid UTF-8 bytes.
+
+# Example: match null terminated string
+
+This shows how to find all null-terminated strings in a slice of bytes:
+
+```rust
+# use regex::bytes::Regex;
+let re = Regex::new(r"(?-u)(?P<cstr>[^\x00]+)\x00").unwrap();
+let text = b"foo\x00bar\x00baz\x00";
+
+// Extract all of the strings without the null terminator from each match.
+// The unwrap is OK here since a match requires the `cstr` capture to match.
+let cstrs: Vec<&[u8]> =
+    re.captures_iter(text)
+      .map(|c| c.name("cstr").unwrap().as_bytes())
+      .collect();
+assert_eq!(vec![&b"foo"[..], &b"bar"[..], &b"baz"[..]], cstrs);
+```
+
+# Example: selectively enable Unicode support
+
+This shows how to match an arbitrary byte pattern followed by a UTF-8 encoded
+string (e.g., to extract a title from a Matroska file):
+
+```rust
+# use std::str;
+# use regex::bytes::Regex;
+let re = Regex::new(
+    r"(?-u)\x7b\xa9(?:[\x80-\xfe]|[\x40-\xff].)(?u:(.*))"
+).unwrap();
+let text = b"\x12\xd0\x3b\x5f\x7b\xa9\x85\xe2\x98\x83\x80\x98\x54\x76\x68\x65";
+let caps = re.captures(text).unwrap();
+
+// Notice that despite the `.*` at the end, it will only match valid UTF-8
+// because Unicode mode was enabled with the `u` flag. Without the `u` flag,
+// the `.*` would match the rest of the bytes.
+let mat = caps.get(1).unwrap();
+assert_eq!((7, 10), (mat.start(), mat.end()));
+
+// If there was a match, Unicode mode guarantees that `title` is valid UTF-8.
+let title = str::from_utf8(&caps[1]).unwrap();
+assert_eq!("☃", title);
+```
+
+In general, if the Unicode flag is enabled in a capture group and that capture
+is part of the overall match, then the capture is *guaranteed* to be valid
+UTF-8.
+
+# Syntax
+
+The supported syntax is pretty much the same as the syntax for Unicode
+regular expressions with a few changes that make sense for matching arbitrary
+bytes:
+
+1. The `u` flag can be disabled even when disabling it might cause the regex to
+match invalid UTF-8. When the `u` flag is disabled, the regex is said to be in
+"ASCII compatible" mode.
+2. In ASCII compatible mode, neither Unicode scalar values nor Unicode
+character classes are allowed.
+3. In ASCII compatible mode, Perl character classes (`\w`, `\d` and `\s`)
+revert to their typical ASCII definition. `\w` maps to `[[:word:]]`, `\d` maps
+to `[[:digit:]]` and `\s` maps to `[[:space:]]`.
+4. In ASCII compatible mode, word boundaries use the ASCII compatible `\w` to
+determine whether a byte is a word byte or not.
+5. Hexadecimal notation can be used to specify arbitrary bytes instead of
+Unicode codepoints. For example, in ASCII compatible mode, `\xFF` matches the
+literal byte `\xFF`, while in Unicode mode, `\xFF` is a Unicode codepoint that
+matches its UTF-8 encoding of `\xC3\xBF`. Similarly for octal notation when
+enabled.
+6. `.` matches any *byte* except for `\n` instead of any Unicode scalar value.
+When the `s` flag is enabled, `.` matches any byte.
+
+# Performance
+
+In general, one should expect performance on `&[u8]` to be roughly similar to
+performance on `&str`.
+*/
+#[cfg(feature = "use_std")]
+pub mod bytes {
+    pub use re_builder::bytes::*;
+    pub use re_builder::set_bytes::*;
+    pub use re_bytes::*;
+    pub use re_set::bytes::*;
+}
+
+mod backtrack;
+mod utf8;
+mod compile;
+mod dfa;
+mod error;
+mod exec;
+mod expand;
+mod freqs;
+mod input;
+mod literal;
+#[cfg(feature = "pattern")]
+mod pattern;
+mod pikevm;
+mod prog;
+mod re_builder;
+mod re_bytes;
+mod re_set;
+mod re_trait;
+mod re_unicode;
+mod sparse;
+mod vector;
+
+/// The `internal` module exists to support suspicious activity, such as
+/// testing different matching engines and supporting the `regex-debug` CLI
+/// utility.
+#[doc(hidden)]
+#[cfg(feature = "use_std")]
+pub mod internal {
+    pub use compile::Compiler;
+    pub use exec::{Exec, ExecBuilder};
+    pub use input::{Char, Input, CharInput, InputAt};
+    pub use literal::LiteralSearcher;
+    pub use prog::{Program, Inst, EmptyLook, InstRanges};
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/literal/mod.rs.html b/target/doc/src/regex/literal/mod.rs.html new file mode 100644 index 0000000..da8579d --- /dev/null +++ b/target/doc/src/regex/literal/mod.rs.html @@ -0,0 +1,2295 @@ +mod.rs.html -- source
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::cmp;
+use std::mem;
+
+use aho_corasick::{self, AhoCorasick, AhoCorasickBuilder};
+use memchr::{memchr, memchr2, memchr3};
+use syntax::hir::literal::{Literal, Literals};
+
+use freqs::BYTE_FREQUENCIES;
+use self::teddy_avx2::{Teddy as TeddyAVX2};
+use self::teddy_ssse3::{Teddy as TeddySSSE3};
+
+mod teddy_avx2;
+mod teddy_ssse3;
+
+/// A prefix extracted from a compiled regular expression.
+///
+/// A regex prefix is a set of literal strings that *must* be matched at the
+/// beginning of a regex in order for the entire regex to match. Similarly
+/// for a regex suffix.
+#[derive(Clone, Debug)]
+pub struct LiteralSearcher {
+    complete: bool,
+    lcp: FreqyPacked,
+    lcs: FreqyPacked,
+    matcher: Matcher,
+}
+
+#[derive(Clone, Debug)]
+enum Matcher {
+    /// No literals. (Never advances through the input.)
+    Empty,
+    /// A set of four or more single byte literals.
+    Bytes(SingleByteSet),
+    /// A single substring, find using memchr and frequency analysis.
+    FreqyPacked(FreqyPacked),
+    /// A single substring, find using Boyer-Moore.
+    BoyerMoore(BoyerMooreSearch),
+    /// An Aho-Corasick automaton.
+    AC { ac: AhoCorasick<u32>, lits: Vec<Literal> },
+    /// A simd accelerated multiple string matcher. Used only for a small
+    /// number of small literals.
+    TeddySSSE3(TeddySSSE3),
+    /// A simd accelerated multiple string matcher. Used only for a small
+    /// number of small literals. This uses 256-bit vectors.
+    TeddyAVX2(TeddyAVX2),
+}
+
+impl LiteralSearcher {
+    /// Returns a matcher that never matches and never advances the input.
+    pub fn empty() -> Self {
+        Self::new(Literals::empty(), Matcher::Empty)
+    }
+
+    /// Returns a matcher for literal prefixes from the given set.
+    pub fn prefixes(lits: Literals) -> Self {
+        let matcher = Matcher::prefixes(&lits);
+        Self::new(lits, matcher)
+    }
+
+    /// Returns a matcher for literal suffixes from the given set.
+    pub fn suffixes(lits: Literals) -> Self {
+        let matcher = Matcher::suffixes(&lits);
+        Self::new(lits, matcher)
+    }
+
+    fn new(lits: Literals, matcher: Matcher) -> Self {
+        let complete = lits.all_complete();
+        LiteralSearcher {
+            complete: complete,
+            lcp: FreqyPacked::new(lits.longest_common_prefix().to_vec()),
+            lcs: FreqyPacked::new(lits.longest_common_suffix().to_vec()),
+            matcher: matcher,
+        }
+    }
+
+    /// Returns true if all matches comprise the entire regular expression.
+    ///
+    /// This does not necessarily mean that a literal match implies a match
+    /// of the regular expression. For example, the regular expresison `^a`
+    /// is comprised of a single complete literal `a`, but the regular
+    /// expression demands that it only match at the beginning of a string.
+    pub fn complete(&self) -> bool {
+        self.complete && !self.is_empty()
+    }
+
+    /// Find the position of a literal in `haystack` if it exists.
+    #[inline(always)] // reduces constant overhead
+    pub fn find(&self, haystack: &[u8]) -> Option<(usize, usize)> {
+        use self::Matcher::*;
+        match self.matcher {
+            Empty => Some((0, 0)),
+            Bytes(ref sset) => sset.find(haystack).map(|i| (i, i + 1)),
+            FreqyPacked(ref s) => s.find(haystack).map(|i| (i, i + s.len())),
+            BoyerMoore(ref s) => s.find(haystack).map(|i| (i, i + s.len())),
+            AC { ref ac, .. } => {
+                ac.find(haystack).map(|m| (m.start(), m.end()))
+            }
+            TeddySSSE3(ref t) => t.find(haystack).map(|m| (m.start, m.end)),
+            TeddyAVX2(ref t) => t.find(haystack).map(|m| (m.start, m.end)),
+        }
+    }
+
+    /// Like find, except matches must start at index `0`.
+    pub fn find_start(&self, haystack: &[u8]) -> Option<(usize, usize)> {
+        for lit in self.iter() {
+            if lit.len() > haystack.len() {
+                continue;
+            }
+            if lit == &haystack[0..lit.len()] {
+                return Some((0, lit.len()));
+            }
+        }
+        None
+    }
+
+    /// Like find, except matches must end at index `haystack.len()`.
+    pub fn find_end(&self, haystack: &[u8]) -> Option<(usize, usize)> {
+        for lit in self.iter() {
+            if lit.len() > haystack.len() {
+                continue;
+            }
+            if lit == &haystack[haystack.len() - lit.len()..] {
+                return Some((haystack.len() - lit.len(), haystack.len()));
+            }
+        }
+        None
+    }
+
+    /// Returns an iterator over all literals to be matched.
+    pub fn iter(&self) -> LiteralIter {
+        match self.matcher {
+            Matcher::Empty => LiteralIter::Empty,
+            Matcher::Bytes(ref sset) => LiteralIter::Bytes(&sset.dense),
+            Matcher::FreqyPacked(ref s) => LiteralIter::Single(&s.pat),
+            Matcher::BoyerMoore(ref s) => LiteralIter::Single(&s.pattern),
+            Matcher::AC { ref lits, .. } => LiteralIter::AC(lits),
+            Matcher::TeddySSSE3(ref ted) => {
+                LiteralIter::TeddySSSE3(ted.patterns())
+            }
+            Matcher::TeddyAVX2(ref ted) => {
+                LiteralIter::TeddyAVX2(ted.patterns())
+            }
+        }
+    }
+
+    /// Returns a matcher for the longest common prefix of this matcher.
+    pub fn lcp(&self) -> &FreqyPacked {
+        &self.lcp
+    }
+
+    /// Returns a matcher for the longest common suffix of this matcher.
+    pub fn lcs(&self) -> &FreqyPacked {
+        &self.lcs
+    }
+
+    /// Returns true iff this prefix is empty.
+    pub fn is_empty(&self) -> bool {
+        self.len() == 0
+    }
+
+    /// Returns the number of prefixes in this machine.
+    pub fn len(&self) -> usize {
+        use self::Matcher::*;
+        match self.matcher {
+            Empty => 0,
+            Bytes(ref sset) => sset.dense.len(),
+            FreqyPacked(_) => 1,
+            BoyerMoore(_) => 1,
+            AC { ref ac, .. } => ac.pattern_count(),
+            TeddySSSE3(ref ted) => ted.len(),
+            TeddyAVX2(ref ted) => ted.len(),
+        }
+    }
+
+    /// Return the approximate heap usage of literals in bytes.
+    pub fn approximate_size(&self) -> usize {
+        use self::Matcher::*;
+        match self.matcher {
+            Empty => 0,
+            Bytes(ref sset) => sset.approximate_size(),
+            FreqyPacked(ref single) => single.approximate_size(),
+            BoyerMoore(ref single) => single.approximate_size(),
+            AC { ref ac, .. } => ac.heap_bytes(),
+            TeddySSSE3(ref ted) => ted.approximate_size(),
+            TeddyAVX2(ref ted) => ted.approximate_size(),
+        }
+    }
+}
+
+impl Matcher {
+    fn prefixes(lits: &Literals) -> Self {
+        let sset = SingleByteSet::prefixes(lits);
+        Matcher::new(lits, sset)
+    }
+
+    fn suffixes(lits: &Literals) -> Self {
+        let sset = SingleByteSet::suffixes(lits);
+        Matcher::new(lits, sset)
+    }
+
+    fn new(lits: &Literals, sset: SingleByteSet) -> Self {
+        if lits.literals().is_empty() {
+            return Matcher::Empty;
+        }
+        if sset.dense.len() >= 26 {
+            // Avoid trying to match a large number of single bytes.
+            // This is *very* sensitive to a frequency analysis comparison
+            // between the bytes in sset and the composition of the haystack.
+            // No matter the size of sset, if its members all are rare in the
+            // haystack, then it'd be worth using it. How to tune this... IDK.
+            // ---AG
+            return Matcher::Empty;
+        }
+        if sset.complete {
+            return Matcher::Bytes(sset);
+        }
+        if lits.literals().len() == 1 {
+            let lit = lits.literals()[0].to_vec();
+            if BoyerMooreSearch::should_use(lit.as_slice()) {
+                return Matcher::BoyerMoore(BoyerMooreSearch::new(lit));
+            } else {
+                return Matcher::FreqyPacked(FreqyPacked::new(lit));
+            }
+        }
+        let is_aho_corasick_fast = sset.dense.len() == 1 && sset.all_ascii;
+        if TeddyAVX2::available() && !is_aho_corasick_fast {
+            const MAX_TEDDY_LITERALS: usize = 32;
+            if lits.literals().len() <= MAX_TEDDY_LITERALS {
+                if let Some(ted) = TeddyAVX2::new(lits) {
+                    return Matcher::TeddyAVX2(ted);
+                }
+            }
+        }
+        if TeddySSSE3::available() && !is_aho_corasick_fast {
+            // Only try Teddy if Aho-Corasick can't use memchr on an ASCII
+            // byte. Also, in its current form, Teddy doesn't scale well to
+            // lots of literals.
+            //
+            // We impose the ASCII restriction since an alternation of
+            // non-ASCII string literals in the same language is likely to all
+            // start with the same byte. Even worse, the corpus being searched
+            // probably has a similar composition, which ends up completely
+            // negating the benefit of memchr.
+            const MAX_TEDDY_LITERALS: usize = 32;
+            if lits.literals().len() <= MAX_TEDDY_LITERALS {
+                if let Some(ted) = TeddySSSE3::new(lits) {
+                    return Matcher::TeddySSSE3(ted);
+                }
+            }
+            // Fallthrough to ol' reliable Aho-Corasick...
+        }
+        let pats = lits.literals().to_owned();
+        let ac = AhoCorasickBuilder::new()
+            .match_kind(aho_corasick::MatchKind::LeftmostFirst)
+            .dfa(true)
+            .build_with_size::<u32, _, _>(&pats)
+            .unwrap();
+        Matcher::AC { ac, lits: pats }
+    }
+}
+
+pub enum LiteralIter<'a> {
+    Empty,
+    Bytes(&'a [u8]),
+    Single(&'a [u8]),
+    AC(&'a [Literal]),
+    TeddySSSE3(&'a [Vec<u8>]),
+    TeddyAVX2(&'a [Vec<u8>]),
+}
+
+impl<'a> Iterator for LiteralIter<'a> {
+    type Item = &'a [u8];
+
+    fn next(&mut self) -> Option<Self::Item> {
+        match *self {
+            LiteralIter::Empty => None,
+            LiteralIter::Bytes(ref mut many) => {
+                if many.is_empty() {
+                    None
+                } else {
+                    let next = &many[0..1];
+                    *many = &many[1..];
+                    Some(next)
+                }
+            }
+            LiteralIter::Single(ref mut one) => {
+                if one.is_empty() {
+                    None
+                } else {
+                    let next = &one[..];
+                    *one = &[];
+                    Some(next)
+                }
+            }
+            LiteralIter::AC(ref mut lits) => {
+                if lits.is_empty() {
+                    None
+                } else {
+                    let next = &lits[0];
+                    *lits = &lits[1..];
+                    Some(&**next)
+                }
+            }
+            LiteralIter::TeddySSSE3(ref mut lits) => {
+                if lits.is_empty() {
+                    None
+                } else {
+                    let next = &lits[0];
+                    *lits = &lits[1..];
+                    Some(&**next)
+                }
+            }
+            LiteralIter::TeddyAVX2(ref mut lits) => {
+                if lits.is_empty() {
+                    None
+                } else {
+                    let next = &lits[0];
+                    *lits = &lits[1..];
+                    Some(&**next)
+                }
+            }
+        }
+    }
+}
+
+#[derive(Clone, Debug)]
+struct SingleByteSet {
+    sparse: Vec<bool>,
+    dense: Vec<u8>,
+    complete: bool,
+    all_ascii: bool,
+}
+
+impl SingleByteSet {
+    fn new() -> SingleByteSet {
+        SingleByteSet {
+            sparse: vec![false; 256],
+            dense: vec![],
+            complete: true,
+            all_ascii: true,
+        }
+    }
+
+    fn prefixes(lits: &Literals) -> SingleByteSet {
+        let mut sset = SingleByteSet::new();
+        for lit in lits.literals() {
+            sset.complete = sset.complete && lit.len() == 1;
+            if let Some(&b) = lit.get(0) {
+                if !sset.sparse[b as usize] {
+                    if b > 0x7F {
+                        sset.all_ascii = false;
+                    }
+                    sset.dense.push(b);
+                    sset.sparse[b as usize] = true;
+                }
+            }
+        }
+        sset
+    }
+
+    fn suffixes(lits: &Literals) -> SingleByteSet {
+        let mut sset = SingleByteSet::new();
+        for lit in lits.literals() {
+            sset.complete = sset.complete && lit.len() == 1;
+            if let Some(&b) = lit.get(lit.len().checked_sub(1).unwrap()) {
+                if !sset.sparse[b as usize] {
+                    if b > 0x7F {
+                        sset.all_ascii = false;
+                    }
+                    sset.dense.push(b);
+                    sset.sparse[b as usize] = true;
+                }
+            }
+        }
+        sset
+    }
+
+    /// Faster find that special cases certain sizes to use memchr.
+    #[inline(always)] // reduces constant overhead
+    fn find(&self, text: &[u8]) -> Option<usize> {
+        match self.dense.len() {
+            0 => None,
+            1 => memchr(self.dense[0], text),
+            2 => memchr2(self.dense[0], self.dense[1], text),
+            3 => memchr3(self.dense[0], self.dense[1], self.dense[2], text),
+            _ => self._find(text),
+        }
+    }
+
+    /// Generic find that works on any sized set.
+    fn _find(&self, haystack: &[u8]) -> Option<usize> {
+        for (i, &b) in haystack.iter().enumerate() {
+            if self.sparse[b as usize] {
+                return Some(i);
+            }
+        }
+        None
+    }
+
+    fn approximate_size(&self) -> usize {
+        (self.dense.len() * mem::size_of::<u8>())
+        + (self.sparse.len() * mem::size_of::<bool>())
+    }
+}
+
+/// Provides an implementation of fast subtring search using frequency
+/// analysis.
+///
+/// memchr is so fast that we do everything we can to keep the loop in memchr
+/// for as long as possible. The easiest way to do this is to intelligently
+/// pick the byte to send to memchr. The best byte is the byte that occurs
+/// least frequently in the haystack. Since doing frequency analysis on the
+/// haystack is far too expensive, we compute a set of fixed frequencies up
+/// front and hard code them in src/freqs.rs. Frequency analysis is done via
+/// scripts/frequencies.py.
+#[derive(Clone, Debug)]
+pub struct FreqyPacked {
+    /// The pattern.
+    pat: Vec<u8>,
+    /// The number of Unicode characters in the pattern. This is useful for
+    /// determining the effective length of a pattern when deciding which
+    /// optimizations to perform. A trailing incomplete UTF-8 sequence counts
+    /// as one character.
+    char_len: usize,
+    /// The rarest byte in the pattern, according to pre-computed frequency
+    /// analysis.
+    rare1: u8,
+    /// The offset of the rarest byte in `pat`.
+    rare1i: usize,
+    /// The second rarest byte in the pattern, according to pre-computed
+    /// frequency analysis. (This may be equivalent to the rarest byte.)
+    ///
+    /// The second rarest byte is used as a type of guard for quickly detecting
+    /// a mismatch after memchr locates an instance of the rarest byte. This
+    /// is a hedge against pathological cases where the pre-computed frequency
+    /// analysis may be off. (But of course, does not prevent *all*
+    /// pathological cases.)
+    rare2: u8,
+    /// The offset of the second rarest byte in `pat`.
+    rare2i: usize,
+}
+
+impl FreqyPacked {
+    fn new(pat: Vec<u8>) -> FreqyPacked {
+        if pat.is_empty() {
+            return FreqyPacked::empty();
+        }
+
+        // Find the rarest two bytes. Try to make them distinct (but it's not
+        // required).
+        let mut rare1 = pat[0];
+        let mut rare2 = pat[0];
+        for b in pat[1..].iter().cloned() {
+            if freq_rank(b) < freq_rank(rare1) {
+                rare1 = b;
+            }
+        }
+        for &b in &pat {
+            if rare1 == rare2 {
+                rare2 = b
+            } else if b != rare1 && freq_rank(b) < freq_rank(rare2) {
+                rare2 = b;
+            }
+        }
+
+        // And find the offsets of their last occurrences.
+        let rare1i = pat.iter().rposition(|&b| b == rare1).unwrap();
+        let rare2i = pat.iter().rposition(|&b| b == rare2).unwrap();
+
+        let char_len = char_len_lossy(&pat);
+        FreqyPacked {
+            pat: pat,
+            char_len: char_len,
+            rare1: rare1,
+            rare1i: rare1i,
+            rare2: rare2,
+            rare2i: rare2i,
+        }
+    }
+
+    fn empty() -> FreqyPacked {
+        FreqyPacked {
+            pat: vec![],
+            char_len: 0,
+            rare1: 0,
+            rare1i: 0,
+            rare2: 0,
+            rare2i: 0,
+        }
+    }
+
+    #[inline(always)] // reduces constant overhead
+    pub fn find(&self, haystack: &[u8]) -> Option<usize> {
+        let pat = &*self.pat;
+        if haystack.len() < pat.len() || pat.is_empty() {
+            return None;
+        }
+        let mut i = self.rare1i;
+        while i < haystack.len() {
+            i += match memchr(self.rare1, &haystack[i..]) {
+                None => return None,
+                Some(i) => i,
+            };
+            let start = i - self.rare1i;
+            let end = start + pat.len();
+            if end > haystack.len() {
+                return None;
+            }
+            let aligned = &haystack[start..end];
+            if aligned[self.rare2i] == self.rare2 && aligned == &*self.pat {
+                return Some(start);
+            }
+            i += 1;
+        }
+        None
+    }
+
+    #[inline(always)] // reduces constant overhead
+    pub fn is_suffix(&self, text: &[u8]) -> bool {
+        if text.len() < self.len() {
+            return false;
+        }
+        text[text.len() - self.len()..] == *self.pat
+    }
+
+    pub fn len(&self) -> usize {
+        self.pat.len()
+    }
+
+    pub fn char_len(&self) -> usize {
+        self.char_len
+    }
+
+    fn approximate_size(&self) -> usize {
+        self.pat.len() * mem::size_of::<u8>()
+    }
+}
+
+fn char_len_lossy(bytes: &[u8]) -> usize {
+    String::from_utf8_lossy(bytes).chars().count()
+}
+
+/// An implementation of Tuned Boyer-Moore as laid out by
+/// Andrew Hume and Daniel Sunday in "Fast String Searching".
+/// O(n) in the size of the input.
+///
+/// Fast string searching algorithms come in many variations,
+/// but they can generally be described in terms of three main
+/// components.
+///
+/// The skip loop is where the string searcher wants to spend
+/// as much time as possible. Exactly which character in the
+/// pattern the skip loop examines varies from algorithm to
+/// algorithm, but in the simplest case this loop repeated
+/// looks at the last character in the pattern and jumps
+/// forward in the input if it is not in the pattern.
+/// Robert Boyer and J Moore called this the "fast" loop in
+/// their original paper.
+///
+/// The match loop is responsible for actually examining the
+/// whole potentially matching substring. In order to fail
+/// faster, the match loop sometimes has a guard test attached.
+/// The guard test uses frequency analysis of the different
+/// characters in the pattern to choose the least frequency
+/// occurring character and use it to find match failures
+/// as quickly as possible.
+///
+/// The shift rule governs how the algorithm will shuffle its
+/// test window in the event of a failure during the match loop.
+/// Certain shift rules allow the worst-case run time of the
+/// algorithm to be shown to be O(n) in the size of the input
+/// rather than O(nm) in the size of the input and the size
+/// of the pattern (as naive Boyer-Moore is).
+///
+/// "Fast String Searching", in addition to presenting a tuned
+/// algorithm, provides a comprehensive taxonomy of the many
+/// different flavors of string searchers. Under that taxonomy
+/// TBM, the algorithm implemented here, uses an unrolled fast
+/// skip loop with memchr fallback, a forward match loop with guard,
+/// and the mini Sunday's delta shift rule. To unpack that you'll have to
+/// read the paper.
+#[derive(Clone, Debug)]
+pub struct BoyerMooreSearch {
+    /// The pattern we are going to look for in the haystack.
+    pattern: Vec<u8>,
+
+    /// The skip table for the skip loop.
+    ///
+    /// Maps the character at the end of the input
+    /// to a shift.
+    skip_table: Vec<usize>,
+
+    /// The guard character (least frequently occurring char).
+    guard: u8,
+    /// The reverse-index of the guard character in the pattern.
+    guard_reverse_idx: usize,
+
+    /// Daniel Sunday's mini generalized delta2 shift table.
+    ///
+    /// We use a skip loop, so we only have to provide a shift
+    /// for the skip char (last char). This is why it is a mini
+    /// shift rule.
+    md2_shift: usize,
+}
+
+impl BoyerMooreSearch {
+    /// Create a new string searcher, performing whatever
+    /// compilation steps are required.
+    fn new(pattern: Vec<u8>) -> Self {
+        debug_assert!(pattern.len() > 0);
+
+        let (g, gi) = Self::select_guard(pattern.as_slice());
+        let skip_table = Self::compile_skip_table(pattern.as_slice());
+        let md2_shift = Self::compile_md2_shift(pattern.as_slice());
+        BoyerMooreSearch {
+            pattern: pattern,
+            skip_table: skip_table,
+            guard: g,
+            guard_reverse_idx: gi,
+            md2_shift: md2_shift,
+        }
+    }
+
+    /// Find the pattern in `haystack`, returning the offset
+    /// of the start of the first occurrence of the pattern
+    /// in `haystack`.
+    #[inline]
+    fn find(&self, haystack: &[u8]) -> Option<usize> {
+        if haystack.len() < self.pattern.len() {
+            return None;
+        }
+
+        let mut window_end = self.pattern.len() - 1;
+
+        // Inspired by the grep source. It is a way
+        // to do correct loop unrolling without having to place
+        // a crashpad of terminating charicters at the end in
+        // the way described in the Fast String Searching paper.
+        const NUM_UNROLL: usize = 10;
+        // 1 for the initial position, and 1 for the md2 shift
+        let short_circut = (NUM_UNROLL + 2) * self.pattern.len();
+
+        if haystack.len() > short_circut {
+            // just 1 for the md2 shift
+            let backstop = haystack.len() - ((NUM_UNROLL + 1) * self.pattern.len());
+            loop {
+                window_end = match self.skip_loop(haystack, window_end, backstop) {
+                    Some(i) => i,
+                    None => return None,
+                };
+                if window_end >= backstop {
+                    break;
+                }
+
+                if self.check_match(haystack, window_end) {
+                    return Some(window_end - (self.pattern.len() - 1));
+                } else {
+                    let skip = self.skip_table[haystack[window_end] as usize];
+                    window_end +=
+                        if skip == 0 { self.md2_shift } else { skip };
+                    continue;
+                }
+            }
+        }
+
+        // now process the input after the backstop
+        while window_end < haystack.len() {
+            let mut skip = self.skip_table[haystack[window_end] as usize];
+            if skip == 0 {
+                if self.check_match(haystack, window_end) {
+                    return Some(window_end - (self.pattern.len() - 1));
+                } else {
+                    skip = self.md2_shift;
+                }
+            }
+            window_end += skip;
+        }
+
+        None
+    }
+
+    fn len(&self) -> usize {
+        return self.pattern.len()
+    }
+
+    /// The key heuristic behind which the BoyerMooreSearch lives.
+    ///
+    /// See `rust-lang/regex/issues/408`.
+    ///
+    /// Tuned Boyer-Moore is actually pretty slow! It turns out a handrolled
+    /// platform-specific memchr routine with a bit of frequency
+    /// analysis sprinkled on top actually wins most of the time.
+    /// However, there are a few cases where Tuned Boyer-Moore still
+    /// wins.
+    ///
+    /// If the haystack is random, frequency analysis doesn't help us,
+    /// so Boyer-Moore will win for sufficiently large needles.
+    /// Unfortunately, there is no obvious way to determine this
+    /// ahead of time.
+    ///
+    /// If the pattern itself consists of very common characters,
+    /// frequency analysis won't get us anywhere. The most extreme
+    /// example of this is a pattern like `eeeeeeeeeeeeeeee`. Fortunately,
+    /// this case is wholly determined by the pattern, so we can actually
+    /// implement the heuristic.
+    ///
+    /// A third case is if the pattern is sufficiently long. The idea
+    /// here is that once the pattern gets long enough the Tuned
+    /// Boyer-Moore skip loop will start making strides long enough
+    /// to beat the asm deep magic that is memchr.
+    fn should_use(pattern: &[u8]) -> bool {
+        // The minimum pattern length required to use TBM.
+        const MIN_LEN: usize = 9;
+        // The minimum frequency rank (lower is rarer) that every byte in the
+        // pattern must have in order to use TBM. That is, if the pattern
+        // contains _any_ byte with a lower rank, then TBM won't be used.
+        const MIN_CUTOFF: usize = 150;
+        // The maximum frequency rank for any byte.
+        const MAX_CUTOFF: usize = 255;
+        // The scaling factor used to determine the actual cutoff frequency
+        // to use (keeping in mind that the minimum frequency rank is bounded
+        // by MIN_CUTOFF). This scaling factor is an attempt to make TBM more
+        // likely to be used as the pattern grows longer. That is, longer
+        // patterns permit somewhat less frequent bytes than shorter patterns,
+        // under the assumption that TBM gets better as the pattern gets
+        // longer.
+        const LEN_CUTOFF_PROPORTION: usize = 4;
+
+        let scaled_rank = pattern.len().wrapping_mul(LEN_CUTOFF_PROPORTION);
+        let cutoff = cmp::max(
+            MIN_CUTOFF,
+            MAX_CUTOFF - cmp::min(MAX_CUTOFF, scaled_rank),
+        );
+        // The pattern must be long enough to be worthwhile. e.g., memchr will
+        // be faster on `e` because it is short even though e is quite common.
+        pattern.len() > MIN_LEN
+            // all the bytes must be more common than the cutoff.
+            && pattern.iter().all(|c| freq_rank(*c) >= cutoff)
+    }
+
+    /// Check to see if there is a match at the given position
+    #[inline]
+    fn check_match(&self, haystack: &[u8], window_end: usize) -> bool {
+        // guard test
+        if haystack[window_end - self.guard_reverse_idx] != self.guard {
+            return false;
+        }
+
+        // match loop
+        let window_start = window_end - (self.pattern.len() - 1);
+        for i in 0..self.pattern.len() {
+            if self.pattern[i] != haystack[window_start + i] {
+                return false;
+            }
+        }
+
+        true
+    }
+
+    /// Skip forward according to the shift table.
+    ///
+    /// Returns the offset of the next occurrence
+    /// of the last char in the pattern, or the none
+    /// if it never reappears. If `skip_loop` hits the backstop
+    /// it will leave early.
+    #[inline]
+    fn skip_loop(&self,
+        haystack: &[u8],
+        mut window_end: usize,
+        backstop: usize,
+    ) -> Option<usize> {
+        let window_end_snapshot = window_end;
+        let skip_of = |we: usize| -> usize {
+            // Unsafe might make this faster, but the benchmarks
+            // were hard to interpret.
+            self.skip_table[haystack[we] as usize]
+        };
+
+        loop {
+            let mut skip = skip_of(window_end); window_end += skip;
+            skip = skip_of(window_end); window_end += skip;
+            if skip != 0 {
+                skip = skip_of(window_end); window_end += skip;
+                skip = skip_of(window_end); window_end += skip;
+                skip = skip_of(window_end); window_end += skip;
+                if skip != 0 {
+                    skip = skip_of(window_end); window_end += skip;
+                    skip = skip_of(window_end); window_end += skip;
+                    skip = skip_of(window_end); window_end += skip;
+                    if skip != 0 {
+                        skip = skip_of(window_end); window_end += skip;
+                        skip = skip_of(window_end); window_end += skip;
+
+                        // If ten iterations did not make at least 16 words
+                        // worth of progress, we just fall back on memchr.
+                        if window_end - window_end_snapshot >
+                             16 * mem::size_of::<usize>() {
+
+                            // Returning a window_end >= backstop will immediatly
+                            // break us out of the inner loop in `find`.
+                            if window_end >= backstop {
+                                return Some(window_end);
+                            }
+
+                            continue; // we made enough progress
+                        } else {
+                            // In case we are already there, and so that
+                            // we will catch the guard char.
+                            window_end = window_end
+                                .checked_sub(1 + self.guard_reverse_idx)
+                                .unwrap_or(0);
+
+                            match memchr(self.guard, &haystack[window_end..]) {
+                                None => return None,
+                                Some(g_idx) => {
+                                    return Some(window_end + g_idx + self.guard_reverse_idx);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            return Some(window_end);
+        }
+    }
+
+    /// Compute the ufast skip table.
+    fn compile_skip_table(pattern: &[u8]) -> Vec<usize> {
+        let mut tab = vec![pattern.len(); 256];
+
+        // For every char in the pattern, we write a skip
+        // that will line us up with the rightmost occurrence.
+        //
+        // N.B. the sentinel (0) is written by the last
+        // loop iteration.
+        for (i, c) in pattern.iter().enumerate() {
+            tab[*c as usize] = (pattern.len() - 1) - i;
+        }
+
+        tab
+    }
+
+    /// Select the guard character based off of the precomputed
+    /// frequency table.
+    fn select_guard(pattern: &[u8]) -> (u8, usize) {
+        let mut rarest = pattern[0];
+        let mut rarest_rev_idx = pattern.len() - 1;
+        for (i, c) in pattern.iter().enumerate() {
+            if freq_rank(*c) < freq_rank(rarest) {
+                rarest = *c;
+                rarest_rev_idx = (pattern.len() - 1) - i;
+            }
+        }
+
+        (rarest, rarest_rev_idx)
+    }
+
+    /// If there is another occurrence of the skip
+    /// char, shift to it, otherwise just shift to
+    /// the next window.
+    fn compile_md2_shift(pattern: &[u8]) -> usize {
+        let shiftc = *pattern.last().unwrap();
+
+        // For a pattern of length 1 we will never apply the
+        // shift rule, so we use a poison value on the principle
+        // that failing fast is a good thing.
+        if pattern.len() == 1 {
+            return 0xDEADBEAF;
+        }
+
+        let mut i = pattern.len() - 2;
+        while i > 0 {
+            if pattern[i] == shiftc {
+                return (pattern.len() - 1) - i;
+            }
+            i -= 1;
+        }
+
+        // The skip char never re-occurs in the pattern, so
+        // we can just shift the whole window length.
+        pattern.len() - 1
+    }
+
+    fn approximate_size(&self) -> usize {
+        (self.pattern.len() * mem::size_of::<u8>())
+            + (256 * mem::size_of::<usize>()) // skip table
+    }
+}
+
+fn freq_rank(b: u8) -> usize {
+    BYTE_FREQUENCIES[b as usize] as usize
+}
+
+#[cfg(test)]
+mod tests {
+    use super::{BoyerMooreSearch, FreqyPacked};
+
+    //
+    // Unit Tests
+    //
+
+    // The "hello, world" of string searching
+    #[test]
+    fn bm_find_subs() {
+        let searcher = BoyerMooreSearch::new(Vec::from(&b"pattern"[..]));
+        let haystack = b"I keep seeing patterns in this text";
+        assert_eq!(14, searcher.find(haystack).unwrap());
+    }
+
+    #[test]
+    fn bm_find_no_subs() {
+        let searcher = BoyerMooreSearch::new(Vec::from(&b"pattern"[..]));
+        let haystack = b"I keep seeing needles in this text";
+        assert_eq!(None, searcher.find(haystack));
+    }
+
+    //
+    // Regression Tests
+    //
+
+    #[test]
+    fn bm_skip_reset_bug() {
+        let haystack = vec![0, 0, 0, 0, 0, 1, 1, 0];
+        let needle = vec![0, 1, 1, 0];
+
+        let searcher = BoyerMooreSearch::new(needle);
+        let offset = searcher.find(haystack.as_slice()).unwrap();
+        assert_eq!(4, offset);
+    }
+
+    #[test]
+    fn bm_backstop_underflow_bug() {
+        let haystack = vec![0, 0];
+        let needle = vec![0, 0];
+
+        let searcher = BoyerMooreSearch::new(needle);
+        let offset = searcher.find(haystack.as_slice()).unwrap();
+        assert_eq!(0, offset);
+    }
+
+    #[test]
+    fn bm_naive_off_by_one_bug() {
+        let haystack = vec![91];
+        let needle = vec![91];
+
+        let naive_offset = naive_find(&needle, &haystack).unwrap();
+        assert_eq!(0, naive_offset);
+    }
+
+    #[test]
+    fn bm_memchr_fallback_indexing_bug() {
+        let mut haystack = vec![
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+        let needle = vec![1, 1, 1, 1, 32, 32, 87];
+        let needle_start = haystack.len();
+        haystack.extend(needle.clone());
+
+        let searcher = BoyerMooreSearch::new(needle);
+        assert_eq!(needle_start, searcher.find(haystack.as_slice()).unwrap());
+    }
+
+    #[test]
+    fn bm_backstop_boundary() {
+        let haystack = b"\
+// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+e_data.clone_created(entity_id, entity_to_add.entity_id);
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+".to_vec();
+        let needle = b"clone_created".to_vec();
+
+        let searcher = BoyerMooreSearch::new(needle);
+        let result = searcher.find(&haystack);
+        assert_eq!(Some(43), result);
+    }
+
+    #[test]
+    fn bm_win_gnu_indexing_bug() {
+        let haystack_raw = vec![
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+        let needle = vec![1, 1, 1, 1, 1, 1, 1];
+        let haystack = haystack_raw.as_slice();
+
+        BoyerMooreSearch::new(needle.clone()).find(haystack);
+    }
+
+    //
+    // QuickCheck Properties
+    //
+
+    use quickcheck::TestResult;
+
+    fn naive_find(needle: &[u8], haystack: &[u8]) -> Option<usize> {
+        assert!(needle.len() <= haystack.len());
+
+        for i in 0..(haystack.len() - (needle.len() - 1)) {
+            if haystack[i] == needle[0]
+                && &haystack[i..(i+needle.len())] == needle {
+                return Some(i)
+            }
+        }
+
+        None
+    }
+
+    quickcheck! {
+        fn qc_bm_equals_nieve_find(pile1: Vec<u8>, pile2: Vec<u8>) -> TestResult {
+            if pile1.len() == 0 || pile2.len() == 0 {
+                return TestResult::discard();
+            }
+
+            let (needle, haystack) = if pile1.len() < pile2.len() {
+                (pile1, pile2.as_slice())
+            } else {
+                (pile2, pile1.as_slice())
+            };
+
+            let searcher = BoyerMooreSearch::new(needle.clone());
+            TestResult::from_bool(
+                searcher.find(haystack) == naive_find(&needle, haystack))
+        }
+
+        fn qc_bm_equals_single(pile1: Vec<u8>, pile2: Vec<u8>) -> TestResult {
+            if pile1.len() == 0 || pile2.len() == 0 {
+                return TestResult::discard();
+            }
+
+            let (needle, haystack) = if pile1.len() < pile2.len() {
+                (pile1, pile2.as_slice())
+            } else {
+                (pile2, pile1.as_slice())
+            };
+
+            let bm_searcher = BoyerMooreSearch::new(needle.clone());
+            let freqy_memchr = FreqyPacked::new(needle);
+            TestResult::from_bool(
+                bm_searcher.find(haystack) == freqy_memchr.find(haystack))
+        }
+
+        fn qc_bm_finds_trailing_needle(
+            haystack_pre: Vec<u8>,
+            needle: Vec<u8>
+        ) -> TestResult {
+            if needle.len() == 0 {
+                return TestResult::discard();
+            }
+
+            let mut haystack = haystack_pre.clone();
+            let searcher = BoyerMooreSearch::new(needle.clone());
+
+            if haystack.len() >= needle.len() &&
+                searcher.find(haystack.as_slice()).is_some() {
+                return TestResult::discard();
+            }
+
+            haystack.extend(needle.clone());
+
+            // What if the the tail of the haystack can start the
+            // needle?
+            let start = haystack_pre.len()
+                .checked_sub(needle.len())
+                .unwrap_or(0);
+            for i in 0..(needle.len() - 1) {
+                if searcher.find(&haystack[(i + start)..]).is_some() {
+                    return TestResult::discard();
+                }
+            }
+
+            TestResult::from_bool(
+                searcher.find(haystack.as_slice())
+                        .map(|x| x == haystack_pre.len())
+                        .unwrap_or(false))
+        }
+
+        // qc_equals_* is only testing the negative case as @burntsushi
+        // pointed out in https://github.com/rust-lang/regex/issues/446.
+        // This quickcheck prop represents an effort to force testing of
+        // the positive case. qc_bm_finds_first and qc_bm_finds_trailing_needle
+        // already check some of the positive cases, but they don't cover
+        // cases where the needle is in the middle of haystack. This prop
+        // fills that hole.
+        fn qc_bm_finds_subslice(
+            haystack: Vec<u8>,
+            needle_start: usize,
+            needle_length: usize
+        ) -> TestResult {
+            if haystack.len() == 0 {
+                return TestResult::discard();
+            }
+
+            let needle_start = needle_start % haystack.len();
+            let needle_length = needle_length % (haystack.len() - needle_start);
+
+            if needle_length == 0 {
+                return TestResult::discard();
+            }
+
+            let needle = &haystack[needle_start..(needle_start + needle_length)];
+
+            let bm_searcher = BoyerMooreSearch::new(needle.to_vec());
+
+            let start = naive_find(&needle, &haystack);
+            match start {
+                None => TestResult::from_bool(false),
+                Some(nf_start) =>
+                    TestResult::from_bool(
+                        nf_start <= needle_start
+                            && bm_searcher.find(&haystack) == start
+                    )
+            }
+        }
+
+        fn qc_bm_finds_first(needle: Vec<u8>) -> TestResult {
+            if needle.len() == 0 {
+                return TestResult::discard();
+            }
+
+            let mut haystack = needle.clone();
+            let searcher = BoyerMooreSearch::new(needle.clone());
+            haystack.extend(needle);
+
+            TestResult::from_bool(
+                searcher.find(haystack.as_slice())
+                        .map(|x| x == 0)
+                        .unwrap_or(false))
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/literal/teddy_avx2/imp.rs.html b/target/doc/src/regex/literal/teddy_avx2/imp.rs.html new file mode 100644 index 0000000..917e160 --- /dev/null +++ b/target/doc/src/regex/literal/teddy_avx2/imp.rs.html @@ -0,0 +1,967 @@ +imp.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+
+/*!
+This is the Teddy searcher, but ported to AVX2.
+
+See the module comments in the SSSE3 Teddy searcher for a more in depth
+explanation of how this algorithm works. For the most part, this port is
+basically the same as the SSSE3 version, but using 256-bit vectors instead of
+128-bit vectors, which increases throughput.
+*/
+
+use std::cmp;
+
+use aho_corasick::{self, AhoCorasick, AhoCorasickBuilder};
+use syntax::hir::literal::Literals;
+
+use vector::avx2::{AVX2VectorBuilder, u8x32};
+
+/// Corresponds to the number of bytes read at a time in the haystack.
+const BLOCK_SIZE: usize = 32;
+
+/// Match reports match information.
+#[derive(Debug, Clone)]
+pub struct Match {
+    /// The index of the pattern that matched. The index is in correspondence
+    /// with the order of the patterns given at construction.
+    pub pat: usize,
+    /// The start byte offset of the match.
+    pub start: usize,
+    /// The end byte offset of the match. This is always `start + pat.len()`.
+    pub end: usize,
+}
+
+/// A SIMD accelerated multi substring searcher.
+#[derive(Debug, Clone)]
+pub struct Teddy {
+    /// A builder for AVX2 empowered vectors.
+    vb: AVX2VectorBuilder,
+    /// A list of substrings to match.
+    pats: Vec<Vec<u8>>,
+    /// An Aho-Corasick automaton of the patterns. We use this when we need to
+    /// search pieces smaller than the Teddy block size.
+    ac: AhoCorasick,
+    /// A set of 8 buckets. Each bucket corresponds to a single member of a
+    /// bitset. A bucket contains zero or more substrings. This is useful
+    /// when the number of substrings exceeds 8, since our bitsets cannot have
+    /// more than 8 members.
+    buckets: Vec<Vec<usize>>,
+    /// Our set of masks. There's one mask for each byte in the fingerprint.
+    masks: Masks,
+}
+
+impl Teddy {
+    /// Returns true if and only if Teddy is supported on this platform.
+    ///
+    /// If this returns `false`, then `Teddy::new(...)` is guaranteed to
+    /// return `None`.
+    pub fn available() -> bool {
+        AVX2VectorBuilder::new().is_some()
+    }
+
+    /// Create a new `Teddy` multi substring matcher.
+    ///
+    /// If a `Teddy` matcher could not be created (e.g., `pats` is empty or has
+    /// an empty substring), then `None` is returned.
+    pub fn new(pats: &Literals) -> Option<Teddy> {
+        let vb = match AVX2VectorBuilder::new() {
+            None => return None,
+            Some(vb) => vb,
+        };
+        if !Teddy::available() {
+            return None;
+        }
+
+        let pats: Vec<_> = pats.literals().iter().map(|p|p.to_vec()).collect();
+        let min_len = pats.iter().map(|p| p.len()).min().unwrap_or(0);
+        // Don't allow any empty patterns and require that we have at
+        // least one pattern.
+        if min_len < 1 {
+            return None;
+        }
+        // Pick the largest mask possible, but no larger than 3.
+        let nmasks = cmp::min(3, min_len);
+        let mut masks = Masks::new(vb, nmasks);
+        let mut buckets = vec![vec![]; 8];
+        // Assign a substring to each bucket, and add the bucket's bitfield to
+        // the appropriate position in the mask.
+        for (pati, pat) in pats.iter().enumerate() {
+            let bucket = pati % 8;
+            buckets[bucket].push(pati);
+            masks.add(bucket as u8, pat);
+        }
+        let ac = AhoCorasickBuilder::new()
+            .match_kind(aho_corasick::MatchKind::LeftmostFirst)
+            .dfa(true)
+            .prefilter(false)
+            .build(&pats);
+        Some(Teddy {
+            vb: vb,
+            pats: pats.to_vec(),
+            ac: ac,
+            buckets: buckets,
+            masks: masks,
+        })
+    }
+
+    /// Returns all of the substrings matched by this `Teddy`.
+    pub fn patterns(&self) -> &[Vec<u8>] {
+        &self.pats
+    }
+
+    /// Returns the number of substrings in this matcher.
+    pub fn len(&self) -> usize {
+        self.pats.len()
+    }
+
+    /// Returns the approximate size on the heap used by this matcher.
+    pub fn approximate_size(&self) -> usize {
+        self.pats.iter().fold(0, |a, b| a + b.len())
+    }
+
+    /// Searches `haystack` for the substrings in this `Teddy`. If a match was
+    /// found, then it is returned. Otherwise, `None` is returned.
+    pub fn find(&self, haystack: &[u8]) -> Option<Match> {
+        // This is safe because the only way we can construct a Teddy type
+        // is if AVX2 is available.
+        unsafe { self.find_impl(haystack) }
+    }
+
+    #[allow(unused_attributes)]
+    #[target_feature(enable = "avx2")]
+    unsafe fn find_impl(&self, haystack: &[u8]) -> Option<Match> {
+        // If our haystack is smaller than the block size, then fall back to
+        // a naive brute force search.
+        if haystack.is_empty() || haystack.len() < (BLOCK_SIZE + 2) {
+            return self.slow(haystack, 0);
+        }
+        match self.masks.len() {
+            0 => None,
+            1 => self.find1(haystack),
+            2 => self.find2(haystack),
+            3 => self.find3(haystack),
+            _ => unreachable!(),
+        }
+    }
+
+    /// `find1` is used when there is only 1 mask. This is the easy case and is
+    /// pretty much as described in the module documentation.
+    #[inline(always)]
+    fn find1(&self, haystack: &[u8]) -> Option<Match> {
+        let mut pos = 0;
+        let zero = self.vb.u8x32_splat(0);
+        let len = haystack.len();
+        debug_assert!(len >= BLOCK_SIZE);
+        while pos <= len - BLOCK_SIZE {
+            let h = unsafe {
+                // I tried and failed to eliminate bounds checks in safe code.
+                // This is safe because of our loop invariant: pos is always
+                // <= len-32.
+                let p = haystack.get_unchecked(pos..);
+                self.vb.u8x32_load_unchecked_unaligned(p)
+            };
+            // N.B. `res0` is our `C` in the module documentation.
+            let res0 = self.masks.members1(h);
+            // Only do expensive verification if there are any non-zero bits.
+            let bitfield = res0.ne(zero).movemask();
+            if bitfield != 0 {
+                if let Some(m) = self.verify(haystack, pos, res0, bitfield) {
+                    return Some(m);
+                }
+            }
+            pos += BLOCK_SIZE;
+        }
+        self.slow(haystack, pos)
+    }
+
+    /// `find2` is used when there are 2 masks, e.g., the fingerprint is 2 bytes
+    /// long.
+    #[inline(always)]
+    fn find2(&self, haystack: &[u8]) -> Option<Match> {
+        // This is an exotic way to right shift a SIMD vector across lanes.
+        // See below at use for more details.
+        let zero = self.vb.u8x32_splat(0);
+        let len = haystack.len();
+        // The previous value of `C` (from the module documentation) for the
+        // *first* byte in the fingerprint. On subsequent iterations, we take
+        // the last bitset from the previous `C` and insert it into the first
+        // position of the current `C`, shifting all other bitsets to the right
+        // one lane. This causes `C` for the first byte to line up with `C` for
+        // the second byte, so that they can be `AND`'d together.
+        let mut prev0 = self.vb.u8x32_splat(0xFF);
+        let mut pos = 1;
+        debug_assert!(len >= BLOCK_SIZE);
+        while pos <= len - BLOCK_SIZE {
+            let h = unsafe {
+                // I tried and failed to eliminate bounds checks in safe code.
+                // This is safe because of our loop invariant: pos is always
+                // <= len-32.
+                let p = haystack.get_unchecked(pos..);
+                self.vb.u8x32_load_unchecked_unaligned(p)
+            };
+            let (res0, res1) = self.masks.members2(h);
+
+            // Do this:
+            //
+            //     (prev0 << 15) | (res0 >> 1)
+            //
+            // This lets us line up our C values for each byte.
+            let res0prev0 = res0.alignr_15(prev0);
+
+            // `AND`'s our `C` values together.
+            let res = res0prev0.and(res1);
+            prev0 = res0;
+
+            let bitfield = res.ne(zero).movemask();
+            if bitfield != 0 {
+                let pos = pos.checked_sub(1).unwrap();
+                if let Some(m) = self.verify(haystack, pos, res, bitfield) {
+                    return Some(m);
+                }
+            }
+            pos += BLOCK_SIZE;
+        }
+        // The windowing above doesn't check the last byte in the last
+        // window, so start the slow search at the last byte of the last
+        // window.
+        self.slow(haystack, pos.checked_sub(1).unwrap())
+    }
+
+    /// `find3` is used when there are 3 masks, e.g., the fingerprint is 3 bytes
+    /// long.
+    ///
+    /// N.B. This is a straight-forward extrapolation of `find2`. The only
+    /// difference is that we need to keep track of two previous values of `C`,
+    /// since we now need to align for three bytes.
+    #[inline(always)]
+    fn find3(&self, haystack: &[u8]) -> Option<Match> {
+        let zero = self.vb.u8x32_splat(0);
+        let len = haystack.len();
+        let mut prev0 = self.vb.u8x32_splat(0xFF);
+        let mut prev1 = self.vb.u8x32_splat(0xFF);
+        let mut pos = 2;
+
+        while pos <= len - BLOCK_SIZE {
+            let h = unsafe {
+                // I tried and failed to eliminate bounds checks in safe code.
+                // This is safe because of our loop invariant: pos is always
+                // <= len-32.
+                let p = haystack.get_unchecked(pos..);
+                self.vb.u8x32_load_unchecked_unaligned(p)
+            };
+            let (res0, res1, res2) = self.masks.members3(h);
+
+            let res0prev0 = res0.alignr_14(prev0);
+            let res1prev1 = res1.alignr_15(prev1);
+            let res = res0prev0.and(res1prev1).and(res2);
+
+            prev0 = res0;
+            prev1 = res1;
+
+            let bitfield = res.ne(zero).movemask();
+            if bitfield != 0 {
+                let pos = pos.checked_sub(2).unwrap();
+                if let Some(m) = self.verify(haystack, pos, res, bitfield) {
+                    return Some(m);
+                }
+            }
+            pos += BLOCK_SIZE;
+        }
+        // The windowing above doesn't check the last two bytes in the last
+        // window, so start the slow search at the penultimate byte of the
+        // last window.
+        // self.slow(haystack, pos.saturating_sub(2))
+        self.slow(haystack, pos.checked_sub(2).unwrap())
+    }
+
+    /// Runs the verification procedure on `res` (i.e., `C` from the module
+    /// documentation), where the haystack block starts at `pos` in
+    /// `haystack`. `bitfield` has ones in the bit positions that `res` has
+    /// non-zero bytes.
+    ///
+    /// If a match exists, it returns the first one.
+    #[inline(always)]
+    fn verify(
+        &self,
+        haystack: &[u8],
+        pos: usize,
+        res: u8x32,
+        mut bitfield: u32,
+    ) -> Option<Match> {
+        let patterns = res.bytes();
+        while bitfield != 0 {
+            // The next offset, relative to pos, where some fingerprint
+            // matched.
+            let byte_pos = bitfield.trailing_zeros() as usize;
+            bitfield &= !(1 << byte_pos);
+
+            // Offset relative to the beginning of the haystack.
+            let start = pos + byte_pos;
+
+            // The bitfield telling us which patterns had fingerprints that
+            // match at this starting position.
+            let mut patterns = patterns[byte_pos];
+            while patterns != 0 {
+                let bucket = patterns.trailing_zeros() as usize;
+                patterns &= !(1 << bucket);
+
+                // Actual substring search verification.
+                if let Some(m) = self.verify_bucket(haystack, bucket, start) {
+                    return Some(m);
+                }
+            }
+        }
+
+        None
+    }
+
+    /// Verifies whether any substring in the given bucket matches in haystack
+    /// at the given starting position.
+    #[inline(always)]
+    fn verify_bucket(
+        &self,
+        haystack: &[u8],
+        bucket: usize,
+        start: usize,
+    ) -> Option<Match> {
+        // This cycles through the patterns in the bucket in the order that
+        // the patterns were given. Therefore, we guarantee leftmost-first
+        // semantics.
+        for &pati in &self.buckets[bucket] {
+            let pat = &*self.pats[pati];
+            if start + pat.len() > haystack.len() {
+                continue;
+            }
+            if pat == &haystack[start..start + pat.len()] {
+                return Some(Match {
+                    pat: pati,
+                    start: start,
+                    end: start + pat.len(),
+                });
+            }
+        }
+        None
+    }
+
+    /// Slow substring search through all patterns in this matcher.
+    ///
+    /// This is used when we don't have enough bytes in the haystack for our
+    /// block based approach.
+    #[inline(never)]
+    fn slow(&self, haystack: &[u8], pos: usize) -> Option<Match> {
+        self.ac.find(&haystack[pos..]).map(|m| {
+            Match {
+                pat: m.pattern(),
+                start: pos + m.start(),
+                end: pos + m.end(),
+            }
+        })
+    }
+}
+
+/// A list of masks. This has length equal to the length of the fingerprint.
+/// The length of the fingerprint is always `min(3, len(smallest_substring))`.
+#[derive(Debug, Clone)]
+struct Masks {
+    vb: AVX2VectorBuilder,
+    masks: [Mask; 3],
+    size: usize,
+}
+
+impl Masks {
+    /// Create a new set of masks of size `n`, where `n` corresponds to the
+    /// number of bytes in a fingerprint.
+    fn new(vb: AVX2VectorBuilder, n: usize) -> Masks {
+        Masks {
+            vb: vb,
+            masks: [Mask::new(vb), Mask::new(vb), Mask::new(vb)],
+            size: n,
+        }
+    }
+
+    /// Returns the number of masks.
+    fn len(&self) -> usize {
+        self.size
+    }
+
+    /// Adds the given pattern to the given bucket. The bucket should be a
+    /// power of `2 <= 2^7`.
+    fn add(&mut self, bucket: u8, pat: &[u8]) {
+        for i in 0..self.len() {
+            self.masks[i].add(bucket, pat[i]);
+        }
+    }
+
+    /// Finds the fingerprints that are in the given haystack block. i.e., this
+    /// returns `C` as described in the module documentation.
+    ///
+    /// More specifically, `for i in 0..16` and `j in 0..8, C[i][j] == 1` if and
+    /// only if `haystack_block[i]` corresponds to a fingerprint that is part
+    /// of a pattern in bucket `j`.
+    #[inline(always)]
+    fn members1(&self, haystack_block: u8x32) -> u8x32 {
+        let masklo = self.vb.u8x32_splat(0xF);
+        let hlo = haystack_block.and(masklo);
+        let hhi = haystack_block.bit_shift_right_4().and(masklo);
+
+        self.masks[0].lo.shuffle(hlo).and(self.masks[0].hi.shuffle(hhi))
+    }
+
+    /// Like members1, but computes C for the first and second bytes in the
+    /// fingerprint.
+    #[inline(always)]
+    fn members2(&self, haystack_block: u8x32) -> (u8x32, u8x32) {
+        let masklo = self.vb.u8x32_splat(0xF);
+        let hlo = haystack_block.and(masklo);
+        let hhi = haystack_block.bit_shift_right_4().and(masklo);
+
+        let res0 =
+            self.masks[0].lo.shuffle(hlo).and(self.masks[0].hi.shuffle(hhi));
+        let res1 =
+            self.masks[1].lo.shuffle(hlo).and(self.masks[1].hi.shuffle(hhi));
+        (res0, res1)
+    }
+
+    /// Like `members1`, but computes `C` for the first, second and third bytes
+    /// in the fingerprint.
+    #[inline(always)]
+    fn members3(&self, haystack_block: u8x32) -> (u8x32, u8x32, u8x32) {
+        let masklo = self.vb.u8x32_splat(0xF);
+        let hlo = haystack_block.and(masklo);
+        let hhi = haystack_block.bit_shift_right_4().and(masklo);
+
+        let res0 =
+            self.masks[0].lo.shuffle(hlo).and(self.masks[0].hi.shuffle(hhi));
+        let res1 =
+            self.masks[1].lo.shuffle(hlo).and(self.masks[1].hi.shuffle(hhi));
+        let res2 =
+            self.masks[2].lo.shuffle(hlo).and(self.masks[2].hi.shuffle(hhi));
+        (res0, res1, res2)
+    }
+}
+
+/// A single mask.
+#[derive(Debug, Clone, Copy)]
+struct Mask {
+    /// Bitsets for the low nybbles in a fingerprint.
+    lo: u8x32,
+    /// Bitsets for the high nybbles in a fingerprint.
+    hi: u8x32,
+}
+
+impl Mask {
+    /// Create a new mask with no members.
+    fn new(vb: AVX2VectorBuilder) -> Mask {
+        Mask {
+            lo: vb.u8x32_splat(0),
+            hi: vb.u8x32_splat(0),
+        }
+    }
+
+    /// Adds the given byte to the given bucket.
+    fn add(&mut self, bucket: u8, byte: u8) {
+        // Split our byte into two nybbles, and add each nybble to our
+        // mask.
+        let byte_lo = (byte & 0xF) as usize;
+        let byte_hi = (byte >> 4) as usize;
+
+        {
+            let mut lo_bytes = self.lo.bytes();
+            let lo = lo_bytes[byte_lo] | ((1 << bucket) as u8);
+            lo_bytes[byte_lo] = lo;
+            lo_bytes[byte_lo + 16] = lo;
+            self.lo.replace_bytes(lo_bytes);
+        }
+
+        {
+            let mut hi_bytes = self.hi.bytes();
+            let hi = hi_bytes[byte_hi] | ((1 << bucket) as u8);
+            hi_bytes[byte_hi] = hi;
+            hi_bytes[byte_hi + 16] = hi;
+            self.hi.replace_bytes(hi_bytes);
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/literal/teddy_avx2/mod.rs.html b/target/doc/src/regex/literal/teddy_avx2/mod.rs.html new file mode 100644 index 0000000..107c749 --- /dev/null +++ b/target/doc/src/regex/literal/teddy_avx2/mod.rs.html @@ -0,0 +1,19 @@ +mod.rs.html -- source
1
+2
+3
+4
+5
+6
+7
+8
+
+pub use self::imp::*;
+
+#[cfg(target_arch = "x86_64")]
+mod imp;
+
+#[cfg(not(target_arch = "x86_64"))]
+#[path = "fallback.rs"]
+mod imp;
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/literal/teddy_ssse3/imp.rs.html b/target/doc/src/regex/literal/teddy_ssse3/imp.rs.html new file mode 100644 index 0000000..378f3e0 --- /dev/null +++ b/target/doc/src/regex/literal/teddy_ssse3/imp.rs.html @@ -0,0 +1,1581 @@ +imp.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+
+/*!
+Teddy is a simd accelerated multiple substring matching algorithm. The name
+and the core ideas in the algorithm were learned from the [Hyperscan][1_u]
+project.
+
+
+Background
+----------
+
+The key idea of Teddy is to do *packed* substring matching. In the literature,
+packed substring matching is the idea of examining multiple bytes in a haystack
+at a time to detect matches. Implementations of, for example, memchr (which
+detects matches of a single byte) have been doing this for years. Only
+recently, with the introduction of various SIMD instructions, has this been
+extended to substring matching. The PCMPESTRI instruction (and its relatives),
+for example, implements substring matching in hardware. It is, however, limited
+to substrings of length 16 bytes or fewer, but this restriction is fine in a
+regex engine, since we rarely care about the performance difference between
+searching for a 16 byte literal and a 16 + N literal; 16 is already long
+enough. The key downside of the PCMPESTRI instruction, on current (2016) CPUs
+at least, is its latency and throughput. As a result, it is often faster to do
+substring search with a Boyer-Moore variant and a well placed memchr to quickly
+skip through the haystack.
+
+There are fewer results from the literature on packed substring matching,
+and even fewer for packed multiple substring matching. Ben-Kiki et al. [2]
+describes use of PCMPESTRI for substring matching, but is mostly theoretical
+and hand-waves performance. There is other theoretical work done by Bille [3]
+as well.
+
+The rest of the work in the field, as far as I'm aware, is by Faro and Kulekci
+and is generally focused on multiple pattern search. Their first paper [4a]
+introduces the concept of a fingerprint, which is computed for every block of
+N bytes in every pattern. The haystack is then scanned N bytes at a time and
+a fingerprint is computed in the same way it was computed for blocks in the
+patterns. If the fingerprint corresponds to one that was found in a pattern,
+then a verification step follows to confirm that one of the substrings with the
+corresponding fingerprint actually matches at the current location. Various
+implementation tricks are employed to make sure the fingerprint lookup is fast;
+typically by truncating the fingerprint. (This may, of course, provoke more
+steps in the verification process, so a balance must be struck.)
+
+The main downside of [4a] is that the minimum substring length is 32 bytes,
+presumably because of how the algorithm uses certain SIMD instructions. This
+essentially makes it useless for general purpose regex matching, where a small
+number of short patterns is far more likely.
+
+Faro and Kulekci published another paper [4b] that is conceptually very similar
+to [4a]. The key difference is that it uses the CRC32 instruction (introduced
+as part of SSE 4.2) to compute fingerprint values. This also enables the
+algorithm to work effectively on substrings as short as 7 bytes with 4 byte
+windows. 7 bytes is unfortunately still too long. The window could be
+technically shrunk to 2 bytes, thereby reducing minimum length to 3, but the
+small window size ends up negating most performance benefits—and it's likely
+the common case in a general purpose regex engine.
+
+Faro and Kulekci also published [4c] that appears to be intended as a
+replacement to using PCMPESTRI. In particular, it is specifically motivated by
+the high throughput/latency time of PCMPESTRI and therefore chooses other SIMD
+instructions that are faster. While this approach works for short substrings,
+I personally couldn't see a way to generalize it to multiple substring search.
+
+Faro and Kulekci have another paper [4d] that I haven't been able to read
+because it is behind a paywall.
+
+
+Teddy
+-----
+
+Finally, we get to Teddy. If the above literature review is complete, then it
+appears that Teddy is a novel algorithm. More than that, in my experience, it
+completely blows away the competition for short substrings, which is exactly
+what we want in a general purpose regex engine. Again, the algorithm appears
+to be developed by the authors of [Hyperscan][1_u]. Hyperscan was open sourced
+late 2015, and no earlier history could be found. Therefore, tracking the exact
+provenance of the algorithm with respect to the published literature seems
+difficult.
+
+DISCLAIMER: My understanding of Teddy is limited to reading auto-generated C
+code, its disassembly and observing its runtime behavior.
+
+At a high level, Teddy works somewhat similarly to the fingerprint algorithms
+published by Faro and Kulekci, but Teddy does it in a way that scales a bit
+better. Namely:
+
+1. Teddy's core algorithm scans the haystack in 16 byte chunks. 16 is
+   significant because it corresponds to the number of bytes in a SIMD vector.
+   If one used AVX2 instructions, then we could scan the haystack in 32 byte
+   chunks. Similarly, if one used AVX512 instructions, we could scan the
+   haystack in 64 byte chunks. Hyperscan implements SSE + AVX2, we only
+   implement SSE for the moment.
+2. Bitwise operations are performed on each chunk to discover if any region of
+   it matches a set of precomputed fingerprints from the patterns. If there are
+   matches, then a verification step is performed. In this implementation, our
+   verification step is naive. This can be improved upon.
+
+The details to make this work are quite clever. First, we must choose how to
+pick our fingerprints. In Hyperscan's implementation, I *believe* they use the
+last N bytes of each substring, where N must be at least the minimum length of
+any substring in the set being searched. In this implementation, we use the
+first N bytes of each substring. (The tradeoffs between these choices aren't
+yet clear to me.) We then must figure out how to quickly test whether an
+occurrence of any fingerprint from the set of patterns appears in a 16 byte
+block from the haystack. To keep things simple, let's assume N = 1 and examine
+some examples to motivate the approach. Here are our patterns:
+
+```ignore
+foo
+bar
+baz
+```
+
+The corresponding fingerprints, for N = 1, are `f`, `b` and `b`. Now let's set
+our 16 byte block to:
+
+```ignore
+bat cat foo bump
+xxxxxxxxxxxxxxxx
+```
+
+To cut to the chase, Teddy works by using bitsets. In particular, Teddy creates
+a mask that allows us to quickly compute membership of a fingerprint in a 16
+byte block that also tells which pattern the fingerprint corresponds to. In
+this case, our fingerprint is a single byte, so an appropriate abstraction is
+a map from a single byte to a list of patterns that contain that fingerprint:
+
+```ignore
+f |--> foo
+b |--> bar, baz
+```
+
+Now, all we need to do is figure out how to represent this map in vector space
+and use normal SIMD operations to perform a lookup. The first simplification
+we can make is to represent our patterns as bit fields occupying a single
+byte. This is important, because a single SIMD vector can store 16 bytes.
+
+```ignore
+f |--> 00000001
+b |--> 00000010, 00000100
+```
+
+How do we perform lookup though? It turns out that SSSE3 introduced a very cool
+instruction called PSHUFB. The instruction takes two SIMD vectors, `A` and `B`,
+and returns a third vector `C`. All vectors are treated as 16 8-bit integers.
+`C` is formed by `C[i] = A[B[i]]`. (This is a bit of a simplification, but true
+for the purposes of this algorithm. For full details, see [Intel's Intrinsics
+Guide][5_u].) This essentially lets us use the values in `B` to lookup values
+in `A`.
+
+If we could somehow cause `B` to contain our 16 byte block from the haystack,
+and if `A` could contain our bitmasks, then we'd end up with something like
+this for `A`:
+
+```ignore
+    0x00 0x01 ... 0x62      ... 0x66      ... 0xFF
+A = 0    0        00000110      00000001      0
+```
+
+And if `B` contains our window from our haystack, we could use shuffle to take
+the values from `B` and use them to look up our bitsets in `A`. But of course,
+we can't do this because `A` in the above example contains 256 bytes, which
+is much larger than the size of a SIMD vector.
+
+Nybbles to the rescue! A nybble is 4 bits. Instead of one mask to hold all of
+our bitsets, we can use two masks, where one mask corresponds to the lower four
+bits of our fingerprint and the other mask corresponds to the upper four bits.
+So our map now looks like:
+
+```ignore
+'f' & 0xF = 0x6 |--> 00000001
+'f' >> 4  = 0x6 |--> 00000111
+'b' & 0xF = 0x2 |--> 00000110
+'b' >> 4  = 0x6 |--> 00000111
+```
+
+Notice that the bitsets for each nybble correspond to the union of all
+fingerprints that contain that nybble. For example, both `f` and `b` have the
+same upper 4 bits but differ on the lower 4 bits. Putting this together, we
+have `A0`, `A1` and `B`, where `A0` is our mask for the lower nybble, `A1` is
+our mask for the upper nybble and `B` is our 16 byte block from the haystack:
+
+```ignore
+      0x00 0x01 0x02      0x03 ... 0x06      ... 0xF
+A0 =  0    0    00000110  0        00000001      0
+A1 =  0    0    0         0        00000111      0
+B  =  b    a    t         _        t             p
+B  =  0x62 0x61 0x74      0x20     0x74          0x70
+```
+
+But of course, we can't use `B` with `PSHUFB` yet, since its values are 8 bits,
+and we need indexes that are at most 4 bits (corresponding to one of 16
+values). We can apply the same transformation to split `B` into lower and upper
+nybbles as we did `A`. As before, `B0` corresponds to the lower nybbles and
+`B1` corresponds to the upper nybbles:
+
+```ignore
+     b   a   t   _   c   a   t   _   f   o   o   _   b   u   m   p
+B0 = 0x2 0x1 0x4 0x0 0x3 0x1 0x4 0x0 0x6 0xF 0xF 0x0 0x2 0x5 0xD 0x0
+B1 = 0x6 0x6 0x7 0x2 0x6 0x6 0x7 0x2 0x6 0x6 0x6 0x2 0x6 0x7 0x6 0x7
+```
+
+And now we have a nice correspondence. `B0` can index `A0` and `B1` can index
+`A1`. Here's what we get when we apply `C0 = PSHUFB(A0, B0)`:
+
+```ignore
+     b         a        ... f         o         ... p
+     A0[0x2]   A0[0x1]      A0[0x6]   A0[0xF]       A0[0x0]
+C0 = 00000110  0            00000001  0             0
+```
+
+And `C1 = PSHUFB(A1, B1)`:
+
+```ignore
+     b         a        ... f         o        ... p
+     A1[0x6]   A1[0x6]      A1[0x6]   A1[0x6]      A1[0x7]
+C1 = 00000111  00000111     00000111  00000111     0
+```
+
+Notice how neither one of `C0` or `C1` is guaranteed to report fully correct
+results all on its own. For example, `C1` claims that `b` is a fingerprint for
+the pattern `foo` (since `A1[0x6] = 00000111`), and that `o` is a fingerprint
+for all of our patterns. But if we combined `C0` and `C1` with an `AND`
+operation:
+
+```ignore
+     b         a        ... f         o        ... p
+C  = 00000110  0            00000001  0            0
+```
+
+Then we now have that `C[i]` contains a bitset corresponding to the matching
+fingerprints in a haystack's 16 byte block, where `i` is the `ith` byte in that
+block.
+
+Once we have that, we can look for the position of the least significant bit
+in `C`. That position, modulo `8`, gives us the pattern that the fingerprint
+matches. That position, integer divided by `8`, also gives us the byte offset
+that the fingerprint occurs in inside the 16 byte haystack block. Using those
+two pieces of information, we can run a verification procedure that tries
+to match all substrings containing that fingerprint at that position in the
+haystack.
+
+
+Implementation notes
+--------------------
+
+The problem with the algorithm as described above is that it uses a single byte
+for a fingerprint. This will work well if the fingerprints are rare in the
+haystack (e.g., capital letters or special characters in normal English text),
+but if the fingerprints are common, you'll wind up spending too much time in
+the verification step, which effectively negate the performance benefits of
+scanning 16 bytes at a time. Remember, the key to the performance of this
+algorithm is to do as little work as possible per 16 bytes.
+
+This algorithm can be extrapolated in a relatively straight-forward way to use
+larger fingerprints. That is, instead of a single byte prefix, we might use a
+three byte prefix. The implementation below implements N = {1, 2, 3} and always
+picks the largest N possible. The rationale is that the bigger the fingerprint,
+the fewer verification steps we'll do. Of course, if N is too large, then we'll
+end up doing too much on each step.
+
+The way to extend it is:
+
+1. Add a mask for each byte in the fingerprint. (Remember that each mask is
+   composed of two SIMD vectors.) This results in a value of `C` for each byte
+   in the fingerprint while searching.
+2. When testing each 16 byte block, each value of `C` must be shifted so that
+   they are aligned. Once aligned, they should all be `AND`'d together. This
+   will give you only the bitsets corresponding to the full match of the
+   fingerprint.
+
+The implementation below is commented to fill in the nitty gritty details.
+
+References
+----------
+
+- **[1]** [Hyperscan on GitHub](https://github.com/01org/hyperscan),
+    [webpage](https://01.org/hyperscan)
+- **[2a]** Ben-Kiki, O., Bille, P., Breslauer, D., Gasieniec, L., Grossi, R.,
+    & Weimann, O. (2011).
+    _Optimal packed string matching_.
+    In LIPIcs-Leibniz International Proceedings in Informatics (Vol. 13).
+    Schloss Dagstuhl-Leibniz-Zentrum fuer Informatik.
+    DOI: 10.4230/LIPIcs.FSTTCS.2011.423.
+    [PDF](http://drops.dagstuhl.de/opus/volltexte/2011/3355/pdf/37.pdf).
+- **[2b]** Ben-Kiki, O., Bille, P., Breslauer, D., Ga̧sieniec, L., Grossi, R.,
+    & Weimann, O. (2014).
+    _Towards optimal packed string matching_.
+    Theoretical Computer Science, 525, 111-129.
+    DOI: 10.1016/j.tcs.2013.06.013.
+    [PDF](http://www.cs.haifa.ac.il/~oren/Publications/bpsm.pdf).
+- **[3]** Bille, P. (2011).
+    _Fast searching in packed strings_.
+    Journal of Discrete Algorithms, 9(1), 49-56.
+    DOI: 10.1016/j.jda.2010.09.003.
+    [PDF](http://www.sciencedirect.com/science/article/pii/S1570866710000353).
+- **[4a]** Faro, S., & Külekci, M. O. (2012, October).
+    _Fast multiple string matching using streaming SIMD extensions technology_.
+    In String Processing and Information Retrieval (pp. 217-228).
+    Springer Berlin Heidelberg.
+    DOI: 10.1007/978-3-642-34109-0_23.
+    [PDF](http://www.dmi.unict.it/~faro/papers/conference/faro32.pdf).
+- **[4b]** Faro, S., & Külekci, M. O. (2013, September).
+    _Towards a Very Fast Multiple String Matching Algorithm for Short Patterns_.
+    In Stringology (pp. 78-91).
+    [PDF](http://www.dmi.unict.it/~faro/papers/conference/faro36.pdf).
+- **[4c]** Faro, S., & Külekci, M. O. (2013, January).
+    _Fast packed string matching for short patterns_.
+    In Proceedings of the Meeting on Algorithm Engineering & Expermiments
+    (pp. 113-121).
+    Society for Industrial and Applied Mathematics.
+    [PDF](http://arxiv.org/pdf/1209.6449.pdf).
+- **[4d]** Faro, S., & Külekci, M. O. (2014).
+    _Fast and flexible packed string matching_.
+    Journal of Discrete Algorithms, 28, 61-72.
+    DOI: 10.1016/j.jda.2014.07.003.
+
+[1_u]: https://github.com/01org/hyperscan
+[5_u]: https://software.intel.com/sites/landingpage/IntrinsicsGuide
+*/
+
+use std::cmp;
+
+use aho_corasick::{self, AhoCorasick, AhoCorasickBuilder};
+use syntax::hir::literal::Literals;
+
+use vector::ssse3::{SSSE3VectorBuilder, u8x16};
+
+/// Corresponds to the number of bytes read at a time in the haystack.
+const BLOCK_SIZE: usize = 16;
+
+/// Match reports match information.
+#[derive(Debug, Clone)]
+pub struct Match {
+    /// The index of the pattern that matched. The index is in correspondence
+    /// with the order of the patterns given at construction.
+    pub pat: usize,
+    /// The start byte offset of the match.
+    pub start: usize,
+    /// The end byte offset of the match. This is always `start + pat.len()`.
+    pub end: usize,
+}
+
+/// A SIMD accelerated multi substring searcher.
+#[derive(Debug, Clone)]
+pub struct Teddy {
+    /// A builder for SSSE3 empowered vectors.
+    vb: SSSE3VectorBuilder,
+    /// A list of substrings to match.
+    pats: Vec<Vec<u8>>,
+    /// An Aho-Corasick automaton of the patterns. We use this when we need to
+    /// search pieces smaller than the Teddy block size.
+    ac: AhoCorasick,
+    /// A set of 8 buckets. Each bucket corresponds to a single member of a
+    /// bitset. A bucket contains zero or more substrings. This is useful
+    /// when the number of substrings exceeds 8, since our bitsets cannot have
+    /// more than 8 members.
+    buckets: Vec<Vec<usize>>,
+    /// Our set of masks. There's one mask for each byte in the fingerprint.
+    masks: Masks,
+}
+
+impl Teddy {
+    /// Returns true if and only if Teddy is supported on this platform.
+    ///
+    /// If this returns `false`, then `Teddy::new(...)` is guaranteed to
+    /// return `None`.
+    pub fn available() -> bool {
+        SSSE3VectorBuilder::new().is_some()
+    }
+
+    /// Create a new `Teddy` multi substring matcher.
+    ///
+    /// If a `Teddy` matcher could not be created (e.g., `pats` is empty or has
+    /// an empty substring), then `None` is returned.
+    pub fn new(pats: &Literals) -> Option<Teddy> {
+        let vb = match SSSE3VectorBuilder::new() {
+            None => return None,
+            Some(vb) => vb,
+        };
+        if !Teddy::available() {
+            return None;
+        }
+
+        let pats: Vec<_> = pats.literals().iter().map(|p|p.to_vec()).collect();
+        let min_len = pats.iter().map(|p| p.len()).min().unwrap_or(0);
+        // Don't allow any empty patterns and require that we have at
+        // least one pattern.
+        if min_len < 1 {
+            return None;
+        }
+        // Pick the largest mask possible, but no larger than 3.
+        let nmasks = cmp::min(3, min_len);
+        let mut masks = Masks::new(vb, nmasks);
+        let mut buckets = vec![vec![]; 8];
+        // Assign a substring to each bucket, and add the bucket's bitfield to
+        // the appropriate position in the mask.
+        for (pati, pat) in pats.iter().enumerate() {
+            let bucket = pati % 8;
+            buckets[bucket].push(pati);
+            masks.add(bucket as u8, pat);
+        }
+        let ac = AhoCorasickBuilder::new()
+            .match_kind(aho_corasick::MatchKind::LeftmostFirst)
+            .dfa(true)
+            .prefilter(false)
+            .build(&pats);
+        Some(Teddy {
+            vb: vb,
+            pats: pats.to_vec(),
+            ac: ac,
+            buckets: buckets,
+            masks: masks,
+        })
+    }
+
+    /// Returns all of the substrings matched by this `Teddy`.
+    pub fn patterns(&self) -> &[Vec<u8>] {
+        &self.pats
+    }
+
+    /// Returns the number of substrings in this matcher.
+    pub fn len(&self) -> usize {
+        self.pats.len()
+    }
+
+    /// Returns the approximate size on the heap used by this matcher.
+    pub fn approximate_size(&self) -> usize {
+        self.pats.iter().fold(0, |a, b| a + b.len())
+    }
+
+    /// Searches `haystack` for the substrings in this `Teddy`. If a match was
+    /// found, then it is returned. Otherwise, `None` is returned.
+    pub fn find(&self, haystack: &[u8]) -> Option<Match> {
+        // This is safe because the only way we can construct a Teddy type
+        // is if SSSE3 is available.
+        unsafe { self.find_impl(haystack) }
+    }
+
+    #[allow(unused_attributes)]
+    #[target_feature(enable = "ssse3")]
+    unsafe fn find_impl(&self, haystack: &[u8]) -> Option<Match> {
+        // If our haystack is smaller than the block size, then fall back to
+        // a naive brute force search.
+        if haystack.is_empty() || haystack.len() < (BLOCK_SIZE + 2) {
+            return self.slow(haystack, 0);
+        }
+        match self.masks.len() {
+            0 => None,
+            1 => self.find1(haystack),
+            2 => self.find2(haystack),
+            3 => self.find3(haystack),
+            _ => unreachable!(),
+        }
+    }
+
+    /// `find1` is used when there is only 1 mask. This is the easy case and is
+    /// pretty much as described in the module documentation.
+    #[inline(always)]
+    fn find1(&self, haystack: &[u8]) -> Option<Match> {
+        let mut pos = 0;
+        let zero = self.vb.u8x16_splat(0);
+        let len = haystack.len();
+        debug_assert!(len >= BLOCK_SIZE);
+        while pos <= len - BLOCK_SIZE {
+            let h = unsafe {
+                // I tried and failed to eliminate bounds checks in safe code.
+                // This is safe because of our loop invariant: pos is always
+                // <= len-16.
+                let p = haystack.get_unchecked(pos..);
+                self.vb.u8x16_load_unchecked_unaligned(p)
+            };
+            // N.B. `res0` is our `C` in the module documentation.
+            let res0 = self.masks.members1(h);
+            // Only do expensive verification if there are any non-zero bits.
+            let bitfield = res0.ne(zero).movemask();
+            if bitfield != 0 {
+                if let Some(m) = self.verify(haystack, pos, res0, bitfield) {
+                    return Some(m);
+                }
+            }
+            pos += BLOCK_SIZE;
+        }
+        self.slow(haystack, pos)
+    }
+
+    /// `find2` is used when there are 2 masks, e.g., the fingerprint is 2 bytes
+    /// long.
+    #[inline(always)]
+    fn find2(&self, haystack: &[u8]) -> Option<Match> {
+        // This is an exotic way to right shift a SIMD vector across lanes.
+        // See below at use for more details.
+        let zero = self.vb.u8x16_splat(0);
+        let len = haystack.len();
+        // The previous value of `C` (from the module documentation) for the
+        // *first* byte in the fingerprint. On subsequent iterations, we take
+        // the last bitset from the previous `C` and insert it into the first
+        // position of the current `C`, shifting all other bitsets to the right
+        // one lane. This causes `C` for the first byte to line up with `C` for
+        // the second byte, so that they can be `AND`'d together.
+        let mut prev0 = self.vb.u8x16_splat(0xFF);
+        let mut pos = 1;
+        debug_assert!(len >= BLOCK_SIZE);
+        while pos <= len - BLOCK_SIZE {
+            let h = unsafe {
+                // I tried and failed to eliminate bounds checks in safe code.
+                // This is safe because of our loop invariant: pos is always
+                // <= len-16.
+                let p = haystack.get_unchecked(pos..);
+                self.vb.u8x16_load_unchecked_unaligned(p)
+            };
+            let (res0, res1) = self.masks.members2(h);
+
+            // Do this:
+            //
+            //     (prev0 << 15) | (res0 >> 1)
+            //
+            // This lets us line up our C values for each byte.
+            let res0prev0 = res0.alignr_15(prev0);
+
+            // `AND`'s our `C` values together.
+            let res = res0prev0.and(res1);
+            prev0 = res0;
+
+            let bitfield = res.ne(zero).movemask();
+            if bitfield != 0 {
+                let pos = pos.checked_sub(1).unwrap();
+                if let Some(m) = self.verify(haystack, pos, res, bitfield) {
+                    return Some(m);
+                }
+            }
+            pos += BLOCK_SIZE;
+        }
+        // The windowing above doesn't check the last byte in the last
+        // window, so start the slow search at the last byte of the last
+        // window.
+        self.slow(haystack, pos.checked_sub(1).unwrap())
+    }
+
+    /// `find3` is used when there are 3 masks, e.g., the fingerprint is 3 bytes
+    /// long.
+    ///
+    /// N.B. This is a straight-forward extrapolation of `find2`. The only
+    /// difference is that we need to keep track of two previous values of `C`,
+    /// since we now need to align for three bytes.
+    #[inline(always)]
+    fn find3(&self, haystack: &[u8]) -> Option<Match> {
+        let zero = self.vb.u8x16_splat(0);
+        let len = haystack.len();
+        let mut prev0 = self.vb.u8x16_splat(0xFF);
+        let mut prev1 = self.vb.u8x16_splat(0xFF);
+        let mut pos = 2;
+        while pos <= len - BLOCK_SIZE {
+            let h = unsafe {
+                // I tried and failed to eliminate bounds checks in safe code.
+                // This is safe because of our loop invariant: pos is always
+                // <= len-16.
+                let p = haystack.get_unchecked(pos..);
+                self.vb.u8x16_load_unchecked_unaligned(p)
+            };
+            let (res0, res1, res2) = self.masks.members3(h);
+
+            let res0prev0 = res0.alignr_14(prev0);
+            let res1prev1 = res1.alignr_15(prev1);
+            let res = res0prev0.and(res1prev1).and(res2);
+
+            prev0 = res0;
+            prev1 = res1;
+
+            let bitfield = res.ne(zero).movemask();
+            if bitfield != 0 {
+                let pos = pos.checked_sub(2).unwrap();
+                if let Some(m) = self.verify(haystack, pos, res, bitfield) {
+                    return Some(m);
+                }
+            }
+            pos += BLOCK_SIZE;
+        }
+        // The windowing above doesn't check the last two bytes in the last
+        // window, so start the slow search at the penultimate byte of the
+        // last window.
+        // self.slow(haystack, pos.saturating_sub(2))
+        self.slow(haystack, pos.checked_sub(2).unwrap())
+    }
+
+    /// Runs the verification procedure on `res` (i.e., `C` from the module
+    /// documentation), where the haystack block starts at `pos` in
+    /// `haystack`. `bitfield` has ones in the bit positions that `res` has
+    /// non-zero bytes.
+    ///
+    /// If a match exists, it returns the first one.
+    #[inline(always)]
+    fn verify(
+        &self,
+        haystack: &[u8],
+        pos: usize,
+        res: u8x16,
+        mut bitfield: u32,
+    ) -> Option<Match> {
+        let patterns = res.bytes();
+        while bitfield != 0 {
+            // The next offset, relative to pos, where some fingerprint
+            // matched.
+            let byte_pos = bitfield.trailing_zeros() as usize;
+            bitfield &= !(1 << byte_pos);
+
+            // Offset relative to the beginning of the haystack.
+            let start = pos + byte_pos;
+
+            // The bitfield telling us which patterns had fingerprints that
+            // match at this starting position.
+            let mut patterns = patterns[byte_pos];
+            while patterns != 0 {
+                let bucket = patterns.trailing_zeros() as usize;
+                patterns &= !(1 << bucket);
+
+                // Actual substring search verification.
+                if let Some(m) = self.verify_bucket(haystack, bucket, start) {
+                    return Some(m);
+                }
+            }
+        }
+
+        None
+    }
+
+    /// Verifies whether any substring in the given bucket matches in haystack
+    /// at the given starting position.
+    #[inline(always)]
+    fn verify_bucket(
+        &self,
+        haystack: &[u8],
+        bucket: usize,
+        start: usize,
+    ) -> Option<Match> {
+        // This cycles through the patterns in the bucket in the order that
+        // the patterns were given. Therefore, we guarantee leftmost-first
+        // semantics.
+        for &pati in &self.buckets[bucket] {
+            let pat = &*self.pats[pati];
+            if start + pat.len() > haystack.len() {
+                continue;
+            }
+            if pat == &haystack[start..start + pat.len()] {
+                return Some(Match {
+                    pat: pati,
+                    start: start,
+                    end: start + pat.len(),
+                });
+            }
+        }
+        None
+    }
+
+    /// Slow substring search through all patterns in this matcher.
+    ///
+    /// This is used when we don't have enough bytes in the haystack for our
+    /// block based approach.
+    #[inline(never)]
+    fn slow(&self, haystack: &[u8], pos: usize) -> Option<Match> {
+        self.ac.find(&haystack[pos..]).map(|m| {
+            Match {
+                pat: m.pattern(),
+                start: pos + m.start(),
+                end: pos + m.end(),
+            }
+        })
+    }
+}
+
+/// A list of masks. This has length equal to the length of the fingerprint.
+/// The length of the fingerprint is always `min(3, len(smallest_substring))`.
+#[derive(Debug, Clone)]
+struct Masks {
+    vb: SSSE3VectorBuilder,
+    masks: [Mask; 3],
+    size: usize,
+}
+
+impl Masks {
+    /// Create a new set of masks of size `n`, where `n` corresponds to the
+    /// number of bytes in a fingerprint.
+    fn new(vb: SSSE3VectorBuilder, n: usize) -> Masks {
+        Masks {
+            vb: vb,
+            masks: [Mask::new(vb), Mask::new(vb), Mask::new(vb)],
+            size: n,
+        }
+    }
+
+    /// Returns the number of masks.
+    fn len(&self) -> usize {
+        self.size
+    }
+
+    /// Adds the given pattern to the given bucket. The bucket should be a
+    /// power of `2 <= 2^7`.
+    fn add(&mut self, bucket: u8, pat: &[u8]) {
+        for i in 0..self.len() {
+            self.masks[i].add(bucket, pat[i]);
+        }
+    }
+
+    /// Finds the fingerprints that are in the given haystack block. i.e., this
+    /// returns `C` as described in the module documentation.
+    ///
+    /// More specifically, `for i in 0..16` and `j in 0..8, C[i][j] == 1` if and
+    /// only if `haystack_block[i]` corresponds to a fingerprint that is part
+    /// of a pattern in bucket `j`.
+    #[inline(always)]
+    fn members1(&self, haystack_block: u8x16) -> u8x16 {
+        let masklo = self.vb.u8x16_splat(0xF);
+        let hlo = haystack_block.and(masklo);
+        let hhi = haystack_block.bit_shift_right_4().and(masklo);
+
+        self.masks[0].lo.shuffle(hlo).and(self.masks[0].hi.shuffle(hhi))
+    }
+
+    /// Like members1, but computes C for the first and second bytes in the
+    /// fingerprint.
+    #[inline(always)]
+    fn members2(&self, haystack_block: u8x16) -> (u8x16, u8x16) {
+        let masklo = self.vb.u8x16_splat(0xF);
+        let hlo = haystack_block.and(masklo);
+        let hhi = haystack_block.bit_shift_right_4().and(masklo);
+
+        let res0 =
+            self.masks[0].lo.shuffle(hlo).and(self.masks[0].hi.shuffle(hhi));
+        let res1 =
+            self.masks[1].lo.shuffle(hlo).and(self.masks[1].hi.shuffle(hhi));
+        (res0, res1)
+    }
+
+    /// Like `members1`, but computes `C` for the first, second and third bytes
+    /// in the fingerprint.
+    #[inline(always)]
+    fn members3(&self, haystack_block: u8x16) -> (u8x16, u8x16, u8x16) {
+        let masklo = self.vb.u8x16_splat(0xF);
+        let hlo = haystack_block.and(masklo);
+        let hhi = haystack_block.bit_shift_right_4().and(masklo);
+
+        let res0 =
+            self.masks[0].lo.shuffle(hlo).and(self.masks[0].hi.shuffle(hhi));
+        let res1 =
+            self.masks[1].lo.shuffle(hlo).and(self.masks[1].hi.shuffle(hhi));
+        let res2 =
+            self.masks[2].lo.shuffle(hlo).and(self.masks[2].hi.shuffle(hhi));
+        (res0, res1, res2)
+    }
+}
+
+/// A single mask.
+#[derive(Debug, Clone, Copy)]
+struct Mask {
+    /// Bitsets for the low nybbles in a fingerprint.
+    lo: u8x16,
+    /// Bitsets for the high nybbles in a fingerprint.
+    hi: u8x16,
+}
+
+impl Mask {
+    /// Create a new mask with no members.
+    fn new(vb: SSSE3VectorBuilder) -> Mask {
+        Mask {
+            lo: vb.u8x16_splat(0),
+            hi: vb.u8x16_splat(0),
+        }
+    }
+
+    /// Adds the given byte to the given bucket.
+    fn add(&mut self, bucket: u8, byte: u8) {
+        // Split our byte into two nybbles, and add each nybble to our
+        // mask.
+        let byte_lo = (byte & 0xF) as usize;
+        let byte_hi = (byte >> 4) as usize;
+
+        {
+            let mut lo_bytes = self.lo.bytes();
+            let lo = lo_bytes[byte_lo];
+            lo_bytes[byte_lo] = ((1 << bucket) as u8) | lo;
+            self.lo.replace_bytes(lo_bytes);
+        }
+        {
+            let mut hi_bytes = self.hi.bytes();
+            let hi = hi_bytes[byte_hi];
+            hi_bytes[byte_hi] = ((1 << bucket) as u8) | hi;
+            self.hi.replace_bytes(hi_bytes);
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/literal/teddy_ssse3/mod.rs.html b/target/doc/src/regex/literal/teddy_ssse3/mod.rs.html new file mode 100644 index 0000000..2bdc44d --- /dev/null +++ b/target/doc/src/regex/literal/teddy_ssse3/mod.rs.html @@ -0,0 +1,19 @@ +mod.rs.html -- source
1
+2
+3
+4
+5
+6
+7
+8
+
+pub use self::imp::*;
+
+#[cfg(target_arch = "x86_64")]
+mod imp;
+
+#[cfg(not(target_arch = "x86_64"))]
+#[path = "fallback.rs"]
+mod imp;
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/pikevm.rs.html b/target/doc/src/regex/pikevm.rs.html new file mode 100644 index 0000000..2fb3553 --- /dev/null +++ b/target/doc/src/regex/pikevm.rs.html @@ -0,0 +1,763 @@ +pikevm.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This module implements the Pike VM. That is, it guarantees linear time
+// search of a regex on any text with memory use proportional to the size of
+// the regex.
+//
+// It is equal in power to the backtracking engine in this crate, except the
+// backtracking engine is typically faster on small regexes/texts at the
+// expense of a bigger memory footprint.
+//
+// It can do more than the DFA can (specifically, record capture locations
+// and execute Unicode word boundary assertions), but at a slower speed.
+// Specifically, the Pike VM exectues a DFA implicitly by repeatedly expanding
+// epsilon transitions. That is, the Pike VM engine can be in multiple states
+// at once where as the DFA is only ever in one state at a time.
+//
+// Therefore, the Pike VM is generally treated as the fallback when the other
+// matching engines either aren't feasible to run or are insufficient.
+
+use std::mem;
+
+use exec::ProgramCache;
+use input::{Input, InputAt};
+use prog::{Program, InstPtr};
+use re_trait::Slot;
+use sparse::SparseSet;
+
+/// An NFA simulation matching engine.
+#[derive(Debug)]
+pub struct Fsm<'r, I> {
+    /// The sequence of opcodes (among other things) that is actually executed.
+    ///
+    /// The program may be byte oriented or Unicode codepoint oriented.
+    prog: &'r Program,
+    /// An explicit stack used for following epsilon transitions. (This is
+    /// borrowed from the cache.)
+    stack: &'r mut Vec<FollowEpsilon>,
+    /// The input to search.
+    input: I,
+}
+
+/// A cached allocation that can be reused on each execution.
+#[derive(Clone, Debug)]
+pub struct Cache {
+    /// A pair of ordered sets for tracking NFA states.
+    clist: Threads,
+    nlist: Threads,
+    /// An explicit stack used for following epsilon transitions.
+    stack: Vec<FollowEpsilon>,
+}
+
+/// An ordered set of NFA states and their captures.
+#[derive(Clone, Debug)]
+struct Threads {
+    /// An ordered set of opcodes (each opcode is an NFA state).
+    set: SparseSet,
+    /// Captures for every NFA state.
+    ///
+    /// It is stored in row-major order, where the columns are the capture
+    /// slots and the rows are the states.
+    caps: Vec<Slot>,
+    /// The number of capture slots stored per thread. (Every capture has
+    /// two slots.)
+    slots_per_thread: usize,
+}
+
+/// A representation of an explicit stack frame when following epsilon
+/// transitions. This is used to avoid recursion.
+#[derive(Clone, Debug)]
+enum FollowEpsilon {
+    /// Follow transitions at the given instruction pointer.
+    IP(InstPtr),
+    /// Restore the capture slot with the given position in the input.
+    Capture { slot: usize, pos: Slot },
+}
+
+impl Cache {
+    /// Create a new allocation used by the NFA machine to record execution
+    /// and captures.
+    pub fn new(_prog: &Program) -> Self {
+        Cache {
+            clist: Threads::new(),
+            nlist: Threads::new(),
+            stack: vec![],
+        }
+    }
+}
+
+impl<'r, I: Input> Fsm<'r, I> {
+    /// Execute the NFA matching engine.
+    ///
+    /// If there's a match, `exec` returns `true` and populates the given
+    /// captures accordingly.
+    pub fn exec(
+        prog: &'r Program,
+        cache: &ProgramCache,
+        matches: &mut [bool],
+        slots: &mut [Slot],
+        quit_after_match: bool,
+        input: I,
+        start: usize,
+        end: usize,
+    ) -> bool {
+        let mut cache = cache.borrow_mut();
+        let cache = &mut cache.pikevm;
+        cache.clist.resize(prog.len(), prog.captures.len());
+        cache.nlist.resize(prog.len(), prog.captures.len());
+        let at = input.at(start);
+        Fsm {
+            prog: prog,
+            stack: &mut cache.stack,
+            input: input,
+        }.exec_(
+            &mut cache.clist,
+            &mut cache.nlist,
+            matches,
+            slots,
+            quit_after_match,
+            at,
+            end,
+        )
+    }
+
+    fn exec_(
+        &mut self,
+        mut clist: &mut Threads,
+        mut nlist: &mut Threads,
+        matches: &mut [bool],
+        slots: &mut [Slot],
+        quit_after_match: bool,
+        mut at: InputAt,
+        end: usize,
+    ) -> bool {
+        let mut matched = false;
+        let mut all_matched = false;
+        clist.set.clear();
+        nlist.set.clear();
+'LOOP:  loop {
+            if clist.set.is_empty() {
+                // Three ways to bail out when our current set of threads is
+                // empty.
+                //
+                // 1. We have a match---so we're done exploring any possible
+                //    alternatives. Time to quit. (We can't do this if we're
+                //    looking for matches for multiple regexes, unless we know
+                //    they all matched.)
+                //
+                // 2. If the expression starts with a '^' we can terminate as
+                //    soon as the last thread dies.
+                if (matched && matches.len() <= 1)
+                    || all_matched
+                    || (!at.is_start() && self.prog.is_anchored_start) {
+                    break;
+                }
+
+                // 3. If there's a literal prefix for the program, try to
+                //    jump ahead quickly. If it can't be found, then we can
+                //    bail out early.
+                if !self.prog.prefixes.is_empty() {
+                    at = match self.input.prefix_at(&self.prog.prefixes, at) {
+                        None => break,
+                        Some(at) => at,
+                    };
+                }
+            }
+
+            // This simulates a preceding '.*?' for every regex by adding
+            // a state starting at the current position in the input for the
+            // beginning of the program only if we don't already have a match.
+            if clist.set.is_empty()
+                || (!self.prog.is_anchored_start && !all_matched) {
+                self.add(&mut clist, slots, 0, at);
+            }
+            // The previous call to "add" actually inspects the position just
+            // before the current character. For stepping through the machine,
+            // we can to look at the current character, so we advance the
+            // input.
+            let at_next = self.input.at(at.next_pos());
+            for i in 0..clist.set.len() {
+                let ip = clist.set[i];
+                if self.step(
+                    &mut nlist,
+                    matches,
+                    slots,
+                    clist.caps(ip),
+                    ip,
+                    at,
+                    at_next,
+                ) {
+                    matched = true;
+                    all_matched = all_matched || matches.iter().all(|&b| b);
+                    if quit_after_match {
+                        // If we only care if a match occurs (not its
+                        // position), then we can quit right now.
+                        break 'LOOP;
+                    }
+                    if self.prog.matches.len() == 1 {
+                        // We don't need to check the rest of the threads
+                        // in this set because we've matched something
+                        // ("leftmost-first"). However, we still need to check
+                        // threads in the next set to support things like
+                        // greedy matching.
+                        //
+                        // This is only true on normal regexes. For regex sets,
+                        // we need to mush on to observe other matches.
+                        break;
+                    }
+                }
+            }
+            if at.pos() == end || at.is_end() {
+                break;
+            }
+            at = at_next;
+            mem::swap(clist, nlist);
+            nlist.set.clear();
+        }
+        matched
+    }
+
+    /// Step through the input, one token (byte or codepoint) at a time.
+    ///
+    /// nlist is the set of states that will be processed on the next token
+    /// in the input.
+    ///
+    /// caps is the set of captures passed by the caller of the NFA. They are
+    /// written to only when a match state is visited.
+    ///
+    /// thread_caps is the set of captures set for the current NFA state, ip.
+    ///
+    /// at and at_next are the current and next positions in the input. at or
+    /// at_next may be EOF.
+    fn step(
+        &mut self,
+        nlist: &mut Threads,
+        matches: &mut [bool],
+        slots: &mut [Slot],
+        thread_caps: &mut [Option<usize>],
+        ip: usize,
+        at: InputAt,
+        at_next: InputAt,
+    ) -> bool {
+        use prog::Inst::*;
+        match self.prog[ip] {
+            Match(match_slot) => {
+                if match_slot < matches.len() {
+                    matches[match_slot] = true;
+                }
+                for (slot, val) in slots.iter_mut().zip(thread_caps.iter()) {
+                    *slot = *val;
+                }
+                true
+            }
+            Char(ref inst) => {
+                if inst.c == at.char() {
+                    self.add(nlist, thread_caps, inst.goto, at_next);
+                }
+                false
+            }
+            Ranges(ref inst) => {
+                if inst.matches(at.char()) {
+                    self.add(nlist, thread_caps, inst.goto, at_next);
+                }
+                false
+            }
+            Bytes(ref inst) => {
+                if let Some(b) = at.byte() {
+                    if inst.matches(b) {
+                        self.add(nlist, thread_caps, inst.goto, at_next);
+                    }
+                }
+                false
+            }
+            EmptyLook(_) | Save(_) | Split(_) => false,
+        }
+    }
+
+    /// Follows epsilon transitions and adds them for processing to nlist,
+    /// starting at and including ip.
+    fn add(
+        &mut self,
+        nlist: &mut Threads,
+        thread_caps: &mut [Option<usize>],
+        ip: usize,
+        at: InputAt,
+    ) {
+        self.stack.push(FollowEpsilon::IP(ip));
+        while let Some(frame) = self.stack.pop() {
+            match frame {
+                FollowEpsilon::IP(ip) => {
+                    self.add_step(nlist, thread_caps, ip, at);
+                }
+                FollowEpsilon::Capture { slot, pos } => {
+                    thread_caps[slot] = pos;
+                }
+            }
+        }
+    }
+
+    /// A helper function for add that avoids excessive pushing to the stack.
+    fn add_step(
+        &mut self,
+        nlist: &mut Threads,
+        thread_caps: &mut [Option<usize>],
+        mut ip: usize,
+        at: InputAt,
+    ) {
+        // Instead of pushing and popping to the stack, we mutate ip as we
+        // traverse the set of states. We only push to the stack when we
+        // absolutely need recursion (restoring captures or following a
+        // branch).
+        use prog::Inst::*;
+        loop {
+            // Don't visit states we've already added.
+            if nlist.set.contains(ip) {
+                return;
+            }
+            nlist.set.insert(ip);
+            match self.prog[ip] {
+                EmptyLook(ref inst) => {
+                    if self.input.is_empty_match(at, inst) {
+                        ip = inst.goto;
+                    }
+                }
+                Save(ref inst) => {
+                    if inst.slot < thread_caps.len() {
+                        self.stack.push(FollowEpsilon::Capture {
+                            slot: inst.slot,
+                            pos: thread_caps[inst.slot],
+                        });
+                        thread_caps[inst.slot] = Some(at.pos());
+                    }
+                    ip = inst.goto;
+                }
+                Split(ref inst) => {
+                    self.stack.push(FollowEpsilon::IP(inst.goto2));
+                    ip = inst.goto1;
+                }
+                Match(_) | Char(_) | Ranges(_) | Bytes(_) => {
+                    let t = &mut nlist.caps(ip);
+                    for (slot, val) in t.iter_mut().zip(thread_caps.iter()) {
+                        *slot = *val;
+                    }
+                    return;
+                }
+            }
+        }
+    }
+}
+
+impl Threads {
+    fn new() -> Self {
+        Threads {
+            set: SparseSet::new(0),
+            caps: vec![],
+            slots_per_thread: 0,
+        }
+    }
+
+    fn resize(&mut self, num_insts: usize, ncaps: usize) {
+        if num_insts == self.set.capacity() {
+            return;
+        }
+        self.slots_per_thread = ncaps * 2;
+        self.set = SparseSet::new(num_insts);
+        self.caps = vec![None; self.slots_per_thread * num_insts];
+    }
+
+    fn caps(&mut self, pc: usize) -> &mut [Option<usize>] {
+        let i = pc * self.slots_per_thread;
+        &mut self.caps[i..i + self.slots_per_thread]
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/prog.rs.html b/target/doc/src/regex/prog.rs.html new file mode 100644 index 0000000..4393fbd --- /dev/null +++ b/target/doc/src/regex/prog.rs.html @@ -0,0 +1,849 @@ +prog.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+
+use std::collections::HashMap;
+use std::cmp::Ordering;
+use std::fmt;
+use std::ops::Deref;
+use std::mem;
+use std::slice;
+use std::sync::Arc;
+
+use input::Char;
+use literal::LiteralSearcher;
+
+/// `InstPtr` represents the index of an instruction in a regex program.
+pub type InstPtr = usize;
+
+/// Program is a sequence of instructions and various facts about thos
+/// instructions.
+#[derive(Clone)]
+pub struct Program {
+    /// A sequence of instructions that represents an NFA.
+    pub insts: Vec<Inst>,
+    /// Pointers to each Match instruction in the sequence.
+    ///
+    /// This is always length 1 unless this program represents a regex set.
+    pub matches: Vec<InstPtr>,
+    /// The ordered sequence of all capture groups extracted from the AST.
+    /// Unnamed groups are `None`.
+    pub captures: Vec<Option<String>>,
+    /// Pointers to all named capture groups into `captures`.
+    pub capture_name_idx: Arc<HashMap<String, usize>>,
+    /// A pointer to the start instruction. This can vary depending on how
+    /// the program was compiled. For example, programs for use with the DFA
+    /// engine have a `.*?` inserted at the beginning of unanchored regular
+    /// expressions. The actual starting point of the program is after the
+    /// `.*?`.
+    pub start: InstPtr,
+    /// A set of equivalence classes for discriminating bytes in the compiled
+    /// program.
+    pub byte_classes: Vec<u8>,
+    /// When true, this program can only match valid UTF-8.
+    pub only_utf8: bool,
+    /// When true, this program uses byte range instructions instead of Unicode
+    /// range instructions.
+    pub is_bytes: bool,
+    /// When true, the program is compiled for DFA matching. For example, this
+    /// implies `is_bytes` and also inserts a preceding `.*?` for unanchored
+    /// regexes.
+    pub is_dfa: bool,
+    /// When true, the program matches text in reverse (for use only in the
+    /// DFA).
+    pub is_reverse: bool,
+    /// Whether the regex must match from the start of the input.
+    pub is_anchored_start: bool,
+    /// Whether the regex must match at the end of the input.
+    pub is_anchored_end: bool,
+    /// Whether this program contains a Unicode word boundary instruction.
+    pub has_unicode_word_boundary: bool,
+    /// A possibly empty machine for very quickly matching prefix literals.
+    pub prefixes: LiteralSearcher,
+    /// A limit on the size of the cache that the DFA is allowed to use while
+    /// matching.
+    ///
+    /// The cache limit specifies approximately how much space we're willing to
+    /// give to the state cache. Once the state cache exceeds the size, it is
+    /// wiped and all states must be re-computed.
+    ///
+    /// Note that this value does not impact correctness. It can be set to 0
+    /// and the DFA will run just fine. (It will only ever store exactly one
+    /// state in the cache, and will likely run very slowly, but it will work.)
+    ///
+    /// Also note that this limit is *per thread of execution*. That is,
+    /// if the same regex is used to search text across multiple threads
+    /// simultaneously, then the DFA cache is not shared. Instead, copies are
+    /// made.
+    pub dfa_size_limit: usize,
+}
+
+impl Program {
+    /// Creates an empty instruction sequence. Fields are given default
+    /// values.
+    pub fn new() -> Self {
+        Program {
+            insts: vec![],
+            matches: vec![],
+            captures: vec![],
+            capture_name_idx: Arc::new(HashMap::new()),
+            start: 0,
+            byte_classes: vec![0; 256],
+            only_utf8: true,
+            is_bytes: false,
+            is_dfa: false,
+            is_reverse: false,
+            is_anchored_start: false,
+            is_anchored_end: false,
+            has_unicode_word_boundary: false,
+            prefixes: LiteralSearcher::empty(),
+            dfa_size_limit: 2 * (1<<20),
+        }
+    }
+
+    /// If pc is an index to a no-op instruction (like Save), then return the
+    /// next pc that is not a no-op instruction.
+    pub fn skip(&self, mut pc: usize) -> usize {
+        loop {
+            match self[pc] {
+                Inst::Save(ref i) => pc = i.goto,
+                _ => return pc,
+            }
+        }
+    }
+
+    /// Return true if and only if an execution engine at instruction `pc` will
+    /// always lead to a match.
+    pub fn leads_to_match(&self, pc: usize) -> bool {
+        if self.matches.len() > 1 {
+            // If we have a regex set, then we have more than one ending
+            // state, so leading to one of those states is generally
+            // meaningless.
+            return false;
+        }
+        match self[self.skip(pc)] {
+            Inst::Match(_) => true,
+            _ => false,
+        }
+    }
+
+    /// Returns true if the current configuration demands that an implicit
+    /// `.*?` be prepended to the instruction sequence.
+    pub fn needs_dotstar(&self) -> bool {
+        self.is_dfa && !self.is_reverse && !self.is_anchored_start
+    }
+
+    /// Returns true if this program uses Byte instructions instead of
+    /// Char/Range instructions.
+    pub fn uses_bytes(&self) -> bool {
+        self.is_bytes || self.is_dfa
+    }
+
+    /// Returns true if this program exclusively matches valid UTF-8 bytes.
+    ///
+    /// That is, if an invalid UTF-8 byte is seen, then no match is possible.
+    pub fn only_utf8(&self) -> bool {
+        self.only_utf8
+    }
+
+    /// Return the approximate heap usage of this instruction sequence in
+    /// bytes.
+    pub fn approximate_size(&self) -> usize {
+        // The only instruction that uses heap space is Ranges (for
+        // Unicode codepoint programs) to store non-overlapping codepoint
+        // ranges. To keep this operation constant time, we ignore them.
+        (self.len() * mem::size_of::<Inst>())
+        + (self.matches.len() * mem::size_of::<InstPtr>())
+        + (self.captures.len() * mem::size_of::<Option<String>>())
+        + (self.capture_name_idx.len() *
+           (mem::size_of::<String>() + mem::size_of::<usize>()))
+        + (self.byte_classes.len() * mem::size_of::<u8>())
+        + self.prefixes.approximate_size()
+    }
+}
+
+impl Deref for Program {
+    type Target = [Inst];
+
+    #[inline(always)]
+    fn deref(&self) -> &Self::Target {
+        &*self.insts
+    }
+}
+
+impl fmt::Debug for Program {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        use self::Inst::*;
+
+        fn with_goto(cur: usize, goto: usize, fmtd: String) -> String {
+            if goto == cur + 1 {
+                fmtd
+            } else {
+                format!("{} (goto: {})", fmtd, goto)
+            }
+        }
+
+        fn visible_byte(b: u8) -> String {
+            use std::ascii::escape_default;
+            let escaped = escape_default(b).collect::<Vec<u8>>();
+            String::from_utf8_lossy(&escaped).into_owned()
+        }
+
+        for (pc, inst) in self.iter().enumerate() {
+            match *inst {
+                Match(slot) => {
+                    write!(f, "{:04} Match({:?})", pc, slot)?
+                }
+                Save(ref inst) => {
+                    let s = format!("{:04} Save({})", pc, inst.slot);
+                    write!(f, "{}", with_goto(pc, inst.goto, s))?;
+                }
+                Split(ref inst) => {
+                    write!(
+                        f, "{:04} Split({}, {})", pc, inst.goto1, inst.goto2)?;
+                }
+                EmptyLook(ref inst) => {
+                    let s = format!("{:?}", inst.look);
+                    write!(f, "{:04} {}", pc, with_goto(pc, inst.goto, s))?;
+                }
+                Char(ref inst) => {
+                    let s = format!("{:?}", inst.c);
+                    write!(f, "{:04} {}", pc, with_goto(pc, inst.goto, s))?;
+                }
+                Ranges(ref inst) => {
+                    let ranges = inst.ranges
+                        .iter()
+                        .map(|r| format!("{:?}-{:?}", r.0, r.1))
+                        .collect::<Vec<String>>()
+                        .join(", ");
+                    write!(
+                        f, "{:04} {}", pc, with_goto(pc, inst.goto, ranges))?;
+                }
+                Bytes(ref inst) => {
+                    let s = format!(
+                        "Bytes({}, {})",
+                        visible_byte(inst.start),
+                        visible_byte(inst.end));
+                    write!(f, "{:04} {}", pc, with_goto(pc, inst.goto, s))?;
+                }
+            }
+            if pc == self.start {
+                write!(f, " (start)")?;
+            }
+            write!(f, "\n")?;
+        }
+        Ok(())
+    }
+}
+
+impl<'a> IntoIterator for &'a Program {
+    type Item = &'a Inst;
+    type IntoIter = slice::Iter<'a, Inst>;
+    fn into_iter(self) -> Self::IntoIter { self.iter() }
+}
+
+/// Inst is an instruction code in a Regex program.
+///
+/// Regrettably, a regex program either contains Unicode codepoint
+/// instructions (Char and Ranges) or it contains byte instructions (Bytes).
+/// A regex program can never contain both.
+///
+/// It would be worth investigating splitting this into two distinct types and
+/// then figuring out how to make the matching engines polymorphic over those
+/// types without sacrificing performance.
+///
+/// Other than the benefit of moving invariants into the type system, another
+/// benefit is the decreased size. If we remove the `Char` and `Ranges`
+/// instructions from the `Inst` enum, then its size shrinks from 40 bytes to
+/// 24 bytes. (This is because of the removal of a `Vec` in the `Ranges`
+/// variant.) Given that byte based machines are typically much bigger than
+/// their Unicode analogues (because they can decode UTF-8 directly), this ends
+/// up being a pretty significant savings.
+#[derive(Clone, Debug)]
+pub enum Inst {
+    /// Match indicates that the program has reached a match state.
+    ///
+    /// The number in the match corresponds to the Nth logical regular
+    /// expression in this program. This index is always 0 for normal regex
+    /// programs. Values greater than 0 appear when compiling regex sets, and
+    /// each match instruction gets its own unique value. The value corresponds
+    /// to the Nth regex in the set.
+    Match(usize),
+    /// Save causes the program to save the current location of the input in
+    /// the slot indicated by InstSave.
+    Save(InstSave),
+    /// Split causes the program to diverge to one of two paths in the
+    /// program, preferring goto1 in InstSplit.
+    Split(InstSplit),
+    /// EmptyLook represents a zero-width assertion in a regex program. A
+    /// zero-width assertion does not consume any of the input text.
+    EmptyLook(InstEmptyLook),
+    /// Char requires the regex program to match the character in InstChar at
+    /// the current position in the input.
+    Char(InstChar),
+    /// Ranges requires the regex program to match the character at the current
+    /// position in the input with one of the ranges specified in InstRanges.
+    Ranges(InstRanges),
+    /// Bytes is like Ranges, except it expresses a single byte range. It is
+    /// used in conjunction with Split instructions to implement multi-byte
+    /// character classes.
+    Bytes(InstBytes),
+}
+
+impl Inst {
+    /// Returns true if and only if this is a match instruction.
+    pub fn is_match(&self) -> bool {
+        match *self {
+            Inst::Match(_) => true,
+            _ => false,
+        }
+    }
+}
+
+/// Representation of the Save instruction.
+#[derive(Clone, Debug)]
+pub struct InstSave {
+    /// The next location to execute in the program.
+    pub goto: InstPtr,
+    /// The capture slot (there are two slots for every capture in a regex,
+    /// including the zeroth capture for the entire match).
+    pub slot: usize,
+}
+
+/// Representation of the Split instruction.
+#[derive(Clone, Debug)]
+pub struct InstSplit {
+    /// The first instruction to try. A match resulting from following goto1
+    /// has precedence over a match resulting from following goto2.
+    pub goto1: InstPtr,
+    /// The second instruction to try. A match resulting from following goto1
+    /// has precedence over a match resulting from following goto2.
+    pub goto2: InstPtr,
+}
+
+/// Representation of the `EmptyLook` instruction.
+#[derive(Clone, Debug)]
+pub struct InstEmptyLook {
+    /// The next location to execute in the program if this instruction
+    /// succeeds.
+    pub goto: InstPtr,
+    /// The type of zero-width assertion to check.
+    pub look: EmptyLook,
+}
+
+/// The set of zero-width match instructions.
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum EmptyLook {
+    /// Start of line or input.
+    StartLine,
+    /// End of line or input.
+    EndLine,
+    /// Start of input.
+    StartText,
+    /// End of input.
+    EndText,
+    /// Word character on one side and non-word character on other.
+    WordBoundary,
+    /// Word character on both sides or non-word character on both sides.
+    NotWordBoundary,
+    /// ASCII word boundary.
+    WordBoundaryAscii,
+    /// Not ASCII word boundary.
+    NotWordBoundaryAscii,
+}
+
+/// Representation of the Char instruction.
+#[derive(Clone, Debug)]
+pub struct InstChar {
+    /// The next location to execute in the program if this instruction
+    /// succeeds.
+    pub goto: InstPtr,
+    /// The character to test.
+    pub c: char,
+}
+
+/// Representation of the Ranges instruction.
+#[derive(Clone, Debug)]
+pub struct InstRanges {
+    /// The next location to execute in the program if this instruction
+    /// succeeds.
+    pub goto: InstPtr,
+    /// The set of Unicode scalar value ranges to test.
+    pub ranges: Vec<(char, char)>,
+}
+
+impl InstRanges {
+    /// Tests whether the given input character matches this instruction.
+    pub fn matches(&self, c: Char) -> bool {
+        // This speeds up the `match_class_unicode` benchmark by checking
+        // some common cases quickly without binary search. e.g., Matching
+        // a Unicode class on predominantly ASCII text.
+        for r in self.ranges.iter().take(4) {
+            if c < r.0 {
+                return false;
+            }
+            if c <= r.1 {
+                return true;
+            }
+        }
+        self.ranges.binary_search_by(|r| {
+            if r.1 < c {
+                Ordering::Less
+            } else if r.0 > c {
+                Ordering::Greater
+            } else {
+                Ordering::Equal
+            }
+        }).is_ok()
+    }
+
+    /// Return the number of distinct characters represented by all of the
+    /// ranges.
+    pub fn num_chars(&self) -> usize {
+        self.ranges.iter()
+            .map(|&(s, e)| 1 + (e as u32) - (s as u32))
+            .fold(0, |acc, len| acc + len)
+            as usize
+    }
+}
+
+/// Representation of the Bytes instruction.
+#[derive(Clone, Debug)]
+pub struct InstBytes {
+    /// The next location to execute in the program if this instruction
+    /// succeeds.
+    pub goto: InstPtr,
+    /// The start (inclusive) of this byte range.
+    pub start: u8,
+    /// The end (inclusive) of this byte range.
+    pub end: u8,
+}
+
+impl InstBytes {
+    /// Returns true if and only if the given byte is in this range.
+    pub fn matches(&self, byte: u8) -> bool {
+        self.start <= byte && byte <= self.end
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/re_builder.rs.html b/target/doc/src/regex/re_builder.rs.html new file mode 100644 index 0000000..a455f43 --- /dev/null +++ b/target/doc/src/regex/re_builder.rs.html @@ -0,0 +1,779 @@ +re_builder.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/// The set of user configurable options for compiling zero or more regexes.
+#[derive(Clone, Debug)]
+#[allow(missing_docs)]
+pub struct RegexOptions {
+    pub pats: Vec<String>,
+    pub size_limit: usize,
+    pub dfa_size_limit: usize,
+    pub nest_limit: u32,
+    pub case_insensitive: bool,
+    pub multi_line: bool,
+    pub dot_matches_new_line: bool,
+    pub swap_greed: bool,
+    pub ignore_whitespace: bool,
+    pub unicode: bool,
+    pub octal: bool,
+}
+
+impl Default for RegexOptions {
+    fn default() -> Self {
+        RegexOptions {
+            pats: vec![],
+            size_limit: 10 * (1<<20),
+            dfa_size_limit: 2 * (1<<20),
+            nest_limit: 250,
+            case_insensitive: false,
+            multi_line: false,
+            dot_matches_new_line: false,
+            swap_greed: false,
+            ignore_whitespace: false,
+            unicode: true,
+            octal: false,
+        }
+    }
+}
+
+macro_rules! define_builder {
+    ($name:ident, $regex_mod:ident, $only_utf8:expr) => {
+        pub mod $name {
+            use error::Error;
+            use exec::ExecBuilder;
+            use super::RegexOptions;
+
+            use $regex_mod::Regex;
+
+/// A configurable builder for a regular expression.
+///
+/// A builder can be used to configure how the regex is built, for example, by
+/// setting the default flags (which can be overridden in the expression
+/// itself) or setting various limits.
+pub struct RegexBuilder(RegexOptions);
+
+impl RegexBuilder {
+    /// Create a new regular expression builder with the given pattern.
+    ///
+    /// If the pattern is invalid, then an error will be returned when
+    /// `build` is called.
+    pub fn new(pattern: &str) -> RegexBuilder {
+        let mut builder = RegexBuilder(RegexOptions::default());
+        builder.0.pats.push(pattern.to_owned());
+        builder
+    }
+
+    /// Consume the builder and compile the regular expression.
+    ///
+    /// Note that calling `as_str` on the resulting `Regex` will produce the
+    /// pattern given to `new` verbatim. Notably, it will not incorporate any
+    /// of the flags set on this builder.
+    pub fn build(&self) -> Result<Regex, Error> {
+        ExecBuilder::new_options(self.0.clone())
+            .only_utf8($only_utf8)
+            .build()
+            .map(Regex::from)
+    }
+
+    /// Set the value for the case insensitive (`i`) flag.
+    ///
+    /// When enabled, letters in the pattern will match both upper case and
+    /// lower case variants.
+    pub fn case_insensitive(&mut self, yes: bool) -> &mut RegexBuilder {
+        self.0.case_insensitive = yes;
+        self
+    }
+
+    /// Set the value for the multi-line matching (`m`) flag.
+    ///
+    /// When enabled, `^` matches the beginning of lines and `$` matches the
+    /// end of lines.
+    ///
+    /// By default, they match beginning/end of the input.
+    pub fn multi_line(&mut self, yes: bool) -> &mut RegexBuilder {
+        self.0.multi_line = yes;
+        self
+    }
+
+    /// Set the value for the any character (`s`) flag, where in `.` matches
+    /// anything when `s` is set and matches anything except for new line when
+    /// it is not set (the default).
+    ///
+    /// N.B. "matches anything" means "any byte" when Unicode is disabled and
+    /// means "any valid UTF-8 encoding of any Unicode scalar value" when
+    /// Unicode is enabled.
+    pub fn dot_matches_new_line(&mut self, yes: bool) -> &mut RegexBuilder {
+        self.0.dot_matches_new_line = yes;
+        self
+    }
+
+    /// Set the value for the greedy swap (`U`) flag.
+    ///
+    /// When enabled, a pattern like `a*` is lazy (tries to find shortest
+    /// match) and `a*?` is greedy (tries to find longest match).
+    ///
+    /// By default, `a*` is greedy and `a*?` is lazy.
+    pub fn swap_greed(&mut self, yes: bool) -> &mut RegexBuilder {
+        self.0.swap_greed = yes;
+        self
+    }
+
+    /// Set the value for the ignore whitespace (`x`) flag.
+    ///
+    /// When enabled, whitespace such as new lines and spaces will be ignored
+    /// between expressions of the pattern, and `#` can be used to start a
+    /// comment until the next new line.
+    pub fn ignore_whitespace(&mut self, yes: bool) -> &mut RegexBuilder {
+        self.0.ignore_whitespace = yes;
+        self
+    }
+
+    /// Set the value for the Unicode (`u`) flag.
+    ///
+    /// Enabled by default. When disabled, character classes such as `\w` only
+    /// match ASCII word characters instead of all Unicode word characters.
+    pub fn unicode(&mut self, yes: bool) -> &mut RegexBuilder {
+        self.0.unicode = yes;
+        self
+    }
+
+    /// Whether to support octal syntax or not.
+    ///
+    /// Octal syntax is a little-known way of uttering Unicode codepoints in
+    /// a regular expression. For example, `a`, `\x61`, `\u0061` and
+    /// `\141` are all equivalent regular expressions, where the last example
+    /// shows octal syntax.
+    ///
+    /// While supporting octal syntax isn't in and of itself a problem, it does
+    /// make good error messages harder. That is, in PCRE based regex engines,
+    /// syntax like `\0` invokes a backreference, which is explicitly
+    /// unsupported in Rust's regex engine. However, many users expect it to
+    /// be supported. Therefore, when octal support is disabled, the error
+    /// message will explicitly mention that backreferences aren't supported.
+    ///
+    /// Octal syntax is disabled by default.
+    pub fn octal(&mut self, yes: bool) -> &mut RegexBuilder {
+        self.0.octal = yes;
+        self
+    }
+
+    /// Set the approximate size limit of the compiled regular expression.
+    ///
+    /// This roughly corresponds to the number of bytes occupied by a single
+    /// compiled program. If the program exceeds this number, then a
+    /// compilation error is returned.
+    pub fn size_limit(&mut self, limit: usize) -> &mut RegexBuilder {
+        self.0.size_limit = limit;
+        self
+    }
+
+    /// Set the approximate size of the cache used by the DFA.
+    ///
+    /// This roughly corresponds to the number of bytes that the DFA will
+    /// use while searching.
+    ///
+    /// Note that this is a *per thread* limit. There is no way to set a global
+    /// limit. In particular, if a regex is used from multiple threads
+    /// simultaneously, then each thread may use up to the number of bytes
+    /// specified here.
+    pub fn dfa_size_limit(&mut self, limit: usize) -> &mut RegexBuilder {
+        self.0.dfa_size_limit = limit;
+        self
+    }
+
+    /// Set the nesting limit for this parser.
+    ///
+    /// The nesting limit controls how deep the abstract syntax tree is allowed
+    /// to be. If the AST exceeds the given limit (e.g., with too many nested
+    /// groups), then an error is returned by the parser.
+    ///
+    /// The purpose of this limit is to act as a heuristic to prevent stack
+    /// overflow for consumers that do structural induction on an `Ast` using
+    /// explicit recursion. While this crate never does this (instead using
+    /// constant stack space and moving the call stack to the heap), other
+    /// crates may.
+    ///
+    /// This limit is not checked until the entire Ast is parsed. Therefore,
+    /// if callers want to put a limit on the amount of heap space used, then
+    /// they should impose a limit on the length, in bytes, of the concrete
+    /// pattern string. In particular, this is viable since this parser
+    /// implementation will limit itself to heap space proportional to the
+    /// length of the pattern string.
+    ///
+    /// Note that a nest limit of `0` will return a nest limit error for most
+    /// patterns but not all. For example, a nest limit of `0` permits `a` but
+    /// not `ab`, since `ab` requires a concatenation, which results in a nest
+    /// depth of `1`. In general, a nest limit is not something that manifests
+    /// in an obvious way in the concrete syntax, therefore, it should not be
+    /// used in a granular way.
+    pub fn nest_limit(&mut self, limit: u32) -> &mut RegexBuilder {
+        self.0.nest_limit = limit;
+        self
+    }
+}
+        }
+    }
+}
+
+define_builder!(bytes, re_bytes, false);
+define_builder!(unicode, re_unicode, true);
+
+macro_rules! define_set_builder {
+    ($name:ident, $regex_mod:ident, $only_utf8:expr) => {
+        pub mod $name {
+            use error::Error;
+            use exec::ExecBuilder;
+            use super::RegexOptions;
+
+            use re_set::$regex_mod::RegexSet;
+
+/// A configurable builder for a set of regular expressions.
+///
+/// A builder can be used to configure how the regexes are built, for example,
+/// by setting the default flags (which can be overridden in the expression
+/// itself) or setting various limits.
+pub struct RegexSetBuilder(RegexOptions);
+
+impl RegexSetBuilder {
+    /// Create a new regular expression builder with the given pattern.
+    ///
+    /// If the pattern is invalid, then an error will be returned when
+    /// `build` is called.
+    pub fn new<I, S>(patterns: I) -> RegexSetBuilder
+            where S: AsRef<str>, I: IntoIterator<Item=S> {
+        let mut builder = RegexSetBuilder(RegexOptions::default());
+        for pat in patterns {
+            builder.0.pats.push(pat.as_ref().to_owned());
+        }
+        builder
+    }
+
+    /// Consume the builder and compile the regular expressions into a set.
+    pub fn build(&self) -> Result<RegexSet, Error> {
+        ExecBuilder::new_options(self.0.clone())
+            .only_utf8($only_utf8)
+            .build()
+            .map(RegexSet::from)
+    }
+
+    /// Set the value for the case insensitive (`i`) flag.
+    pub fn case_insensitive(&mut self, yes: bool) -> &mut RegexSetBuilder {
+        self.0.case_insensitive = yes;
+        self
+    }
+
+    /// Set the value for the multi-line matching (`m`) flag.
+    pub fn multi_line(&mut self, yes: bool) -> &mut RegexSetBuilder {
+        self.0.multi_line = yes;
+        self
+    }
+
+    /// Set the value for the any character (`s`) flag, where in `.` matches
+    /// anything when `s` is set and matches anything except for new line when
+    /// it is not set (the default).
+    ///
+    /// N.B. "matches anything" means "any byte" for `regex::bytes::RegexSet`
+    /// expressions and means "any Unicode scalar value" for `regex::RegexSet`
+    /// expressions.
+    pub fn dot_matches_new_line(&mut self, yes: bool) -> &mut RegexSetBuilder {
+        self.0.dot_matches_new_line = yes;
+        self
+    }
+
+    /// Set the value for the greedy swap (`U`) flag.
+    pub fn swap_greed(&mut self, yes: bool) -> &mut RegexSetBuilder {
+        self.0.swap_greed = yes;
+        self
+    }
+
+    /// Set the value for the ignore whitespace (`x`) flag.
+    pub fn ignore_whitespace(&mut self, yes: bool) -> &mut RegexSetBuilder {
+        self.0.ignore_whitespace = yes;
+        self
+    }
+
+    /// Set the value for the Unicode (`u`) flag.
+    pub fn unicode(&mut self, yes: bool) -> &mut RegexSetBuilder {
+        self.0.unicode = yes;
+        self
+    }
+
+    /// Whether to support octal syntax or not.
+    ///
+    /// Octal syntax is a little-known way of uttering Unicode codepoints in
+    /// a regular expression. For example, `a`, `\x61`, `\u0061` and
+    /// `\141` are all equivalent regular expressions, where the last example
+    /// shows octal syntax.
+    ///
+    /// While supporting octal syntax isn't in and of itself a problem, it does
+    /// make good error messages harder. That is, in PCRE based regex engines,
+    /// syntax like `\0` invokes a backreference, which is explicitly
+    /// unsupported in Rust's regex engine. However, many users expect it to
+    /// be supported. Therefore, when octal support is disabled, the error
+    /// message will explicitly mention that backreferences aren't supported.
+    ///
+    /// Octal syntax is disabled by default.
+    pub fn octal(&mut self, yes: bool) -> &mut RegexSetBuilder {
+        self.0.octal = yes;
+        self
+    }
+
+    /// Set the approximate size limit of the compiled regular expression.
+    ///
+    /// This roughly corresponds to the number of bytes occupied by a single
+    /// compiled program. If the program exceeds this number, then a
+    /// compilation error is returned.
+    pub fn size_limit(&mut self, limit: usize) -> &mut RegexSetBuilder {
+        self.0.size_limit = limit;
+        self
+    }
+
+    /// Set the approximate size of the cache used by the DFA.
+    ///
+    /// This roughly corresponds to the number of bytes that the DFA will
+    /// use while searching.
+    ///
+    /// Note that this is a *per thread* limit. There is no way to set a global
+    /// limit. In particular, if a regex is used from multiple threads
+    /// simultaneously, then each thread may use up to the number of bytes
+    /// specified here.
+    pub fn dfa_size_limit(&mut self, limit: usize) -> &mut RegexSetBuilder {
+        self.0.dfa_size_limit = limit;
+        self
+    }
+
+    /// Set the nesting limit for this parser.
+    ///
+    /// The nesting limit controls how deep the abstract syntax tree is allowed
+    /// to be. If the AST exceeds the given limit (e.g., with too many nested
+    /// groups), then an error is returned by the parser.
+    ///
+    /// The purpose of this limit is to act as a heuristic to prevent stack
+    /// overflow for consumers that do structural induction on an `Ast` using
+    /// explicit recursion. While this crate never does this (instead using
+    /// constant stack space and moving the call stack to the heap), other
+    /// crates may.
+    ///
+    /// This limit is not checked until the entire Ast is parsed. Therefore,
+    /// if callers want to put a limit on the amount of heap space used, then
+    /// they should impose a limit on the length, in bytes, of the concrete
+    /// pattern string. In particular, this is viable since this parser
+    /// implementation will limit itself to heap space proportional to the
+    /// length of the pattern string.
+    ///
+    /// Note that a nest limit of `0` will return a nest limit error for most
+    /// patterns but not all. For example, a nest limit of `0` permits `a` but
+    /// not `ab`, since `ab` requires a concatenation, which results in a nest
+    /// depth of `1`. In general, a nest limit is not something that manifests
+    /// in an obvious way in the concrete syntax, therefore, it should not be
+    /// used in a granular way.
+    pub fn nest_limit(&mut self, limit: u32) -> &mut RegexSetBuilder {
+        self.0.nest_limit = limit;
+        self
+    }
+
+}
+        }
+    }
+}
+
+define_set_builder!(set_bytes, bytes, false);
+define_set_builder!(set_unicode, unicode, true);
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/re_bytes.rs.html b/target/doc/src/regex/re_bytes.rs.html new file mode 100644 index 0000000..d6852df --- /dev/null +++ b/target/doc/src/regex/re_bytes.rs.html @@ -0,0 +1,2341 @@ +re_bytes.rs.html -- source
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::borrow::Cow;
+use std::collections::HashMap;
+use std::fmt;
+use std::ops::Index;
+use std::str::FromStr;
+use std::sync::Arc;
+
+use memchr::memchr;
+
+use exec::{Exec, ExecNoSync};
+use expand::expand_bytes;
+use error::Error;
+use re_builder::bytes::RegexBuilder;
+use re_trait::{self, RegularExpression, SubCapturesPosIter};
+
+/// Match represents a single match of a regex in a haystack.
+///
+/// The lifetime parameter `'t` refers to the lifetime of the matched text.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub struct Match<'t> {
+    text: &'t [u8],
+    start: usize,
+    end: usize,
+}
+
+impl<'t> Match<'t> {
+    /// Returns the starting byte offset of the match in the haystack.
+    #[inline]
+    pub fn start(&self) -> usize {
+        self.start
+    }
+
+    /// Returns the ending byte offset of the match in the haystack.
+    #[inline]
+    pub fn end(&self) -> usize {
+        self.end
+    }
+
+    /// Returns the matched text.
+    #[inline]
+    pub fn as_bytes(&self) -> &'t [u8] {
+        &self.text[self.start..self.end]
+    }
+
+    /// Creates a new match from the given haystack and byte offsets.
+    #[inline]
+    fn new(haystack: &'t [u8], start: usize, end: usize) -> Match<'t> {
+        Match {
+            text: haystack,
+            start: start,
+            end: end,
+        }
+    }
+}
+
+/// A compiled regular expression for matching arbitrary bytes.
+///
+/// It can be used to search, split or replace text. All searching is done with
+/// an implicit `.*?` at the beginning and end of an expression. To force an
+/// expression to match the whole string (or a prefix or a suffix), you must
+/// use an anchor like `^` or `$` (or `\A` and `\z`).
+///
+/// Like the `Regex` type in the parent module, matches with this regex return
+/// byte offsets into the search text. **Unlike** the parent `Regex` type,
+/// these byte offsets may not correspond to UTF-8 sequence boundaries since
+/// the regexes in this module can match arbitrary bytes.
+#[derive(Clone)]
+pub struct Regex(Exec);
+
+impl fmt::Display for Regex {
+    /// Shows the original regular expression.
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}", self.as_str())
+    }
+}
+
+impl fmt::Debug for Regex {
+    /// Shows the original regular expression.
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(self, f)
+    }
+}
+
+/// A constructor for Regex from an Exec.
+///
+/// This is hidden because Exec isn't actually part of the public API.
+#[doc(hidden)]
+impl From<Exec> for Regex {
+    fn from(exec: Exec) -> Regex {
+        Regex(exec)
+    }
+}
+
+impl FromStr for Regex {
+    type Err = Error;
+
+    /// Attempts to parse a string into a regular expression
+    fn from_str(s: &str) -> Result<Regex, Error> {
+        Regex::new(s)
+    }
+}
+
+/// Core regular expression methods.
+impl Regex {
+    /// Compiles a regular expression. Once compiled, it can be used repeatedly
+    /// to search, split or replace text in a string.
+    ///
+    /// If an invalid expression is given, then an error is returned.
+    pub fn new(re: &str) -> Result<Regex, Error> {
+        RegexBuilder::new(re).build()
+    }
+
+    /// Returns true if and only if the regex matches the string given.
+    ///
+    /// It is recommended to use this method if all you need to do is test
+    /// a match, since the underlying matching engine may be able to do less
+    /// work.
+    ///
+    /// # Example
+    ///
+    /// Test if some text contains at least one word with exactly 13 ASCII word
+    /// bytes:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::bytes::Regex;
+    /// # fn main() {
+    /// let text = b"I categorically deny having triskaidekaphobia.";
+    /// assert!(Regex::new(r"\b\w{13}\b").unwrap().is_match(text));
+    /// # }
+    /// ```
+    pub fn is_match(&self, text: &[u8]) -> bool {
+        self.is_match_at(text, 0)
+    }
+
+    /// Returns the start and end byte range of the leftmost-first match in
+    /// `text`. If no match exists, then `None` is returned.
+    ///
+    /// Note that this should only be used if you want to discover the position
+    /// of the match. Testing the existence of a match is faster if you use
+    /// `is_match`.
+    ///
+    /// # Example
+    ///
+    /// Find the start and end location of the first word with exactly 13
+    /// ASCII word bytes:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::bytes::Regex;
+    /// # fn main() {
+    /// let text = b"I categorically deny having triskaidekaphobia.";
+    /// let mat = Regex::new(r"\b\w{13}\b").unwrap().find(text).unwrap();
+    /// assert_eq!((mat.start(), mat.end()), (2, 15));
+    /// # }
+    /// ```
+    pub fn find<'t>(&self, text: &'t [u8]) -> Option<Match<'t>> {
+        self.find_at(text, 0)
+    }
+
+    /// Returns an iterator for each successive non-overlapping match in
+    /// `text`, returning the start and end byte indices with respect to
+    /// `text`.
+    ///
+    /// # Example
+    ///
+    /// Find the start and end location of every word with exactly 13 ASCII
+    /// word bytes:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::bytes::Regex;
+    /// # fn main() {
+    /// let text = b"Retroactively relinquishing remunerations is reprehensible.";
+    /// for mat in Regex::new(r"\b\w{13}\b").unwrap().find_iter(text) {
+    ///     println!("{:?}", mat);
+    /// }
+    /// # }
+    /// ```
+    pub fn find_iter<'r, 't>(&'r self, text: &'t [u8]) -> Matches<'r, 't> {
+        Matches(self.0.searcher().find_iter(text))
+    }
+
+    /// Returns the capture groups corresponding to the leftmost-first
+    /// match in `text`. Capture group `0` always corresponds to the entire
+    /// match. If no match is found, then `None` is returned.
+    ///
+    /// You should only use `captures` if you need access to the location of
+    /// capturing group matches. Otherwise, `find` is faster for discovering
+    /// the location of the overall match.
+    ///
+    /// # Examples
+    ///
+    /// Say you have some text with movie names and their release years,
+    /// like "'Citizen Kane' (1941)". It'd be nice if we could search for text
+    /// looking like that, while also extracting the movie name and its release
+    /// year separately.
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::bytes::Regex;
+    /// # fn main() {
+    /// let re = Regex::new(r"'([^']+)'\s+\((\d{4})\)").unwrap();
+    /// let text = b"Not my favorite movie: 'Citizen Kane' (1941).";
+    /// let caps = re.captures(text).unwrap();
+    /// assert_eq!(caps.get(1).unwrap().as_bytes(), &b"Citizen Kane"[..]);
+    /// assert_eq!(caps.get(2).unwrap().as_bytes(), &b"1941"[..]);
+    /// assert_eq!(caps.get(0).unwrap().as_bytes(), &b"'Citizen Kane' (1941)"[..]);
+    /// // You can also access the groups by index using the Index notation.
+    /// // Note that this will panic on an invalid index.
+    /// assert_eq!(&caps[1], b"Citizen Kane");
+    /// assert_eq!(&caps[2], b"1941");
+    /// assert_eq!(&caps[0], b"'Citizen Kane' (1941)");
+    /// # }
+    /// ```
+    ///
+    /// Note that the full match is at capture group `0`. Each subsequent
+    /// capture group is indexed by the order of its opening `(`.
+    ///
+    /// We can make this example a bit clearer by using *named* capture groups:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::bytes::Regex;
+    /// # fn main() {
+    /// let re = Regex::new(r"'(?P<title>[^']+)'\s+\((?P<year>\d{4})\)")
+    ///                .unwrap();
+    /// let text = b"Not my favorite movie: 'Citizen Kane' (1941).";
+    /// let caps = re.captures(text).unwrap();
+    /// assert_eq!(caps.name("title").unwrap().as_bytes(), b"Citizen Kane");
+    /// assert_eq!(caps.name("year").unwrap().as_bytes(), b"1941");
+    /// assert_eq!(caps.get(0).unwrap().as_bytes(), &b"'Citizen Kane' (1941)"[..]);
+    /// // You can also access the groups by name using the Index notation.
+    /// // Note that this will panic on an invalid group name.
+    /// assert_eq!(&caps["title"], b"Citizen Kane");
+    /// assert_eq!(&caps["year"], b"1941");
+    /// assert_eq!(&caps[0], b"'Citizen Kane' (1941)");
+    ///
+    /// # }
+    /// ```
+    ///
+    /// Here we name the capture groups, which we can access with the `name`
+    /// method or the `Index` notation with a `&str`. Note that the named
+    /// capture groups are still accessible with `get` or the `Index` notation
+    /// with a `usize`.
+    ///
+    /// The `0`th capture group is always unnamed, so it must always be
+    /// accessed with `get(0)` or `[0]`.
+    pub fn captures<'t>(&self, text: &'t [u8]) -> Option<Captures<'t>> {
+        let mut locs = self.capture_locations();
+        self.captures_read_at(&mut locs, text, 0).map(move |_| Captures {
+            text: text,
+            locs: locs.0,
+            named_groups: self.0.capture_name_idx().clone(),
+        })
+    }
+
+    /// Returns an iterator over all the non-overlapping capture groups matched
+    /// in `text`. This is operationally the same as `find_iter`, except it
+    /// yields information about capturing group matches.
+    ///
+    /// # Example
+    ///
+    /// We can use this to find all movie titles and their release years in
+    /// some text, where the movie is formatted like "'Title' (xxxx)":
+    ///
+    /// ```rust
+    /// # extern crate regex; use std::str; use regex::bytes::Regex;
+    /// # fn main() {
+    /// let re = Regex::new(r"'(?P<title>[^']+)'\s+\((?P<year>\d{4})\)")
+    ///                .unwrap();
+    /// let text = b"'Citizen Kane' (1941), 'The Wizard of Oz' (1939), 'M' (1931).";
+    /// for caps in re.captures_iter(text) {
+    ///     let title = str::from_utf8(&caps["title"]).unwrap();
+    ///     let year = str::from_utf8(&caps["year"]).unwrap();
+    ///     println!("Movie: {:?}, Released: {:?}", title, year);
+    /// }
+    /// // Output:
+    /// // Movie: Citizen Kane, Released: 1941
+    /// // Movie: The Wizard of Oz, Released: 1939
+    /// // Movie: M, Released: 1931
+    /// # }
+    /// ```
+    pub fn captures_iter<'r, 't>(
+        &'r self,
+        text: &'t [u8],
+    ) -> CaptureMatches<'r, 't> {
+        CaptureMatches(self.0.searcher().captures_iter(text))
+    }
+
+    /// Returns an iterator of substrings of `text` delimited by a match of the
+    /// regular expression. Namely, each element of the iterator corresponds to
+    /// text that *isn't* matched by the regular expression.
+    ///
+    /// This method will *not* copy the text given.
+    ///
+    /// # Example
+    ///
+    /// To split a string delimited by arbitrary amounts of spaces or tabs:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::bytes::Regex;
+    /// # fn main() {
+    /// let re = Regex::new(r"[ \t]+").unwrap();
+    /// let fields: Vec<&[u8]> = re.split(b"a b \t  c\td    e").collect();
+    /// assert_eq!(fields, vec![
+    ///     &b"a"[..], &b"b"[..], &b"c"[..], &b"d"[..], &b"e"[..],
+    /// ]);
+    /// # }
+    /// ```
+    pub fn split<'r, 't>(&'r self, text: &'t [u8]) -> Split<'r, 't> {
+        Split {
+            finder: self.find_iter(text),
+            last: 0,
+        }
+    }
+
+    /// Returns an iterator of at most `limit` substrings of `text` delimited
+    /// by a match of the regular expression. (A `limit` of `0` will return no
+    /// substrings.) Namely, each element of the iterator corresponds to text
+    /// that *isn't* matched by the regular expression. The remainder of the
+    /// string that is not split will be the last element in the iterator.
+    ///
+    /// This method will *not* copy the text given.
+    ///
+    /// # Example
+    ///
+    /// Get the first two words in some text:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::bytes::Regex;
+    /// # fn main() {
+    /// let re = Regex::new(r"\W+").unwrap();
+    /// let fields: Vec<&[u8]> = re.splitn(b"Hey! How are you?", 3).collect();
+    /// assert_eq!(fields, vec![&b"Hey"[..], &b"How"[..], &b"are you?"[..]]);
+    /// # }
+    /// ```
+    pub fn splitn<'r, 't>(
+        &'r self,
+        text: &'t [u8],
+        limit: usize,
+    ) -> SplitN<'r, 't> {
+        SplitN {
+            splits: self.split(text),
+            n: limit,
+        }
+    }
+
+    /// Replaces the leftmost-first match with the replacement provided. The
+    /// replacement can be a regular byte string (where `$N` and `$name` are
+    /// expanded to match capture groups) or a function that takes the matches'
+    /// `Captures` and returns the replaced byte string.
+    ///
+    /// If no match is found, then a copy of the byte string is returned
+    /// unchanged.
+    ///
+    /// # Replacement string syntax
+    ///
+    /// All instances of `$name` in the replacement text is replaced with the
+    /// corresponding capture group `name`.
+    ///
+    /// `name` may be an integer corresponding to the index of the
+    /// capture group (counted by order of opening parenthesis where `0` is the
+    /// entire match) or it can be a name (consisting of letters, digits or
+    /// underscores) corresponding to a named capture group.
+    ///
+    /// If `name` isn't a valid capture group (whether the name doesn't exist
+    /// or isn't a valid index), then it is replaced with the empty string.
+    ///
+    /// The longest possible name is used. e.g., `$1a` looks up the capture
+    /// group named `1a` and not the capture group at index `1`. To exert more
+    /// precise control over the name, use braces, e.g., `${1}a`.
+    ///
+    /// To write a literal `$` use `$$`.
+    ///
+    /// # Examples
+    ///
+    /// Note that this function is polymorphic with respect to the replacement.
+    /// In typical usage, this can just be a normal byte string:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::bytes::Regex;
+    /// # fn main() {
+    /// let re = Regex::new("[^01]+").unwrap();
+    /// assert_eq!(re.replace(b"1078910", &b""[..]), &b"1010"[..]);
+    /// # }
+    /// ```
+    ///
+    /// But anything satisfying the `Replacer` trait will work. For example, a
+    /// closure of type `|&Captures| -> Vec<u8>` provides direct access to the
+    /// captures corresponding to a match. This allows one to access capturing
+    /// group matches easily:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::bytes::Regex;
+    /// # use regex::bytes::Captures; fn main() {
+    /// let re = Regex::new(r"([^,\s]+),\s+(\S+)").unwrap();
+    /// let result = re.replace(b"Springsteen, Bruce", |caps: &Captures| {
+    ///     let mut replacement = caps[2].to_owned();
+    ///     replacement.push(b' ');
+    ///     replacement.extend(&caps[1]);
+    ///     replacement
+    /// });
+    /// assert_eq!(result, &b"Bruce Springsteen"[..]);
+    /// # }
+    /// ```
+    ///
+    /// But this is a bit cumbersome to use all the time. Instead, a simple
+    /// syntax is supported that expands `$name` into the corresponding capture
+    /// group. Here's the last example, but using this expansion technique
+    /// with named capture groups:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::bytes::Regex;
+    /// # fn main() {
+    /// let re = Regex::new(r"(?P<last>[^,\s]+),\s+(?P<first>\S+)").unwrap();
+    /// let result = re.replace(b"Springsteen, Bruce", &b"$first $last"[..]);
+    /// assert_eq!(result, &b"Bruce Springsteen"[..]);
+    /// # }
+    /// ```
+    ///
+    /// Note that using `$2` instead of `$first` or `$1` instead of `$last`
+    /// would produce the same result. To write a literal `$` use `$$`.
+    ///
+    /// Sometimes the replacement string requires use of curly braces to
+    /// delineate a capture group replacement and surrounding literal text.
+    /// For example, if we wanted to join two words together with an
+    /// underscore:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::bytes::Regex;
+    /// # fn main() {
+    /// let re = Regex::new(r"(?P<first>\w+)\s+(?P<second>\w+)").unwrap();
+    /// let result = re.replace(b"deep fried", &b"${first}_$second"[..]);
+    /// assert_eq!(result, &b"deep_fried"[..]);
+    /// # }
+    /// ```
+    ///
+    /// Without the curly braces, the capture group name `first_` would be
+    /// used, and since it doesn't exist, it would be replaced with the empty
+    /// string.
+    ///
+    /// Finally, sometimes you just want to replace a literal string with no
+    /// regard for capturing group expansion. This can be done by wrapping a
+    /// byte string with `NoExpand`:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::bytes::Regex;
+    /// # fn main() {
+    /// use regex::bytes::NoExpand;
+    ///
+    /// let re = Regex::new(r"(?P<last>[^,\s]+),\s+(\S+)").unwrap();
+    /// let result = re.replace(b"Springsteen, Bruce", NoExpand(b"$2 $last"));
+    /// assert_eq!(result, &b"$2 $last"[..]);
+    /// # }
+    /// ```
+    pub fn replace<'t, R: Replacer>(
+        &self,
+        text: &'t [u8],
+        rep: R,
+    ) -> Cow<'t, [u8]> {
+        self.replacen(text, 1, rep)
+    }
+
+    /// Replaces all non-overlapping matches in `text` with the replacement
+    /// provided. This is the same as calling `replacen` with `limit` set to
+    /// `0`.
+    ///
+    /// See the documentation for `replace` for details on how to access
+    /// capturing group matches in the replacement text.
+    pub fn replace_all<'t, R: Replacer>(
+        &self,
+        text: &'t [u8],
+        rep: R,
+    ) -> Cow<'t, [u8]> {
+        self.replacen(text, 0, rep)
+    }
+
+    /// Replaces at most `limit` non-overlapping matches in `text` with the
+    /// replacement provided. If `limit` is 0, then all non-overlapping matches
+    /// are replaced.
+    ///
+    /// See the documentation for `replace` for details on how to access
+    /// capturing group matches in the replacement text.
+    pub fn replacen<'t, R: Replacer>(
+        &self,
+        text: &'t [u8],
+        limit: usize,
+        mut rep: R,
+    ) -> Cow<'t, [u8]> {
+        if let Some(rep) = rep.no_expansion() {
+            let mut it = self.find_iter(text).enumerate().peekable();
+            if it.peek().is_none() {
+                return Cow::Borrowed(text);
+            }
+            let mut new = Vec::with_capacity(text.len());
+            let mut last_match = 0;
+            for (i, m) in it {
+                if limit > 0 && i >= limit {
+                    break
+                }
+                new.extend_from_slice(&text[last_match..m.start()]);
+                new.extend_from_slice(&rep);
+                last_match = m.end();
+            }
+            new.extend_from_slice(&text[last_match..]);
+            return Cow::Owned(new);
+        }
+
+        // The slower path, which we use if the replacement needs access to
+        // capture groups.
+        let mut it = self.captures_iter(text).enumerate().peekable();
+        if it.peek().is_none() {
+            return Cow::Borrowed(text);
+        }
+        let mut new = Vec::with_capacity(text.len());
+        let mut last_match = 0;
+        for (i, cap) in it {
+            if limit > 0 && i >= limit {
+                break
+            }
+            // unwrap on 0 is OK because captures only reports matches
+            let m = cap.get(0).unwrap();
+            new.extend_from_slice(&text[last_match..m.start()]);
+            rep.replace_append(&cap, &mut new);
+            last_match = m.end();
+        }
+        new.extend_from_slice(&text[last_match..]);
+        Cow::Owned(new)
+    }
+}
+
+/// Advanced or "lower level" search methods.
+impl Regex {
+    /// Returns the end location of a match in the text given.
+    ///
+    /// This method may have the same performance characteristics as
+    /// `is_match`, except it provides an end location for a match. In
+    /// particular, the location returned *may be shorter* than the proper end
+    /// of the leftmost-first match.
+    ///
+    /// # Example
+    ///
+    /// Typically, `a+` would match the entire first sequence of `a` in some
+    /// text, but `shortest_match` can give up as soon as it sees the first
+    /// `a`.
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::bytes::Regex;
+    /// # fn main() {
+    /// let text = b"aaaaa";
+    /// let pos = Regex::new(r"a+").unwrap().shortest_match(text);
+    /// assert_eq!(pos, Some(1));
+    /// # }
+    /// ```
+    pub fn shortest_match(&self, text: &[u8]) -> Option<usize> {
+        self.shortest_match_at(text, 0)
+    }
+
+    /// Returns the same as shortest_match, but starts the search at the given
+    /// offset.
+    ///
+    /// The significance of the starting point is that it takes the surrounding
+    /// context into consideration. For example, the `\A` anchor can only
+    /// match when `start == 0`.
+    pub fn shortest_match_at(
+        &self,
+        text: &[u8],
+        start: usize,
+    ) -> Option<usize> {
+        self.0.searcher().shortest_match_at(text, start)
+    }
+
+    /// Returns the same as is_match, but starts the search at the given
+    /// offset.
+    ///
+    /// The significance of the starting point is that it takes the surrounding
+    /// context into consideration. For example, the `\A` anchor can only
+    /// match when `start == 0`.
+    pub fn is_match_at(&self, text: &[u8], start: usize) -> bool {
+        self.shortest_match_at(text, start).is_some()
+    }
+
+    /// Returns the same as find, but starts the search at the given
+    /// offset.
+    ///
+    /// The significance of the starting point is that it takes the surrounding
+    /// context into consideration. For example, the `\A` anchor can only
+    /// match when `start == 0`.
+    pub fn find_at<'t>(
+        &self,
+        text: &'t [u8],
+        start: usize,
+    ) -> Option<Match<'t>> {
+        self.0.searcher().find_at(text, start)
+            .map(|(s, e)| Match::new(text, s, e))
+    }
+
+    /// This is like `captures`, but uses
+    /// [`CaptureLocations`](struct.CaptureLocations.html)
+    /// instead of
+    /// [`Captures`](struct.Captures.html) in order to amortize allocations.
+    ///
+    /// To create a `CaptureLocations` value, use the
+    /// `Regex::capture_locations` method.
+    ///
+    /// This returns the overall match if this was successful, which is always
+    /// equivalence to the `0`th capture group.
+    pub fn captures_read<'t>(
+        &self,
+        locs: &mut CaptureLocations,
+        text: &'t [u8],
+    ) -> Option<Match<'t>> {
+        self.captures_read_at(locs, text, 0)
+    }
+
+    /// Returns the same as `captures_read`, but starts the search at the given
+    /// offset and populates the capture locations given.
+    ///
+    /// The significance of the starting point is that it takes the surrounding
+    /// context into consideration. For example, the `\A` anchor can only
+    /// match when `start == 0`.
+    pub fn captures_read_at<'t>(
+        &self,
+        locs: &mut CaptureLocations,
+        text: &'t [u8],
+        start: usize,
+    ) -> Option<Match<'t>> {
+        self.0
+            .searcher()
+            .captures_read_at(&mut locs.0, text, start)
+            .map(|(s, e)| Match::new(text, s, e))
+    }
+
+    /// An undocumented alias for `captures_read_at`.
+    ///
+    /// The `regex-capi` crate previously used this routine, so to avoid
+    /// breaking that crate, we continue to provide the name as an undocumented
+    /// alias.
+    #[doc(hidden)]
+    pub fn read_captures_at<'t>(
+        &self,
+        locs: &mut CaptureLocations,
+        text: &'t [u8],
+        start: usize,
+    ) -> Option<Match<'t>> {
+        self.captures_read_at(locs, text, start)
+    }
+}
+
+/// Auxiliary methods.
+impl Regex {
+    /// Returns the original string of this regex.
+    pub fn as_str(&self) -> &str {
+        &self.0.regex_strings()[0]
+    }
+
+    /// Returns an iterator over the capture names.
+    pub fn capture_names(&self) -> CaptureNames {
+        CaptureNames(self.0.capture_names().iter())
+    }
+
+    /// Returns the number of captures.
+    pub fn captures_len(&self) -> usize {
+        self.0.capture_names().len()
+    }
+
+    /// Returns an empty set of capture locations that can be reused in
+    /// multiple calls to `captures_read` or `captures_read_at`.
+    pub fn capture_locations(&self) -> CaptureLocations {
+        CaptureLocations(self.0.searcher().locations())
+    }
+
+    /// An alias for `capture_locations` to preserve backward compatibility.
+    ///
+    /// The `regex-capi` crate uses this method, so to avoid breaking that
+    /// crate, we continue to export it as an undocumented API.
+    #[doc(hidden)]
+    pub fn locations(&self) -> CaptureLocations {
+        CaptureLocations(self.0.searcher().locations())
+    }
+}
+
+/// An iterator over all non-overlapping matches for a particular string.
+///
+/// The iterator yields a tuple of integers corresponding to the start and end
+/// of the match. The indices are byte offsets. The iterator stops when no more
+/// matches can be found.
+///
+/// `'r` is the lifetime of the compiled regular expression and `'t` is the
+/// lifetime of the matched byte string.
+pub struct Matches<'r, 't>(re_trait::Matches<'t, ExecNoSync<'r>>);
+
+impl<'r, 't> Iterator for Matches<'r, 't> {
+    type Item = Match<'t>;
+
+    fn next(&mut self) -> Option<Match<'t>> {
+        let text = self.0.text();
+        self.0.next().map(|(s, e)| Match::new(text, s, e))
+    }
+}
+
+/// An iterator that yields all non-overlapping capture groups matching a
+/// particular regular expression.
+///
+/// The iterator stops when no more matches can be found.
+///
+/// `'r` is the lifetime of the compiled regular expression and `'t` is the
+/// lifetime of the matched byte string.
+pub struct CaptureMatches<'r, 't>(re_trait::CaptureMatches<'t, ExecNoSync<'r>>);
+
+impl<'r, 't> Iterator for CaptureMatches<'r, 't> {
+    type Item = Captures<'t>;
+
+    fn next(&mut self) -> Option<Captures<'t>> {
+        self.0.next().map(|locs| Captures {
+            text: self.0.text(),
+            locs: locs,
+            named_groups: self.0.regex().capture_name_idx().clone(),
+        })
+    }
+}
+
+/// Yields all substrings delimited by a regular expression match.
+///
+/// `'r` is the lifetime of the compiled regular expression and `'t` is the
+/// lifetime of the byte string being split.
+pub struct Split<'r, 't> {
+    finder: Matches<'r, 't>,
+    last: usize,
+}
+
+impl<'r, 't> Iterator for Split<'r, 't> {
+    type Item = &'t [u8];
+
+    fn next(&mut self) -> Option<&'t [u8]> {
+        let text = self.finder.0.text();
+        match self.finder.next() {
+            None => {
+                if self.last >= text.len() {
+                    None
+                } else {
+                    let s = &text[self.last..];
+                    self.last = text.len();
+                    Some(s)
+                }
+            }
+            Some(m) => {
+                let matched = &text[self.last..m.start()];
+                self.last = m.end();
+                Some(matched)
+            }
+        }
+    }
+}
+
+/// Yields at most `N` substrings delimited by a regular expression match.
+///
+/// The last substring will be whatever remains after splitting.
+///
+/// `'r` is the lifetime of the compiled regular expression and `'t` is the
+/// lifetime of the byte string being split.
+pub struct SplitN<'r, 't> {
+    splits: Split<'r, 't>,
+    n: usize,
+}
+
+impl<'r, 't> Iterator for SplitN<'r, 't> {
+    type Item = &'t [u8];
+
+    fn next(&mut self) -> Option<&'t [u8]> {
+        if self.n == 0 {
+            return None
+        }
+        self.n -= 1;
+        if self.n == 0 {
+            let text = self.splits.finder.0.text();
+            Some(&text[self.splits.last..])
+        } else {
+            self.splits.next()
+        }
+    }
+}
+
+/// An iterator over the names of all possible captures.
+///
+/// `None` indicates an unnamed capture; the first element (capture 0, the
+/// whole matched region) is always unnamed.
+///
+/// `'r` is the lifetime of the compiled regular expression.
+pub struct CaptureNames<'r>(::std::slice::Iter<'r, Option<String>>);
+
+impl<'r> Iterator for CaptureNames<'r> {
+    type Item = Option<&'r str>;
+
+    fn next(&mut self) -> Option<Option<&'r str>> {
+        self.0.next().as_ref()
+            .map(|slot| slot.as_ref().map(|name| name.as_ref()))
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint()
+    }
+}
+
+/// CaptureLocations is a low level representation of the raw offsets of each
+/// submatch.
+///
+/// You can think of this as a lower level
+/// [`Captures`](struct.Captures.html), where this type does not support
+/// named capturing groups directly and it does not borrow the text that these
+/// offsets were matched on.
+///
+/// Primarily, this type is useful when using the lower level `Regex` APIs
+/// such as `read_captures`, which permits amortizing the allocation in which
+/// capture match locations are stored.
+///
+/// In order to build a value of this type, you'll need to call the
+/// `capture_locations` method on the `Regex` being used to execute the search.
+/// The value returned can then be reused in subsequent searches.
+#[derive(Clone, Debug)]
+pub struct CaptureLocations(re_trait::Locations);
+
+/// A type alias for `CaptureLocations` for backwards compatibility.
+///
+/// Previously, we exported `CaptureLocations` as `Locations` in an
+/// undocumented API. To prevent breaking that code (e.g., in `regex-capi`),
+/// we continue re-exporting the same undocumented API.
+#[doc(hidden)]
+pub type Locations = CaptureLocations;
+
+impl CaptureLocations {
+    /// Returns the start and end positions of the Nth capture group. Returns
+    /// `None` if `i` is not a valid capture group or if the capture group did
+    /// not match anything. The positions returned are *always* byte indices
+    /// with respect to the original string matched.
+    #[inline]
+    pub fn get(&self, i: usize) -> Option<(usize, usize)> {
+        self.0.pos(i)
+    }
+
+    /// Returns the total number of capturing groups.
+    ///
+    /// This is always at least `1` since every regex has at least `1`
+    /// capturing group that corresponds to the entire match.
+    #[inline]
+    pub fn len(&self) -> usize {
+        self.0.len()
+    }
+
+    /// An alias for the `get` method for backwards compatibility.
+    ///
+    /// Previously, we exported `get` as `pos` in an undocumented API. To
+    /// prevent breaking that code (e.g., in `regex-capi`), we continue
+    /// re-exporting the same undocumented API.
+    #[doc(hidden)]
+    #[inline]
+    pub fn pos(&self, i: usize) -> Option<(usize, usize)> {
+        self.get(i)
+    }
+}
+
+/// Captures represents a group of captured byte strings for a single match.
+///
+/// The 0th capture always corresponds to the entire match. Each subsequent
+/// index corresponds to the next capture group in the regex. If a capture
+/// group is named, then the matched byte string is *also* available via the
+/// `name` method. (Note that the 0th capture is always unnamed and so must be
+/// accessed with the `get` method.)
+///
+/// Positions returned from a capture group are always byte indices.
+///
+/// `'t` is the lifetime of the matched text.
+pub struct Captures<'t> {
+    text: &'t [u8],
+    locs: re_trait::Locations,
+    named_groups: Arc<HashMap<String, usize>>,
+}
+
+impl<'t> Captures<'t> {
+    /// Returns the match associated with the capture group at index `i`. If
+    /// `i` does not correspond to a capture group, or if the capture group
+    /// did not participate in the match, then `None` is returned.
+    ///
+    /// # Examples
+    ///
+    /// Get the text of the match with a default of an empty string if this
+    /// group didn't participate in the match:
+    ///
+    /// ```rust
+    /// # use regex::bytes::Regex;
+    /// let re = Regex::new(r"[a-z]+(?:([0-9]+)|([A-Z]+))").unwrap();
+    /// let caps = re.captures(b"abc123").unwrap();
+    ///
+    /// let text1 = caps.get(1).map_or(&b""[..], |m| m.as_bytes());
+    /// let text2 = caps.get(2).map_or(&b""[..], |m| m.as_bytes());
+    /// assert_eq!(text1, &b"123"[..]);
+    /// assert_eq!(text2, &b""[..]);
+    /// ```
+    pub fn get(&self, i: usize) -> Option<Match<'t>> {
+        self.locs.pos(i).map(|(s, e)| Match::new(self.text, s, e))
+    }
+
+    /// Returns the match for the capture group named `name`. If `name` isn't a
+    /// valid capture group or didn't match anything, then `None` is returned.
+    pub fn name(&self, name: &str) -> Option<Match<'t>> {
+        self.named_groups.get(name).and_then(|&i| self.get(i))
+    }
+
+    /// An iterator that yields all capturing matches in the order in which
+    /// they appear in the regex. If a particular capture group didn't
+    /// participate in the match, then `None` is yielded for that capture.
+    ///
+    /// The first match always corresponds to the overall match of the regex.
+    pub fn iter<'c>(&'c self) -> SubCaptureMatches<'c, 't> {
+        SubCaptureMatches {
+            caps: self,
+            it: self.locs.iter(),
+        }
+    }
+
+    /// Expands all instances of `$name` in `replacement` to the corresponding
+    /// capture group `name`, and writes them to the `dst` buffer given.
+    ///
+    /// `name` may be an integer corresponding to the index of the
+    /// capture group (counted by order of opening parenthesis where `0` is the
+    /// entire match) or it can be a name (consisting of letters, digits or
+    /// underscores) corresponding to a named capture group.
+    ///
+    /// If `name` isn't a valid capture group (whether the name doesn't exist
+    /// or isn't a valid index), then it is replaced with the empty string.
+    ///
+    /// The longest possible name is used. e.g., `$1a` looks up the capture
+    /// group named `1a` and not the capture group at index `1`. To exert more
+    /// precise control over the name, use braces, e.g., `${1}a`.
+    ///
+    /// To write a literal `$` use `$$`.
+    pub fn expand(&self, replacement: &[u8], dst: &mut Vec<u8>) {
+        expand_bytes(self, replacement, dst)
+    }
+
+    /// Returns the number of captured groups.
+    ///
+    /// This is always at least `1`, since every regex has at least one capture
+    /// group that corresponds to the full match.
+    #[inline]
+    pub fn len(&self) -> usize {
+        self.locs.len()
+    }
+}
+
+impl<'t> fmt::Debug for Captures<'t> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_tuple("Captures").field(&CapturesDebug(self)).finish()
+    }
+}
+
+struct CapturesDebug<'c, 't: 'c>(&'c Captures<'t>);
+
+impl<'c, 't> fmt::Debug for CapturesDebug<'c, 't> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fn escape_bytes(bytes: &[u8]) -> String {
+            let mut s = String::new();
+            for &b in bytes {
+                s.push_str(&escape_byte(b));
+            }
+            s
+        }
+
+        fn escape_byte(byte: u8) -> String {
+            use std::ascii::escape_default;
+
+            let escaped: Vec<u8> = escape_default(byte).collect();
+            String::from_utf8_lossy(&escaped).into_owned()
+        }
+
+        // We'd like to show something nice here, even if it means an
+        // allocation to build a reverse index.
+        let slot_to_name: HashMap<&usize, &String> =
+            self.0.named_groups.iter().map(|(a, b)| (b, a)).collect();
+        let mut map = f.debug_map();
+        for (slot, m) in self.0.locs.iter().enumerate() {
+            let m = m.map(|(s, e)| escape_bytes(&self.0.text[s..e]));
+            if let Some(name) = slot_to_name.get(&slot) {
+                map.entry(&name, &m);
+            } else {
+                map.entry(&slot, &m);
+            }
+        }
+        map.finish()
+    }
+}
+
+/// Get a group by index.
+///
+/// `'t` is the lifetime of the matched text.
+///
+/// The text can't outlive the `Captures` object if this method is
+/// used, because of how `Index` is defined (normally `a[i]` is part
+/// of `a` and can't outlive it); to do that, use `get()` instead.
+///
+/// # Panics
+///
+/// If there is no group at the given index.
+impl<'t> Index<usize> for Captures<'t> {
+    type Output = [u8];
+
+    fn index(&self, i: usize) -> &[u8] {
+        self.get(i).map(|m| m.as_bytes())
+            .unwrap_or_else(|| panic!("no group at index '{}'", i))
+    }
+}
+
+/// Get a group by name.
+///
+/// `'t` is the lifetime of the matched text and `'i` is the lifetime
+/// of the group name (the index).
+///
+/// The text can't outlive the `Captures` object if this method is
+/// used, because of how `Index` is defined (normally `a[i]` is part
+/// of `a` and can't outlive it); to do that, use `name` instead.
+///
+/// # Panics
+///
+/// If there is no group named by the given value.
+impl<'t, 'i> Index<&'i str> for Captures<'t> {
+    type Output = [u8];
+
+    fn index<'a>(&'a self, name: &'i str) -> &'a [u8] {
+        self.name(name).map(|m| m.as_bytes())
+            .unwrap_or_else(|| panic!("no group named '{}'", name))
+    }
+}
+
+/// An iterator that yields all capturing matches in the order in which they
+/// appear in the regex.
+///
+/// If a particular capture group didn't participate in the match, then `None`
+/// is yielded for that capture. The first match always corresponds to the
+/// overall match of the regex.
+///
+/// The lifetime `'c` corresponds to the lifetime of the `Captures` value, and
+/// the lifetime `'t` corresponds to the originally matched text.
+pub struct SubCaptureMatches<'c, 't: 'c> {
+    caps: &'c Captures<'t>,
+    it: SubCapturesPosIter<'c>,
+}
+
+impl<'c, 't> Iterator for SubCaptureMatches<'c, 't> {
+    type Item = Option<Match<'t>>;
+
+    fn next(&mut self) -> Option<Option<Match<'t>>> {
+        self.it.next()
+            .map(|cap| cap.map(|(s, e)| Match::new(self.caps.text, s, e)))
+    }
+}
+
+/// Replacer describes types that can be used to replace matches in a byte
+/// string.
+///
+/// In general, users of this crate shouldn't need to implement this trait,
+/// since implementations are already provided for `&[u8]` and
+/// `FnMut(&Captures) -> Vec<u8>` (or any `FnMut(&Captures) -> T`
+/// where `T: AsRef<[u8]>`), which covers most use cases.
+pub trait Replacer {
+    /// Appends text to `dst` to replace the current match.
+    ///
+    /// The current match is represented by `caps`, which is guaranteed to
+    /// have a match at capture group `0`.
+    ///
+    /// For example, a no-op replacement would be
+    /// `dst.extend(&caps[0])`.
+    fn replace_append(&mut self, caps: &Captures, dst: &mut Vec<u8>);
+
+    /// Return a fixed unchanging replacement byte string.
+    ///
+    /// When doing replacements, if access to `Captures` is not needed (e.g.,
+    /// the replacement byte string does not need `$` expansion), then it can
+    /// be beneficial to avoid finding sub-captures.
+    ///
+    /// In general, this is called once for every call to `replacen`.
+    fn no_expansion<'r>(&'r mut self) -> Option<Cow<'r, [u8]>> {
+        None
+    }
+
+    /// Return a `Replacer` that borrows and wraps this `Replacer`.
+    ///
+    /// This is useful when you want to take a generic `Replacer` (which might
+    /// not be cloneable) and use it without consuming it, so it can be used
+    /// more than once.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use regex::bytes::{Regex, Replacer};
+    ///
+    /// fn replace_all_twice<R: Replacer>(
+    ///     re: Regex,
+    ///     src: &[u8],
+    ///     mut rep: R,
+    /// ) -> Vec<u8> {
+    ///     let dst = re.replace_all(src, rep.by_ref());
+    ///     let dst = re.replace_all(&dst, rep.by_ref());
+    ///     dst.into_owned()
+    /// }
+    /// ```
+    fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self> {
+        ReplacerRef(self)
+    }
+}
+
+/// By-reference adaptor for a `Replacer`
+///
+/// Returned by [`Replacer::by_ref`](trait.Replacer.html#method.by_ref).
+#[derive(Debug)]
+pub struct ReplacerRef<'a, R: ?Sized + 'a>(&'a mut R);
+
+impl<'a, R: Replacer + ?Sized + 'a> Replacer for ReplacerRef<'a, R> {
+    fn replace_append(&mut self, caps: &Captures, dst: &mut Vec<u8>) {
+        self.0.replace_append(caps, dst)
+    }
+    fn no_expansion<'r>(&'r mut self) -> Option<Cow<'r, [u8]>> {
+        self.0.no_expansion()
+    }
+}
+
+impl<'a> Replacer for &'a [u8] {
+    fn replace_append(&mut self, caps: &Captures, dst: &mut Vec<u8>) {
+        caps.expand(*self, dst);
+    }
+
+    fn no_expansion(&mut self) -> Option<Cow<[u8]>> {
+        match memchr(b'$', *self) {
+            Some(_) => None,
+            None => Some(Cow::Borrowed(*self)),
+        }
+    }
+}
+
+impl<F, T> Replacer for F where F: FnMut(&Captures) -> T, T: AsRef<[u8]> {
+    fn replace_append(&mut self, caps: &Captures, dst: &mut Vec<u8>) {
+        dst.extend_from_slice((*self)(caps).as_ref());
+    }
+}
+
+/// `NoExpand` indicates literal byte string replacement.
+///
+/// It can be used with `replace` and `replace_all` to do a literal byte string
+/// replacement without expanding `$name` to their corresponding capture
+/// groups. This can be both convenient (to avoid escaping `$`, for example)
+/// and performant (since capture groups don't need to be found).
+///
+/// `'t` is the lifetime of the literal text.
+pub struct NoExpand<'t>(pub &'t [u8]);
+
+impl<'t> Replacer for NoExpand<'t> {
+    fn replace_append(&mut self, _: &Captures, dst: &mut Vec<u8>) {
+        dst.extend_from_slice(self.0);
+    }
+
+    fn no_expansion(&mut self) -> Option<Cow<[u8]>> {
+        Some(Cow::Borrowed(self.0))
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/re_set.rs.html b/target/doc/src/regex/re_set.rs.html new file mode 100644 index 0000000..2cc711b --- /dev/null +++ b/target/doc/src/regex/re_set.rs.html @@ -0,0 +1,927 @@ +re_set.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+macro_rules! define_set {
+    ($name:ident, $builder_mod:ident, $text_ty:ty, $as_bytes:expr,
+     $(#[$doc_regexset_example:meta])* ) => {
+        pub mod $name {
+            use std::fmt;
+            use std::iter;
+            use std::slice;
+            use std::vec;
+
+            use error::Error;
+            use exec::Exec;
+            use re_builder::$builder_mod::RegexSetBuilder;
+            use re_trait::RegularExpression;
+
+/// Match multiple (possibly overlapping) regular expressions in a single scan.
+///
+/// A regex set corresponds to the union of two or more regular expressions.
+/// That is, a regex set will match text where at least one of its
+/// constituent regular expressions matches. A regex set as its formulated here
+/// provides a touch more power: it will also report *which* regular
+/// expressions in the set match. Indeed, this is the key difference between
+/// regex sets and a single `Regex` with many alternates, since only one
+/// alternate can match at a time.
+///
+/// For example, consider regular expressions to match email addresses and
+/// domains: `[a-z]+@[a-z]+\.(com|org|net)` and `[a-z]+\.(com|org|net)`. If a
+/// regex set is constructed from those regexes, then searching the text
+/// `foo@example.com` will report both regexes as matching. Of course, one
+/// could accomplish this by compiling each regex on its own and doing two
+/// searches over the text. The key advantage of using a regex set is that it
+/// will report the matching regexes using a *single pass through the text*.
+/// If one has hundreds or thousands of regexes to match repeatedly (like a URL
+/// router for a complex web application or a user agent matcher), then a regex
+/// set can realize huge performance gains.
+///
+/// # Example
+///
+/// This shows how the above two regexes (for matching email addresses and
+/// domains) might work:
+///
+$(#[$doc_regexset_example])*
+///
+/// Note that it would be possible to adapt the above example to using `Regex`
+/// with an expression like:
+///
+/// ```ignore
+/// (?P<email>[a-z]+@(?P<email_domain>[a-z]+[.](com|org|net)))|(?P<domain>[a-z]+[.](com|org|net))
+/// ```
+///
+/// After a match, one could then inspect the capture groups to figure out
+/// which alternates matched. The problem is that it is hard to make this
+/// approach scale when there are many regexes since the overlap between each
+/// alternate isn't always obvious to reason about.
+///
+/// # Limitations
+///
+/// Regex sets are limited to answering the following two questions:
+///
+/// 1. Does any regex in the set match?
+/// 2. If so, which regexes in the set match?
+///
+/// As with the main `Regex` type, it is cheaper to ask (1) instead of (2)
+/// since the matching engines can stop after the first match is found.
+///
+/// Other features like finding the location of successive matches or their
+/// sub-captures aren't supported. If you need this functionality, the
+/// recommended approach is to compile each regex in the set independently and
+/// selectively match them based on which regexes in the set matched.
+///
+/// # Performance
+///
+/// A `RegexSet` has the same performance characteristics as `Regex`. Namely,
+/// search takes `O(mn)` time, where `m` is proportional to the size of the
+/// regex set and `n` is proportional to the length of the search text.
+#[derive(Clone)]
+pub struct RegexSet(Exec);
+
+impl RegexSet {
+    /// Create a new regex set with the given regular expressions.
+    ///
+    /// This takes an iterator of `S`, where `S` is something that can produce
+    /// a `&str`. If any of the strings in the iterator are not valid regular
+    /// expressions, then an error is returned.
+    ///
+    /// # Example
+    ///
+    /// Create a new regex set from an iterator of strings:
+    ///
+    /// ```rust
+    /// # use regex::RegexSet;
+    /// let set = RegexSet::new(&[r"\w+", r"\d+"]).unwrap();
+    /// assert!(set.is_match("foo"));
+    /// ```
+    pub fn new<I, S>(exprs: I) -> Result<RegexSet, Error>
+            where S: AsRef<str>, I: IntoIterator<Item=S> {
+        RegexSetBuilder::new(exprs).build()
+    }
+
+    /// Returns true if and only if one of the regexes in this set matches
+    /// the text given.
+    ///
+    /// This method should be preferred if you only need to test whether any
+    /// of the regexes in the set should match, but don't care about *which*
+    /// regexes matched. This is because the underlying matching engine will
+    /// quit immediately after seeing the first match instead of continuing to
+    /// find all matches.
+    ///
+    /// Note that as with searches using `Regex`, the expression is unanchored
+    /// by default. That is, if the regex does not start with `^` or `\A`, or
+    /// end with `$` or `\z`, then it is permitted to match anywhere in the
+    /// text.
+    ///
+    /// # Example
+    ///
+    /// Tests whether a set matches some text:
+    ///
+    /// ```rust
+    /// # use regex::RegexSet;
+    /// let set = RegexSet::new(&[r"\w+", r"\d+"]).unwrap();
+    /// assert!(set.is_match("foo"));
+    /// assert!(!set.is_match("☃"));
+    /// ```
+    pub fn is_match(&self, text: $text_ty) -> bool {
+        self.is_match_at(text, 0)
+    }
+
+    /// Returns the same as is_match, but starts the search at the given
+    /// offset.
+    ///
+    /// The significance of the starting point is that it takes the surrounding
+    /// context into consideration. For example, the `\A` anchor can only
+    /// match when `start == 0`.
+    #[doc(hidden)]
+    pub fn is_match_at(&self, text: $text_ty, start: usize) -> bool {
+        self.0.searcher().is_match_at($as_bytes(text), start)
+    }
+
+    /// Returns the set of regular expressions that match in the given text.
+    ///
+    /// The set returned contains the index of each regular expression that
+    /// matches in the given text. The index is in correspondence with the
+    /// order of regular expressions given to `RegexSet`'s constructor.
+    ///
+    /// The set can also be used to iterate over the matched indices.
+    ///
+    /// Note that as with searches using `Regex`, the expression is unanchored
+    /// by default. That is, if the regex does not start with `^` or `\A`, or
+    /// end with `$` or `\z`, then it is permitted to match anywhere in the
+    /// text.
+    ///
+    /// # Example
+    ///
+    /// Tests which regular expressions match the given text:
+    ///
+    /// ```rust
+    /// # use regex::RegexSet;
+    /// let set = RegexSet::new(&[
+    ///     r"\w+",
+    ///     r"\d+",
+    ///     r"\pL+",
+    ///     r"foo",
+    ///     r"bar",
+    ///     r"barfoo",
+    ///     r"foobar",
+    /// ]).unwrap();
+    /// let matches: Vec<_> = set.matches("foobar").into_iter().collect();
+    /// assert_eq!(matches, vec![0, 2, 3, 4, 6]);
+    ///
+    /// // You can also test whether a particular regex matched:
+    /// let matches = set.matches("foobar");
+    /// assert!(!matches.matched(5));
+    /// assert!(matches.matched(6));
+    /// ```
+    pub fn matches(&self, text: $text_ty) -> SetMatches {
+        let mut matches = vec![false; self.0.regex_strings().len()];
+        let any = self.read_matches_at(&mut matches, text, 0);
+        SetMatches {
+            matched_any: any,
+            matches: matches,
+        }
+    }
+
+    /// Returns the same as matches, but starts the search at the given
+    /// offset and stores the matches into the slice given.
+    ///
+    /// The significance of the starting point is that it takes the surrounding
+    /// context into consideration. For example, the `\A` anchor can only
+    /// match when `start == 0`.
+    ///
+    /// `matches` must have a length that is at least the number of regexes
+    /// in this set.
+    ///
+    /// This method returns true if and only if at least one member of
+    /// `matches` is true after executing the set against `text`.
+    #[doc(hidden)]
+    pub fn read_matches_at(
+        &self,
+        matches: &mut [bool],
+        text: $text_ty,
+        start: usize,
+    ) -> bool {
+        self.0.searcher().many_matches_at(matches, $as_bytes(text), start)
+    }
+
+    /// Returns the total number of regular expressions in this set.
+    pub fn len(&self) -> usize {
+        self.0.regex_strings().len()
+    }
+
+    /// Returns the patterns that this set will match on.
+    ///
+    /// This function can be used to determine the pattern for a match. The 
+    /// slice returned has exactly as many patterns givens to this regex set, 
+    /// and the order of the slice is the same as the order of the patterns 
+    /// provided to the set.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// # use regex::RegexSet;
+    /// let set = RegexSet::new(&[
+    ///     r"\w+",
+    ///     r"\d+",
+    ///     r"\pL+",
+    ///     r"foo",
+    ///     r"bar",
+    ///     r"barfoo",
+    ///     r"foobar",
+    /// ]).unwrap();
+    /// let matches: Vec<_> = set
+    ///     .matches("foobar")
+    ///     .into_iter()
+    ///     .map(|match_idx| &set.patterns()[match_idx])
+    ///     .collect();
+    /// assert_eq!(matches, vec![r"\w+", r"\pL+", r"foo", r"bar", r"foobar"]);
+    /// ```
+    pub fn patterns(&self) -> &[String] {
+        self.0.regex_strings()
+    }
+}
+
+/// A set of matches returned by a regex set.
+#[derive(Clone, Debug)]
+pub struct SetMatches {
+    matched_any: bool,
+    matches: Vec<bool>,
+}
+
+impl SetMatches {
+    /// Whether this set contains any matches.
+    pub fn matched_any(&self) -> bool {
+        self.matched_any
+    }
+
+    /// Whether the regex at the given index matched.
+    ///
+    /// The index for a regex is determined by its insertion order upon the
+    /// initial construction of a `RegexSet`, starting at `0`.
+    ///
+    /// # Panics
+    ///
+    /// If `regex_index` is greater than or equal to `self.len()`.
+    pub fn matched(&self, regex_index: usize) -> bool {
+        self.matches[regex_index]
+    }
+
+    /// The total number of regexes in the set that created these matches.
+    pub fn len(&self) -> usize {
+        self.matches.len()
+    }
+
+    /// Returns an iterator over indexes in the regex that matched.
+    ///
+    /// This will always produces matches in ascending order of index, where
+    /// the index corresponds to the index of the regex that matched with
+    /// respect to its position when initially building the set.
+    pub fn iter(&self) -> SetMatchesIter {
+        SetMatchesIter((&*self.matches).into_iter().enumerate())
+    }
+}
+
+impl IntoIterator for SetMatches {
+    type IntoIter = SetMatchesIntoIter;
+    type Item = usize;
+
+    fn into_iter(self) -> Self::IntoIter {
+        SetMatchesIntoIter(self.matches.into_iter().enumerate())
+    }
+}
+
+impl<'a> IntoIterator for &'a SetMatches {
+    type IntoIter = SetMatchesIter<'a>;
+    type Item = usize;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.iter()
+    }
+}
+
+/// An owned iterator over the set of matches from a regex set.
+///
+/// This will always produces matches in ascending order of index, where the
+/// index corresponds to the index of the regex that matched with respect to
+/// its position when initially building the set.
+pub struct SetMatchesIntoIter(iter::Enumerate<vec::IntoIter<bool>>);
+
+impl Iterator for SetMatchesIntoIter {
+    type Item = usize;
+
+    fn next(&mut self) -> Option<usize> {
+        loop {
+            match self.0.next() {
+                None => return None,
+                Some((_, false)) => {}
+                Some((i, true)) => return Some(i),
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint() 
+    }
+}
+
+impl DoubleEndedIterator for SetMatchesIntoIter {
+    fn next_back(&mut self) -> Option<usize> {
+        loop {
+            match self.0.next_back() {
+                None => return None,
+                Some((_, false)) => {}
+                Some((i, true)) => return Some(i),
+            }
+        }
+    }
+}
+
+/// A borrowed iterator over the set of matches from a regex set.
+///
+/// The lifetime `'a` refers to the lifetime of a `SetMatches` value.
+///
+/// This will always produces matches in ascending order of index, where the
+/// index corresponds to the index of the regex that matched with respect to
+/// its position when initially building the set.
+#[derive(Clone)]
+pub struct SetMatchesIter<'a>(iter::Enumerate<slice::Iter<'a, bool>>);
+
+impl<'a> Iterator for SetMatchesIter<'a> {
+    type Item = usize;
+
+    fn next(&mut self) -> Option<usize> {
+        loop {
+            match self.0.next() {
+                None => return None,
+                Some((_, &false)) => {}
+                Some((i, &true)) => return Some(i),
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint() 
+    }
+}
+
+impl<'a> DoubleEndedIterator for SetMatchesIter<'a> {
+    fn next_back(&mut self) -> Option<usize> {
+        loop {
+            match self.0.next_back() {
+                None => return None,
+                Some((_, &false)) => {}
+                Some((i, &true)) => return Some(i),
+            }
+        }
+    }
+}
+
+#[doc(hidden)]
+impl From<Exec> for RegexSet {
+    fn from(exec: Exec) -> Self {
+        RegexSet(exec)
+    }
+}
+
+impl fmt::Debug for RegexSet {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "RegexSet({:?})", self.0.regex_strings())
+    }
+}
+
+#[allow(dead_code)] fn as_bytes_str(text: &str) -> &[u8] { text.as_bytes() }
+#[allow(dead_code)] fn as_bytes_bytes(text: &[u8]) -> &[u8] { text }
+        }
+    }
+}
+
+define_set! {
+    unicode,
+    set_unicode,
+    &str,
+    as_bytes_str,
+/// ```rust
+/// # use regex::RegexSet;
+/// let set = RegexSet::new(&[
+///     r"[a-z]+@[a-z]+\.(com|org|net)",
+///     r"[a-z]+\.(com|org|net)",
+/// ]).unwrap();
+///
+/// // Ask whether any regexes in the set match.
+/// assert!(set.is_match("foo@example.com"));
+///
+/// // Identify which regexes in the set match.
+/// let matches: Vec<_> = set.matches("foo@example.com").into_iter().collect();
+/// assert_eq!(vec![0, 1], matches);
+///
+/// // Try again, but with text that only matches one of the regexes.
+/// let matches: Vec<_> = set.matches("example.com").into_iter().collect();
+/// assert_eq!(vec![1], matches);
+///
+/// // Try again, but with text that doesn't match any regex in the set.
+/// let matches: Vec<_> = set.matches("example").into_iter().collect();
+/// assert!(matches.is_empty());
+/// ```
+}
+
+define_set! {
+    bytes,
+    set_bytes,
+    &[u8],
+    as_bytes_bytes,
+/// ```rust
+/// # use regex::bytes::RegexSet;
+/// let set = RegexSet::new(&[
+///     r"[a-z]+@[a-z]+\.(com|org|net)",
+///     r"[a-z]+\.(com|org|net)",
+/// ]).unwrap();
+///
+/// // Ask whether any regexes in the set match.
+/// assert!(set.is_match(b"foo@example.com"));
+///
+/// // Identify which regexes in the set match.
+/// let matches: Vec<_> = set.matches(b"foo@example.com").into_iter().collect();
+/// assert_eq!(vec![0, 1], matches);
+///
+/// // Try again, but with text that only matches one of the regexes.
+/// let matches: Vec<_> = set.matches(b"example.com").into_iter().collect();
+/// assert_eq!(vec![1], matches);
+///
+/// // Try again, but with text that doesn't match any regex in the set.
+/// let matches: Vec<_> = set.matches(b"example").into_iter().collect();
+/// assert!(matches.is_empty());
+/// ```
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/re_trait.rs.html b/target/doc/src/regex/re_trait.rs.html new file mode 100644 index 0000000..cdfd4bb --- /dev/null +++ b/target/doc/src/regex/re_trait.rs.html @@ -0,0 +1,539 @@ +re_trait.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/// Slot is a single saved capture location. Note that there are two slots for
+/// every capture in a regular expression (one slot each for the start and end
+/// of the capture).
+pub type Slot = Option<usize>;
+
+/// Locations represents the offsets of each capturing group in a regex for
+/// a single match.
+///
+/// Unlike `Captures`, a `Locations` value only stores offsets.
+#[doc(hidden)]
+#[derive(Clone, Debug)]
+pub struct Locations(Vec<Slot>);
+
+impl Locations {
+    /// Returns the start and end positions of the Nth capture group. Returns
+    /// `None` if `i` is not a valid capture group or if the capture group did
+    /// not match anything. The positions returned are *always* byte indices
+    /// with respect to the original string matched.
+    pub fn pos(&self, i: usize) -> Option<(usize, usize)> {
+        let (s, e) = (i * 2, i * 2 + 1);
+        match (self.0.get(s), self.0.get(e)) {
+            (Some(&Some(s)), Some(&Some(e))) => Some((s, e)),
+            _ => None,
+        }
+    }
+
+    /// Creates an iterator of all the capture group positions in order of
+    /// appearance in the regular expression. Positions are byte indices
+    /// in terms of the original string matched.
+    pub fn iter(&self) -> SubCapturesPosIter {
+        SubCapturesPosIter { idx: 0, locs: self }
+    }
+
+    /// Returns the total number of capturing groups.
+    ///
+    /// This is always at least `1` since every regex has at least `1`
+    /// capturing group that corresponds to the entire match.
+    pub fn len(&self) -> usize {
+        self.0.len() / 2
+    }
+
+    /// Return the individual slots as a slice.
+    pub(crate) fn as_slots(&mut self) -> &mut [Slot] {
+        &mut self.0
+    }
+}
+
+/// An iterator over capture group positions for a particular match of a
+/// regular expression.
+///
+/// Positions are byte indices in terms of the original string matched.
+///
+/// `'c` is the lifetime of the captures.
+pub struct SubCapturesPosIter<'c> {
+    idx: usize,
+    locs: &'c Locations,
+}
+
+impl<'c> Iterator for SubCapturesPosIter<'c> {
+    type Item = Option<(usize, usize)>;
+
+    fn next(&mut self) -> Option<Option<(usize, usize)>> {
+        if self.idx >= self.locs.len() {
+            return None;
+        }
+        let x = match self.locs.pos(self.idx) {
+            None => Some(None),
+            Some((s, e)) => {
+                Some(Some((s, e)))
+            }
+        };
+        self.idx += 1;
+        x
+    }
+}
+
+/// `RegularExpression` describes types that can implement regex searching.
+///
+/// This trait is my attempt at reducing code duplication and to standardize
+/// the internal API. Specific duplication that is avoided are the `find`
+/// and `capture` iterators, which are slightly tricky.
+///
+/// It's not clear whether this trait is worth it, and it also isn't
+/// clear whether it's useful as a public trait or not. Methods like
+/// `next_after_empty` reak of bad design, but the rest of the methods seem
+/// somewhat reasonable. One particular thing this trait would expose would be
+/// the ability to start the search of a regex anywhere in a haystack, which
+/// isn't possible in the current public API.
+pub trait RegularExpression: Sized {
+    /// The type of the haystack.
+    type Text: ?Sized;
+
+    /// The number of capture slots in the compiled regular expression. This is
+    /// always two times the number of capture groups (two slots per group).
+    fn slots_len(&self) -> usize;
+
+    /// Allocates fresh space for all capturing groups in this regex.
+    fn locations(&self) -> Locations {
+        Locations(vec![None; self.slots_len()])
+    }
+
+    /// Returns the position of the next character after `i`.
+    ///
+    /// For example, a haystack with type `&[u8]` probably returns `i+1`,
+    /// whereas a haystack with type `&str` probably returns `i` plus the
+    /// length of the next UTF-8 sequence.
+    fn next_after_empty(&self, text: &Self::Text, i: usize) -> usize;
+
+    /// Returns the location of the shortest match.
+    fn shortest_match_at(
+        &self,
+        text: &Self::Text,
+        start: usize,
+    ) -> Option<usize>;
+
+    /// Returns whether the regex matches the text given.
+    fn is_match_at(
+        &self,
+        text: &Self::Text,
+        start: usize,
+    ) -> bool;
+
+    /// Returns the leftmost-first match location if one exists.
+    fn find_at(
+        &self,
+        text: &Self::Text,
+        start: usize,
+    ) -> Option<(usize, usize)>;
+
+    /// Returns the leftmost-first match location if one exists, and also
+    /// fills in any matching capture slot locations.
+    fn captures_read_at(
+        &self,
+        locs: &mut Locations,
+        text: &Self::Text,
+        start: usize,
+    ) -> Option<(usize, usize)>;
+
+    /// Returns an iterator over all non-overlapping successive leftmost-first
+    /// matches.
+    fn find_iter (
+        self,
+        text: &Self::Text,
+    ) -> Matches<Self> {
+        Matches {
+            re: self,
+            text: text,
+            last_end: 0,
+            last_match: None,
+        }
+    }
+
+    /// Returns an iterator over all non-overlapping successive leftmost-first
+    /// matches with captures.
+    fn captures_iter(
+        self,
+        text: &Self::Text,
+    ) -> CaptureMatches<Self> {
+        CaptureMatches(self.find_iter(text))
+    }
+}
+
+/// An iterator over all non-overlapping successive leftmost-first matches.
+pub struct Matches<'t, R> where R: RegularExpression, R::Text: 't {
+    re: R,
+    text: &'t R::Text,
+    last_end: usize,
+    last_match: Option<usize>,
+}
+
+impl<'t, R> Matches<'t, R> where R: RegularExpression, R::Text: 't {
+    /// Return the text being searched.
+    pub fn text(&self) -> &'t R::Text {
+        self.text
+    }
+
+    /// Return the underlying regex.
+    pub fn regex(&self) -> &R {
+        &self.re
+    }
+}
+
+impl<'t, R> Iterator for Matches<'t, R>
+        where R: RegularExpression, R::Text: 't + AsRef<[u8]> {
+    type Item = (usize, usize);
+
+    fn next(&mut self) -> Option<(usize, usize)> {
+        if self.last_end > self.text.as_ref().len() {
+            return None;
+        }
+        let (s, e) = match self.re.find_at(self.text, self.last_end) {
+            None => return None,
+            Some((s, e)) => (s, e),
+        };
+        if s == e {
+            // This is an empty match. To ensure we make progress, start
+            // the next search at the smallest possible starting position
+            // of the next match following this one.
+            self.last_end = self.re.next_after_empty(self.text, e);
+            // Don't accept empty matches immediately following a match.
+            // Just move on to the next match.
+            if Some(e) == self.last_match {
+                return self.next();
+            }
+        } else {
+            self.last_end = e;
+        }
+        self.last_match = Some(e);
+        Some((s, e))
+    }
+}
+
+/// An iterator over all non-overlapping successive leftmost-first matches with
+/// captures.
+pub struct CaptureMatches<'t, R>(Matches<'t, R>)
+    where R: RegularExpression, R::Text: 't;
+
+impl<'t, R> CaptureMatches<'t, R> where R: RegularExpression, R::Text: 't {
+    /// Return the text being searched.
+    pub fn text(&self) -> &'t R::Text {
+        self.0.text()
+    }
+
+    /// Return the underlying regex.
+    pub fn regex(&self) -> &R {
+        self.0.regex()
+    }
+}
+
+impl<'t, R> Iterator for CaptureMatches<'t, R>
+        where R: RegularExpression, R::Text: 't + AsRef<[u8]> {
+    type Item = Locations;
+
+    fn next(&mut self) -> Option<Locations> {
+        if self.0.last_end > self.0.text.as_ref().len() {
+            return None
+        }
+        let mut locs = self.0.re.locations();
+        let (s, e) = match self.0.re.captures_read_at(
+            &mut locs,
+            self.0.text,
+            self.0.last_end,
+        ) {
+            None => return None,
+            Some((s, e)) => (s, e),
+        };
+        if s == e {
+            self.0.last_end = self.0.re.next_after_empty(self.0.text, e);
+            if Some(e) == self.0.last_match {
+                return self.next();
+            }
+        } else {
+            self.0.last_end = e;
+        }
+        self.0.last_match = Some(e);
+        Some(locs)
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/re_unicode.rs.html b/target/doc/src/regex/re_unicode.rs.html new file mode 100644 index 0000000..69d763d --- /dev/null +++ b/target/doc/src/regex/re_unicode.rs.html @@ -0,0 +1,2425 @@ +re_unicode.rs.html -- source
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::borrow::Cow;
+use std::collections::HashMap;
+use std::fmt;
+use std::ops::Index;
+use std::str::FromStr;
+use std::sync::Arc;
+
+use memchr::memchr;
+use syntax;
+
+use error::Error;
+use exec::{Exec, ExecNoSyncStr};
+use expand::expand_str;
+use re_builder::unicode::RegexBuilder;
+use re_trait::{self, RegularExpression, SubCapturesPosIter};
+
+/// Escapes all regular expression meta characters in `text`.
+///
+/// The string returned may be safely used as a literal in a regular
+/// expression.
+pub fn escape(text: &str) -> String {
+    syntax::escape(text)
+}
+
+/// Match represents a single match of a regex in a haystack.
+///
+/// The lifetime parameter `'t` refers to the lifetime of the matched text.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub struct Match<'t> {
+    text: &'t str,
+    start: usize,
+    end: usize,
+}
+
+impl<'t> Match<'t> {
+    /// Returns the starting byte offset of the match in the haystack.
+    #[inline]
+    pub fn start(&self) -> usize {
+        self.start
+    }
+
+    /// Returns the ending byte offset of the match in the haystack.
+    #[inline]
+    pub fn end(&self) -> usize {
+        self.end
+    }
+
+    /// Returns the matched text.
+    #[inline]
+    pub fn as_str(&self) -> &'t str {
+        &self.text[self.start..self.end]
+    }
+
+    /// Creates a new match from the given haystack and byte offsets.
+    #[inline]
+    fn new(haystack: &'t str, start: usize, end: usize) -> Match<'t> {
+        Match {
+            text: haystack,
+            start: start,
+            end: end,
+        }
+    }
+}
+
+impl<'t> From<Match<'t>> for &'t str {
+    fn from(m: Match<'t>) -> &'t str {
+        m.as_str()
+    }
+}
+
+/// A compiled regular expression for matching Unicode strings.
+///
+/// It is represented as either a sequence of bytecode instructions (dynamic)
+/// or as a specialized Rust function (native). It can be used to search, split
+/// or replace text. All searching is done with an implicit `.*?` at the
+/// beginning and end of an expression. To force an expression to match the
+/// whole string (or a prefix or a suffix), you must use an anchor like `^` or
+/// `$` (or `\A` and `\z`).
+///
+/// While this crate will handle Unicode strings (whether in the regular
+/// expression or in the search text), all positions returned are **byte
+/// indices**. Every byte index is guaranteed to be at a Unicode code point
+/// boundary.
+///
+/// The lifetimes `'r` and `'t` in this crate correspond to the lifetime of a
+/// compiled regular expression and text to search, respectively.
+///
+/// The only methods that allocate new strings are the string replacement
+/// methods. All other methods (searching and splitting) return borrowed
+/// pointers into the string given.
+///
+/// # Examples
+///
+/// Find the location of a US phone number:
+///
+/// ```rust
+/// # use regex::Regex;
+/// let re = Regex::new("[0-9]{3}-[0-9]{3}-[0-9]{4}").unwrap();
+/// let mat = re.find("phone: 111-222-3333").unwrap();
+/// assert_eq!((mat.start(), mat.end()), (7, 19));
+/// ```
+///
+/// # Using the `std::str::pattern` methods with `Regex`
+///
+/// > **Note**: This section requires that this crate is compiled with the
+/// > `pattern` Cargo feature enabled, which **requires nightly Rust**.
+///
+/// Since `Regex` implements `Pattern`, you can use regexes with methods
+/// defined on `&str`. For example, `is_match`, `find`, `find_iter`
+/// and `split` can be replaced with `str::contains`, `str::find`,
+/// `str::match_indices` and `str::split`.
+///
+/// Here are some examples:
+///
+/// ```rust,ignore
+/// # use regex::Regex;
+/// let re = Regex::new(r"\d+").unwrap();
+/// let haystack = "a111b222c";
+///
+/// assert!(haystack.contains(&re));
+/// assert_eq!(haystack.find(&re), Some(1));
+/// assert_eq!(haystack.match_indices(&re).collect::<Vec<_>>(),
+///            vec![(1, 4), (5, 8)]);
+/// assert_eq!(haystack.split(&re).collect::<Vec<_>>(), vec!["a", "b", "c"]);
+/// ```
+#[derive(Clone)]
+pub struct Regex(Exec);
+
+impl fmt::Display for Regex {
+    /// Shows the original regular expression.
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}", self.as_str())
+    }
+}
+
+impl fmt::Debug for Regex {
+    /// Shows the original regular expression.
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(self, f)
+    }
+}
+
+#[doc(hidden)]
+impl From<Exec> for Regex {
+    fn from(exec: Exec) -> Regex {
+        Regex(exec)
+    }
+}
+
+impl FromStr for Regex {
+    type Err = Error;
+
+    /// Attempts to parse a string into a regular expression
+    fn from_str(s: &str) -> Result<Regex, Error> {
+        Regex::new(s)
+    }
+}
+
+/// Core regular expression methods.
+impl Regex {
+    /// Compiles a regular expression. Once compiled, it can be used repeatedly
+    /// to search, split or replace text in a string.
+    ///
+    /// If an invalid expression is given, then an error is returned.
+    pub fn new(re: &str) -> Result<Regex, Error> {
+        RegexBuilder::new(re).build()
+    }
+
+    /// Returns true if and only if the regex matches the string given.
+    ///
+    /// It is recommended to use this method if all you need to do is test
+    /// a match, since the underlying matching engine may be able to do less
+    /// work.
+    ///
+    /// # Example
+    ///
+    /// Test if some text contains at least one word with exactly 13
+    /// Unicode word characters:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::Regex;
+    /// # fn main() {
+    /// let text = "I categorically deny having triskaidekaphobia.";
+    /// assert!(Regex::new(r"\b\w{13}\b").unwrap().is_match(text));
+    /// # }
+    /// ```
+    pub fn is_match(&self, text: &str) -> bool {
+        self.is_match_at(text, 0)
+    }
+
+    /// Returns the start and end byte range of the leftmost-first match in
+    /// `text`. If no match exists, then `None` is returned.
+    ///
+    /// Note that this should only be used if you want to discover the position
+    /// of the match. Testing the existence of a match is faster if you use
+    /// `is_match`.
+    ///
+    /// # Example
+    ///
+    /// Find the start and end location of the first word with exactly 13
+    /// Unicode word characters:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::Regex;
+    /// # fn main() {
+    /// let text = "I categorically deny having triskaidekaphobia.";
+    /// let mat = Regex::new(r"\b\w{13}\b").unwrap().find(text).unwrap();
+    /// assert_eq!(mat.start(), 2);
+    /// assert_eq!(mat.end(), 15);
+    /// # }
+    /// ```
+    pub fn find<'t>(&self, text: &'t str) -> Option<Match<'t>> {
+        self.find_at(text, 0)
+    }
+
+    /// Returns an iterator for each successive non-overlapping match in
+    /// `text`, returning the start and end byte indices with respect to
+    /// `text`.
+    ///
+    /// # Example
+    ///
+    /// Find the start and end location of every word with exactly 13 Unicode
+    /// word characters:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::Regex;
+    /// # fn main() {
+    /// let text = "Retroactively relinquishing remunerations is reprehensible.";
+    /// for mat in Regex::new(r"\b\w{13}\b").unwrap().find_iter(text) {
+    ///     println!("{:?}", mat);
+    /// }
+    /// # }
+    /// ```
+    pub fn find_iter<'r, 't>(&'r self, text: &'t str) -> Matches<'r, 't> {
+        Matches(self.0.searcher_str().find_iter(text))
+    }
+
+    /// Returns the capture groups corresponding to the leftmost-first
+    /// match in `text`. Capture group `0` always corresponds to the entire
+    /// match. If no match is found, then `None` is returned.
+    ///
+    /// You should only use `captures` if you need access to the location of
+    /// capturing group matches. Otherwise, `find` is faster for discovering
+    /// the location of the overall match.
+    ///
+    /// # Examples
+    ///
+    /// Say you have some text with movie names and their release years,
+    /// like "'Citizen Kane' (1941)". It'd be nice if we could search for text
+    /// looking like that, while also extracting the movie name and its release
+    /// year separately.
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::Regex;
+    /// # fn main() {
+    /// let re = Regex::new(r"'([^']+)'\s+\((\d{4})\)").unwrap();
+    /// let text = "Not my favorite movie: 'Citizen Kane' (1941).";
+    /// let caps = re.captures(text).unwrap();
+    /// assert_eq!(caps.get(1).unwrap().as_str(), "Citizen Kane");
+    /// assert_eq!(caps.get(2).unwrap().as_str(), "1941");
+    /// assert_eq!(caps.get(0).unwrap().as_str(), "'Citizen Kane' (1941)");
+    /// // You can also access the groups by index using the Index notation.
+    /// // Note that this will panic on an invalid index.
+    /// assert_eq!(&caps[1], "Citizen Kane");
+    /// assert_eq!(&caps[2], "1941");
+    /// assert_eq!(&caps[0], "'Citizen Kane' (1941)");
+    /// # }
+    /// ```
+    ///
+    /// Note that the full match is at capture group `0`. Each subsequent
+    /// capture group is indexed by the order of its opening `(`.
+    ///
+    /// We can make this example a bit clearer by using *named* capture groups:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::Regex;
+    /// # fn main() {
+    /// let re = Regex::new(r"'(?P<title>[^']+)'\s+\((?P<year>\d{4})\)")
+    ///                .unwrap();
+    /// let text = "Not my favorite movie: 'Citizen Kane' (1941).";
+    /// let caps = re.captures(text).unwrap();
+    /// assert_eq!(caps.name("title").unwrap().as_str(), "Citizen Kane");
+    /// assert_eq!(caps.name("year").unwrap().as_str(), "1941");
+    /// assert_eq!(caps.get(0).unwrap().as_str(), "'Citizen Kane' (1941)");
+    /// // You can also access the groups by name using the Index notation.
+    /// // Note that this will panic on an invalid group name.
+    /// assert_eq!(&caps["title"], "Citizen Kane");
+    /// assert_eq!(&caps["year"], "1941");
+    /// assert_eq!(&caps[0], "'Citizen Kane' (1941)");
+    ///
+    /// # }
+    /// ```
+    ///
+    /// Here we name the capture groups, which we can access with the `name`
+    /// method or the `Index` notation with a `&str`. Note that the named
+    /// capture groups are still accessible with `get` or the `Index` notation
+    /// with a `usize`.
+    ///
+    /// The `0`th capture group is always unnamed, so it must always be
+    /// accessed with `get(0)` or `[0]`.
+    pub fn captures<'t>(&self, text: &'t str) -> Option<Captures<'t>> {
+        let mut locs = self.capture_locations();
+        self.captures_read_at(&mut locs, text, 0).map(move |_| Captures {
+            text: text,
+            locs: locs.0,
+            named_groups: self.0.capture_name_idx().clone(),
+        })
+    }
+
+    /// Returns an iterator over all the non-overlapping capture groups matched
+    /// in `text`. This is operationally the same as `find_iter`, except it
+    /// yields information about capturing group matches.
+    ///
+    /// # Example
+    ///
+    /// We can use this to find all movie titles and their release years in
+    /// some text, where the movie is formatted like "'Title' (xxxx)":
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::Regex;
+    /// # fn main() {
+    /// let re = Regex::new(r"'(?P<title>[^']+)'\s+\((?P<year>\d{4})\)")
+    ///                .unwrap();
+    /// let text = "'Citizen Kane' (1941), 'The Wizard of Oz' (1939), 'M' (1931).";
+    /// for caps in re.captures_iter(text) {
+    ///     println!("Movie: {:?}, Released: {:?}",
+    ///              &caps["title"], &caps["year"]);
+    /// }
+    /// // Output:
+    /// // Movie: Citizen Kane, Released: 1941
+    /// // Movie: The Wizard of Oz, Released: 1939
+    /// // Movie: M, Released: 1931
+    /// # }
+    /// ```
+    pub fn captures_iter<'r, 't>(
+        &'r self,
+        text: &'t str,
+    ) -> CaptureMatches<'r, 't> {
+        CaptureMatches(self.0.searcher_str().captures_iter(text))
+    }
+
+    /// Returns an iterator of substrings of `text` delimited by a match of the
+    /// regular expression. Namely, each element of the iterator corresponds to
+    /// text that *isn't* matched by the regular expression.
+    ///
+    /// This method will *not* copy the text given.
+    ///
+    /// # Example
+    ///
+    /// To split a string delimited by arbitrary amounts of spaces or tabs:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::Regex;
+    /// # fn main() {
+    /// let re = Regex::new(r"[ \t]+").unwrap();
+    /// let fields: Vec<&str> = re.split("a b \t  c\td    e").collect();
+    /// assert_eq!(fields, vec!["a", "b", "c", "d", "e"]);
+    /// # }
+    /// ```
+    pub fn split<'r, 't>(&'r self, text: &'t str) -> Split<'r, 't> {
+        Split {
+            finder: self.find_iter(text),
+            last: 0,
+        }
+    }
+
+    /// Returns an iterator of at most `limit` substrings of `text` delimited
+    /// by a match of the regular expression. (A `limit` of `0` will return no
+    /// substrings.) Namely, each element of the iterator corresponds to text
+    /// that *isn't* matched by the regular expression. The remainder of the
+    /// string that is not split will be the last element in the iterator.
+    ///
+    /// This method will *not* copy the text given.
+    ///
+    /// # Example
+    ///
+    /// Get the first two words in some text:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::Regex;
+    /// # fn main() {
+    /// let re = Regex::new(r"\W+").unwrap();
+    /// let fields: Vec<&str> = re.splitn("Hey! How are you?", 3).collect();
+    /// assert_eq!(fields, vec!("Hey", "How", "are you?"));
+    /// # }
+    /// ```
+    pub fn splitn<'r, 't>(&'r self, text: &'t str, limit: usize)
+                         -> SplitN<'r, 't> {
+        SplitN {
+            splits: self.split(text),
+            n: limit,
+        }
+    }
+
+    /// Replaces the leftmost-first match with the replacement provided.
+    /// The replacement can be a regular string (where `$N` and `$name` are
+    /// expanded to match capture groups) or a function that takes the matches'
+    /// `Captures` and returns the replaced string.
+    ///
+    /// If no match is found, then a copy of the string is returned unchanged.
+    ///
+    /// # Replacement string syntax
+    ///
+    /// All instances of `$name` in the replacement text is replaced with the
+    /// corresponding capture group `name`.
+    ///
+    /// `name` may be an integer corresponding to the index of the
+    /// capture group (counted by order of opening parenthesis where `0` is the
+    /// entire match) or it can be a name (consisting of letters, digits or
+    /// underscores) corresponding to a named capture group.
+    ///
+    /// If `name` isn't a valid capture group (whether the name doesn't exist
+    /// or isn't a valid index), then it is replaced with the empty string.
+    ///
+    /// The longest possible name is used. e.g., `$1a` looks up the capture
+    /// group named `1a` and not the capture group at index `1`. To exert more
+    /// precise control over the name, use braces, e.g., `${1}a`.
+    ///
+    /// To write a literal `$` use `$$`.
+    ///
+    /// # Examples
+    ///
+    /// Note that this function is polymorphic with respect to the replacement.
+    /// In typical usage, this can just be a normal string:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::Regex;
+    /// # fn main() {
+    /// let re = Regex::new("[^01]+").unwrap();
+    /// assert_eq!(re.replace("1078910", ""), "1010");
+    /// # }
+    /// ```
+    ///
+    /// But anything satisfying the `Replacer` trait will work. For example,
+    /// a closure of type `|&Captures| -> String` provides direct access to the
+    /// captures corresponding to a match. This allows one to access
+    /// capturing group matches easily:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::Regex;
+    /// # use regex::Captures; fn main() {
+    /// let re = Regex::new(r"([^,\s]+),\s+(\S+)").unwrap();
+    /// let result = re.replace("Springsteen, Bruce", |caps: &Captures| {
+    ///     format!("{} {}", &caps[2], &caps[1])
+    /// });
+    /// assert_eq!(result, "Bruce Springsteen");
+    /// # }
+    /// ```
+    ///
+    /// But this is a bit cumbersome to use all the time. Instead, a simple
+    /// syntax is supported that expands `$name` into the corresponding capture
+    /// group. Here's the last example, but using this expansion technique
+    /// with named capture groups:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::Regex;
+    /// # fn main() {
+    /// let re = Regex::new(r"(?P<last>[^,\s]+),\s+(?P<first>\S+)").unwrap();
+    /// let result = re.replace("Springsteen, Bruce", "$first $last");
+    /// assert_eq!(result, "Bruce Springsteen");
+    /// # }
+    /// ```
+    ///
+    /// Note that using `$2` instead of `$first` or `$1` instead of `$last`
+    /// would produce the same result. To write a literal `$` use `$$`.
+    ///
+    /// Sometimes the replacement string requires use of curly braces to
+    /// delineate a capture group replacement and surrounding literal text.
+    /// For example, if we wanted to join two words together with an
+    /// underscore:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::Regex;
+    /// # fn main() {
+    /// let re = Regex::new(r"(?P<first>\w+)\s+(?P<second>\w+)").unwrap();
+    /// let result = re.replace("deep fried", "${first}_$second");
+    /// assert_eq!(result, "deep_fried");
+    /// # }
+    /// ```
+    ///
+    /// Without the curly braces, the capture group name `first_` would be
+    /// used, and since it doesn't exist, it would be replaced with the empty
+    /// string.
+    ///
+    /// Finally, sometimes you just want to replace a literal string with no
+    /// regard for capturing group expansion. This can be done by wrapping a
+    /// byte string with `NoExpand`:
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::Regex;
+    /// # fn main() {
+    /// use regex::NoExpand;
+    ///
+    /// let re = Regex::new(r"(?P<last>[^,\s]+),\s+(\S+)").unwrap();
+    /// let result = re.replace("Springsteen, Bruce", NoExpand("$2 $last"));
+    /// assert_eq!(result, "$2 $last");
+    /// # }
+    /// ```
+    pub fn replace<'t, R: Replacer>(
+        &self,
+        text: &'t str,
+        rep: R,
+    ) -> Cow<'t, str> {
+        self.replacen(text, 1, rep)
+    }
+
+    /// Replaces all non-overlapping matches in `text` with the replacement
+    /// provided. This is the same as calling `replacen` with `limit` set to
+    /// `0`.
+    ///
+    /// See the documentation for `replace` for details on how to access
+    /// capturing group matches in the replacement string.
+    pub fn replace_all<'t, R: Replacer>(
+        &self,
+        text: &'t str,
+        rep: R,
+    ) -> Cow<'t, str> {
+        self.replacen(text, 0, rep)
+    }
+
+    /// Replaces at most `limit` non-overlapping matches in `text` with the
+    /// replacement provided. If `limit` is 0, then all non-overlapping matches
+    /// are replaced.
+    ///
+    /// See the documentation for `replace` for details on how to access
+    /// capturing group matches in the replacement string.
+    pub fn replacen<'t, R: Replacer>(
+        &self,
+        text: &'t str,
+        limit: usize,
+        mut rep: R,
+    ) -> Cow<'t, str> {
+        // If we know that the replacement doesn't have any capture expansions,
+        // then we can fast path. The fast path can make a tremendous
+        // difference:
+        //
+        //   1) We use `find_iter` instead of `captures_iter`. Not asking for
+        //      captures generally makes the regex engines faster.
+        //   2) We don't need to look up all of the capture groups and do
+        //      replacements inside the replacement string. We just push it
+        //      at each match and be done with it.
+        if let Some(rep) = rep.no_expansion() {
+            let mut it = self.find_iter(text).enumerate().peekable();
+            if it.peek().is_none() {
+                return Cow::Borrowed(text);
+            }
+            let mut new = String::with_capacity(text.len());
+            let mut last_match = 0;
+            for (i, m) in it {
+                if limit > 0 && i >= limit {
+                    break
+                }
+                new.push_str(&text[last_match..m.start()]);
+                new.push_str(&rep);
+                last_match = m.end();
+            }
+            new.push_str(&text[last_match..]);
+            return Cow::Owned(new);
+        }
+
+        // The slower path, which we use if the replacement needs access to
+        // capture groups.
+        let mut it = self.captures_iter(text).enumerate().peekable();
+        if it.peek().is_none() {
+            return Cow::Borrowed(text);
+        }
+        let mut new = String::with_capacity(text.len());
+        let mut last_match = 0;
+        for (i, cap) in it {
+            if limit > 0 && i >= limit {
+                break
+            }
+            // unwrap on 0 is OK because captures only reports matches
+            let m = cap.get(0).unwrap();
+            new.push_str(&text[last_match..m.start()]);
+            rep.replace_append(&cap, &mut new);
+            last_match = m.end();
+        }
+        new.push_str(&text[last_match..]);
+        Cow::Owned(new)
+    }
+}
+
+/// Advanced or "lower level" search methods.
+impl Regex {
+    /// Returns the end location of a match in the text given.
+    ///
+    /// This method may have the same performance characteristics as
+    /// `is_match`, except it provides an end location for a match. In
+    /// particular, the location returned *may be shorter* than the proper end
+    /// of the leftmost-first match.
+    ///
+    /// # Example
+    ///
+    /// Typically, `a+` would match the entire first sequence of `a` in some
+    /// text, but `shortest_match` can give up as soon as it sees the first
+    /// `a`.
+    ///
+    /// ```rust
+    /// # extern crate regex; use regex::Regex;
+    /// # fn main() {
+    /// let text = "aaaaa";
+    /// let pos = Regex::new(r"a+").unwrap().shortest_match(text);
+    /// assert_eq!(pos, Some(1));
+    /// # }
+    /// ```
+    pub fn shortest_match(&self, text: &str) -> Option<usize> {
+        self.shortest_match_at(text, 0)
+    }
+
+    /// Returns the same as shortest_match, but starts the search at the given
+    /// offset.
+    ///
+    /// The significance of the starting point is that it takes the surrounding
+    /// context into consideration. For example, the `\A` anchor can only
+    /// match when `start == 0`.
+    pub fn shortest_match_at(
+        &self,
+        text: &str,
+        start: usize,
+    ) -> Option<usize> {
+        self.0.searcher_str().shortest_match_at(text, start)
+    }
+
+    /// Returns the same as is_match, but starts the search at the given
+    /// offset.
+    ///
+    /// The significance of the starting point is that it takes the surrounding
+    /// context into consideration. For example, the `\A` anchor can only
+    /// match when `start == 0`.
+    pub fn is_match_at(&self, text: &str, start: usize) -> bool {
+        self.shortest_match_at(text, start).is_some()
+    }
+
+    /// Returns the same as find, but starts the search at the given
+    /// offset.
+    ///
+    /// The significance of the starting point is that it takes the surrounding
+    /// context into consideration. For example, the `\A` anchor can only
+    /// match when `start == 0`.
+    pub fn find_at<'t>(
+        &self,
+        text: &'t str,
+        start: usize,
+    ) -> Option<Match<'t>> {
+        self.0.searcher_str().find_at(text, start).map(|(s, e)| {
+            Match::new(text, s, e)
+        })
+    }
+
+    /// This is like `captures`, but uses
+    /// [`CaptureLocations`](struct.CaptureLocations.html)
+    /// instead of
+    /// [`Captures`](struct.Captures.html) in order to amortize allocations.
+    ///
+    /// To create a `CaptureLocations` value, use the
+    /// `Regex::capture_locations` method.
+    ///
+    /// This returns the overall match if this was successful, which is always
+    /// equivalence to the `0`th capture group.
+    pub fn captures_read<'t>(
+        &self,
+        locs: &mut CaptureLocations,
+        text: &'t str,
+    ) -> Option<Match<'t>> {
+        self.captures_read_at(locs, text, 0)
+    }
+
+    /// Returns the same as captures, but starts the search at the given
+    /// offset and populates the capture locations given.
+    ///
+    /// The significance of the starting point is that it takes the surrounding
+    /// context into consideration. For example, the `\A` anchor can only
+    /// match when `start == 0`.
+    pub fn captures_read_at<'t>(
+        &self,
+        locs: &mut CaptureLocations,
+        text: &'t str,
+        start: usize,
+    ) -> Option<Match<'t>> {
+        self.0
+            .searcher_str()
+            .captures_read_at(&mut locs.0, text, start)
+            .map(|(s, e)| Match::new(text, s, e))
+    }
+
+    /// An undocumented alias for `captures_read_at`.
+    ///
+    /// The `regex-capi` crate previously used this routine, so to avoid
+    /// breaking that crate, we continue to provide the name as an undocumented
+    /// alias.
+    #[doc(hidden)]
+    pub fn read_captures_at<'t>(
+        &self,
+        locs: &mut CaptureLocations,
+        text: &'t str,
+        start: usize,
+    ) -> Option<Match<'t>> {
+        self.captures_read_at(locs, text, start)
+    }
+}
+
+/// Auxiliary methods.
+impl Regex {
+    /// Returns the original string of this regex.
+    pub fn as_str(&self) -> &str {
+        &self.0.regex_strings()[0]
+    }
+
+    /// Returns an iterator over the capture names.
+    pub fn capture_names(&self) -> CaptureNames {
+        CaptureNames(self.0.capture_names().iter())
+    }
+
+    /// Returns the number of captures.
+    pub fn captures_len(&self) -> usize {
+        self.0.capture_names().len()
+    }
+
+    /// Returns an empty set of capture locations that can be reused in
+    /// multiple calls to `captures_read` or `captures_read_at`.
+    pub fn capture_locations(&self) -> CaptureLocations {
+        CaptureLocations(self.0.searcher_str().locations())
+    }
+
+    /// An alias for `capture_locations` to preserve backward compatibility.
+    ///
+    /// The `regex-capi` crate uses this method, so to avoid breaking that
+    /// crate, we continue to export it as an undocumented API.
+    #[doc(hidden)]
+    pub fn locations(&self) -> CaptureLocations {
+        CaptureLocations(self.0.searcher_str().locations())
+    }
+}
+
+/// An iterator over the names of all possible captures.
+///
+/// `None` indicates an unnamed capture; the first element (capture 0, the
+/// whole matched region) is always unnamed.
+///
+/// `'r` is the lifetime of the compiled regular expression.
+pub struct CaptureNames<'r>(::std::slice::Iter<'r, Option<String>>);
+
+impl<'r> Iterator for CaptureNames<'r> {
+    type Item = Option<&'r str>;
+
+    fn next(&mut self) -> Option<Option<&'r str>> {
+        self.0
+            .next()
+            .as_ref()
+            .map(|slot| slot.as_ref().map(|name| name.as_ref()))
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint()
+    }
+}
+
+/// Yields all substrings delimited by a regular expression match.
+///
+/// `'r` is the lifetime of the compiled regular expression and `'t` is the
+/// lifetime of the string being split.
+pub struct Split<'r, 't> {
+    finder: Matches<'r, 't>,
+    last: usize,
+}
+
+impl<'r, 't> Iterator for Split<'r, 't> {
+    type Item = &'t str;
+
+    fn next(&mut self) -> Option<&'t str> {
+        let text = self.finder.0.text();
+        match self.finder.next() {
+            None => {
+                if self.last >= text.len() {
+                    None
+                } else {
+                    let s = &text[self.last..];
+                    self.last = text.len();
+                    Some(s)
+                }
+            }
+            Some(m) => {
+                let matched = &text[self.last..m.start()];
+                self.last = m.end();
+                Some(matched)
+            }
+        }
+    }
+}
+
+/// Yields at most `N` substrings delimited by a regular expression match.
+///
+/// The last substring will be whatever remains after splitting.
+///
+/// `'r` is the lifetime of the compiled regular expression and `'t` is the
+/// lifetime of the string being split.
+pub struct SplitN<'r, 't> {
+    splits: Split<'r, 't>,
+    n: usize,
+}
+
+impl<'r, 't> Iterator for SplitN<'r, 't> {
+    type Item = &'t str;
+
+    fn next(&mut self) -> Option<&'t str> {
+        if self.n == 0 {
+            return None
+        }
+        self.n -= 1;
+        if self.n == 0 {
+            let text = self.splits.finder.0.text();
+            Some(&text[self.splits.last..])
+        } else {
+            self.splits.next()
+        }
+    }
+}
+
+/// CaptureLocations is a low level representation of the raw offsets of each
+/// submatch.
+///
+/// You can think of this as a lower level
+/// [`Captures`](struct.Captures.html), where this type does not support
+/// named capturing groups directly and it does not borrow the text that these
+/// offsets were matched on.
+///
+/// Primarily, this type is useful when using the lower level `Regex` APIs
+/// such as `read_captures`, which permits amortizing the allocation in which
+/// capture match locations are stored.
+///
+/// In order to build a value of this type, you'll need to call the
+/// `capture_locations` method on the `Regex` being used to execute the search.
+/// The value returned can then be reused in subsequent searches.
+#[derive(Clone, Debug)]
+pub struct CaptureLocations(re_trait::Locations);
+
+/// A type alias for `CaptureLocations` for backwards compatibility.
+///
+/// Previously, we exported `CaptureLocations` as `Locations` in an
+/// undocumented API. To prevent breaking that code (e.g., in `regex-capi`),
+/// we continue re-exporting the same undocumented API.
+#[doc(hidden)]
+pub type Locations = CaptureLocations;
+
+impl CaptureLocations {
+    /// Returns the start and end positions of the Nth capture group. Returns
+    /// `None` if `i` is not a valid capture group or if the capture group did
+    /// not match anything. The positions returned are *always* byte indices
+    /// with respect to the original string matched.
+    #[inline]
+    pub fn get(&self, i: usize) -> Option<(usize, usize)> {
+        self.0.pos(i)
+    }
+
+    /// Returns the total number of capturing groups.
+    ///
+    /// This is always at least `1` since every regex has at least `1`
+    /// capturing group that corresponds to the entire match.
+    #[inline]
+    pub fn len(&self) -> usize {
+        self.0.len()
+    }
+
+    /// An alias for the `get` method for backwards compatibility.
+    ///
+    /// Previously, we exported `get` as `pos` in an undocumented API. To
+    /// prevent breaking that code (e.g., in `regex-capi`), we continue
+    /// re-exporting the same undocumented API.
+    #[doc(hidden)]
+    #[inline]
+    pub fn pos(&self, i: usize) -> Option<(usize, usize)> {
+        self.get(i)
+    }
+}
+
+/// Captures represents a group of captured strings for a single match.
+///
+/// The 0th capture always corresponds to the entire match. Each subsequent
+/// index corresponds to the next capture group in the regex. If a capture
+/// group is named, then the matched string is *also* available via the `name`
+/// method. (Note that the 0th capture is always unnamed and so must be
+/// accessed with the `get` method.)
+///
+/// Positions returned from a capture group are always byte indices.
+///
+/// `'t` is the lifetime of the matched text.
+pub struct Captures<'t> {
+    text: &'t str,
+    locs: re_trait::Locations,
+    named_groups: Arc<HashMap<String, usize>>,
+}
+
+impl<'t> Captures<'t> {
+    /// Returns the match associated with the capture group at index `i`. If
+    /// `i` does not correspond to a capture group, or if the capture group
+    /// did not participate in the match, then `None` is returned.
+    ///
+    /// # Examples
+    ///
+    /// Get the text of the match with a default of an empty string if this
+    /// group didn't participate in the match:
+    ///
+    /// ```rust
+    /// # use regex::Regex;
+    /// let re = Regex::new(r"[a-z]+(?:([0-9]+)|([A-Z]+))").unwrap();
+    /// let caps = re.captures("abc123").unwrap();
+    ///
+    /// let text1 = caps.get(1).map_or("", |m| m.as_str());
+    /// let text2 = caps.get(2).map_or("", |m| m.as_str());
+    /// assert_eq!(text1, "123");
+    /// assert_eq!(text2, "");
+    /// ```
+    pub fn get(&self, i: usize) -> Option<Match<'t>> {
+        self.locs.pos(i).map(|(s, e)| Match::new(self.text, s, e))
+    }
+
+    /// Returns the match for the capture group named `name`. If `name` isn't a
+    /// valid capture group or didn't match anything, then `None` is returned.
+    pub fn name(&self, name: &str) -> Option<Match<'t>> {
+        self.named_groups.get(name).and_then(|&i| self.get(i))
+    }
+
+    /// An iterator that yields all capturing matches in the order in which
+    /// they appear in the regex. If a particular capture group didn't
+    /// participate in the match, then `None` is yielded for that capture.
+    ///
+    /// The first match always corresponds to the overall match of the regex.
+    pub fn iter<'c>(&'c self) -> SubCaptureMatches<'c, 't> {
+        SubCaptureMatches {
+            caps: self,
+            it: self.locs.iter(),
+        }
+    }
+
+    /// Expands all instances of `$name` in `replacement` to the corresponding
+    /// capture group `name`, and writes them to the `dst` buffer given.
+    ///
+    /// `name` may be an integer corresponding to the index of the
+    /// capture group (counted by order of opening parenthesis where `0` is the
+    /// entire match) or it can be a name (consisting of letters, digits or
+    /// underscores) corresponding to a named capture group.
+    ///
+    /// If `name` isn't a valid capture group (whether the name doesn't exist
+    /// or isn't a valid index), then it is replaced with the empty string.
+    ///
+    /// The longest possible name is used. e.g., `$1a` looks up the capture
+    /// group named `1a` and not the capture group at index `1`. To exert more
+    /// precise control over the name, use braces, e.g., `${1}a`.
+    ///
+    /// To write a literal `$` use `$$`.
+    pub fn expand(&self, replacement: &str, dst: &mut String) {
+        expand_str(self, replacement, dst)
+    }
+
+    /// Returns the number of captured groups.
+    ///
+    /// This is always at least `1`, since every regex has at least one capture
+    /// group that corresponds to the full match.
+    #[inline]
+    pub fn len(&self) -> usize {
+        self.locs.len()
+    }
+}
+
+impl<'t> fmt::Debug for Captures<'t> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_tuple("Captures").field(&CapturesDebug(self)).finish()
+    }
+}
+
+struct CapturesDebug<'c, 't: 'c>(&'c Captures<'t>);
+
+impl<'c, 't> fmt::Debug for CapturesDebug<'c, 't> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        // We'd like to show something nice here, even if it means an
+        // allocation to build a reverse index.
+        let slot_to_name: HashMap<&usize, &String> =
+            self.0.named_groups.iter().map(|(a, b)| (b, a)).collect();
+        let mut map = f.debug_map();
+        for (slot, m) in self.0.locs.iter().enumerate() {
+            let m = m.map(|(s, e)| &self.0.text[s..e]);
+            if let Some(name) = slot_to_name.get(&slot) {
+                map.entry(&name, &m);
+            } else {
+                map.entry(&slot, &m);
+            }
+        }
+        map.finish()
+    }
+}
+
+/// Get a group by index.
+///
+/// `'t` is the lifetime of the matched text.
+///
+/// The text can't outlive the `Captures` object if this method is
+/// used, because of how `Index` is defined (normally `a[i]` is part
+/// of `a` and can't outlive it); to do that, use `get()` instead.
+///
+/// # Panics
+///
+/// If there is no group at the given index.
+impl<'t> Index<usize> for Captures<'t> {
+    type Output = str;
+
+    fn index(&self, i: usize) -> &str {
+        self.get(i).map(|m| m.as_str())
+            .unwrap_or_else(|| panic!("no group at index '{}'", i))
+    }
+}
+
+/// Get a group by name.
+///
+/// `'t` is the lifetime of the matched text and `'i` is the lifetime
+/// of the group name (the index).
+///
+/// The text can't outlive the `Captures` object if this method is
+/// used, because of how `Index` is defined (normally `a[i]` is part
+/// of `a` and can't outlive it); to do that, use `name` instead.
+///
+/// # Panics
+///
+/// If there is no group named by the given value.
+impl<'t, 'i> Index<&'i str> for Captures<'t> {
+    type Output = str;
+
+    fn index<'a>(&'a self, name: &'i str) -> &'a str {
+        self.name(name).map(|m| m.as_str())
+            .unwrap_or_else(|| panic!("no group named '{}'", name))
+    }
+}
+
+/// An iterator that yields all capturing matches in the order in which they
+/// appear in the regex.
+///
+/// If a particular capture group didn't participate in the match, then `None`
+/// is yielded for that capture. The first match always corresponds to the
+/// overall match of the regex.
+///
+/// The lifetime `'c` corresponds to the lifetime of the `Captures` value, and
+/// the lifetime `'t` corresponds to the originally matched text.
+pub struct SubCaptureMatches<'c, 't: 'c> {
+    caps: &'c Captures<'t>,
+    it: SubCapturesPosIter<'c>,
+}
+
+impl<'c, 't> Iterator for SubCaptureMatches<'c, 't> {
+    type Item = Option<Match<'t>>;
+
+    fn next(&mut self) -> Option<Option<Match<'t>>> {
+        self.it.next()
+            .map(|cap| cap.map(|(s, e)| Match::new(self.caps.text, s, e)))
+    }
+}
+
+/// An iterator that yields all non-overlapping capture groups matching a
+/// particular regular expression.
+///
+/// The iterator stops when no more matches can be found.
+///
+/// `'r` is the lifetime of the compiled regular expression and `'t` is the
+/// lifetime of the matched string.
+pub struct CaptureMatches<'r, 't>(re_trait::CaptureMatches<'t, ExecNoSyncStr<'r>>);
+
+impl<'r, 't> Iterator for CaptureMatches<'r, 't> {
+    type Item = Captures<'t>;
+
+    fn next(&mut self) -> Option<Captures<'t>> {
+        self.0.next().map(|locs| Captures {
+            text: self.0.text(),
+            locs: locs,
+            named_groups: self.0.regex().capture_name_idx().clone(),
+        })
+    }
+}
+
+/// An iterator over all non-overlapping matches for a particular string.
+///
+/// The iterator yields a `Match` value. The iterator stops when no more
+/// matches can be found.
+///
+/// `'r` is the lifetime of the compiled regular expression and `'t` is the
+/// lifetime of the matched string.
+pub struct Matches<'r, 't>(re_trait::Matches<'t, ExecNoSyncStr<'r>>);
+
+impl<'r, 't> Iterator for Matches<'r, 't> {
+    type Item = Match<'t>;
+
+    fn next(&mut self) -> Option<Match<'t>> {
+        let text = self.0.text();
+        self.0.next().map(|(s, e)| Match::new(text, s, e))
+    }
+}
+
+/// Replacer describes types that can be used to replace matches in a string.
+///
+/// In general, users of this crate shouldn't need to implement this trait,
+/// since implementations are already provided for `&str` and
+/// `FnMut(&Captures) -> String` (or any `FnMut(&Captures) -> T`
+/// where `T: AsRef<str>`), which covers most use cases.
+pub trait Replacer {
+    /// Appends text to `dst` to replace the current match.
+    ///
+    /// The current match is represented by `caps`, which is guaranteed to
+    /// have a match at capture group `0`.
+    ///
+    /// For example, a no-op replacement would be
+    /// `dst.extend(caps.get(0).unwrap().as_str())`.
+    fn replace_append(&mut self, caps: &Captures, dst: &mut String);
+
+    /// Return a fixed unchanging replacement string.
+    ///
+    /// When doing replacements, if access to `Captures` is not needed (e.g.,
+    /// the replacement byte string does not need `$` expansion), then it can
+    /// be beneficial to avoid finding sub-captures.
+    ///
+    /// In general, this is called once for every call to `replacen`.
+    fn no_expansion<'r>(&'r mut self) -> Option<Cow<'r, str>> {
+        None
+    }
+
+    /// Return a `Replacer` that borrows and wraps this `Replacer`.
+    ///
+    /// This is useful when you want to take a generic `Replacer` (which might
+    /// not be cloneable) and use it without consuming it, so it can be used
+    /// more than once.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use regex::{Regex, Replacer};
+    ///
+    /// fn replace_all_twice<R: Replacer>(
+    ///     re: Regex,
+    ///     src: &str,
+    ///     mut rep: R,
+    /// ) -> String {
+    ///     let dst = re.replace_all(src, rep.by_ref());
+    ///     let dst = re.replace_all(&dst, rep.by_ref());
+    ///     dst.into_owned()
+    /// }
+    /// ```
+    fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self> {
+        ReplacerRef(self)
+    }
+}
+
+/// By-reference adaptor for a `Replacer`
+///
+/// Returned by [`Replacer::by_ref`](trait.Replacer.html#method.by_ref).
+#[derive(Debug)]
+pub struct ReplacerRef<'a, R: ?Sized + 'a>(&'a mut R);
+
+impl<'a, R: Replacer + ?Sized + 'a> Replacer for ReplacerRef<'a, R> {
+    fn replace_append(&mut self, caps: &Captures, dst: &mut String) {
+        self.0.replace_append(caps, dst)
+    }
+    fn no_expansion(&mut self) -> Option<Cow<str>> {
+        self.0.no_expansion()
+    }
+}
+
+impl<'a> Replacer for &'a str {
+    fn replace_append(&mut self, caps: &Captures, dst: &mut String) {
+        caps.expand(*self, dst);
+    }
+
+    fn no_expansion(&mut self) -> Option<Cow<str>> {
+        match memchr(b'$', self.as_bytes()) {
+            Some(_) => None,
+            None => Some(Cow::Borrowed(*self)),
+        }
+    }
+}
+
+impl<F, T> Replacer for F where F: FnMut(&Captures) -> T, T: AsRef<str> {
+    fn replace_append(&mut self, caps: &Captures, dst: &mut String) {
+        dst.push_str((*self)(caps).as_ref());
+    }
+}
+
+/// `NoExpand` indicates literal string replacement.
+///
+/// It can be used with `replace` and `replace_all` to do a literal string
+/// replacement without expanding `$name` to their corresponding capture
+/// groups. This can be both convenient (to avoid escaping `$`, for example)
+/// and performant (since capture groups don't need to be found).
+///
+/// `'t` is the lifetime of the literal text.
+pub struct NoExpand<'t>(pub &'t str);
+
+impl<'t> Replacer for NoExpand<'t> {
+    fn replace_append(&mut self, _: &Captures, dst: &mut String) {
+        dst.push_str(self.0);
+    }
+
+    fn no_expansion(&mut self) -> Option<Cow<str>> {
+        Some(Cow::Borrowed(self.0))
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/sparse.rs.html b/target/doc/src/regex/sparse.rs.html new file mode 100644 index 0000000..2b91eb4 --- /dev/null +++ b/target/doc/src/regex/sparse.rs.html @@ -0,0 +1,153 @@ +sparse.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+
+use std::ops::Deref;
+use std::slice;
+
+/// A sparse set used for representing ordered NFA states.
+///
+/// This supports constant time addition and membership testing. Clearing an
+/// entire set can also be done in constant time. Iteration yields elements
+/// in the order in which they were inserted.
+///
+/// The data structure is based on: http://research.swtch.com/sparse
+/// Note though that we don't actually use uninitialized memory. We generally
+/// reuse allocations, so the initial allocation cost is bareable. However,
+/// its other properties listed above are extremely useful.
+#[derive(Clone, Debug)]
+pub struct SparseSet {
+    /// Dense contains the instruction pointers in the order in which they
+    /// were inserted.
+    dense: Vec<usize>,
+    /// Sparse maps instruction pointers to their location in dense.
+    ///
+    /// An instruction pointer is in the set if and only if
+    /// sparse[ip] < dense.len() && ip == dense[sparse[ip]].
+    sparse: Box<[usize]>,
+}
+
+impl SparseSet {
+    pub fn new(size: usize) -> SparseSet {
+        SparseSet {
+            dense: Vec::with_capacity(size),
+            sparse: vec![0; size].into_boxed_slice(),
+        }
+    }
+
+    pub fn len(&self) -> usize {
+        self.dense.len()
+    }
+
+    pub fn is_empty(&self) -> bool {
+        self.dense.is_empty()
+    }
+
+    pub fn capacity(&self) -> usize {
+        self.dense.capacity()
+    }
+
+    pub fn insert(&mut self, value: usize) {
+        let i = self.len();
+        assert!(i < self.capacity());
+        self.dense.push(value);
+        self.sparse[value] = i;
+    }
+
+    pub fn contains(&self, value: usize) -> bool {
+        let i = self.sparse[value];
+        self.dense.get(i) == Some(&value)
+    }
+
+    pub fn clear(&mut self) {
+        self.dense.clear();
+    }
+}
+
+impl Deref for SparseSet {
+    type Target = [usize];
+
+    fn deref(&self) -> &Self::Target {
+        &self.dense
+    }
+}
+
+impl<'a> IntoIterator for &'a SparseSet {
+    type Item = &'a usize;
+    type IntoIter = slice::Iter<'a, usize>;
+    fn into_iter(self) -> Self::IntoIter { self.iter() }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/utf8.rs.html b/target/doc/src/regex/utf8.rs.html new file mode 100644 index 0000000..70e75c3 --- /dev/null +++ b/target/doc/src/regex/utf8.rs.html @@ -0,0 +1,521 @@ +utf8.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+
+/// A few elementary UTF-8 encoding and decoding functions used by the matching
+/// engines.
+///
+/// In an ideal world, the matching engines operate on `&str` and we can just
+/// lean on the standard library for all our UTF-8 needs. However, to support
+/// byte based regexes (that can match on arbitrary bytes which may contain
+/// UTF-8), we need to be capable of searching and decoding UTF-8 on a `&[u8]`.
+/// The standard library doesn't really recognize this use case, so we have
+/// to build it out ourselves.
+///
+/// Should this be factored out into a separate crate? It seems independently
+/// useful. There are other crates that already exist (e.g., `utf-8`) that have
+/// overlapping use cases. Not sure what to do.
+
+use std::char;
+
+const TAG_CONT: u8 = 0b1000_0000;
+const TAG_TWO: u8 = 0b1100_0000;
+const TAG_THREE: u8 = 0b1110_0000;
+const TAG_FOUR: u8 = 0b1111_0000;
+
+/// Returns the smallest possible index of the next valid UTF-8 sequence
+/// starting after `i`.
+pub fn next_utf8(text: &[u8], i: usize) -> usize {
+    let b = match text.get(i) {
+        None => return i + 1,
+        Some(&b) => b,
+    };
+    let inc = if b <= 0x7F {
+        1
+    } else if b <= 0b110_11111 {
+        2
+    } else if b <= 0b1110_1111 {
+        3
+    } else {
+        4
+    };
+    i + inc
+}
+
+/// Decode a single UTF-8 sequence into a single Unicode codepoint from `src`.
+///
+/// If no valid UTF-8 sequence could be found, then `None` is returned.
+/// Otherwise, the decoded codepoint and the number of bytes read is returned.
+/// The number of bytes read (for a valid UTF-8 sequence) is guaranteed to be
+/// 1, 2, 3 or 4.
+///
+/// Note that a UTF-8 sequence is invalid if it is incorrect UTF-8, encodes a
+/// codepoint that is out of range (surrogate codepoints are out of range) or
+/// is not the shortest possible UTF-8 sequence for that codepoint.
+#[inline]
+pub fn decode_utf8(src: &[u8]) -> Option<(char, usize)> {
+    let b0 = match src.get(0) {
+        None => return None,
+        Some(&b) if b <= 0x7F => return Some((b as char, 1)),
+        Some(&b) => b,
+    };
+    match b0 {
+        0b110_00000 ..= 0b110_11111 => {
+            if src.len() < 2 {
+                return None;
+            }
+            let b1 = src[1];
+            if 0b11_000000 & b1 != TAG_CONT {
+                return None;
+            }
+            let cp = ((b0 & !TAG_TWO) as u32) << 6
+                     | ((b1 & !TAG_CONT) as u32);
+            match cp {
+                0x80 ..= 0x7FF => char::from_u32(cp).map(|cp| (cp, 2)),
+                _ => None,
+            }
+        }
+        0b1110_0000 ..= 0b1110_1111 => {
+            if src.len() < 3 {
+                return None;
+            }
+            let (b1, b2) = (src[1], src[2]);
+            if 0b11_000000 & b1 != TAG_CONT {
+                return None;
+            }
+            if 0b11_000000 & b2 != TAG_CONT {
+                return None;
+            }
+            let cp = ((b0 & !TAG_THREE) as u32) << 12
+                     | ((b1 & !TAG_CONT) as u32) << 6
+                     | ((b2 & !TAG_CONT) as u32);
+            match cp {
+                // char::from_u32 will disallow surrogate codepoints.
+                0x800 ..= 0xFFFF => char::from_u32(cp).map(|cp| (cp, 3)),
+                _ => None,
+            }
+        }
+        0b11110_000 ..= 0b11110_111 => {
+            if src.len() < 4 {
+                return None;
+            }
+            let (b1, b2, b3) = (src[1], src[2], src[3]);
+            if 0b11_000000 & b1 != TAG_CONT {
+                return None;
+            }
+            if 0b11_000000 & b2 != TAG_CONT {
+                return None;
+            }
+            if 0b11_000000 & b3 != TAG_CONT {
+                return None;
+            }
+            let cp = ((b0 & !TAG_FOUR) as u32) << 18
+                     | ((b1 & !TAG_CONT) as u32) << 12
+                     | ((b2 & !TAG_CONT) as u32) << 6
+                     | ((b3 & !TAG_CONT) as u32);
+            match cp {
+                0x10000 ..= 0x10FFFF => char::from_u32(cp).map(|cp| (cp, 4)),
+                _ => None,
+            }
+        }
+        _ => None,
+    }
+}
+
+/// Like `decode_utf8`, but decodes the last UTF-8 sequence in `src` instead
+/// of the first.
+pub fn decode_last_utf8(src: &[u8]) -> Option<(char, usize)> {
+    if src.is_empty() {
+        return None;
+    }
+    let mut start = src.len() - 1;
+    if src[start] <= 0x7F {
+        return Some((src[start] as char, 1));
+    }
+    while start > src.len().saturating_sub(4) {
+        start -= 1;
+        if is_start_byte(src[start]) {
+            break;
+        }
+    }
+    match decode_utf8(&src[start..]) {
+        None => None,
+        Some((_, n)) if n < src.len() - start => None,
+        Some((cp, n)) => Some((cp, n)),
+    }
+}
+
+fn is_start_byte(b: u8) -> bool {
+    b & 0b11_000000 != 0b1_0000000
+}
+
+#[cfg(test)]
+mod tests {
+    use std::str;
+
+    use quickcheck::quickcheck;
+
+    use super::{
+        TAG_CONT, TAG_TWO, TAG_THREE, TAG_FOUR,
+        decode_utf8, decode_last_utf8,
+    };
+
+    #[test]
+    fn prop_roundtrip() {
+        fn p(given_cp: char) -> bool {
+            let mut tmp = [0; 4];
+            let encoded_len = given_cp.encode_utf8(&mut tmp).len();
+            let (got_cp, got_len) = decode_utf8(&tmp[..encoded_len]).unwrap();
+            encoded_len == got_len && given_cp == got_cp
+        }
+        quickcheck(p as fn(char) -> bool)
+    }
+
+    #[test]
+    fn prop_roundtrip_last() {
+        fn p(given_cp: char) -> bool {
+            let mut tmp = [0; 4];
+            let encoded_len = given_cp.encode_utf8(&mut tmp).len();
+            let (got_cp, got_len) =
+                decode_last_utf8(&tmp[..encoded_len]).unwrap();
+            encoded_len == got_len && given_cp == got_cp
+        }
+        quickcheck(p as fn(char) -> bool)
+    }
+
+    #[test]
+    fn prop_encode_matches_std() {
+        fn p(cp: char) -> bool {
+            let mut got = [0; 4];
+            let n = cp.encode_utf8(&mut got).len();
+            let expected = cp.to_string();
+            &got[..n] == expected.as_bytes()
+        }
+        quickcheck(p as fn(char) -> bool)
+    }
+
+    #[test]
+    fn prop_decode_matches_std() {
+        fn p(given_cp: char) -> bool {
+            let mut tmp = [0; 4];
+            let n = given_cp.encode_utf8(&mut tmp).len();
+            let (got_cp, _) = decode_utf8(&tmp[..n]).unwrap();
+            let expected_cp =
+                str::from_utf8(&tmp[..n]).unwrap().chars().next().unwrap();
+            got_cp == expected_cp
+        }
+        quickcheck(p as fn(char) -> bool)
+    }
+
+    #[test]
+    fn prop_decode_last_matches_std() {
+        fn p(given_cp: char) -> bool {
+            let mut tmp = [0; 4];
+            let n = given_cp.encode_utf8(&mut tmp).len();
+            let (got_cp, _) = decode_last_utf8(&tmp[..n]).unwrap();
+            let expected_cp =
+                str::from_utf8(&tmp[..n]).unwrap()
+                    .chars().rev().next().unwrap();
+            got_cp == expected_cp
+        }
+        quickcheck(p as fn(char) -> bool)
+    }
+
+    #[test]
+    fn reject_invalid() {
+        // Invalid start byte
+        assert_eq!(decode_utf8(&[0xFF]), None);
+        // Surrogate pair
+        assert_eq!(decode_utf8(&[0xED, 0xA0, 0x81]), None);
+        // Invalid continuation byte.
+        assert_eq!(decode_utf8(&[0xD4, 0xC2]), None);
+        // Bad lengths
+        assert_eq!(decode_utf8(&[0xC3]), None); // 2 bytes
+        assert_eq!(decode_utf8(&[0xEF, 0xBF]), None); // 3 bytes
+        assert_eq!(decode_utf8(&[0xF4, 0x8F, 0xBF]), None); // 4 bytes
+        // Not a minimal UTF-8 sequence
+        assert_eq!(decode_utf8(&[TAG_TWO, TAG_CONT | b'a']), None);
+        assert_eq!(decode_utf8(&[TAG_THREE, TAG_CONT, TAG_CONT | b'a']), None);
+        assert_eq!(decode_utf8(&[
+            TAG_FOUR, TAG_CONT, TAG_CONT, TAG_CONT | b'a',
+        ]), None);
+    }
+
+    #[test]
+    fn reject_invalid_last() {
+        // Invalid start byte
+        assert_eq!(decode_last_utf8(&[0xFF]), None);
+        // Surrogate pair
+        assert_eq!(decode_last_utf8(&[0xED, 0xA0, 0x81]), None);
+        // Bad lengths
+        assert_eq!(decode_last_utf8(&[0xC3]), None); // 2 bytes
+        assert_eq!(decode_last_utf8(&[0xEF, 0xBF]), None); // 3 bytes
+        assert_eq!(decode_last_utf8(&[0xF4, 0x8F, 0xBF]), None); // 4 bytes
+        // Not a minimal UTF-8 sequence
+        assert_eq!(decode_last_utf8(&[TAG_TWO, TAG_CONT | b'a']), None);
+        assert_eq!(decode_last_utf8(&[
+            TAG_THREE, TAG_CONT, TAG_CONT | b'a',
+        ]), None);
+        assert_eq!(decode_last_utf8(&[
+            TAG_FOUR, TAG_CONT, TAG_CONT, TAG_CONT | b'a',
+        ]), None);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/vector/avx2.rs.html b/target/doc/src/regex/vector/avx2.rs.html new file mode 100644 index 0000000..73356a8 --- /dev/null +++ b/target/doc/src/regex/vector/avx2.rs.html @@ -0,0 +1,377 @@ +avx2.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+
+#![allow(dead_code)]
+
+use std::arch::x86_64::*;
+use std::fmt;
+use std::mem;
+
+#[derive(Clone, Copy, Debug)]
+pub struct AVX2VectorBuilder(());
+
+impl AVX2VectorBuilder {
+    pub fn new() -> Option<AVX2VectorBuilder> {
+        if is_x86_feature_detected!("avx2") {
+            Some(AVX2VectorBuilder(()))
+        } else {
+            None
+        }
+    }
+
+    /// Create a new u8x32 AVX2 vector where all of the bytes are set to
+    /// the given value.
+    #[inline]
+    pub fn u8x32_splat(self, n: u8) -> u8x32 {
+        // Safe because we know AVX2 is enabled.
+        unsafe { u8x32::splat(n) }
+    }
+
+    /// Load 32 bytes from the given slice, with bounds checks.
+    #[inline]
+    pub fn u8x32_load_unaligned(self, slice: &[u8]) -> u8x32 {
+        // Safe because we know AVX2 is enabled.
+        unsafe { u8x32::load_unaligned(slice) }
+    }
+
+    /// Load 32 bytes from the given slice, without bounds checks.
+    #[inline]
+    pub unsafe fn u8x32_load_unchecked_unaligned(self, slice: &[u8]) -> u8x32 {
+        // Safe because we know AVX2 is enabled, but still unsafe
+        // because we aren't doing bounds checks.
+        u8x32::load_unchecked_unaligned(slice)
+    }
+
+    /// Load 32 bytes from the given slice, with bound and alignment checks.
+    #[inline]
+    pub fn u8x32_load(self, slice: &[u8]) -> u8x32 {
+        // Safe because we know AVX2 is enabled.
+        unsafe { u8x32::load(slice) }
+    }
+
+    /// Load 32 bytes from the given slice, without bound or alignment checks.
+    #[inline]
+    pub unsafe fn u8x32_load_unchecked(self, slice: &[u8]) -> u8x32 {
+        // Safe because we know AVX2 is enabled, but still unsafe
+        // because we aren't doing bounds checks.
+        u8x32::load_unchecked(slice)
+    }
+}
+
+#[derive(Clone, Copy)]
+#[allow(non_camel_case_types)]
+#[repr(transparent)]
+pub struct u8x32 {
+    vector: __m256i
+}
+
+impl u8x32 {
+    #[inline]
+    unsafe fn splat(n: u8) -> u8x32 {
+        u8x32 { vector: _mm256_set1_epi8(n as i8) }
+    }
+
+    #[inline]
+    unsafe fn load_unaligned(slice: &[u8]) -> u8x32 {
+        assert!(slice.len() >= 32);
+        u8x32::load_unchecked_unaligned(slice)
+    }
+
+    #[inline]
+    unsafe fn load_unchecked_unaligned(slice: &[u8]) -> u8x32 {
+        let p = slice.as_ptr() as *const u8 as *const __m256i;
+        u8x32 { vector: _mm256_loadu_si256(p) }
+    }
+
+    #[inline]
+    unsafe fn load(slice: &[u8]) -> u8x32 {
+        assert!(slice.len() >= 32);
+        assert!(slice.as_ptr() as usize % 32 == 0);
+        u8x32::load_unchecked(slice)
+    }
+
+    #[inline]
+    unsafe fn load_unchecked(slice: &[u8]) -> u8x32 {
+        let p = slice.as_ptr() as *const u8 as *const __m256i;
+        u8x32 { vector: _mm256_load_si256(p) }
+    }
+
+    #[inline]
+    pub fn shuffle(self, indices: u8x32) -> u8x32 {
+        // Safe because we know AVX2 is enabled.
+        unsafe {
+            u8x32 { vector: _mm256_shuffle_epi8(self.vector, indices.vector) }
+        }
+    }
+
+    #[inline]
+    pub fn ne(self, other: u8x32) -> u8x32 {
+        // Safe because we know AVX2 is enabled.
+        unsafe {
+            let boolv = _mm256_cmpeq_epi8(self.vector, other.vector);
+            let ones = _mm256_set1_epi8(0xFF as u8 as i8);
+            u8x32 { vector: _mm256_andnot_si256(boolv, ones) }
+        }
+    }
+
+    #[inline]
+    pub fn and(self, other: u8x32) -> u8x32 {
+        // Safe because we know AVX2 is enabled.
+        unsafe {
+            u8x32 { vector: _mm256_and_si256(self.vector, other.vector) }
+        }
+    }
+
+    #[inline]
+    pub fn movemask(self) -> u32 {
+        // Safe because we know AVX2 is enabled.
+        unsafe {
+            _mm256_movemask_epi8(self.vector) as u32
+        }
+    }
+
+    #[inline]
+    pub fn alignr_14(self, other: u8x32) -> u8x32 {
+        // Safe because we know AVX2 is enabled.
+        unsafe {
+            // Credit goes to jneem for figuring this out:
+            // https://github.com/jneem/teddy/blob/9ab5e899ad6ef6911aecd3cf1033f1abe6e1f66c/src/x86/teddy_simd.rs#L145-L184
+            //
+            // TL;DR avx2's PALIGNR instruction is actually just two 128-bit
+            // PALIGNR instructions, which is not what we want, so we need to
+            // do some extra shuffling.
+            let v = _mm256_permute2x128_si256(other.vector, self.vector, 0x21);
+            let v = _mm256_alignr_epi8(self.vector, v, 14);
+            u8x32 { vector: v }
+        }
+    }
+
+    #[inline]
+    pub fn alignr_15(self, other: u8x32) -> u8x32 {
+        // Safe because we know AVX2 is enabled.
+        unsafe {
+            // Credit goes to jneem for figuring this out:
+            // https://github.com/jneem/teddy/blob/9ab5e899ad6ef6911aecd3cf1033f1abe6e1f66c/src/x86/teddy_simd.rs#L145-L184
+            //
+            // TL;DR avx2's PALIGNR instruction is actually just two 128-bit
+            // PALIGNR instructions, which is not what we want, so we need to
+            // do some extra shuffling.
+            let v = _mm256_permute2x128_si256(other.vector, self.vector, 0x21);
+            let v = _mm256_alignr_epi8(self.vector, v, 15);
+            u8x32 { vector: v }
+        }
+    }
+
+    #[inline]
+    pub fn bit_shift_right_4(self) -> u8x32 {
+        // Safe because we know AVX2 is enabled.
+        unsafe {
+            u8x32 { vector: _mm256_srli_epi16(self.vector, 4) }
+        }
+    }
+
+    #[inline]
+    pub fn bytes(self) -> [u8; 32] {
+        // Safe because __m256i and [u8; 32] are layout compatible
+        unsafe { mem::transmute(self) }
+    }
+
+    #[inline]
+    pub fn replace_bytes(&mut self, value: [u8; 32]) {
+        // Safe because __m256i and [u8; 32] are layout compatible
+        self.vector = unsafe { mem::transmute(value) };
+    }
+}
+
+impl fmt::Debug for u8x32 {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.bytes().fmt(f)
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/vector/mod.rs.html b/target/doc/src/regex/vector/mod.rs.html new file mode 100644 index 0000000..474fa29 --- /dev/null +++ b/target/doc/src/regex/vector/mod.rs.html @@ -0,0 +1,11 @@ +mod.rs.html -- source
1
+2
+3
+4
+
+#[cfg(target_arch = "x86_64")]
+pub mod avx2;
+#[cfg(target_arch = "x86_64")]
+pub mod ssse3;
+
+
\ No newline at end of file diff --git a/target/doc/src/regex/vector/ssse3.rs.html b/target/doc/src/regex/vector/ssse3.rs.html new file mode 100644 index 0000000..7447a9d --- /dev/null +++ b/target/doc/src/regex/vector/ssse3.rs.html @@ -0,0 +1,387 @@ +ssse3.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+
+#![allow(dead_code)]
+
+use std::arch::x86_64::*;
+use std::fmt;
+use std::mem;
+
+/// A builder for SSSE3 empowered vectors.
+///
+/// This builder represents a receipt that the SSSE3 target feature is enabled
+/// on the currently running CPU. Namely, the only way to get a value of this
+/// type is if the SSSE3 feature is enabled.
+///
+/// This type can then be used to build vector types that use SSSE3 features
+/// safely.
+#[derive(Clone, Copy, Debug)]
+pub struct SSSE3VectorBuilder(());
+
+impl SSSE3VectorBuilder {
+    /// Create a new SSSE3 vector builder.
+    ///
+    /// If the SSSE3 feature is not enabled for the current target, then
+    /// return `None`.
+    pub fn new() -> Option<SSSE3VectorBuilder> {
+        if is_x86_feature_detected!("ssse3") {
+            Some(SSSE3VectorBuilder(()))
+        } else {
+            None
+        }
+    }
+
+    /// Create a new u8x16 SSSE3 vector where all of the bytes are set to
+    /// the given value.
+    #[inline]
+    pub fn u8x16_splat(self, n: u8) -> u8x16 {
+        // Safe because we know SSSE3 is enabled.
+        unsafe { u8x16::splat(n) }
+    }
+
+    /// Load 16 bytes from the given slice, with bounds checks.
+    #[inline]
+    pub fn u8x16_load_unaligned(self, slice: &[u8]) -> u8x16 {
+        // Safe because we know SSSE3 is enabled.
+        unsafe { u8x16::load_unaligned(slice) }
+    }
+
+    /// Load 16 bytes from the given slice, without bounds checks.
+    #[inline]
+    pub unsafe fn u8x16_load_unchecked_unaligned(self, slice: &[u8]) -> u8x16 {
+        // Safe because we know SSSE3 is enabled, but still unsafe
+        // because we aren't doing bounds checks.
+        u8x16::load_unchecked_unaligned(slice)
+    }
+
+    /// Load 16 bytes from the given slice, with bound and alignment checks.
+    #[inline]
+    pub fn u8x16_load(self, slice: &[u8]) -> u8x16 {
+        // Safe because we know SSSE3 is enabled.
+        unsafe { u8x16::load(slice) }
+    }
+
+    /// Load 16 bytes from the given slice, without bound or alignment checks.
+    #[inline]
+    pub unsafe fn u8x16_load_unchecked(self, slice: &[u8]) -> u8x16 {
+        // Safe because we know SSSE3 is enabled, but still unsafe
+        // because we aren't doing bounds checks.
+        u8x16::load_unchecked(slice)
+    }
+}
+
+/// A u8x16 is a 128-bit vector with 16 single-byte lanes.
+///
+/// It provides a safe API that uses only SSE2 or SSSE3 instructions.
+/// The only way for callers to construct a value of this type is
+/// through the SSSE3VectorBuilder type, and the only way to get a
+/// SSSE3VectorBuilder is if the `ssse3` target feature is enabled.
+///
+/// Note that generally speaking, all uses of this type should get
+/// inlined, otherwise you probably have a performance bug.
+#[derive(Clone, Copy)]
+#[allow(non_camel_case_types)]
+#[repr(transparent)]
+pub struct u8x16 {
+    vector: __m128i
+}
+
+impl u8x16 {
+    #[inline]
+    unsafe fn splat(n: u8) -> u8x16 {
+        u8x16 { vector: _mm_set1_epi8(n as i8) }
+    }
+
+    #[inline]
+    unsafe fn load_unaligned(slice: &[u8]) -> u8x16 {
+        assert!(slice.len() >= 16);
+        u8x16::load_unchecked(slice)
+    }
+
+    #[inline]
+    unsafe fn load_unchecked_unaligned(slice: &[u8]) -> u8x16 {
+        let v = _mm_loadu_si128(slice.as_ptr() as *const u8 as *const __m128i);
+        u8x16 { vector: v }
+    }
+
+    #[inline]
+    unsafe fn load(slice: &[u8]) -> u8x16 {
+        assert!(slice.len() >= 16);
+        assert!(slice.as_ptr() as usize % 16 == 0);
+        u8x16::load_unchecked(slice)
+    }
+
+    #[inline]
+    unsafe fn load_unchecked(slice: &[u8]) -> u8x16 {
+        let v = _mm_load_si128(slice.as_ptr() as *const u8 as *const __m128i);
+        u8x16 { vector: v }
+    }
+
+    #[inline]
+    pub fn shuffle(self, indices: u8x16) -> u8x16 {
+        // Safe because we know SSSE3 is enabled.
+        unsafe {
+            u8x16 { vector: _mm_shuffle_epi8(self.vector, indices.vector) }
+        }
+    }
+
+    #[inline]
+    pub fn ne(self, other: u8x16) -> u8x16 {
+        // Safe because we know SSSE3 is enabled.
+        unsafe {
+            let boolv = _mm_cmpeq_epi8(self.vector, other.vector);
+            let ones = _mm_set1_epi8(0xFF as u8 as i8);
+            u8x16 { vector: _mm_andnot_si128(boolv, ones) }
+        }
+    }
+
+    #[inline]
+    pub fn and(self, other: u8x16) -> u8x16 {
+        // Safe because we know SSSE3 is enabled.
+        unsafe {
+            u8x16 { vector: _mm_and_si128(self.vector, other.vector) }
+        }
+    }
+
+    #[inline]
+    pub fn movemask(self) -> u32 {
+        // Safe because we know SSSE3 is enabled.
+        unsafe {
+            _mm_movemask_epi8(self.vector) as u32
+        }
+    }
+
+    #[inline]
+    pub fn alignr_14(self, other: u8x16) -> u8x16 {
+        // Safe because we know SSSE3 is enabled.
+        unsafe {
+            u8x16 { vector: _mm_alignr_epi8(self.vector, other.vector, 14) }
+        }
+    }
+
+    #[inline]
+    pub fn alignr_15(self, other: u8x16) -> u8x16 {
+        // Safe because we know SSSE3 is enabled.
+        unsafe {
+            u8x16 { vector: _mm_alignr_epi8(self.vector, other.vector, 15) }
+        }
+    }
+
+    #[inline]
+    pub fn bit_shift_right_4(self) -> u8x16 {
+        // Safe because we know SSSE3 is enabled.
+        unsafe {
+            u8x16 { vector: _mm_srli_epi16(self.vector, 4) }
+        }
+    }
+
+    #[inline]
+    pub fn bytes(self) -> [u8; 16] {
+        // Safe because __m128i and [u8; 16] are layout compatible
+        unsafe { mem::transmute(self) }
+    }
+
+    #[inline]
+    pub fn replace_bytes(&mut self, value: [u8; 16]) {
+        // Safe because __m128i and [u8; 16] are layout compatible
+        self.vector = unsafe { mem::transmute(value) };
+    }
+}
+
+impl fmt::Debug for u8x16 {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.bytes().fmt(f)
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/ast/mod.rs.html b/target/doc/src/regex_syntax/ast/mod.rs.html new file mode 100644 index 0000000..2bfadc9 --- /dev/null +++ b/target/doc/src/regex_syntax/ast/mod.rs.html @@ -0,0 +1,3051 @@ +mod.rs.html -- source
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+Defines an abstract syntax for regular expressions.
+*/
+
+use std::cmp::Ordering;
+use std::error;
+use std::fmt;
+
+pub use ast::visitor::{Visitor, visit};
+
+pub mod parse;
+pub mod print;
+mod visitor;
+
+/// An error that occurred while parsing a regular expression into an abstract
+/// syntax tree.
+///
+/// Note that note all ASTs represents a valid regular expression. For example,
+/// an AST is constructed without error for `\p{Quux}`, but `Quux` is not a
+/// valid Unicode property name. That particular error is reported when
+/// translating an AST to the high-level intermediate representation (`HIR`).
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Error {
+    /// The kind of error.
+    kind: ErrorKind,
+    /// The original pattern that the parser generated the error from. Every
+    /// span in an error is a valid range into this string.
+    pattern: String,
+    /// The span of this error.
+    span: Span,
+}
+
+impl Error {
+    /// Return the type of this error.
+    pub fn kind(&self) -> &ErrorKind {
+        &self.kind
+    }
+
+    /// The original pattern string in which this error occurred.
+    ///
+    /// Every span reported by this error is reported in terms of this string.
+    pub fn pattern(&self) -> &str {
+        &self.pattern
+    }
+
+    /// Return the span at which this error occurred.
+    pub fn span(&self) -> &Span {
+        &self.span
+    }
+
+    /// Return an auxiliary span. This span exists only for some errors that
+    /// benefit from being able to point to two locations in the original
+    /// regular expression. For example, "duplicate" errors will have the
+    /// main error position set to the duplicate occurrence while its
+    /// auxiliary span will be set to the initial occurrence.
+    pub fn auxiliary_span(&self) -> Option<&Span> {
+        use self::ErrorKind::*;
+        match self.kind {
+            FlagDuplicate { ref original } => Some(original),
+            FlagRepeatedNegation { ref original, .. } => Some(original),
+            GroupNameDuplicate { ref original, .. } => Some(original),
+            _ => None,
+        }
+    }
+}
+
+/// The type of an error that occurred while building an AST.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum ErrorKind {
+    /// The capturing group limit was exceeded.
+    ///
+    /// Note that this represents a limit on the total number of capturing
+    /// groups in a regex and not necessarily the number of nested capturing
+    /// groups. That is, the nest limit can be low and it is still possible for
+    /// this error to occur.
+    CaptureLimitExceeded,
+    /// An invalid escape sequence was found in a character class set.
+    ClassEscapeInvalid,
+    /// An invalid character class range was found. An invalid range is any
+    /// range where the start is greater than the end.
+    ClassRangeInvalid,
+    /// An invalid range boundary was found in a character class. Range
+    /// boundaries must be a single literal codepoint, but this error indicates
+    /// that something else was found, such as a nested class.
+    ClassRangeLiteral,
+    /// An opening `[` was found with no corresponding closing `]`.
+    ClassUnclosed,
+    /// Note that this error variant is no longer used. Namely, a decimal
+    /// number can only appear as a repetition quantifier. When the number
+    /// in a repetition quantifier is empty, then it gets its own specialized
+    /// error, `RepetitionCountDecimalEmpty`.
+    DecimalEmpty,
+    /// An invalid decimal number was given where one was expected.
+    DecimalInvalid,
+    /// A bracketed hex literal was empty.
+    EscapeHexEmpty,
+    /// A bracketed hex literal did not correspond to a Unicode scalar value.
+    EscapeHexInvalid,
+    /// An invalid hexadecimal digit was found.
+    EscapeHexInvalidDigit,
+    /// EOF was found before an escape sequence was completed.
+    EscapeUnexpectedEof,
+    /// An unrecognized escape sequence.
+    EscapeUnrecognized,
+    /// A dangling negation was used when setting flags, e.g., `i-`.
+    FlagDanglingNegation,
+    /// A flag was used twice, e.g., `i-i`.
+    FlagDuplicate {
+        /// The position of the original flag. The error position
+        /// points to the duplicate flag.
+        original: Span,
+    },
+    /// The negation operator was used twice, e.g., `-i-s`.
+    FlagRepeatedNegation {
+        /// The position of the original negation operator. The error position
+        /// points to the duplicate negation operator.
+        original: Span,
+    },
+    /// Expected a flag but got EOF, e.g., `(?`.
+    FlagUnexpectedEof,
+    /// Unrecognized flag, e.g., `a`.
+    FlagUnrecognized,
+    /// A duplicate capture name was found.
+    GroupNameDuplicate {
+        /// The position of the initial occurrence of the capture name. The
+        /// error position itself points to the duplicate occurrence.
+        original: Span,
+    },
+    /// A capture group name is empty, e.g., `(?P<>abc)`.
+    GroupNameEmpty,
+    /// An invalid character was seen for a capture group name. This includes
+    /// errors where the first character is a digit (even though subsequent
+    /// characters are allowed to be digits).
+    GroupNameInvalid,
+    /// A closing `>` could not be found for a capture group name.
+    GroupNameUnexpectedEof,
+    /// An unclosed group, e.g., `(ab`.
+    ///
+    /// The span of this error corresponds to the unclosed parenthesis.
+    GroupUnclosed,
+    /// An unopened group, e.g., `ab)`.
+    GroupUnopened,
+    /// The nest limit was exceeded. The limit stored here is the limit
+    /// configured in the parser.
+    NestLimitExceeded(u32),
+    /// The range provided in a counted repetition operator is invalid. The
+    /// range is invalid if the start is greater than the end.
+    RepetitionCountInvalid,
+    /// An opening `{` was not followed by a valid decimal value.
+    /// For example, `x{}` or `x{]}` would fail.
+    RepetitionCountDecimalEmpty,
+    /// An opening `{` was found with no corresponding closing `}`.
+    RepetitionCountUnclosed,
+    /// A repetition operator was applied to a missing sub-expression. This
+    /// occurs, for example, in the regex consisting of just a `*` or even
+    /// `(?i)*`. It is, however, possible to create a repetition operating on
+    /// an empty sub-expression. For example, `()*` is still considered valid.
+    RepetitionMissing,
+    /// When octal support is disabled, this error is produced when an octal
+    /// escape is used. The octal escape is assumed to be an invocation of
+    /// a backreference, which is the common case.
+    UnsupportedBackreference,
+    /// When syntax similar to PCRE's look-around is used, this error is
+    /// returned. Some example syntaxes that are rejected include, but are
+    /// not necessarily limited to, `(?=re)`, `(?!re)`, `(?<=re)` and
+    /// `(?<!re)`. Note that all of these syntaxes are otherwise invalid; this
+    /// error is used to improve the user experience.
+    UnsupportedLookAround,
+    /// Hints that destructuring should not be exhaustive.
+    ///
+    /// This enum may grow additional variants, so this makes sure clients
+    /// don't count on exhaustive matching. (Otherwise, adding a new variant
+    /// could break existing code.)
+    #[doc(hidden)]
+    __Nonexhaustive,
+}
+
+impl error::Error for Error {
+    fn description(&self) -> &str {
+        use self::ErrorKind::*;
+        match self.kind {
+            CaptureLimitExceeded => "capture group limit exceeded",
+            ClassEscapeInvalid => "invalid escape sequence in character class",
+            ClassRangeInvalid => "invalid character class range",
+            ClassRangeLiteral => "invalid range boundary, must be a literal",
+            ClassUnclosed => "unclosed character class",
+            DecimalEmpty => "empty decimal literal",
+            DecimalInvalid => "invalid decimal literal",
+            EscapeHexEmpty => "empty hexadecimal literal",
+            EscapeHexInvalid => "invalid hexadecimal literal",
+            EscapeHexInvalidDigit => "invalid hexadecimal digit",
+            EscapeUnexpectedEof => "unexpected eof (escape sequence)",
+            EscapeUnrecognized => "unrecognized escape sequence",
+            FlagDanglingNegation => "dangling flag negation operator",
+            FlagDuplicate{..} => "duplicate flag",
+            FlagRepeatedNegation{..} => "repeated negation",
+            FlagUnexpectedEof => "unexpected eof (flag)",
+            FlagUnrecognized => "unrecognized flag",
+            GroupNameDuplicate{..} => "duplicate capture group name",
+            GroupNameEmpty => "empty capture group name",
+            GroupNameInvalid => "invalid capture group name",
+            GroupNameUnexpectedEof => "unclosed capture group name",
+            GroupUnclosed => "unclosed group",
+            GroupUnopened => "unopened group",
+            NestLimitExceeded(_) => "nest limit exceeded",
+            RepetitionCountInvalid => "invalid repetition count range",
+            RepetitionCountUnclosed => "unclosed counted repetition",
+            RepetitionMissing => "repetition operator missing expression",
+            UnsupportedBackreference => "backreferences are not supported",
+            UnsupportedLookAround => "look-around is not supported",
+            _ => unreachable!(),
+        }
+    }
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        ::error::Formatter::from(self).fmt(f)
+    }
+}
+
+impl fmt::Display for ErrorKind {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        use self::ErrorKind::*;
+        match *self {
+            CaptureLimitExceeded => {
+                write!(f, "exceeded the maximum number of \
+                           capturing groups ({})", ::std::u32::MAX)
+            }
+            ClassEscapeInvalid => {
+                write!(f, "invalid escape sequence found in character class")
+            }
+            ClassRangeInvalid => {
+                write!(f, "invalid character class range, \
+                           the start must be <= the end")
+            }
+            ClassRangeLiteral => {
+                write!(f, "invalid range boundary, must be a literal")
+            }
+            ClassUnclosed => {
+                write!(f, "unclosed character class")
+            }
+            DecimalEmpty => {
+                write!(f, "decimal literal empty")
+            }
+            DecimalInvalid => {
+                write!(f, "decimal literal invalid")
+            }
+            EscapeHexEmpty => {
+                write!(f, "hexadecimal literal empty")
+            }
+            EscapeHexInvalid => {
+                write!(f, "hexadecimal literal is not a Unicode scalar value")
+            }
+            EscapeHexInvalidDigit => {
+                write!(f, "invalid hexadecimal digit")
+            }
+            EscapeUnexpectedEof => {
+                write!(f, "incomplete escape sequence, \
+                           reached end of pattern prematurely")
+            }
+            EscapeUnrecognized => {
+                write!(f, "unrecognized escape sequence")
+            }
+            FlagDanglingNegation => {
+                write!(f, "dangling flag negation operator")
+            }
+            FlagDuplicate{..} => {
+                write!(f, "duplicate flag")
+            }
+            FlagRepeatedNegation{..} => {
+                write!(f, "flag negation operator repeated")
+            }
+            FlagUnexpectedEof => {
+                write!(f, "expected flag but got end of regex")
+            }
+            FlagUnrecognized => {
+                write!(f, "unrecognized flag")
+            }
+            GroupNameDuplicate{..} => {
+                write!(f, "duplicate capture group name")
+            }
+            GroupNameEmpty => {
+                write!(f, "empty capture group name")
+            }
+            GroupNameInvalid => {
+                write!(f, "invalid capture group character")
+            }
+            GroupNameUnexpectedEof => {
+                write!(f, "unclosed capture group name")
+            }
+            GroupUnclosed => {
+                write!(f, "unclosed group")
+            }
+            GroupUnopened => {
+                write!(f, "unopened group")
+            }
+            NestLimitExceeded(limit) => {
+                write!(f, "exceed the maximum number of \
+                           nested parentheses/brackets ({})", limit)
+            }
+            RepetitionCountInvalid => {
+                write!(f, "invalid repetition count range, \
+                           the start must be <= the end")
+            }
+            RepetitionCountDecimalEmpty => {
+                write!(f, "repetition quantifier expects a valid decimal")
+            }
+            RepetitionCountUnclosed => {
+                write!(f, "unclosed counted repetition")
+            }
+            RepetitionMissing => {
+                write!(f, "repetition operator missing expression")
+            }
+            UnsupportedBackreference => {
+                write!(f, "backreferences are not supported")
+            }
+            UnsupportedLookAround => {
+                write!(f, "look-around, including look-ahead and look-behind, \
+                           is not supported")
+            }
+            _ => unreachable!(),
+        }
+    }
+}
+
+/// Span represents the position information of a single AST item.
+///
+/// All span positions are absolute byte offsets that can be used on the
+/// original regular expression that was parsed.
+#[derive(Clone, Copy, Eq, PartialEq)]
+pub struct Span {
+    /// The start byte offset.
+    pub start: Position,
+    /// The end byte offset.
+    pub end: Position,
+}
+
+impl fmt::Debug for Span {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "Span({:?}, {:?})", self.start, self.end)
+    }
+}
+
+impl Ord for Span {
+    fn cmp(&self, other: &Span) -> Ordering {
+        (&self.start, &self.end).cmp(&(&other.start, &other.end))
+    }
+}
+
+impl PartialOrd for Span {
+    fn partial_cmp(&self, other: &Span) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+/// A single position in a regular expression.
+///
+/// A position encodes one half of a span, and include the byte offset, line
+/// number and column number.
+#[derive(Clone, Copy, Eq, PartialEq)]
+pub struct Position {
+    /// The absolute offset of this position, starting at `0` from the
+    /// beginning of the regular expression pattern string.
+    pub offset: usize,
+    /// The line number, starting at `1`.
+    pub line: usize,
+    /// The approximate column number, starting at `1`.
+    pub column: usize,
+}
+
+impl fmt::Debug for Position {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(
+            f,
+            "Position(o: {:?}, l: {:?}, c: {:?})",
+            self.offset, self.line, self.column)
+    }
+}
+
+impl Ord for Position {
+    fn cmp(&self, other: &Position) -> Ordering {
+        self.offset.cmp(&other.offset)
+    }
+}
+
+impl PartialOrd for Position {
+    fn partial_cmp(&self, other: &Position) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Span {
+    /// Create a new span with the given positions.
+    pub fn new(start: Position, end: Position) -> Span {
+        Span { start: start, end: end }
+    }
+
+    /// Create a new span using the given position as the start and end.
+    pub fn splat(pos: Position) -> Span {
+        Span::new(pos, pos)
+    }
+
+    /// Create a new span by replacing the starting the position with the one
+    /// given.
+    pub fn with_start(self, pos: Position) -> Span {
+        Span { start: pos, ..self }
+    }
+
+    /// Create a new span by replacing the ending the position with the one
+    /// given.
+    pub fn with_end(self, pos: Position) -> Span {
+        Span { end: pos, ..self }
+    }
+
+    /// Returns true if and only if this span occurs on a single line.
+    pub fn is_one_line(&self) -> bool {
+        self.start.line == self.end.line
+    }
+
+    /// Returns true if and only if this span is empty. That is, it points to
+    /// a single position in the concrete syntax of a regular expression.
+    pub fn is_empty(&self) -> bool {
+        self.start.offset == self.end.offset
+    }
+}
+
+impl Position {
+    /// Create a new position with the given information.
+    ///
+    /// `offset` is the absolute offset of the position, starting at `0` from
+    /// the beginning of the regular expression pattern string.
+    ///
+    /// `line` is the line number, starting at `1`.
+    ///
+    /// `column` is the approximate column number, starting at `1`.
+    pub fn new(offset: usize, line: usize, column: usize) -> Position {
+        Position { offset: offset, line: line, column: column }
+    }
+}
+
+/// An abstract syntax tree for a singular expression along with comments
+/// found.
+///
+/// Comments are not stored in the tree itself to avoid complexity. Each
+/// comment contains a span of precisely where it occurred in the original
+/// regular expression.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct WithComments {
+    /// The actual ast.
+    pub ast: Ast,
+    /// All comments found in the original regular expression.
+    pub comments: Vec<Comment>,
+}
+
+/// A comment from a regular expression with an associated span.
+///
+/// A regular expression can only contain comments when the `x` flag is
+/// enabled.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Comment {
+    /// The span of this comment, including the beginning `#` and ending `\n`.
+    pub span: Span,
+    /// The comment text, starting with the first character following the `#`
+    /// and ending with the last character preceding the `\n`.
+    pub comment: String,
+}
+
+/// An abstract syntax tree for a single regular expression.
+///
+/// An `Ast`'s `fmt::Display` implementation uses constant stack space and heap
+/// space proportional to the size of the `Ast`.
+///
+/// This type defines its own destructor that uses constant stack space and
+/// heap space proportional to the size of the `Ast`.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum Ast {
+    /// An empty regex that matches everything.
+    Empty(Span),
+    /// A set of flags, e.g., `(?is)`.
+    Flags(SetFlags),
+    /// A single character literal, which includes escape sequences.
+    Literal(Literal),
+    /// The "any character" class.
+    Dot(Span),
+    /// A single zero-width assertion.
+    Assertion(Assertion),
+    /// A single character class. This includes all forms of character classes
+    /// except for `.`. e.g., `\d`, `\pN`, `[a-z]` and `[[:alpha:]]`.
+    Class(Class),
+    /// A repetition operator applied to an arbitrary regular expression.
+    Repetition(Repetition),
+    /// A grouped regular expression.
+    Group(Group),
+    /// An alternation of regular expressions.
+    Alternation(Alternation),
+    /// A concatenation of regular expressions.
+    Concat(Concat),
+}
+
+impl Ast {
+    /// Return the span of this abstract syntax tree.
+    pub fn span(&self) -> &Span {
+        match *self {
+            Ast::Empty(ref span) => span,
+            Ast::Flags(ref x) => &x.span,
+            Ast::Literal(ref x) => &x.span,
+            Ast::Dot(ref span) => span,
+            Ast::Assertion(ref x) => &x.span,
+            Ast::Class(ref x) => x.span(),
+            Ast::Repetition(ref x) => &x.span,
+            Ast::Group(ref x) => &x.span,
+            Ast::Alternation(ref x) => &x.span,
+            Ast::Concat(ref x) => &x.span,
+        }
+    }
+
+    /// Return true if and only if this Ast is empty.
+    pub fn is_empty(&self) -> bool {
+        match *self {
+            Ast::Empty(_) => true,
+            _ => false,
+        }
+    }
+
+    /// Returns true if and only if this AST has any (including possibly empty)
+    /// subexpressions.
+    fn has_subexprs(&self) -> bool {
+        match *self {
+            Ast::Empty(_)
+            | Ast::Flags(_)
+            | Ast::Literal(_)
+            | Ast::Dot(_)
+            | Ast::Assertion(_) => false,
+            Ast::Class(_)
+            | Ast::Repetition(_)
+            | Ast::Group(_)
+            | Ast::Alternation(_)
+            | Ast::Concat(_) => true,
+        }
+    }
+}
+
+/// Print a display representation of this Ast.
+///
+/// This does not preserve any of the original whitespace formatting that may
+/// have originally been present in the concrete syntax from which this Ast
+/// was generated.
+///
+/// This implementation uses constant stack space and heap space proportional
+/// to the size of the `Ast`.
+impl fmt::Display for Ast {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        use ast::print::Printer;
+        Printer::new().print(self, f)
+    }
+}
+
+/// An alternation of regular expressions.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Alternation {
+    /// The span of this alternation.
+    pub span: Span,
+    /// The alternate regular expressions.
+    pub asts: Vec<Ast>,
+}
+
+impl Alternation {
+    /// Return this alternation as an AST.
+    ///
+    /// If this alternation contains zero ASTs, then Ast::Empty is
+    /// returned. If this alternation contains exactly 1 AST, then the
+    /// corresponding AST is returned. Otherwise, Ast::Alternation is returned.
+    pub fn into_ast(mut self) -> Ast {
+        match self.asts.len() {
+            0 => Ast::Empty(self.span),
+            1 => self.asts.pop().unwrap(),
+            _ => Ast::Alternation(self),
+        }
+    }
+}
+
+/// A concatenation of regular expressions.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Concat {
+    /// The span of this concatenation.
+    pub span: Span,
+    /// The concatenation regular expressions.
+    pub asts: Vec<Ast>,
+}
+
+impl Concat {
+    /// Return this concatenation as an AST.
+    ///
+    /// If this concatenation contains zero ASTs, then Ast::Empty is
+    /// returned. If this concatenation contains exactly 1 AST, then the
+    /// corresponding AST is returned. Otherwise, Ast::Concat is returned.
+    pub fn into_ast(mut self) -> Ast {
+        match self.asts.len() {
+            0 => Ast::Empty(self.span),
+            1 => self.asts.pop().unwrap(),
+            _ => Ast::Concat(self),
+        }
+    }
+}
+
+/// A single literal expression.
+///
+/// A literal corresponds to a single Unicode scalar value. Literals may be
+/// represented in their literal form, e.g., `a` or in their escaped form,
+/// e.g., `\x61`.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Literal {
+    /// The span of this literal.
+    pub span: Span,
+    /// The kind of this literal.
+    pub kind: LiteralKind,
+    /// The Unicode scalar value corresponding to this literal.
+    pub c: char,
+}
+
+impl Literal {
+    /// If this literal was written as a `\x` hex escape, then this returns
+    /// the corresponding byte value. Otherwise, this returns `None`.
+    pub fn byte(&self) -> Option<u8> {
+        let short_hex = LiteralKind::HexFixed(HexLiteralKind::X);
+        if self.c as u32 <= 255 && self.kind == short_hex {
+            Some(self.c as u8)
+        } else {
+            None
+        }
+    }
+}
+
+/// The kind of a single literal expression.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum LiteralKind {
+    /// The literal is written verbatim, e.g., `a` or `☃`.
+    Verbatim,
+    /// The literal is written as an escape because it is punctuation, e.g.,
+    /// `\*` or `\[`.
+    Punctuation,
+    /// The literal is written as an octal escape, e.g., `\141`.
+    Octal,
+    /// The literal is written as a hex code with a fixed number of digits
+    /// depending on the type of the escape, e.g., `\x61` or or `\u0061` or
+    /// `\U00000061`.
+    HexFixed(HexLiteralKind),
+    /// The literal is written as a hex code with a bracketed number of
+    /// digits. The only restriction is that the bracketed hex code must refer
+    /// to a valid Unicode scalar value.
+    HexBrace(HexLiteralKind),
+    /// The literal is written as a specially recognized escape, e.g., `\f`
+    /// or `\n`.
+    Special(SpecialLiteralKind),
+}
+
+/// The type of a special literal.
+///
+/// A special literal is a special escape sequence recognized by the regex
+/// parser, e.g., `\f` or `\n`.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum SpecialLiteralKind {
+    /// Bell, spelled `\a` (`\x07`).
+    Bell,
+    /// Form feed, spelled `\f` (`\x0C`).
+    FormFeed,
+    /// Tab, spelled `\t` (`\x09`).
+    Tab,
+    /// Line feed, spelled `\n` (`\x0A`).
+    LineFeed,
+    /// Carriage return, spelled `\r` (`\x0D`).
+    CarriageReturn,
+    /// Vertical tab, spelled `\v` (`\x0B`).
+    VerticalTab,
+    /// Space, spelled `\ ` (`\x20`). Note that this can only appear when
+    /// parsing in verbose mode.
+    Space,
+}
+
+/// The type of a Unicode hex literal.
+///
+/// Note that all variants behave the same when used with brackets. They only
+/// differ when used without brackets in the number of hex digits that must
+/// follow.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum HexLiteralKind {
+    /// A `\x` prefix. When used without brackets, this form is limited to
+    /// two digits.
+    X,
+    /// A `\u` prefix. When used without brackets, this form is limited to
+    /// four digits.
+    UnicodeShort,
+    /// A `\U` prefix. When used without brackets, this form is limited to
+    /// eight digits.
+    UnicodeLong,
+}
+
+impl HexLiteralKind {
+    /// The number of digits that must be used with this literal form when
+    /// used without brackets. When used with brackets, there is no
+    /// restriction on the number of digits.
+    pub fn digits(&self) -> u32 {
+        match *self {
+            HexLiteralKind::X => 2,
+            HexLiteralKind::UnicodeShort => 4,
+            HexLiteralKind::UnicodeLong => 8,
+        }
+    }
+}
+
+/// A single character class expression.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum Class {
+    /// A Unicode character class, e.g., `\pL` or `\p{Greek}`.
+    Unicode(ClassUnicode),
+    /// A perl character class, e.g., `\d` or `\W`.
+    Perl(ClassPerl),
+    /// A bracketed character class set, which may contain zero or more
+    /// character ranges and/or zero or more nested classes. e.g.,
+    /// `[a-zA-Z\pL]`.
+    Bracketed(ClassBracketed),
+}
+
+impl Class {
+    /// Return the span of this character class.
+    pub fn span(&self) -> &Span {
+        match *self {
+            Class::Perl(ref x) => &x.span,
+            Class::Unicode(ref x) => &x.span,
+            Class::Bracketed(ref x) => &x.span,
+        }
+    }
+}
+
+/// A Perl character class.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct ClassPerl {
+    /// The span of this class.
+    pub span: Span,
+    /// The kind of Perl class.
+    pub kind: ClassPerlKind,
+    /// Whether the class is negated or not. e.g., `\d` is not negated but
+    /// `\D` is.
+    pub negated: bool,
+}
+
+/// The available Perl character classes.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum ClassPerlKind {
+    /// Decimal numbers.
+    Digit,
+    /// Whitespace.
+    Space,
+    /// Word characters.
+    Word,
+}
+
+/// An ASCII character class.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct ClassAscii {
+    /// The span of this class.
+    pub span: Span,
+    /// The kind of ASCII class.
+    pub kind: ClassAsciiKind,
+    /// Whether the class is negated or not. e.g., `[[:alpha:]]` is not negated
+    /// but `[[:^alpha:]]` is.
+    pub negated: bool,
+}
+
+/// The available ASCII character classes.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum ClassAsciiKind {
+    /// `[0-9A-Za-z]`
+    Alnum,
+    /// `[A-Za-z]`
+    Alpha,
+    /// `[\x00-\x7F]`
+    Ascii,
+    /// `[ \t]`
+    Blank,
+    /// `[\x00-\x1F\x7F]`
+    Cntrl,
+    /// `[0-9]`
+    Digit,
+    /// `[!-~]`
+    Graph,
+    /// `[a-z]`
+    Lower,
+    /// `[ -~]`
+    Print,
+    /// `[!-/:-@\[-`{-~]`
+    Punct,
+    /// `[\t\n\v\f\r ]`
+    Space,
+    /// `[A-Z]`
+    Upper,
+    /// `[0-9A-Za-z_]`
+    Word,
+    /// `[0-9A-Fa-f]`
+    Xdigit,
+}
+
+impl ClassAsciiKind {
+    /// Return the corresponding ClassAsciiKind variant for the given name.
+    ///
+    /// The name given should correspond to the lowercase version of the
+    /// variant name. e.g., `cntrl` is the name for `ClassAsciiKind::Cntrl`.
+    ///
+    /// If no variant with the corresponding name exists, then `None` is
+    /// returned.
+    pub fn from_name(name: &str) -> Option<ClassAsciiKind> {
+        use self::ClassAsciiKind::*;
+        match name {
+            "alnum" => Some(Alnum),
+            "alpha" => Some(Alpha),
+            "ascii" => Some(Ascii),
+            "blank" => Some(Blank),
+            "cntrl" => Some(Cntrl),
+            "digit" => Some(Digit),
+            "graph" => Some(Graph),
+            "lower" => Some(Lower),
+            "print" => Some(Print),
+            "punct" => Some(Punct),
+            "space" => Some(Space),
+            "upper" => Some(Upper),
+            "word" => Some(Word),
+            "xdigit" => Some(Xdigit),
+            _ => None,
+        }
+    }
+}
+
+/// A Unicode character class.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct ClassUnicode {
+    /// The span of this class.
+    pub span: Span,
+    /// Whether this class is negated or not.
+    ///
+    /// Note: be careful when using this attribute. This specifically refers
+    /// to whether the class is written as `\p` or `\P`, where the latter
+    /// is `negated = true`. However, it also possible to write something like
+    /// `\P{scx!=Katakana}` which is actually equivalent to
+    /// `\p{scx=Katakana}` and is therefore not actually negated even though
+    /// `negated = true` here. To test whether this class is truly negated
+    /// or not, use the `is_negated` method.
+    pub negated: bool,
+    /// The kind of Unicode class.
+    pub kind: ClassUnicodeKind,
+}
+
+impl ClassUnicode {
+    /// Returns true if this class has been negated.
+    ///
+    /// Note that this takes the Unicode op into account, if it's present.
+    /// e.g., `is_negated` for `\P{scx!=Katakana}` will return `false`.
+    pub fn is_negated(&self) -> bool {
+        match self.kind {
+            ClassUnicodeKind::NamedValue {
+                op: ClassUnicodeOpKind::NotEqual, ..
+            } => !self.negated,
+            _ => self.negated,
+        }
+    }
+}
+
+/// The available forms of Unicode character classes.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum ClassUnicodeKind {
+    /// A one letter abbreviated class, e.g., `\pN`.
+    OneLetter(char),
+    /// A binary property, general category or script. The string may be
+    /// empty.
+    Named(String),
+    /// A property name and an associated value.
+    NamedValue {
+        /// The type of Unicode op used to associate `name` with `value`.
+        op: ClassUnicodeOpKind,
+        /// The property name (which may be empty).
+        name: String,
+        /// The property value (which may be empty).
+        value: String,
+    },
+}
+
+/// The type of op used in a Unicode character class.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum ClassUnicodeOpKind {
+    /// A property set to a specific value, e.g., `\p{scx=Katakana}`.
+    Equal,
+    /// A property set to a specific value using a colon, e.g.,
+    /// `\p{scx:Katakana}`.
+    Colon,
+    /// A property that isn't a particular value, e.g., `\p{scx!=Katakana}`.
+    NotEqual,
+}
+
+impl ClassUnicodeOpKind {
+    /// Whether the op is an equality op or not.
+    pub fn is_equal(&self) -> bool {
+        match *self {
+            ClassUnicodeOpKind::Equal|ClassUnicodeOpKind::Colon => true,
+            _ => false,
+        }
+    }
+}
+
+/// A bracketed character class, e.g., `[a-z0-9]`.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct ClassBracketed {
+    /// The span of this class.
+    pub span: Span,
+    /// Whether this class is negated or not. e.g., `[a]` is not negated but
+    /// `[^a]` is.
+    pub negated: bool,
+    /// The type of this set. A set is either a normal union of things, e.g.,
+    /// `[abc]` or a result of applying set operations, e.g., `[\pL--c]`.
+    pub kind: ClassSet,
+}
+
+/// A character class set.
+///
+/// This type corresponds to the internal structure of a bracketed character
+/// class. That is, every bracketed character is one of two types: a union of
+/// items (literals, ranges, other bracketed classes) or a tree of binary set
+/// operations.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum ClassSet {
+    /// An item, which can be a single literal, range, nested character class
+    /// or a union of items.
+    Item(ClassSetItem),
+    /// A single binary operation (i.e., &&, -- or ~~).
+    BinaryOp(ClassSetBinaryOp),
+}
+
+impl ClassSet {
+    /// Build a set from a union.
+    pub fn union(ast: ClassSetUnion) -> ClassSet {
+        ClassSet::Item(ClassSetItem::Union(ast))
+    }
+
+    /// Return the span of this character class set.
+    pub fn span(&self) -> &Span {
+        match *self {
+            ClassSet::Item(ref x) => x.span(),
+            ClassSet::BinaryOp(ref x) => &x.span,
+        }
+    }
+
+    /// Return true if and only if this class set is empty.
+    fn is_empty(&self) -> bool {
+        match *self {
+            ClassSet::Item(ClassSetItem::Empty(_)) => true,
+            _ => false,
+        }
+    }
+}
+
+/// A single component of a character class set.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum ClassSetItem {
+    /// An empty item.
+    ///
+    /// Note that a bracketed character class cannot contain a single empty
+    /// item. Empty items can appear when using one of the binary operators.
+    /// For example, `[&&]` is the intersection of two empty classes.
+    Empty(Span),
+    /// A single literal.
+    Literal(Literal),
+    /// A range between two literals.
+    Range(ClassSetRange),
+    /// An ASCII character class, e.g., `[:alnum:]` or `[:punct:]`.
+    Ascii(ClassAscii),
+    /// A Unicode character class, e.g., `\pL` or `\p{Greek}`.
+    Unicode(ClassUnicode),
+    /// A perl character class, e.g., `\d` or `\W`.
+    Perl(ClassPerl),
+    /// A bracketed character class set, which may contain zero or more
+    /// character ranges and/or zero or more nested classes. e.g.,
+    /// `[a-zA-Z\pL]`.
+    Bracketed(Box<ClassBracketed>),
+    /// A union of items.
+    Union(ClassSetUnion),
+}
+
+impl ClassSetItem {
+    /// Return the span of this character class set item.
+    pub fn span(&self) -> &Span {
+        match *self {
+            ClassSetItem::Empty(ref span) => span,
+            ClassSetItem::Literal(ref x) => &x.span,
+            ClassSetItem::Range(ref x) => &x.span,
+            ClassSetItem::Ascii(ref x) => &x.span,
+            ClassSetItem::Perl(ref x) => &x.span,
+            ClassSetItem::Unicode(ref x) => &x.span,
+            ClassSetItem::Bracketed(ref x) => &x.span,
+            ClassSetItem::Union(ref x) => &x.span,
+        }
+    }
+}
+
+/// A single character class range in a set.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct ClassSetRange {
+    /// The span of this range.
+    pub span: Span,
+    /// The start of this range.
+    pub start: Literal,
+    /// The end of this range.
+    pub end: Literal,
+}
+
+impl ClassSetRange {
+    /// Returns true if and only if this character class range is valid.
+    ///
+    /// The only case where a range is invalid is if its start is greater than
+    /// its end.
+    pub fn is_valid(&self) -> bool {
+        self.start.c <= self.end.c
+    }
+}
+
+/// A union of items inside a character class set.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct ClassSetUnion {
+    /// The span of the items in this operation. e.g., the `a-z0-9` in
+    /// `[^a-z0-9]`
+    pub span: Span,
+    /// The sequence of items that make up this union.
+    pub items: Vec<ClassSetItem>,
+}
+
+impl ClassSetUnion {
+    /// Push a new item in this union.
+    ///
+    /// The ending position of this union's span is updated to the ending
+    /// position of the span of the item given. If the union is empty, then
+    /// the starting position of this union is set to the starting position
+    /// of this item.
+    ///
+    /// In other words, if you only use this method to add items to a union
+    /// and you set the spans on each item correctly, then you should never
+    /// need to adjust the span of the union directly.
+    pub fn push(&mut self, item: ClassSetItem) {
+        if self.items.is_empty() {
+            self.span.start = item.span().start;
+        }
+        self.span.end = item.span().end;
+        self.items.push(item);
+    }
+
+    /// Return this union as a character class set item.
+    ///
+    /// If this union contains zero items, then an empty union is
+    /// returned. If this concatenation contains exactly 1 item, then the
+    /// corresponding item is returned. Otherwise, ClassSetItem::Union is
+    /// returned.
+    pub fn into_item(mut self) -> ClassSetItem {
+        match self.items.len() {
+            0 => ClassSetItem::Empty(self.span),
+            1 => self.items.pop().unwrap(),
+            _ => ClassSetItem::Union(self),
+        }
+    }
+}
+
+/// A Unicode character class set operation.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct ClassSetBinaryOp {
+    /// The span of this operation. e.g., the `a-z--[h-p]` in `[a-z--h-p]`.
+    pub span: Span,
+    /// The type of this set operation.
+    pub kind: ClassSetBinaryOpKind,
+    /// The left hand side of the operation.
+    pub lhs: Box<ClassSet>,
+    /// The right hand side of the operation.
+    pub rhs: Box<ClassSet>,
+}
+
+/// The type of a Unicode character class set operation.
+///
+/// Note that this doesn't explicitly represent union since there is no
+/// explicit union operator. Concatenation inside a character class corresponds
+/// to the union operation.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum ClassSetBinaryOpKind {
+    /// The intersection of two sets, e.g., `\pN&&[a-z]`.
+    Intersection,
+    /// The difference of two sets, e.g., `\pN--[0-9]`.
+    Difference,
+    /// The symmetric difference of two sets. The symmetric difference is the
+    /// set of elements belonging to one but not both sets.
+    /// e.g., `[\pL~~[:ascii:]]`.
+    SymmetricDifference,
+}
+
+/// A single zero-width assertion.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Assertion {
+    /// The span of this assertion.
+    pub span: Span,
+    /// The assertion kind, e.g., `\b` or `^`.
+    pub kind: AssertionKind,
+}
+
+/// An assertion kind.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum AssertionKind {
+    /// `^`
+    StartLine,
+    /// `$`
+    EndLine,
+    /// `\A`
+    StartText,
+    /// `\z`
+    EndText,
+    /// `\b`
+    WordBoundary,
+    /// `\B`
+    NotWordBoundary,
+}
+
+/// A repetition operation applied to a regular expression.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Repetition {
+    /// The span of this operation.
+    pub span: Span,
+    /// The actual operation.
+    pub op: RepetitionOp,
+    /// Whether this operation was applied greedily or not.
+    pub greedy: bool,
+    /// The regular expression under repetition.
+    pub ast: Box<Ast>,
+}
+
+/// The repetition operator itself.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct RepetitionOp {
+    /// The span of this operator. This includes things like `+`, `*?` and
+    /// `{m,n}`.
+    pub span: Span,
+    /// The type of operation.
+    pub kind: RepetitionKind,
+}
+
+/// The kind of a repetition operator.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum RepetitionKind {
+    /// `?`
+    ZeroOrOne,
+    /// `*`
+    ZeroOrMore,
+    /// `+`
+    OneOrMore,
+    /// `{m,n}`
+    Range(RepetitionRange),
+}
+
+/// A range repetition operator.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum RepetitionRange {
+    /// `{m}`
+    Exactly(u32),
+    /// `{m,}`
+    AtLeast(u32),
+    /// `{m,n}`
+    Bounded(u32, u32),
+}
+
+impl RepetitionRange {
+    /// Returns true if and only if this repetition range is valid.
+    ///
+    /// The only case where a repetition range is invalid is if it is bounded
+    /// and its start is greater than its end.
+    pub fn is_valid(&self) -> bool {
+        match *self {
+            RepetitionRange::Bounded(s, e) if s > e => false,
+            _ => true,
+        }
+    }
+}
+
+/// A grouped regular expression.
+///
+/// This includes both capturing and non-capturing groups. This does **not**
+/// include flag-only groups like `(?is)`, but does contain any group that
+/// contains a sub-expression, e.g., `(a)`, `(?P<name>a)`, `(?:a)` and
+/// `(?is:a)`.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Group {
+    /// The span of this group.
+    pub span: Span,
+    /// The kind of this group.
+    pub kind: GroupKind,
+    /// The regular expression in this group.
+    pub ast: Box<Ast>,
+}
+
+impl Group {
+    /// If this group is non-capturing, then this returns the (possibly empty)
+    /// set of flags. Otherwise, `None` is returned.
+    pub fn flags(&self) -> Option<&Flags> {
+        match self.kind {
+            GroupKind::NonCapturing(ref flags) => Some(flags),
+            _ => None,
+        }
+    }
+
+    /// Returns true if and only if this group is capturing.
+    pub fn is_capturing(&self) -> bool {
+        match self.kind {
+            GroupKind::CaptureIndex(_) | GroupKind::CaptureName(_) => true,
+            GroupKind::NonCapturing(_) => false,
+        }
+    }
+
+    /// Returns the capture index of this group, if this is a capturing group.
+    ///
+    /// This returns a capture index precisely when `is_capturing` is `true`.
+    pub fn capture_index(&self) -> Option<u32> {
+        match self.kind {
+            GroupKind::CaptureIndex(i) => Some(i),
+            GroupKind::CaptureName(ref x) => Some(x.index),
+            GroupKind::NonCapturing(_) => None,
+        }
+    }
+}
+
+/// The kind of a group.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum GroupKind {
+    /// `(a)`
+    CaptureIndex(u32),
+    /// `(?P<name>a)`
+    CaptureName(CaptureName),
+    /// `(?:a)` and `(?i:a)`
+    NonCapturing(Flags),
+}
+
+/// A capture name.
+///
+/// This corresponds to the name itself between the angle brackets in, e.g.,
+/// `(?P<foo>expr)`.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct CaptureName {
+    /// The span of this capture name.
+    pub span: Span,
+    /// The capture name.
+    pub name: String,
+    /// The capture index.
+    pub index: u32,
+}
+
+/// A group of flags that is not applied to a particular regular expression.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct SetFlags {
+    /// The span of these flags, including the grouping parentheses.
+    pub span: Span,
+    /// The actual sequence of flags.
+    pub flags: Flags,
+}
+
+/// A group of flags.
+///
+/// This corresponds only to the sequence of flags themselves, e.g., `is-u`.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Flags {
+    /// The span of this group of flags.
+    pub span: Span,
+    /// A sequence of flag items. Each item is either a flag or a negation
+    /// operator.
+    pub items: Vec<FlagsItem>,
+}
+
+impl Flags {
+    /// Add the given item to this sequence of flags.
+    ///
+    /// If the item was added successfully, then `None` is returned. If the
+    /// given item is a duplicate, then `Some(i)` is returned, where
+    /// `items[i].kind == item.kind`.
+    pub fn add_item(&mut self, item: FlagsItem) -> Option<usize> {
+        for (i, x) in self.items.iter().enumerate() {
+            if x.kind == item.kind {
+                return Some(i);
+            }
+        }
+        self.items.push(item);
+        None
+    }
+
+    /// Returns the state of the given flag in this set.
+    ///
+    /// If the given flag is in the set but is negated, then `Some(false)` is
+    /// returned.
+    ///
+    /// If the given flag is in the set and is not negated, then `Some(true)`
+    /// is returned.
+    ///
+    /// Otherwise, `None` is returned.
+    pub fn flag_state(&self, flag: Flag) -> Option<bool> {
+        let mut negated = false;
+        for x in &self.items {
+            match x.kind {
+                FlagsItemKind::Negation => {
+                    negated = true;
+                }
+                FlagsItemKind::Flag(ref xflag) if xflag == &flag => {
+                    return Some(!negated);
+                }
+                _ => {}
+            }
+        }
+        None
+    }
+}
+
+/// A single item in a group of flags.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct FlagsItem {
+    /// The span of this item.
+    pub span: Span,
+    /// The kind of this item.
+    pub kind: FlagsItemKind,
+}
+
+/// The kind of an item in a group of flags.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum FlagsItemKind {
+    /// A negation operator applied to all subsequent flags in the enclosing
+    /// group.
+    Negation,
+    /// A single flag in a group.
+    Flag(Flag),
+}
+
+impl FlagsItemKind {
+    /// Returns true if and only if this item is a negation operator.
+    pub fn is_negation(&self) -> bool {
+        match *self {
+            FlagsItemKind::Negation => true,
+            _ => false,
+        }
+    }
+}
+
+/// A single flag.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum Flag {
+    /// `i`
+    CaseInsensitive,
+    /// `m`
+    MultiLine,
+    /// `s`
+    DotMatchesNewLine,
+    /// `U`
+    SwapGreed,
+    /// `u`
+    Unicode,
+    /// `x`
+    IgnoreWhitespace,
+}
+
+/// A custom `Drop` impl is used for `Ast` such that it uses constant stack
+/// space but heap space proportional to the depth of the `Ast`.
+impl Drop for Ast {
+    fn drop(&mut self) {
+        use std::mem;
+
+        match *self {
+            Ast::Empty(_)
+            | Ast::Flags(_)
+            | Ast::Literal(_)
+            | Ast::Dot(_)
+            | Ast::Assertion(_)
+            // Classes are recursive, so they get their own Drop impl.
+            | Ast::Class(_) => return,
+            Ast::Repetition(ref x) if !x.ast.has_subexprs() => return,
+            Ast::Group(ref x) if !x.ast.has_subexprs() => return,
+            Ast::Alternation(ref x) if x.asts.is_empty() => return,
+            Ast::Concat(ref x) if x.asts.is_empty() => return,
+            _ => {}
+        }
+
+        let empty_span = || Span::splat(Position::new(0, 0, 0));
+        let empty_ast = || Ast::Empty(empty_span());
+        let mut stack = vec![mem::replace(self, empty_ast())];
+        while let Some(mut ast) = stack.pop() {
+            match ast {
+                Ast::Empty(_)
+                | Ast::Flags(_)
+                | Ast::Literal(_)
+                | Ast::Dot(_)
+                | Ast::Assertion(_)
+                // Classes are recursive, so they get their own Drop impl.
+                | Ast::Class(_) => {}
+                Ast::Repetition(ref mut x) => {
+                    stack.push(mem::replace(&mut x.ast, empty_ast()));
+                }
+                Ast::Group(ref mut x) => {
+                    stack.push(mem::replace(&mut x.ast, empty_ast()));
+                }
+                Ast::Alternation(ref mut x) => {
+                    stack.extend(x.asts.drain(..));
+                }
+                Ast::Concat(ref mut x) => {
+                    stack.extend(x.asts.drain(..));
+                }
+            }
+        }
+    }
+}
+
+/// A custom `Drop` impl is used for `ClassSet` such that it uses constant
+/// stack space but heap space proportional to the depth of the `ClassSet`.
+impl Drop for ClassSet {
+    fn drop(&mut self) {
+        use std::mem;
+
+        match *self {
+            ClassSet::Item(ref item) => {
+                match *item {
+                    ClassSetItem::Empty(_)
+                    | ClassSetItem::Literal(_)
+                    | ClassSetItem::Range(_)
+                    | ClassSetItem::Ascii(_)
+                    | ClassSetItem::Unicode(_)
+                    | ClassSetItem::Perl(_) => return,
+                    ClassSetItem::Bracketed(ref x) => {
+                        if x.kind.is_empty() {
+                            return;
+                        }
+                    }
+                    ClassSetItem::Union(ref x) => {
+                        if x.items.is_empty() {
+                            return;
+                        }
+                    }
+                }
+            }
+            ClassSet::BinaryOp(ref op) => {
+                if op.lhs.is_empty() && op.rhs.is_empty() {
+                    return;
+                }
+            }
+        }
+
+        let empty_span = || Span::splat(Position::new(0, 0, 0));
+        let empty_set = || ClassSet::Item(ClassSetItem::Empty(empty_span()));
+        let mut stack = vec![mem::replace(self, empty_set())];
+        while let Some(mut set) = stack.pop() {
+            match set {
+                ClassSet::Item(ref mut item) => {
+                    match *item {
+                        ClassSetItem::Empty(_)
+                        | ClassSetItem::Literal(_)
+                        | ClassSetItem::Range(_)
+                        | ClassSetItem::Ascii(_)
+                        | ClassSetItem::Unicode(_)
+                        | ClassSetItem::Perl(_) => {}
+                        ClassSetItem::Bracketed(ref mut x) => {
+                            stack.push(mem::replace(&mut x.kind, empty_set()));
+                        }
+                        ClassSetItem::Union(ref mut x) => {
+                            stack.extend(
+                                x.items.drain(..).map(ClassSet::Item));
+                        }
+                    }
+                }
+                ClassSet::BinaryOp(ref mut op) => {
+                    stack.push(mem::replace(&mut op.lhs, empty_set()));
+                    stack.push(mem::replace(&mut op.rhs, empty_set()));
+                }
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    // We use a thread with an explicit stack size to test that our destructor
+    // for Ast 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.
+    #[test]
+    #[cfg(any(unix, windows))]
+    fn no_stack_overflow_on_drop() {
+        use std::thread;
+
+        let run = || {
+            let span = || Span::splat(Position::new(0, 0, 0));
+            let mut ast = Ast::Empty(span());
+            for i in 0..200 {
+                ast = Ast::Group(Group {
+                    span: span(),
+                    kind: GroupKind::CaptureIndex(i),
+                    ast: Box::new(ast),
+                });
+            }
+            assert!(!ast.is_empty());
+        };
+
+        // We run our test on a thread with a small stack size so we can
+        // force the issue more easily.
+        thread::Builder::new()
+            .stack_size(1<<10)
+            .spawn(run)
+            .unwrap()
+            .join()
+            .unwrap();
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/ast/parse.rs.html b/target/doc/src/regex_syntax/ast/parse.rs.html new file mode 100644 index 0000000..8ff7938 --- /dev/null +++ b/target/doc/src/regex_syntax/ast/parse.rs.html @@ -0,0 +1,10857 @@ +parse.rs.html -- source
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+2035
+2036
+2037
+2038
+2039
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2047
+2048
+2049
+2050
+2051
+2052
+2053
+2054
+2055
+2056
+2057
+2058
+2059
+2060
+2061
+2062
+2063
+2064
+2065
+2066
+2067
+2068
+2069
+2070
+2071
+2072
+2073
+2074
+2075
+2076
+2077
+2078
+2079
+2080
+2081
+2082
+2083
+2084
+2085
+2086
+2087
+2088
+2089
+2090
+2091
+2092
+2093
+2094
+2095
+2096
+2097
+2098
+2099
+2100
+2101
+2102
+2103
+2104
+2105
+2106
+2107
+2108
+2109
+2110
+2111
+2112
+2113
+2114
+2115
+2116
+2117
+2118
+2119
+2120
+2121
+2122
+2123
+2124
+2125
+2126
+2127
+2128
+2129
+2130
+2131
+2132
+2133
+2134
+2135
+2136
+2137
+2138
+2139
+2140
+2141
+2142
+2143
+2144
+2145
+2146
+2147
+2148
+2149
+2150
+2151
+2152
+2153
+2154
+2155
+2156
+2157
+2158
+2159
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
+2178
+2179
+2180
+2181
+2182
+2183
+2184
+2185
+2186
+2187
+2188
+2189
+2190
+2191
+2192
+2193
+2194
+2195
+2196
+2197
+2198
+2199
+2200
+2201
+2202
+2203
+2204
+2205
+2206
+2207
+2208
+2209
+2210
+2211
+2212
+2213
+2214
+2215
+2216
+2217
+2218
+2219
+2220
+2221
+2222
+2223
+2224
+2225
+2226
+2227
+2228
+2229
+2230
+2231
+2232
+2233
+2234
+2235
+2236
+2237
+2238
+2239
+2240
+2241
+2242
+2243
+2244
+2245
+2246
+2247
+2248
+2249
+2250
+2251
+2252
+2253
+2254
+2255
+2256
+2257
+2258
+2259
+2260
+2261
+2262
+2263
+2264
+2265
+2266
+2267
+2268
+2269
+2270
+2271
+2272
+2273
+2274
+2275
+2276
+2277
+2278
+2279
+2280
+2281
+2282
+2283
+2284
+2285
+2286
+2287
+2288
+2289
+2290
+2291
+2292
+2293
+2294
+2295
+2296
+2297
+2298
+2299
+2300
+2301
+2302
+2303
+2304
+2305
+2306
+2307
+2308
+2309
+2310
+2311
+2312
+2313
+2314
+2315
+2316
+2317
+2318
+2319
+2320
+2321
+2322
+2323
+2324
+2325
+2326
+2327
+2328
+2329
+2330
+2331
+2332
+2333
+2334
+2335
+2336
+2337
+2338
+2339
+2340
+2341
+2342
+2343
+2344
+2345
+2346
+2347
+2348
+2349
+2350
+2351
+2352
+2353
+2354
+2355
+2356
+2357
+2358
+2359
+2360
+2361
+2362
+2363
+2364
+2365
+2366
+2367
+2368
+2369
+2370
+2371
+2372
+2373
+2374
+2375
+2376
+2377
+2378
+2379
+2380
+2381
+2382
+2383
+2384
+2385
+2386
+2387
+2388
+2389
+2390
+2391
+2392
+2393
+2394
+2395
+2396
+2397
+2398
+2399
+2400
+2401
+2402
+2403
+2404
+2405
+2406
+2407
+2408
+2409
+2410
+2411
+2412
+2413
+2414
+2415
+2416
+2417
+2418
+2419
+2420
+2421
+2422
+2423
+2424
+2425
+2426
+2427
+2428
+2429
+2430
+2431
+2432
+2433
+2434
+2435
+2436
+2437
+2438
+2439
+2440
+2441
+2442
+2443
+2444
+2445
+2446
+2447
+2448
+2449
+2450
+2451
+2452
+2453
+2454
+2455
+2456
+2457
+2458
+2459
+2460
+2461
+2462
+2463
+2464
+2465
+2466
+2467
+2468
+2469
+2470
+2471
+2472
+2473
+2474
+2475
+2476
+2477
+2478
+2479
+2480
+2481
+2482
+2483
+2484
+2485
+2486
+2487
+2488
+2489
+2490
+2491
+2492
+2493
+2494
+2495
+2496
+2497
+2498
+2499
+2500
+2501
+2502
+2503
+2504
+2505
+2506
+2507
+2508
+2509
+2510
+2511
+2512
+2513
+2514
+2515
+2516
+2517
+2518
+2519
+2520
+2521
+2522
+2523
+2524
+2525
+2526
+2527
+2528
+2529
+2530
+2531
+2532
+2533
+2534
+2535
+2536
+2537
+2538
+2539
+2540
+2541
+2542
+2543
+2544
+2545
+2546
+2547
+2548
+2549
+2550
+2551
+2552
+2553
+2554
+2555
+2556
+2557
+2558
+2559
+2560
+2561
+2562
+2563
+2564
+2565
+2566
+2567
+2568
+2569
+2570
+2571
+2572
+2573
+2574
+2575
+2576
+2577
+2578
+2579
+2580
+2581
+2582
+2583
+2584
+2585
+2586
+2587
+2588
+2589
+2590
+2591
+2592
+2593
+2594
+2595
+2596
+2597
+2598
+2599
+2600
+2601
+2602
+2603
+2604
+2605
+2606
+2607
+2608
+2609
+2610
+2611
+2612
+2613
+2614
+2615
+2616
+2617
+2618
+2619
+2620
+2621
+2622
+2623
+2624
+2625
+2626
+2627
+2628
+2629
+2630
+2631
+2632
+2633
+2634
+2635
+2636
+2637
+2638
+2639
+2640
+2641
+2642
+2643
+2644
+2645
+2646
+2647
+2648
+2649
+2650
+2651
+2652
+2653
+2654
+2655
+2656
+2657
+2658
+2659
+2660
+2661
+2662
+2663
+2664
+2665
+2666
+2667
+2668
+2669
+2670
+2671
+2672
+2673
+2674
+2675
+2676
+2677
+2678
+2679
+2680
+2681
+2682
+2683
+2684
+2685
+2686
+2687
+2688
+2689
+2690
+2691
+2692
+2693
+2694
+2695
+2696
+2697
+2698
+2699
+2700
+2701
+2702
+2703
+2704
+2705
+2706
+2707
+2708
+2709
+2710
+2711
+2712
+2713
+2714
+2715
+2716
+2717
+2718
+2719
+2720
+2721
+2722
+2723
+2724
+2725
+2726
+2727
+2728
+2729
+2730
+2731
+2732
+2733
+2734
+2735
+2736
+2737
+2738
+2739
+2740
+2741
+2742
+2743
+2744
+2745
+2746
+2747
+2748
+2749
+2750
+2751
+2752
+2753
+2754
+2755
+2756
+2757
+2758
+2759
+2760
+2761
+2762
+2763
+2764
+2765
+2766
+2767
+2768
+2769
+2770
+2771
+2772
+2773
+2774
+2775
+2776
+2777
+2778
+2779
+2780
+2781
+2782
+2783
+2784
+2785
+2786
+2787
+2788
+2789
+2790
+2791
+2792
+2793
+2794
+2795
+2796
+2797
+2798
+2799
+2800
+2801
+2802
+2803
+2804
+2805
+2806
+2807
+2808
+2809
+2810
+2811
+2812
+2813
+2814
+2815
+2816
+2817
+2818
+2819
+2820
+2821
+2822
+2823
+2824
+2825
+2826
+2827
+2828
+2829
+2830
+2831
+2832
+2833
+2834
+2835
+2836
+2837
+2838
+2839
+2840
+2841
+2842
+2843
+2844
+2845
+2846
+2847
+2848
+2849
+2850
+2851
+2852
+2853
+2854
+2855
+2856
+2857
+2858
+2859
+2860
+2861
+2862
+2863
+2864
+2865
+2866
+2867
+2868
+2869
+2870
+2871
+2872
+2873
+2874
+2875
+2876
+2877
+2878
+2879
+2880
+2881
+2882
+2883
+2884
+2885
+2886
+2887
+2888
+2889
+2890
+2891
+2892
+2893
+2894
+2895
+2896
+2897
+2898
+2899
+2900
+2901
+2902
+2903
+2904
+2905
+2906
+2907
+2908
+2909
+2910
+2911
+2912
+2913
+2914
+2915
+2916
+2917
+2918
+2919
+2920
+2921
+2922
+2923
+2924
+2925
+2926
+2927
+2928
+2929
+2930
+2931
+2932
+2933
+2934
+2935
+2936
+2937
+2938
+2939
+2940
+2941
+2942
+2943
+2944
+2945
+2946
+2947
+2948
+2949
+2950
+2951
+2952
+2953
+2954
+2955
+2956
+2957
+2958
+2959
+2960
+2961
+2962
+2963
+2964
+2965
+2966
+2967
+2968
+2969
+2970
+2971
+2972
+2973
+2974
+2975
+2976
+2977
+2978
+2979
+2980
+2981
+2982
+2983
+2984
+2985
+2986
+2987
+2988
+2989
+2990
+2991
+2992
+2993
+2994
+2995
+2996
+2997
+2998
+2999
+3000
+3001
+3002
+3003
+3004
+3005
+3006
+3007
+3008
+3009
+3010
+3011
+3012
+3013
+3014
+3015
+3016
+3017
+3018
+3019
+3020
+3021
+3022
+3023
+3024
+3025
+3026
+3027
+3028
+3029
+3030
+3031
+3032
+3033
+3034
+3035
+3036
+3037
+3038
+3039
+3040
+3041
+3042
+3043
+3044
+3045
+3046
+3047
+3048
+3049
+3050
+3051
+3052
+3053
+3054
+3055
+3056
+3057
+3058
+3059
+3060
+3061
+3062
+3063
+3064
+3065
+3066
+3067
+3068
+3069
+3070
+3071
+3072
+3073
+3074
+3075
+3076
+3077
+3078
+3079
+3080
+3081
+3082
+3083
+3084
+3085
+3086
+3087
+3088
+3089
+3090
+3091
+3092
+3093
+3094
+3095
+3096
+3097
+3098
+3099
+3100
+3101
+3102
+3103
+3104
+3105
+3106
+3107
+3108
+3109
+3110
+3111
+3112
+3113
+3114
+3115
+3116
+3117
+3118
+3119
+3120
+3121
+3122
+3123
+3124
+3125
+3126
+3127
+3128
+3129
+3130
+3131
+3132
+3133
+3134
+3135
+3136
+3137
+3138
+3139
+3140
+3141
+3142
+3143
+3144
+3145
+3146
+3147
+3148
+3149
+3150
+3151
+3152
+3153
+3154
+3155
+3156
+3157
+3158
+3159
+3160
+3161
+3162
+3163
+3164
+3165
+3166
+3167
+3168
+3169
+3170
+3171
+3172
+3173
+3174
+3175
+3176
+3177
+3178
+3179
+3180
+3181
+3182
+3183
+3184
+3185
+3186
+3187
+3188
+3189
+3190
+3191
+3192
+3193
+3194
+3195
+3196
+3197
+3198
+3199
+3200
+3201
+3202
+3203
+3204
+3205
+3206
+3207
+3208
+3209
+3210
+3211
+3212
+3213
+3214
+3215
+3216
+3217
+3218
+3219
+3220
+3221
+3222
+3223
+3224
+3225
+3226
+3227
+3228
+3229
+3230
+3231
+3232
+3233
+3234
+3235
+3236
+3237
+3238
+3239
+3240
+3241
+3242
+3243
+3244
+3245
+3246
+3247
+3248
+3249
+3250
+3251
+3252
+3253
+3254
+3255
+3256
+3257
+3258
+3259
+3260
+3261
+3262
+3263
+3264
+3265
+3266
+3267
+3268
+3269
+3270
+3271
+3272
+3273
+3274
+3275
+3276
+3277
+3278
+3279
+3280
+3281
+3282
+3283
+3284
+3285
+3286
+3287
+3288
+3289
+3290
+3291
+3292
+3293
+3294
+3295
+3296
+3297
+3298
+3299
+3300
+3301
+3302
+3303
+3304
+3305
+3306
+3307
+3308
+3309
+3310
+3311
+3312
+3313
+3314
+3315
+3316
+3317
+3318
+3319
+3320
+3321
+3322
+3323
+3324
+3325
+3326
+3327
+3328
+3329
+3330
+3331
+3332
+3333
+3334
+3335
+3336
+3337
+3338
+3339
+3340
+3341
+3342
+3343
+3344
+3345
+3346
+3347
+3348
+3349
+3350
+3351
+3352
+3353
+3354
+3355
+3356
+3357
+3358
+3359
+3360
+3361
+3362
+3363
+3364
+3365
+3366
+3367
+3368
+3369
+3370
+3371
+3372
+3373
+3374
+3375
+3376
+3377
+3378
+3379
+3380
+3381
+3382
+3383
+3384
+3385
+3386
+3387
+3388
+3389
+3390
+3391
+3392
+3393
+3394
+3395
+3396
+3397
+3398
+3399
+3400
+3401
+3402
+3403
+3404
+3405
+3406
+3407
+3408
+3409
+3410
+3411
+3412
+3413
+3414
+3415
+3416
+3417
+3418
+3419
+3420
+3421
+3422
+3423
+3424
+3425
+3426
+3427
+3428
+3429
+3430
+3431
+3432
+3433
+3434
+3435
+3436
+3437
+3438
+3439
+3440
+3441
+3442
+3443
+3444
+3445
+3446
+3447
+3448
+3449
+3450
+3451
+3452
+3453
+3454
+3455
+3456
+3457
+3458
+3459
+3460
+3461
+3462
+3463
+3464
+3465
+3466
+3467
+3468
+3469
+3470
+3471
+3472
+3473
+3474
+3475
+3476
+3477
+3478
+3479
+3480
+3481
+3482
+3483
+3484
+3485
+3486
+3487
+3488
+3489
+3490
+3491
+3492
+3493
+3494
+3495
+3496
+3497
+3498
+3499
+3500
+3501
+3502
+3503
+3504
+3505
+3506
+3507
+3508
+3509
+3510
+3511
+3512
+3513
+3514
+3515
+3516
+3517
+3518
+3519
+3520
+3521
+3522
+3523
+3524
+3525
+3526
+3527
+3528
+3529
+3530
+3531
+3532
+3533
+3534
+3535
+3536
+3537
+3538
+3539
+3540
+3541
+3542
+3543
+3544
+3545
+3546
+3547
+3548
+3549
+3550
+3551
+3552
+3553
+3554
+3555
+3556
+3557
+3558
+3559
+3560
+3561
+3562
+3563
+3564
+3565
+3566
+3567
+3568
+3569
+3570
+3571
+3572
+3573
+3574
+3575
+3576
+3577
+3578
+3579
+3580
+3581
+3582
+3583
+3584
+3585
+3586
+3587
+3588
+3589
+3590
+3591
+3592
+3593
+3594
+3595
+3596
+3597
+3598
+3599
+3600
+3601
+3602
+3603
+3604
+3605
+3606
+3607
+3608
+3609
+3610
+3611
+3612
+3613
+3614
+3615
+3616
+3617
+3618
+3619
+3620
+3621
+3622
+3623
+3624
+3625
+3626
+3627
+3628
+3629
+3630
+3631
+3632
+3633
+3634
+3635
+3636
+3637
+3638
+3639
+3640
+3641
+3642
+3643
+3644
+3645
+3646
+3647
+3648
+3649
+3650
+3651
+3652
+3653
+3654
+3655
+3656
+3657
+3658
+3659
+3660
+3661
+3662
+3663
+3664
+3665
+3666
+3667
+3668
+3669
+3670
+3671
+3672
+3673
+3674
+3675
+3676
+3677
+3678
+3679
+3680
+3681
+3682
+3683
+3684
+3685
+3686
+3687
+3688
+3689
+3690
+3691
+3692
+3693
+3694
+3695
+3696
+3697
+3698
+3699
+3700
+3701
+3702
+3703
+3704
+3705
+3706
+3707
+3708
+3709
+3710
+3711
+3712
+3713
+3714
+3715
+3716
+3717
+3718
+3719
+3720
+3721
+3722
+3723
+3724
+3725
+3726
+3727
+3728
+3729
+3730
+3731
+3732
+3733
+3734
+3735
+3736
+3737
+3738
+3739
+3740
+3741
+3742
+3743
+3744
+3745
+3746
+3747
+3748
+3749
+3750
+3751
+3752
+3753
+3754
+3755
+3756
+3757
+3758
+3759
+3760
+3761
+3762
+3763
+3764
+3765
+3766
+3767
+3768
+3769
+3770
+3771
+3772
+3773
+3774
+3775
+3776
+3777
+3778
+3779
+3780
+3781
+3782
+3783
+3784
+3785
+3786
+3787
+3788
+3789
+3790
+3791
+3792
+3793
+3794
+3795
+3796
+3797
+3798
+3799
+3800
+3801
+3802
+3803
+3804
+3805
+3806
+3807
+3808
+3809
+3810
+3811
+3812
+3813
+3814
+3815
+3816
+3817
+3818
+3819
+3820
+3821
+3822
+3823
+3824
+3825
+3826
+3827
+3828
+3829
+3830
+3831
+3832
+3833
+3834
+3835
+3836
+3837
+3838
+3839
+3840
+3841
+3842
+3843
+3844
+3845
+3846
+3847
+3848
+3849
+3850
+3851
+3852
+3853
+3854
+3855
+3856
+3857
+3858
+3859
+3860
+3861
+3862
+3863
+3864
+3865
+3866
+3867
+3868
+3869
+3870
+3871
+3872
+3873
+3874
+3875
+3876
+3877
+3878
+3879
+3880
+3881
+3882
+3883
+3884
+3885
+3886
+3887
+3888
+3889
+3890
+3891
+3892
+3893
+3894
+3895
+3896
+3897
+3898
+3899
+3900
+3901
+3902
+3903
+3904
+3905
+3906
+3907
+3908
+3909
+3910
+3911
+3912
+3913
+3914
+3915
+3916
+3917
+3918
+3919
+3920
+3921
+3922
+3923
+3924
+3925
+3926
+3927
+3928
+3929
+3930
+3931
+3932
+3933
+3934
+3935
+3936
+3937
+3938
+3939
+3940
+3941
+3942
+3943
+3944
+3945
+3946
+3947
+3948
+3949
+3950
+3951
+3952
+3953
+3954
+3955
+3956
+3957
+3958
+3959
+3960
+3961
+3962
+3963
+3964
+3965
+3966
+3967
+3968
+3969
+3970
+3971
+3972
+3973
+3974
+3975
+3976
+3977
+3978
+3979
+3980
+3981
+3982
+3983
+3984
+3985
+3986
+3987
+3988
+3989
+3990
+3991
+3992
+3993
+3994
+3995
+3996
+3997
+3998
+3999
+4000
+4001
+4002
+4003
+4004
+4005
+4006
+4007
+4008
+4009
+4010
+4011
+4012
+4013
+4014
+4015
+4016
+4017
+4018
+4019
+4020
+4021
+4022
+4023
+4024
+4025
+4026
+4027
+4028
+4029
+4030
+4031
+4032
+4033
+4034
+4035
+4036
+4037
+4038
+4039
+4040
+4041
+4042
+4043
+4044
+4045
+4046
+4047
+4048
+4049
+4050
+4051
+4052
+4053
+4054
+4055
+4056
+4057
+4058
+4059
+4060
+4061
+4062
+4063
+4064
+4065
+4066
+4067
+4068
+4069
+4070
+4071
+4072
+4073
+4074
+4075
+4076
+4077
+4078
+4079
+4080
+4081
+4082
+4083
+4084
+4085
+4086
+4087
+4088
+4089
+4090
+4091
+4092
+4093
+4094
+4095
+4096
+4097
+4098
+4099
+4100
+4101
+4102
+4103
+4104
+4105
+4106
+4107
+4108
+4109
+4110
+4111
+4112
+4113
+4114
+4115
+4116
+4117
+4118
+4119
+4120
+4121
+4122
+4123
+4124
+4125
+4126
+4127
+4128
+4129
+4130
+4131
+4132
+4133
+4134
+4135
+4136
+4137
+4138
+4139
+4140
+4141
+4142
+4143
+4144
+4145
+4146
+4147
+4148
+4149
+4150
+4151
+4152
+4153
+4154
+4155
+4156
+4157
+4158
+4159
+4160
+4161
+4162
+4163
+4164
+4165
+4166
+4167
+4168
+4169
+4170
+4171
+4172
+4173
+4174
+4175
+4176
+4177
+4178
+4179
+4180
+4181
+4182
+4183
+4184
+4185
+4186
+4187
+4188
+4189
+4190
+4191
+4192
+4193
+4194
+4195
+4196
+4197
+4198
+4199
+4200
+4201
+4202
+4203
+4204
+4205
+4206
+4207
+4208
+4209
+4210
+4211
+4212
+4213
+4214
+4215
+4216
+4217
+4218
+4219
+4220
+4221
+4222
+4223
+4224
+4225
+4226
+4227
+4228
+4229
+4230
+4231
+4232
+4233
+4234
+4235
+4236
+4237
+4238
+4239
+4240
+4241
+4242
+4243
+4244
+4245
+4246
+4247
+4248
+4249
+4250
+4251
+4252
+4253
+4254
+4255
+4256
+4257
+4258
+4259
+4260
+4261
+4262
+4263
+4264
+4265
+4266
+4267
+4268
+4269
+4270
+4271
+4272
+4273
+4274
+4275
+4276
+4277
+4278
+4279
+4280
+4281
+4282
+4283
+4284
+4285
+4286
+4287
+4288
+4289
+4290
+4291
+4292
+4293
+4294
+4295
+4296
+4297
+4298
+4299
+4300
+4301
+4302
+4303
+4304
+4305
+4306
+4307
+4308
+4309
+4310
+4311
+4312
+4313
+4314
+4315
+4316
+4317
+4318
+4319
+4320
+4321
+4322
+4323
+4324
+4325
+4326
+4327
+4328
+4329
+4330
+4331
+4332
+4333
+4334
+4335
+4336
+4337
+4338
+4339
+4340
+4341
+4342
+4343
+4344
+4345
+4346
+4347
+4348
+4349
+4350
+4351
+4352
+4353
+4354
+4355
+4356
+4357
+4358
+4359
+4360
+4361
+4362
+4363
+4364
+4365
+4366
+4367
+4368
+4369
+4370
+4371
+4372
+4373
+4374
+4375
+4376
+4377
+4378
+4379
+4380
+4381
+4382
+4383
+4384
+4385
+4386
+4387
+4388
+4389
+4390
+4391
+4392
+4393
+4394
+4395
+4396
+4397
+4398
+4399
+4400
+4401
+4402
+4403
+4404
+4405
+4406
+4407
+4408
+4409
+4410
+4411
+4412
+4413
+4414
+4415
+4416
+4417
+4418
+4419
+4420
+4421
+4422
+4423
+4424
+4425
+4426
+4427
+4428
+4429
+4430
+4431
+4432
+4433
+4434
+4435
+4436
+4437
+4438
+4439
+4440
+4441
+4442
+4443
+4444
+4445
+4446
+4447
+4448
+4449
+4450
+4451
+4452
+4453
+4454
+4455
+4456
+4457
+4458
+4459
+4460
+4461
+4462
+4463
+4464
+4465
+4466
+4467
+4468
+4469
+4470
+4471
+4472
+4473
+4474
+4475
+4476
+4477
+4478
+4479
+4480
+4481
+4482
+4483
+4484
+4485
+4486
+4487
+4488
+4489
+4490
+4491
+4492
+4493
+4494
+4495
+4496
+4497
+4498
+4499
+4500
+4501
+4502
+4503
+4504
+4505
+4506
+4507
+4508
+4509
+4510
+4511
+4512
+4513
+4514
+4515
+4516
+4517
+4518
+4519
+4520
+4521
+4522
+4523
+4524
+4525
+4526
+4527
+4528
+4529
+4530
+4531
+4532
+4533
+4534
+4535
+4536
+4537
+4538
+4539
+4540
+4541
+4542
+4543
+4544
+4545
+4546
+4547
+4548
+4549
+4550
+4551
+4552
+4553
+4554
+4555
+4556
+4557
+4558
+4559
+4560
+4561
+4562
+4563
+4564
+4565
+4566
+4567
+4568
+4569
+4570
+4571
+4572
+4573
+4574
+4575
+4576
+4577
+4578
+4579
+4580
+4581
+4582
+4583
+4584
+4585
+4586
+4587
+4588
+4589
+4590
+4591
+4592
+4593
+4594
+4595
+4596
+4597
+4598
+4599
+4600
+4601
+4602
+4603
+4604
+4605
+4606
+4607
+4608
+4609
+4610
+4611
+4612
+4613
+4614
+4615
+4616
+4617
+4618
+4619
+4620
+4621
+4622
+4623
+4624
+4625
+4626
+4627
+4628
+4629
+4630
+4631
+4632
+4633
+4634
+4635
+4636
+4637
+4638
+4639
+4640
+4641
+4642
+4643
+4644
+4645
+4646
+4647
+4648
+4649
+4650
+4651
+4652
+4653
+4654
+4655
+4656
+4657
+4658
+4659
+4660
+4661
+4662
+4663
+4664
+4665
+4666
+4667
+4668
+4669
+4670
+4671
+4672
+4673
+4674
+4675
+4676
+4677
+4678
+4679
+4680
+4681
+4682
+4683
+4684
+4685
+4686
+4687
+4688
+4689
+4690
+4691
+4692
+4693
+4694
+4695
+4696
+4697
+4698
+4699
+4700
+4701
+4702
+4703
+4704
+4705
+4706
+4707
+4708
+4709
+4710
+4711
+4712
+4713
+4714
+4715
+4716
+4717
+4718
+4719
+4720
+4721
+4722
+4723
+4724
+4725
+4726
+4727
+4728
+4729
+4730
+4731
+4732
+4733
+4734
+4735
+4736
+4737
+4738
+4739
+4740
+4741
+4742
+4743
+4744
+4745
+4746
+4747
+4748
+4749
+4750
+4751
+4752
+4753
+4754
+4755
+4756
+4757
+4758
+4759
+4760
+4761
+4762
+4763
+4764
+4765
+4766
+4767
+4768
+4769
+4770
+4771
+4772
+4773
+4774
+4775
+4776
+4777
+4778
+4779
+4780
+4781
+4782
+4783
+4784
+4785
+4786
+4787
+4788
+4789
+4790
+4791
+4792
+4793
+4794
+4795
+4796
+4797
+4798
+4799
+4800
+4801
+4802
+4803
+4804
+4805
+4806
+4807
+4808
+4809
+4810
+4811
+4812
+4813
+4814
+4815
+4816
+4817
+4818
+4819
+4820
+4821
+4822
+4823
+4824
+4825
+4826
+4827
+4828
+4829
+4830
+4831
+4832
+4833
+4834
+4835
+4836
+4837
+4838
+4839
+4840
+4841
+4842
+4843
+4844
+4845
+4846
+4847
+4848
+4849
+4850
+4851
+4852
+4853
+4854
+4855
+4856
+4857
+4858
+4859
+4860
+4861
+4862
+4863
+4864
+4865
+4866
+4867
+4868
+4869
+4870
+4871
+4872
+4873
+4874
+4875
+4876
+4877
+4878
+4879
+4880
+4881
+4882
+4883
+4884
+4885
+4886
+4887
+4888
+4889
+4890
+4891
+4892
+4893
+4894
+4895
+4896
+4897
+4898
+4899
+4900
+4901
+4902
+4903
+4904
+4905
+4906
+4907
+4908
+4909
+4910
+4911
+4912
+4913
+4914
+4915
+4916
+4917
+4918
+4919
+4920
+4921
+4922
+4923
+4924
+4925
+4926
+4927
+4928
+4929
+4930
+4931
+4932
+4933
+4934
+4935
+4936
+4937
+4938
+4939
+4940
+4941
+4942
+4943
+4944
+4945
+4946
+4947
+4948
+4949
+4950
+4951
+4952
+4953
+4954
+4955
+4956
+4957
+4958
+4959
+4960
+4961
+4962
+4963
+4964
+4965
+4966
+4967
+4968
+4969
+4970
+4971
+4972
+4973
+4974
+4975
+4976
+4977
+4978
+4979
+4980
+4981
+4982
+4983
+4984
+4985
+4986
+4987
+4988
+4989
+4990
+4991
+4992
+4993
+4994
+4995
+4996
+4997
+4998
+4999
+5000
+5001
+5002
+5003
+5004
+5005
+5006
+5007
+5008
+5009
+5010
+5011
+5012
+5013
+5014
+5015
+5016
+5017
+5018
+5019
+5020
+5021
+5022
+5023
+5024
+5025
+5026
+5027
+5028
+5029
+5030
+5031
+5032
+5033
+5034
+5035
+5036
+5037
+5038
+5039
+5040
+5041
+5042
+5043
+5044
+5045
+5046
+5047
+5048
+5049
+5050
+5051
+5052
+5053
+5054
+5055
+5056
+5057
+5058
+5059
+5060
+5061
+5062
+5063
+5064
+5065
+5066
+5067
+5068
+5069
+5070
+5071
+5072
+5073
+5074
+5075
+5076
+5077
+5078
+5079
+5080
+5081
+5082
+5083
+5084
+5085
+5086
+5087
+5088
+5089
+5090
+5091
+5092
+5093
+5094
+5095
+5096
+5097
+5098
+5099
+5100
+5101
+5102
+5103
+5104
+5105
+5106
+5107
+5108
+5109
+5110
+5111
+5112
+5113
+5114
+5115
+5116
+5117
+5118
+5119
+5120
+5121
+5122
+5123
+5124
+5125
+5126
+5127
+5128
+5129
+5130
+5131
+5132
+5133
+5134
+5135
+5136
+5137
+5138
+5139
+5140
+5141
+5142
+5143
+5144
+5145
+5146
+5147
+5148
+5149
+5150
+5151
+5152
+5153
+5154
+5155
+5156
+5157
+5158
+5159
+5160
+5161
+5162
+5163
+5164
+5165
+5166
+5167
+5168
+5169
+5170
+5171
+5172
+5173
+5174
+5175
+5176
+5177
+5178
+5179
+5180
+5181
+5182
+5183
+5184
+5185
+5186
+5187
+5188
+5189
+5190
+5191
+5192
+5193
+5194
+5195
+5196
+5197
+5198
+5199
+5200
+5201
+5202
+5203
+5204
+5205
+5206
+5207
+5208
+5209
+5210
+5211
+5212
+5213
+5214
+5215
+5216
+5217
+5218
+5219
+5220
+5221
+5222
+5223
+5224
+5225
+5226
+5227
+5228
+5229
+5230
+5231
+5232
+5233
+5234
+5235
+5236
+5237
+5238
+5239
+5240
+5241
+5242
+5243
+5244
+5245
+5246
+5247
+5248
+5249
+5250
+5251
+5252
+5253
+5254
+5255
+5256
+5257
+5258
+5259
+5260
+5261
+5262
+5263
+5264
+5265
+5266
+5267
+5268
+5269
+5270
+5271
+5272
+5273
+5274
+5275
+5276
+5277
+5278
+5279
+5280
+5281
+5282
+5283
+5284
+5285
+5286
+5287
+5288
+5289
+5290
+5291
+5292
+5293
+5294
+5295
+5296
+5297
+5298
+5299
+5300
+5301
+5302
+5303
+5304
+5305
+5306
+5307
+5308
+5309
+5310
+5311
+5312
+5313
+5314
+5315
+5316
+5317
+5318
+5319
+5320
+5321
+5322
+5323
+5324
+5325
+5326
+5327
+5328
+5329
+5330
+5331
+5332
+5333
+5334
+5335
+5336
+5337
+5338
+5339
+5340
+5341
+5342
+5343
+5344
+5345
+5346
+5347
+5348
+5349
+5350
+5351
+5352
+5353
+5354
+5355
+5356
+5357
+5358
+5359
+5360
+5361
+5362
+5363
+5364
+5365
+5366
+5367
+5368
+5369
+5370
+5371
+5372
+5373
+5374
+5375
+5376
+5377
+5378
+5379
+5380
+5381
+5382
+5383
+5384
+5385
+5386
+5387
+5388
+5389
+5390
+5391
+5392
+5393
+5394
+5395
+5396
+5397
+5398
+5399
+5400
+5401
+5402
+5403
+5404
+5405
+5406
+5407
+5408
+5409
+5410
+5411
+5412
+5413
+5414
+5415
+5416
+5417
+5418
+5419
+5420
+5421
+5422
+5423
+5424
+5425
+5426
+5427
+
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+This module provides a regular expression parser.
+*/
+
+use std::borrow::Borrow;
+use std::cell::{Cell, RefCell};
+use std::mem;
+use std::result;
+
+use ast::{self, Ast, Position, Span};
+use either::Either;
+
+use is_meta_character;
+
+type Result<T> = result::Result<T, ast::Error>;
+
+/// A primitive is an expression with no sub-expressions. This includes
+/// literals, assertions and non-set character classes. This representation
+/// is used as intermediate state in the parser.
+///
+/// This does not include ASCII character classes, since they can only appear
+/// within a set character class.
+#[derive(Clone, Debug, Eq, PartialEq)]
+enum Primitive {
+    Literal(ast::Literal),
+    Assertion(ast::Assertion),
+    Dot(Span),
+    Perl(ast::ClassPerl),
+    Unicode(ast::ClassUnicode),
+}
+
+impl Primitive {
+    /// Return the span of this primitive.
+    fn span(&self) -> &Span {
+        match *self {
+            Primitive::Literal(ref x) => &x.span,
+            Primitive::Assertion(ref x) => &x.span,
+            Primitive::Dot(ref span) => span,
+            Primitive::Perl(ref x) => &x.span,
+            Primitive::Unicode(ref x) => &x.span,
+        }
+    }
+
+    /// Convert this primitive into a proper AST.
+    fn into_ast(self) -> Ast {
+        match self {
+            Primitive::Literal(lit) => Ast::Literal(lit),
+            Primitive::Assertion(assert) => Ast::Assertion(assert),
+            Primitive::Dot(span) => Ast::Dot(span),
+            Primitive::Perl(cls) => Ast::Class(ast::Class::Perl(cls)),
+            Primitive::Unicode(cls) => Ast::Class(ast::Class::Unicode(cls)),
+        }
+    }
+
+    /// Convert this primitive into an item in a character class.
+    ///
+    /// If this primitive is not a legal item (i.e., an assertion or a dot),
+    /// then return an error.
+    fn into_class_set_item<P: Borrow<Parser>>(
+        self,
+        p: &ParserI<P>,
+    ) -> Result<ast::ClassSetItem> {
+        use ast::ClassSetItem;
+        use self::Primitive::*;
+
+        match self {
+            Literal(lit) => Ok(ClassSetItem::Literal(lit)),
+            Perl(cls) => Ok(ClassSetItem::Perl(cls)),
+            Unicode(cls) => Ok(ClassSetItem::Unicode(cls)),
+            x => Err(p.error(*x.span(), ast::ErrorKind::ClassEscapeInvalid)),
+        }
+    }
+
+    /// Convert this primitive into a literal in a character class. In
+    /// particular, literals are the only valid items that can appear in
+    /// ranges.
+    ///
+    /// If this primitive is not a legal item (i.e., a class, assertion or a
+    /// dot), then return an error.
+    fn into_class_literal<P: Borrow<Parser>>(
+        self,
+        p: &ParserI<P>,
+    ) -> Result<ast::Literal> {
+        use self::Primitive::*;
+
+        match self {
+            Literal(lit) => Ok(lit),
+            x => Err(p.error(*x.span(), ast::ErrorKind::ClassRangeLiteral)),
+        }
+    }
+}
+
+/// Returns true if the given character is a hexadecimal digit.
+fn is_hex(c: char) -> bool {
+    ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')
+}
+
+/// Returns true if the given character is a valid in a capture group name.
+///
+/// If `first` is true, then `c` is treated as the first character in the
+/// group name (which is not allowed to be a digit).
+fn is_capture_char(c: char, first: bool) -> bool {
+    c == '_' || (!first && c >= '0' && c <= '9')
+    || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
+}
+
+/// A builder for a regular expression parser.
+///
+/// This builder permits modifying configuration options for the parser.
+#[derive(Clone, Debug)]
+pub struct ParserBuilder {
+    ignore_whitespace: bool,
+    nest_limit: u32,
+    octal: bool,
+}
+
+impl Default for ParserBuilder {
+    fn default() -> ParserBuilder {
+        ParserBuilder::new()
+    }
+}
+
+impl ParserBuilder {
+    /// Create a new parser builder with a default configuration.
+    pub fn new() -> ParserBuilder {
+        ParserBuilder {
+            ignore_whitespace: false,
+            nest_limit: 250,
+            octal: false,
+        }
+    }
+
+    /// Build a parser from this configuration with the given pattern.
+    pub fn build(&self) -> Parser {
+        Parser {
+            pos: Cell::new(Position { offset: 0, line: 1, column: 1 }),
+            capture_index: Cell::new(0),
+            nest_limit: self.nest_limit,
+            octal: self.octal,
+            initial_ignore_whitespace: self.ignore_whitespace,
+            ignore_whitespace: Cell::new(self.ignore_whitespace),
+            comments: RefCell::new(vec![]),
+            stack_group: RefCell::new(vec![]),
+            stack_class: RefCell::new(vec![]),
+            capture_names: RefCell::new(vec![]),
+            scratch: RefCell::new(String::new()),
+        }
+    }
+
+    /// Set the nesting limit for this parser.
+    ///
+    /// The nesting limit controls how deep the abstract syntax tree is allowed
+    /// to be. If the AST exceeds the given limit (e.g., with too many nested
+    /// groups), then an error is returned by the parser.
+    ///
+    /// The purpose of this limit is to act as a heuristic to prevent stack
+    /// overflow for consumers that do structural induction on an `Ast` using
+    /// explicit recursion. While this crate never does this (instead using
+    /// constant stack space and moving the call stack to the heap), other
+    /// crates may.
+    ///
+    /// This limit is not checked until the entire Ast is parsed. Therefore,
+    /// if callers want to put a limit on the amount of heap space used, then
+    /// they should impose a limit on the length, in bytes, of the concrete
+    /// pattern string. In particular, this is viable since this parser
+    /// implementation will limit itself to heap space proportional to the
+    /// lenth of the pattern string.
+    ///
+    /// Note that a nest limit of `0` will return a nest limit error for most
+    /// patterns but not all. For example, a nest limit of `0` permits `a` but
+    /// not `ab`, since `ab` requires a concatenation, which results in a nest
+    /// depth of `1`. In general, a nest limit is not something that manifests
+    /// in an obvious way in the concrete syntax, therefore, it should not be
+    /// used in a granular way.
+    pub fn nest_limit(&mut self, limit: u32) -> &mut ParserBuilder {
+        self.nest_limit = limit;
+        self
+    }
+
+    /// Whether to support octal syntax or not.
+    ///
+    /// Octal syntax is a little-known way of uttering Unicode codepoints in
+    /// a regular expression. For example, `a`, `\x61`, `\u0061` and
+    /// `\141` are all equivalent regular expressions, where the last example
+    /// shows octal syntax.
+    ///
+    /// While supporting octal syntax isn't in and of itself a problem, it does
+    /// make good error messages harder. That is, in PCRE based regex engines,
+    /// syntax like `\0` invokes a backreference, which is explicitly
+    /// unsupported in Rust's regex engine. However, many users expect it to
+    /// be supported. Therefore, when octal support is disabled, the error
+    /// message will explicitly mention that backreferences aren't supported.
+    ///
+    /// Octal syntax is disabled by default.
+    pub fn octal(&mut self, yes: bool) -> &mut ParserBuilder {
+        self.octal = yes;
+        self
+    }
+
+    /// Enable verbose mode in the regular expression.
+    ///
+    /// When enabled, verbose mode permits insigificant whitespace in many
+    /// places in the regular expression, as well as comments. Comments are
+    /// started using `#` and continue until the end of the line.
+    ///
+    /// By default, this is disabled. It may be selectively enabled in the
+    /// regular expression by using the `x` flag regardless of this setting.
+    pub fn ignore_whitespace(&mut self, yes: bool) -> &mut ParserBuilder {
+        self.ignore_whitespace = yes;
+        self
+    }
+}
+
+/// A regular expression parser.
+///
+/// This parses a string representation of a regular expression into an
+/// abstract syntax tree. The size of the tree is proportional to the length
+/// of the regular expression pattern.
+///
+/// A `Parser` can be configured in more detail via a
+/// [`ParserBuilder`](struct.ParserBuilder.html).
+#[derive(Clone, Debug)]
+pub struct Parser {
+    /// The current position of the parser.
+    pos: Cell<Position>,
+    /// The current capture index.
+    capture_index: Cell<u32>,
+    /// The maximum number of open parens/brackets allowed. If the parser
+    /// exceeds this number, then an error is returned.
+    nest_limit: u32,
+    /// Whether to support octal syntax or not. When `false`, the parser will
+    /// return an error helpfully pointing out that backreferences are not
+    /// supported.
+    octal: bool,
+    /// The initial setting for `ignore_whitespace` as provided by
+    /// Th`ParserBuilder`. is is used when reseting the parser's state.
+    initial_ignore_whitespace: bool,
+    /// Whether whitespace should be ignored. When enabled, comments are
+    /// also permitted.
+    ignore_whitespace: Cell<bool>,
+    /// A list of comments, in order of appearance.
+    comments: RefCell<Vec<ast::Comment>>,
+    /// A stack of grouped sub-expressions, including alternations.
+    stack_group: RefCell<Vec<GroupState>>,
+    /// A stack of nested character classes. This is only non-empty when
+    /// parsing a class.
+    stack_class: RefCell<Vec<ClassState>>,
+    /// A sorted sequence of capture names. This is used to detect duplicate
+    /// capture names and report an error if one is detected.
+    capture_names: RefCell<Vec<ast::CaptureName>>,
+    /// A scratch buffer used in various places. Mostly this is used to
+    /// accumulate relevant characters from parts of a pattern.
+    scratch: RefCell<String>,
+}
+
+/// ParserI is the internal parser implementation.
+///
+/// We use this separate type so that we can carry the provided pattern string
+/// along with us. In particular, a `Parser` internal state is not tied to any
+/// one pattern, but `ParserI` is.
+///
+/// This type also lets us use `ParserI<&Parser>` in production code while
+/// retaining the convenience of `ParserI<Parser>` for tests, which sometimes
+/// work against the internal interface of the parser.
+#[derive(Clone, Debug)]
+struct ParserI<'s, P> {
+    /// The parser state/configuration.
+    parser: P,
+    /// The full regular expression provided by the user.
+    pattern: &'s str,
+}
+
+/// GroupState represents a single stack frame while parsing nested groups
+/// and alternations. Each frame records the state up to an opening parenthesis
+/// or a alternating bracket `|`.
+#[derive(Clone, Debug)]
+enum GroupState {
+    /// This state is pushed whenever an opening group is found.
+    Group {
+        /// The concatenation immediately preceding the opening group.
+        concat: ast::Concat,
+        /// The group that has been opened. Its sub-AST is always empty.
+        group: ast::Group,
+        /// Whether this group has the `x` flag enabled or not.
+        ignore_whitespace: bool,
+    },
+    /// This state is pushed whenever a new alternation branch is found. If
+    /// an alternation branch is found and this state is at the top of the
+    /// stack, then this state should be modified to include the new
+    /// alternation.
+    Alternation(ast::Alternation),
+}
+
+/// ClassState represents a single stack frame while parsing character classes.
+/// Each frame records the state up to an intersection, difference, symmetric
+/// difference or nested class.
+///
+/// Note that a parser's character class stack is only non-empty when parsing
+/// a character class. In all other cases, it is empty.
+#[derive(Clone, Debug)]
+enum ClassState {
+    /// This state is pushed whenever an opening bracket is found.
+    Open {
+        /// The union of class items immediately preceding this class.
+        union: ast::ClassSetUnion,
+        /// The class that has been opened. Typically this just corresponds
+        /// to the `[`, but it can also include `[^` since `^` indicates
+        /// negation of the class.
+        set: ast::ClassBracketed,
+    },
+    /// This state is pushed when a operator is seen. When popped, the stored
+    /// set becomes the left hand side of the operator.
+    Op {
+        /// The type of the operation, i.e., &&, -- or ~~.
+        kind: ast::ClassSetBinaryOpKind,
+        /// The left-hand side of the operator.
+        lhs: ast::ClassSet,
+    },
+}
+
+impl Parser {
+    /// Create a new parser with a default configuration.
+    ///
+    /// The parser can be run with either the `parse` or `parse_with_comments`
+    /// methods. The parse methods return an abstract syntax tree.
+    ///
+    /// To set configuration options on the parser, use
+    /// [`ParserBuilder`](struct.ParserBuilder.html).
+    pub fn new() -> Parser {
+        ParserBuilder::new().build()
+    }
+
+    /// Parse the regular expression into an abstract syntax tree.
+    pub fn parse(&mut self, pattern: &str) -> Result<Ast> {
+        ParserI::new(self, pattern).parse()
+    }
+
+    /// Parse the regular expression and return an abstract syntax tree with
+    /// all of the comments found in the pattern.
+    pub fn parse_with_comments(
+        &mut self,
+        pattern: &str,
+    ) -> Result<ast::WithComments> {
+        ParserI::new(self, pattern).parse_with_comments()
+    }
+
+    /// Reset the internal state of a parser.
+    ///
+    /// This is called at the beginning of every parse. This prevents the
+    /// parser from running with inconsistent state (say, if a previous
+    /// invocation returned an error and the parser is reused).
+    fn reset(&self) {
+        // These settings should be in line with the construction
+        // in `ParserBuilder::build`.
+        self.pos.set(Position { offset: 0, line: 1, column: 1});
+        self.ignore_whitespace.set(self.initial_ignore_whitespace);
+        self.comments.borrow_mut().clear();
+        self.stack_group.borrow_mut().clear();
+        self.stack_class.borrow_mut().clear();
+    }
+}
+
+impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
+    /// Build an internal parser from a parser configuration and a pattern.
+    fn new(parser: P, pattern: &'s str) -> ParserI<'s, P> {
+        ParserI { parser: parser, pattern: pattern }
+    }
+
+    /// Return a reference to the parser state.
+    fn parser(&self) -> &Parser {
+        self.parser.borrow()
+    }
+
+    /// Return a reference to the pattern being parsed.
+    fn pattern(&self) -> &str {
+        self.pattern.borrow()
+    }
+
+    /// Create a new error with the given span and error type.
+    fn error(&self, span: Span, kind: ast::ErrorKind) -> ast::Error {
+        ast::Error {
+            kind: kind,
+            pattern: self.pattern().to_string(),
+            span: span,
+        }
+    }
+
+    /// Return the current offset of the parser.
+    ///
+    /// The offset starts at `0` from the beginning of the regular expression
+    /// pattern string.
+    fn offset(&self) -> usize {
+        self.parser().pos.get().offset
+    }
+
+    /// Return the current line number of the parser.
+    ///
+    /// The line number starts at `1`.
+    fn line(&self) -> usize {
+        self.parser().pos.get().line
+    }
+
+    /// Return the current column of the parser.
+    ///
+    /// The column number starts at `1` and is reset whenever a `\n` is seen.
+    fn column(&self) -> usize {
+        self.parser().pos.get().column
+    }
+
+    /// Return the next capturing index. Each subsequent call increments the
+    /// internal index.
+    ///
+    /// The span given should correspond to the location of the opening
+    /// parenthesis.
+    ///
+    /// If the capture limit is exceeded, then an error is returned.
+    fn next_capture_index(&self, span: Span) -> Result<u32> {
+        let current = self.parser().capture_index.get();
+        let i = current.checked_add(1).ok_or_else(|| {
+            self.error(span, ast::ErrorKind::CaptureLimitExceeded)
+        })?;
+        self.parser().capture_index.set(i);
+        Ok(i)
+    }
+
+    /// Adds the given capture name to this parser. If this capture name has
+    /// already been used, then an error is returned.
+    fn add_capture_name(&self, cap: &ast::CaptureName) -> Result<()> {
+        let mut names = self.parser().capture_names.borrow_mut();
+        match names.binary_search_by_key(
+            &cap.name.as_str(),
+            |c| c.name.as_str(),
+        ) {
+            Err(i) => {
+                names.insert(i, cap.clone());
+                Ok(())
+            }
+            Ok(i) => {
+                Err(self.error(cap.span, ast::ErrorKind::GroupNameDuplicate {
+                    original: names[i].span,
+                }))
+            }
+        }
+    }
+
+    /// Return whether the parser should ignore whitespace or not.
+    fn ignore_whitespace(&self) -> bool {
+        self.parser().ignore_whitespace.get()
+    }
+
+    /// Return the character at the current position of the parser.
+    ///
+    /// This panics if the current position does not point to a valid char.
+    fn char(&self) -> char {
+        self.char_at(self.offset())
+    }
+
+    /// Return the character at the given position.
+    ///
+    /// This panics if the given position does not point to a valid char.
+    fn char_at(&self, i: usize) -> char {
+        self.pattern()[i..].chars().next()
+            .unwrap_or_else(|| {
+                panic!("expected char at offset {}", i)
+            })
+    }
+
+    /// Bump the parser to the next Unicode scalar value.
+    ///
+    /// If the end of the input has been reached, then `false` is returned.
+    fn bump(&self) -> bool {
+        if self.is_eof() {
+            return false;
+        }
+        let Position { mut offset, mut line, mut column } = self.pos();
+        if self.char() == '\n' {
+            line = line.checked_add(1).unwrap();
+            column = 1;
+        } else {
+            column = column.checked_add(1).unwrap();
+        }
+        offset += self.char().len_utf8();
+        self.parser().pos.set(Position {
+            offset: offset,
+            line: line,
+            column: column,
+        });
+        self.pattern()[self.offset()..].chars().next().is_some()
+    }
+
+    /// If the substring starting at the current position of the parser has
+    /// the given prefix, then bump the parser to the character immediately
+    /// following the prefix and return true. Otherwise, don't bump the parser
+    /// and return false.
+    fn bump_if(&self, prefix: &str) -> bool {
+        if self.pattern()[self.offset()..].starts_with(prefix) {
+            for _ in 0..prefix.chars().count() {
+                self.bump();
+            }
+            true
+        } else {
+            false
+        }
+    }
+
+    /// Returns true if and only if the parser is positioned at a look-around
+    /// prefix. The conditions under which this returns true must always
+    /// correspond to a regular expression that would otherwise be consider
+    /// invalid.
+    ///
+    /// This should only be called immediately after parsing the opening of
+    /// a group or a set of flags.
+    fn is_lookaround_prefix(&self) -> bool {
+        self.bump_if("?=")
+        || self.bump_if("?!")
+        || self.bump_if("?<=")
+        || self.bump_if("?<!")
+    }
+
+    /// Bump the parser, and if the `x` flag is enabled, bump through any
+    /// subsequent spaces. Return true if and only if the parser is not at
+    /// EOF.
+    fn bump_and_bump_space(&self) -> bool {
+        if !self.bump() {
+            return false;
+        }
+        self.bump_space();
+        !self.is_eof()
+    }
+
+    /// If the `x` flag is enabled (i.e., whitespace insensitivity with
+    /// comments), then this will advance the parser through all whitespace
+    /// and comments to the next non-whitespace non-comment byte.
+    ///
+    /// If the `x` flag is disabled, then this is a no-op.
+    ///
+    /// This should be used selectively throughout the parser where
+    /// arbitrary whitespace is permitted when the `x` flag is enabled. For
+    /// example, `{   5  , 6}` is equivalent to `{5,6}`.
+    fn bump_space(&self) {
+        if !self.ignore_whitespace() {
+            return;
+        }
+        while !self.is_eof() {
+            if self.char().is_whitespace() {
+                self.bump();
+            } else if self.char() == '#' {
+                let start = self.pos();
+                let mut comment_text = String::new();
+                self.bump();
+                while !self.is_eof() {
+                    let c = self.char();
+                    self.bump();
+                    if c == '\n' {
+                        break;
+                    }
+                    comment_text.push(c);
+                }
+                let comment = ast::Comment {
+                    span: Span::new(start, self.pos()),
+                    comment: comment_text,
+                };
+                self.parser().comments.borrow_mut().push(comment);
+            } else {
+                break;
+            }
+        }
+    }
+
+    /// Peek at the next character in the input without advancing the parser.
+    ///
+    /// If the input has been exhausted, then this returns `None`.
+    fn peek(&self) -> Option<char> {
+        if self.is_eof() {
+            return None;
+        }
+        self.pattern()[self.offset() + self.char().len_utf8()..].chars().next()
+    }
+
+    /// Like peek, but will ignore spaces when the parser is in whitespace
+    /// insensitive mode.
+    fn peek_space(&self) -> Option<char> {
+        if !self.ignore_whitespace() {
+            return self.peek();
+        }
+        if self.is_eof() {
+            return None;
+        }
+        let mut start = self.offset() + self.char().len_utf8();
+        let mut in_comment = false;
+        for (i, c) in self.pattern()[start..].char_indices() {
+            if c.is_whitespace() {
+                continue;
+            } else if !in_comment && c == '#' {
+                in_comment = true;
+            } else if in_comment && c == '\n' {
+                in_comment = false;
+            } else {
+                start += i;
+                break;
+            }
+        }
+        self.pattern()[start..].chars().next()
+    }
+
+    /// Returns true if the next call to `bump` would return false.
+    fn is_eof(&self) -> bool {
+        self.offset() == self.pattern().len()
+    }
+
+    /// Return the current position of the parser, which includes the offset,
+    /// line and column.
+    fn pos(&self) -> Position {
+        self.parser().pos.get()
+    }
+
+    /// Create a span at the current position of the parser. Both the start
+    /// and end of the span are set.
+    fn span(&self) -> Span {
+        Span::splat(self.pos())
+    }
+
+    /// Create a span that covers the current character.
+    fn span_char(&self) -> Span {
+        let mut next = Position {
+            offset: self.offset().checked_add(self.char().len_utf8()).unwrap(),
+            line: self.line(),
+            column: self.column().checked_add(1).unwrap(),
+        };
+        if self.char() == '\n' {
+            next.line += 1;
+            next.column = 1;
+        }
+        Span::new(self.pos(), next)
+    }
+
+    /// Parse and push a single alternation on to the parser's internal stack.
+    /// If the top of the stack already has an alternation, then add to that
+    /// instead of pushing a new one.
+    ///
+    /// The concatenation given corresponds to a single alternation branch.
+    /// The concatenation returned starts the next branch and is empty.
+    ///
+    /// This assumes the parser is currently positioned at `|` and will advance
+    /// the parser to the character following `|`.
+    fn push_alternate(&self, mut concat: ast::Concat) -> Result<ast::Concat> {
+        assert_eq!(self.char(), '|');
+        concat.span.end = self.pos();
+        self.push_or_add_alternation(concat);
+        self.bump();
+        Ok(ast::Concat {
+            span: self.span(),
+            asts: vec![],
+        })
+    }
+
+    /// Pushes or adds the given branch of an alternation to the parser's
+    /// internal stack of state.
+    fn push_or_add_alternation(&self, concat: ast::Concat) {
+        use self::GroupState::*;
+
+        let mut stack = self.parser().stack_group.borrow_mut();
+        if let Some(&mut Alternation(ref mut alts)) = stack.last_mut() {
+            alts.asts.push(concat.into_ast());
+            return;
+        }
+        stack.push(Alternation(ast::Alternation {
+            span: Span::new(concat.span.start, self.pos()),
+            asts: vec![concat.into_ast()],
+        }));
+    }
+
+    /// Parse and push a group AST (and its parent concatenation) on to the
+    /// parser's internal stack. Return a fresh concatenation corresponding
+    /// to the group's sub-AST.
+    ///
+    /// If a set of flags was found (with no group), then the concatenation
+    /// is returned with that set of flags added.
+    ///
+    /// This assumes that the parser is currently positioned on the opening
+    /// parenthesis. It advances the parser to the character at the start
+    /// of the sub-expression (or adjoining expression).
+    ///
+    /// If there was a problem parsing the start of the group, then an error
+    /// is returned.
+    fn push_group(&self, mut concat: ast::Concat) -> Result<ast::Concat> {
+        assert_eq!(self.char(), '(');
+        match self.parse_group()? {
+            Either::Left(set) => {
+                let ignore = set.flags.flag_state(ast::Flag::IgnoreWhitespace);
+                if let Some(v) = ignore {
+                    self.parser().ignore_whitespace.set(v);
+                }
+
+                concat.asts.push(Ast::Flags(set));
+                Ok(concat)
+            }
+            Either::Right(group) => {
+                let old_ignore_whitespace = self.ignore_whitespace();
+                let new_ignore_whitespace = group
+                    .flags()
+                    .and_then(|f| f.flag_state(ast::Flag::IgnoreWhitespace))
+                    .unwrap_or(old_ignore_whitespace);
+                self.parser().stack_group.borrow_mut().push(GroupState::Group {
+                    concat: concat,
+                    group: group,
+                    ignore_whitespace: old_ignore_whitespace,
+                });
+                self.parser().ignore_whitespace.set(new_ignore_whitespace);
+                Ok(ast::Concat {
+                    span: self.span(),
+                    asts: vec![],
+                })
+            }
+        }
+    }
+
+    /// Pop a group AST from the parser's internal stack and set the group's
+    /// AST to the given concatenation. Return the concatenation containing
+    /// the group.
+    ///
+    /// This assumes that the parser is currently positioned on the closing
+    /// parenthesis and advances the parser to the character following the `)`.
+    ///
+    /// If no such group could be popped, then an unopened group error is
+    /// returned.
+    fn pop_group(&self, mut group_concat: ast::Concat) -> Result<ast::Concat> {
+        use self::GroupState::*;
+
+        assert_eq!(self.char(), ')');
+        let mut stack = self.parser().stack_group.borrow_mut();
+        let (mut prior_concat, mut group, ignore_whitespace, alt) =
+            match stack.pop() {
+                Some(Group { concat, group, ignore_whitespace }) => {
+                    (concat, group, ignore_whitespace, None)
+                }
+                Some(Alternation(alt)) => {
+                    match stack.pop() {
+                        Some(Group { concat, group, ignore_whitespace }) => {
+                            (concat, group, ignore_whitespace, Some(alt))
+                        }
+                        None | Some(Alternation(_)) => {
+                            return Err(self.error(
+                                self.span_char(),
+                                ast::ErrorKind::GroupUnopened,
+                            ));
+                        }
+                    }
+                }
+                None => {
+                    return Err(self.error(
+                        self.span_char(),
+                        ast::ErrorKind::GroupUnopened,
+                    ));
+                }
+            };
+        self.parser().ignore_whitespace.set(ignore_whitespace);
+        group_concat.span.end = self.pos();
+        self.bump();
+        group.span.end = self.pos();
+        match alt {
+            Some(mut alt) => {
+                alt.span.end = group_concat.span.end;
+                alt.asts.push(group_concat.into_ast());
+                group.ast = Box::new(alt.into_ast());
+            }
+            None => {
+                group.ast = Box::new(group_concat.into_ast());
+            }
+        }
+        prior_concat.asts.push(Ast::Group(group));
+        Ok(prior_concat)
+    }
+
+    /// Pop the last state from the parser's internal stack, if it exists, and
+    /// add the given concatenation to it. There either must be no state or a
+    /// single alternation item on the stack. Any other scenario produces an
+    /// error.
+    ///
+    /// This assumes that the parser has advanced to the end.
+    fn pop_group_end(&self, mut concat: ast::Concat) -> Result<Ast> {
+        concat.span.end = self.pos();
+        let mut stack = self.parser().stack_group.borrow_mut();
+        let ast = match stack.pop() {
+            None => Ok(concat.into_ast()),
+            Some(GroupState::Alternation(mut alt)) => {
+                alt.span.end = self.pos();
+                alt.asts.push(concat.into_ast());
+                Ok(Ast::Alternation(alt))
+            }
+            Some(GroupState::Group { group, .. }) => {
+                return Err(self.error(
+                    group.span,
+                    ast::ErrorKind::GroupUnclosed,
+                ));
+            }
+        };
+        // If we try to pop again, there should be nothing.
+        match stack.pop() {
+            None => ast,
+            Some(GroupState::Alternation(_)) => {
+                // This unreachable is unfortunate. This case can't happen
+                // because the only way we can be here is if there were two
+                // `GroupState::Alternation`s adjacent in the parser's stack,
+                // which we guarantee to never happen because we never push a
+                // `GroupState::Alternation` if one is already at the top of
+                // the stack.
+                unreachable!()
+            }
+            Some(GroupState::Group { group, .. }) => {
+                Err(self.error(group.span, ast::ErrorKind::GroupUnclosed))
+            }
+        }
+    }
+
+    /// Parse the opening of a character class and push the current class
+    /// parsing context onto the parser's stack. This assumes that the parser
+    /// is positioned at an opening `[`. The given union should correspond to
+    /// the union of set items built up before seeing the `[`.
+    ///
+    /// If there was a problem parsing the opening of the class, then an error
+    /// is returned. Otherwise, a new union of set items for the class is
+    /// returned (which may be populated with either a `]` or a `-`).
+    fn push_class_open(
+        &self,
+        parent_union: ast::ClassSetUnion,
+    ) -> Result<ast::ClassSetUnion> {
+        assert_eq!(self.char(), '[');
+
+        let (nested_set, nested_union) = self.parse_set_class_open()?;
+        self.parser().stack_class.borrow_mut().push(ClassState::Open {
+            union: parent_union,
+            set: nested_set,
+        });
+        Ok(nested_union)
+    }
+
+    /// Parse the end of a character class set and pop the character class
+    /// parser stack. The union given corresponds to the last union built
+    /// before seeing the closing `]`. The union returned corresponds to the
+    /// parent character class set with the nested class added to it.
+    ///
+    /// This assumes that the parser is positioned at a `]` and will advance
+    /// the parser to the byte immediately following the `]`.
+    ///
+    /// If the stack is empty after popping, then this returns the final
+    /// "top-level" character class AST (where a "top-level" character class
+    /// is one that is not nested inside any other character class).
+    ///
+    /// If there is no corresponding opening bracket on the parser's stack,
+    /// then an error is returned.
+    fn pop_class(
+        &self,
+        nested_union: ast::ClassSetUnion,
+    ) -> Result<Either<ast::ClassSetUnion, ast::Class>> {
+        assert_eq!(self.char(), ']');
+
+        let item = ast::ClassSet::Item(nested_union.into_item());
+        let prevset = self.pop_class_op(item);
+        let mut stack = self.parser().stack_class.borrow_mut();
+        match stack.pop() {
+            None => {
+                // We can never observe an empty stack:
+                //
+                // 1) We are guaranteed to start with a non-empty stack since
+                //    the character class parser is only initiated when it sees
+                //    a `[`.
+                // 2) If we ever observe an empty stack while popping after
+                //    seeing a `]`, then we signal the character class parser
+                //    to terminate.
+                panic!("unexpected empty character class stack")
+            },
+            Some(ClassState::Op { .. }) => {
+                // This panic is unfortunate, but this case is impossible
+                // since we already popped the Op state if one exists above.
+                // Namely, every push to the class parser stack is guarded by
+                // whether an existing Op is already on the top of the stack.
+                // If it is, the existing Op is modified. That is, the stack
+                // can never have consecutive Op states.
+                panic!("unexpected ClassState::Op")
+            }
+            Some(ClassState::Open { mut union, mut set }) => {
+                self.bump();
+                set.span.end = self.pos();
+                set.kind = prevset;
+                if stack.is_empty() {
+                    Ok(Either::Right(ast::Class::Bracketed(set)))
+                } else {
+                    union.push(ast::ClassSetItem::Bracketed(Box::new(set)));
+                    Ok(Either::Left(union))
+                }
+            }
+        }
+    }
+
+    /// Return an "unclosed class" error whose span points to the most
+    /// recently opened class.
+    ///
+    /// This should only be called while parsing a character class.
+    fn unclosed_class_error(&self) -> ast::Error {
+        for state in self.parser().stack_class.borrow().iter().rev() {
+            match *state {
+                ClassState::Open { ref set, .. } => {
+                    return self.error(set.span, ast::ErrorKind::ClassUnclosed);
+                }
+                _ => {}
+            }
+        }
+        // We are guaranteed to have a non-empty stack with at least
+        // one open bracket, so we should never get here.
+        panic!("no open character class found")
+    }
+
+    /// Push the current set of class items on to the class parser's stack as
+    /// the left hand side of the given operator.
+    ///
+    /// A fresh set union is returned, which should be used to build the right
+    /// hand side of this operator.
+    fn push_class_op(
+        &self,
+        next_kind: ast::ClassSetBinaryOpKind,
+        next_union: ast::ClassSetUnion,
+    ) -> ast::ClassSetUnion {
+
+        let item = ast::ClassSet::Item(next_union.into_item());
+        let new_lhs = self.pop_class_op(item);
+        self.parser().stack_class.borrow_mut().push(ClassState::Op {
+            kind: next_kind,
+            lhs: new_lhs,
+        });
+        ast::ClassSetUnion { span: self.span(), items: vec![] }
+    }
+
+    /// Pop a character class set from the character class parser stack. If the
+    /// top of the stack is just an item (not an operation), then return the
+    /// given set unchanged. If the top of the stack is an operation, then the
+    /// given set will be used as the rhs of the operation on the top of the
+    /// stack. In that case, the binary operation is returned as a set.
+    fn pop_class_op(&self, rhs: ast::ClassSet) -> ast::ClassSet {
+        let mut stack = self.parser().stack_class.borrow_mut();
+        let (kind, lhs) = match stack.pop() {
+            Some(ClassState::Op { kind, lhs }) => (kind, lhs),
+            Some(state @ ClassState::Open { .. }) => {
+                stack.push(state);
+                return rhs;
+            }
+            None => unreachable!(),
+        };
+        let span = Span::new(lhs.span().start, rhs.span().end);
+        ast::ClassSet::BinaryOp(ast::ClassSetBinaryOp {
+            span: span,
+            kind: kind,
+            lhs: Box::new(lhs),
+            rhs: Box::new(rhs),
+        })
+    }
+}
+
+impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
+    /// Parse the regular expression into an abstract syntax tree.
+    fn parse(&self) -> Result<Ast> {
+        self.parse_with_comments().map(|astc| astc.ast)
+    }
+
+    /// Parse the regular expression and return an abstract syntax tree with
+    /// all of the comments found in the pattern.
+    fn parse_with_comments(&self) -> Result<ast::WithComments> {
+        assert_eq!(self.offset(), 0, "parser can only be used once");
+        self.parser().reset();
+        let mut concat = ast::Concat {
+            span: self.span(),
+            asts: vec![],
+        };
+        loop {
+            self.bump_space();
+            if self.is_eof() {
+                break;
+            }
+            match self.char() {
+                '(' => concat = self.push_group(concat)?,
+                ')' => concat = self.pop_group(concat)?,
+                '|' => concat = self.push_alternate(concat)?,
+                '[' => {
+                    let class = self.parse_set_class()?;
+                    concat.asts.push(Ast::Class(class));
+                }
+                '?' => {
+                    concat = self.parse_uncounted_repetition(
+                        concat, ast::RepetitionKind::ZeroOrOne)?;
+                }
+                '*' => {
+                    concat = self.parse_uncounted_repetition(
+                        concat, ast::RepetitionKind::ZeroOrMore)?;
+                }
+                '+' => {
+                    concat = self.parse_uncounted_repetition(
+                        concat, ast::RepetitionKind::OneOrMore)?;
+                }
+                '{' => {
+                    concat = self.parse_counted_repetition(concat)?;
+                }
+                _ => concat.asts.push(self.parse_primitive()?.into_ast()),
+            }
+        }
+        let ast = self.pop_group_end(concat)?;
+        NestLimiter::new(self).check(&ast)?;
+        Ok(ast::WithComments {
+            ast: ast,
+            comments: mem::replace(
+                &mut *self.parser().comments.borrow_mut(),
+                vec![],
+            ),
+        })
+    }
+
+    /// Parses an uncounted repetition operation. An uncounted repetition
+    /// operator includes ?, * and +, but does not include the {m,n} syntax.
+    /// The given `kind` should correspond to the operator observed by the
+    /// caller.
+    ///
+    /// This assumes that the paser is currently positioned at the repetition
+    /// operator and advances the parser to the first character after the
+    /// operator. (Note that the operator may include a single additional `?`,
+    /// which makes the operator ungreedy.)
+    ///
+    /// The caller should include the concatenation that is being built. The
+    /// concatenation returned includes the repetition operator applied to the
+    /// last expression in the given concatenation.
+    fn parse_uncounted_repetition(
+        &self,
+        mut concat: ast::Concat,
+        kind: ast::RepetitionKind,
+    ) -> Result<ast::Concat> {
+        assert!(
+            self.char() == '?' || self.char() == '*' || self.char() == '+');
+        let op_start = self.pos();
+        let ast = match concat.asts.pop() {
+            Some(ast) => ast,
+            None => return Err(self.error(
+                self.span(),
+                ast::ErrorKind::RepetitionMissing,
+            )),
+        };
+        match ast {
+            Ast::Empty(_) | Ast::Flags(_) => return Err(self.error(
+                self.span(),
+                ast::ErrorKind::RepetitionMissing,
+            )),
+            _ => {}
+        }
+        let mut greedy = true;
+        if self.bump() && self.char() == '?' {
+            greedy = false;
+            self.bump();
+        }
+        concat.asts.push(Ast::Repetition(ast::Repetition {
+            span: ast.span().with_end(self.pos()),
+            op: ast::RepetitionOp {
+                span: Span::new(op_start, self.pos()),
+                kind: kind,
+            },
+            greedy: greedy,
+            ast: Box::new(ast),
+        }));
+        Ok(concat)
+    }
+
+    /// Parses a counted repetition operation. A counted repetition operator
+    /// corresponds to the {m,n} syntax, and does not include the ?, * or +
+    /// operators.
+    ///
+    /// This assumes that the paser is currently positioned at the opening `{`
+    /// and advances the parser to the first character after the operator.
+    /// (Note that the operator may include a single additional `?`, which
+    /// makes the operator ungreedy.)
+    ///
+    /// The caller should include the concatenation that is being built. The
+    /// concatenation returned includes the repetition operator applied to the
+    /// last expression in the given concatenation.
+    fn parse_counted_repetition(
+        &self,
+        mut concat: ast::Concat,
+    ) -> Result<ast::Concat> {
+        assert!(self.char() == '{');
+        let start = self.pos();
+        let ast = match concat.asts.pop() {
+            Some(ast) => ast,
+            None => return Err(self.error(
+                self.span(),
+                ast::ErrorKind::RepetitionMissing,
+            )),
+        };
+        match ast {
+            Ast::Empty(_) | Ast::Flags(_) => return Err(self.error(
+                self.span(),
+                ast::ErrorKind::RepetitionMissing,
+            )),
+            _ => {}
+        }
+        if !self.bump_and_bump_space() {
+            return Err(self.error(
+                Span::new(start, self.pos()),
+                ast::ErrorKind::RepetitionCountUnclosed,
+            ));
+        }
+        let count_start = specialize_err(
+            self.parse_decimal(),
+            ast::ErrorKind::DecimalEmpty,
+            ast::ErrorKind::RepetitionCountDecimalEmpty,
+        )?;
+        let mut range = ast::RepetitionRange::Exactly(count_start);
+        if self.is_eof() {
+            return Err(self.error(
+                Span::new(start, self.pos()),
+                ast::ErrorKind::RepetitionCountUnclosed,
+            ));
+        }
+        if self.char() == ',' {
+            if !self.bump_and_bump_space() {
+                return Err(self.error(
+                    Span::new(start, self.pos()),
+                    ast::ErrorKind::RepetitionCountUnclosed,
+                ));
+            }
+            if self.char() != '}' {
+                let count_end = specialize_err(
+                    self.parse_decimal(),
+                    ast::ErrorKind::DecimalEmpty,
+                    ast::ErrorKind::RepetitionCountDecimalEmpty,
+                )?;
+                range = ast::RepetitionRange::Bounded(count_start, count_end);
+            } else {
+                range = ast::RepetitionRange::AtLeast(count_start);
+            }
+        }
+        if self.is_eof() || self.char() != '}' {
+            return Err(self.error(
+                Span::new(start, self.pos()),
+                ast::ErrorKind::RepetitionCountUnclosed,
+            ));
+        }
+
+        let mut greedy = true;
+        if self.bump_and_bump_space() && self.char() == '?' {
+            greedy = false;
+            self.bump();
+        }
+
+        let op_span = Span::new(start, self.pos());
+        if !range.is_valid() {
+            return Err(self.error(
+                op_span,
+                ast::ErrorKind::RepetitionCountInvalid,
+            ));
+        }
+        concat.asts.push(Ast::Repetition(ast::Repetition {
+            span: ast.span().with_end(self.pos()),
+            op: ast::RepetitionOp {
+                span: op_span,
+                kind: ast::RepetitionKind::Range(range),
+            },
+            greedy: greedy,
+            ast: Box::new(ast),
+        }));
+        Ok(concat)
+    }
+
+    /// Parse a group (which contains a sub-expression) or a set of flags.
+    ///
+    /// If a group was found, then it is returned with an empty AST. If a set
+    /// of flags is found, then that set is returned.
+    ///
+    /// The parser should be positioned at the opening parenthesis.
+    ///
+    /// This advances the parser to the character before the start of the
+    /// sub-expression (in the case of a group) or to the closing parenthesis
+    /// immediately following the set of flags.
+    ///
+    /// # Errors
+    ///
+    /// If flags are given and incorrectly specified, then a corresponding
+    /// error is returned.
+    ///
+    /// If a capture name is given and it is incorrectly specified, then a
+    /// corresponding error is returned.
+    fn parse_group(&self) -> Result<Either<ast::SetFlags, ast::Group>> {
+        assert_eq!(self.char(), '(');
+        let open_span = self.span_char();
+        self.bump();
+        self.bump_space();
+        if self.is_lookaround_prefix() {
+            return Err(self.error(
+                Span::new(open_span.start, self.span().end),
+                ast::ErrorKind::UnsupportedLookAround,
+            ));
+        }
+        let inner_span = self.span();
+        if self.bump_if("?P<") {
+            let capture_index = self.next_capture_index(open_span)?;
+            let cap = self.parse_capture_name(capture_index)?;
+            Ok(Either::Right(ast::Group {
+                span: open_span,
+                kind: ast::GroupKind::CaptureName(cap),
+                ast: Box::new(Ast::Empty(self.span())),
+            }))
+        } else if self.bump_if("?") {
+            if self.is_eof() {
+                return Err(self.error(
+                    open_span,
+                    ast::ErrorKind::GroupUnclosed,
+                ));
+            }
+            let flags = self.parse_flags()?;
+            let char_end = self.char();
+            self.bump();
+            if char_end == ')' {
+                // We don't allow empty flags, e.g., `(?)`. We instead
+                // interpret it as a repetition operator missing its argument.
+                if flags.items.is_empty() {
+                    return Err(self.error(
+                        inner_span,
+                        ast::ErrorKind::RepetitionMissing,
+                    ));
+                }
+                Ok(Either::Left(ast::SetFlags {
+                    span: Span { end: self.pos(), ..open_span },
+                    flags: flags,
+                }))
+            } else {
+                assert_eq!(char_end, ':');
+                Ok(Either::Right(ast::Group {
+                    span: open_span,
+                    kind: ast::GroupKind::NonCapturing(flags),
+                    ast: Box::new(Ast::Empty(self.span())),
+                }))
+            }
+        } else {
+            let capture_index = self.next_capture_index(open_span)?;
+            Ok(Either::Right(ast::Group {
+                span: open_span,
+                kind: ast::GroupKind::CaptureIndex(capture_index),
+                ast: Box::new(Ast::Empty(self.span())),
+            }))
+        }
+    }
+
+    /// Parses a capture group name. Assumes that the parser is positioned at
+    /// the first character in the name following the opening `<` (and may
+    /// possibly be EOF). This advances the parser to the first character
+    /// following the closing `>`.
+    ///
+    /// The caller must provide the capture index of the group for this name.
+    fn parse_capture_name(
+        &self,
+        capture_index: u32,
+    ) -> Result<ast::CaptureName> {
+        if self.is_eof() {
+            return Err(self.error(
+                self.span(),
+                ast::ErrorKind::GroupNameUnexpectedEof,
+            ));
+        }
+        let start = self.pos();
+        loop {
+            if self.char() == '>' {
+                break;
+            }
+            if !is_capture_char(self.char(), self.pos() == start) {
+                return Err(self.error(
+                    self.span_char(),
+                    ast::ErrorKind::GroupNameInvalid,
+                ));
+            }
+            if !self.bump() {
+                break;
+            }
+        }
+        let end = self.pos();
+        if self.is_eof() {
+            return Err(self.error(
+                self.span(),
+                ast::ErrorKind::GroupNameUnexpectedEof,
+            ));
+        }
+        assert_eq!(self.char(), '>');
+        self.bump();
+        let name = &self.pattern()[start.offset..end.offset];
+        if name.is_empty() {
+            return Err(self.error(
+                Span::new(start, start),
+                ast::ErrorKind::GroupNameEmpty,
+            ));
+        }
+        let capname = ast::CaptureName {
+            span: Span::new(start, end),
+            name: name.to_string(),
+            index: capture_index,
+        };
+        self.add_capture_name(&capname)?;
+        Ok(capname)
+    }
+
+    /// Parse a sequence of flags starting at the current character.
+    ///
+    /// This advances the parser to the character immediately following the
+    /// flags, which is guaranteed to be either `:` or `)`.
+    ///
+    /// # Errors
+    ///
+    /// If any flags are duplicated, then an error is returned.
+    ///
+    /// If the negation operator is used more than once, then an error is
+    /// returned.
+    ///
+    /// If no flags could be found or if the negation operation is not followed
+    /// by any flags, then an error is returned.
+    fn parse_flags(&self) -> Result<ast::Flags> {
+        let mut flags = ast::Flags {
+            span: self.span(),
+            items: vec![],
+        };
+        let mut last_was_negation = None;
+        while self.char() != ':' && self.char() != ')' {
+            if self.char() == '-' {
+                last_was_negation = Some(self.span_char());
+                let item = ast::FlagsItem {
+                    span: self.span_char(),
+                    kind: ast::FlagsItemKind::Negation,
+                };
+                if let Some(i) = flags.add_item(item) {
+                    return Err(self.error(
+                        self.span_char(),
+                        ast::ErrorKind::FlagRepeatedNegation {
+                            original: flags.items[i].span,
+                        },
+                    ));
+                }
+            } else {
+                last_was_negation = None;
+                let item = ast::FlagsItem {
+                    span: self.span_char(),
+                    kind: ast::FlagsItemKind::Flag(self.parse_flag()?),
+                };
+                if let Some(i) = flags.add_item(item) {
+                    return Err(self.error(
+                        self.span_char(),
+                        ast::ErrorKind::FlagDuplicate {
+                            original: flags.items[i].span,
+                        },
+                    ));
+                }
+            }
+            if !self.bump() {
+                return Err(self.error(
+                    self.span(),
+                    ast::ErrorKind::FlagUnexpectedEof,
+                ));
+            }
+        }
+        if let Some(span) = last_was_negation {
+            return Err(self.error(span, ast::ErrorKind::FlagDanglingNegation));
+        }
+        flags.span.end = self.pos();
+        Ok(flags)
+    }
+
+    /// Parse the current character as a flag. Do not advance the parser.
+    ///
+    /// # Errors
+    ///
+    /// If the flag is not recognized, then an error is returned.
+    fn parse_flag(&self) -> Result<ast::Flag> {
+        match self.char() {
+            'i' => Ok(ast::Flag::CaseInsensitive),
+            'm' => Ok(ast::Flag::MultiLine),
+            's' => Ok(ast::Flag::DotMatchesNewLine),
+            'U' => Ok(ast::Flag::SwapGreed),
+            'u' => Ok(ast::Flag::Unicode),
+            'x' => Ok(ast::Flag::IgnoreWhitespace),
+            _ => Err(self.error(
+                self.span_char(),
+                ast::ErrorKind::FlagUnrecognized,
+            )),
+        }
+    }
+
+    /// Parse a primitive AST. e.g., A literal, non-set character class or
+    /// assertion.
+    ///
+    /// This assumes that the parser expects a primitive at the current
+    /// location. i.e., All other non-primitive cases have been handled.
+    /// For example, if the parser's position is at `|`, then `|` will be
+    /// treated as a literal (e.g., inside a character class).
+    ///
+    /// This advances the parser to the first character immediately following
+    /// the primitive.
+    fn parse_primitive(&self) -> Result<Primitive> {
+        match self.char() {
+            '\\' => self.parse_escape(),
+            '.' => {
+                let ast = Primitive::Dot(self.span_char());
+                self.bump();
+                Ok(ast)
+            }
+            '^' => {
+                let ast = Primitive::Assertion(ast::Assertion {
+                    span: self.span_char(),
+                    kind: ast::AssertionKind::StartLine,
+                });
+                self.bump();
+                Ok(ast)
+            }
+            '$' => {
+                let ast = Primitive::Assertion(ast::Assertion {
+                    span: self.span_char(),
+                    kind: ast::AssertionKind::EndLine,
+                });
+                self.bump();
+                Ok(ast)
+            }
+            c => {
+                let ast = Primitive::Literal(ast::Literal {
+                    span: self.span_char(),
+                    kind: ast::LiteralKind::Verbatim,
+                    c: c,
+                });
+                self.bump();
+                Ok(ast)
+            }
+        }
+    }
+
+    /// Parse an escape sequence as a primitive AST.
+    ///
+    /// This assumes the parser is positioned at the start of the escape
+    /// sequence, i.e., `\`. It advances the parser to the first position
+    /// immediately following the escape sequence.
+    fn parse_escape(&self) -> Result<Primitive> {
+        assert_eq!(self.char(), '\\');
+        let start = self.pos();
+        if !self.bump() {
+            return Err(self.error(
+                Span::new(start, self.pos()),
+                ast::ErrorKind::EscapeUnexpectedEof,
+            ));
+        }
+        let c = self.char();
+        // Put some of the more complicated routines into helpers.
+        match c {
+            '0'..='7' => {
+                if !self.parser().octal {
+                    return Err(self.error(
+                        Span::new(start, self.span_char().end),
+                        ast::ErrorKind::UnsupportedBackreference,
+                    ));
+                }
+                let mut lit = self.parse_octal();
+                lit.span.start = start;
+                return Ok(Primitive::Literal(lit));
+            }
+            '8'..='9' if !self.parser().octal => {
+                return Err(self.error(
+                    Span::new(start, self.span_char().end),
+                    ast::ErrorKind::UnsupportedBackreference,
+                ));
+            }
+            'x' | 'u' | 'U' => {
+                let mut lit = self.parse_hex()?;
+                lit.span.start = start;
+                return Ok(Primitive::Literal(lit));
+            }
+            'p' | 'P' => {
+                let mut cls = self.parse_unicode_class()?;
+                cls.span.start = start;
+                return Ok(Primitive::Unicode(cls));
+            }
+            'd' | 's' | 'w' | 'D' | 'S' | 'W' => {
+                let mut cls = self.parse_perl_class();
+                cls.span.start = start;
+                return Ok(Primitive::Perl(cls));
+            }
+            _ => {}
+        }
+
+        // Handle all of the one letter sequences inline.
+        self.bump();
+        let span = Span::new(start, self.pos());
+        if is_meta_character(c) {
+            return Ok(Primitive::Literal(ast::Literal {
+                span: span,
+                kind: ast::LiteralKind::Punctuation,
+                c: c,
+            }));
+        }
+        let special = |kind, c| Ok(Primitive::Literal(ast::Literal {
+            span: span,
+            kind: ast::LiteralKind::Special(kind),
+            c: c,
+        }));
+        match c {
+            'a' => special(ast::SpecialLiteralKind::Bell, '\x07'),
+            'f' => special(ast::SpecialLiteralKind::FormFeed, '\x0C'),
+            't' => special(ast::SpecialLiteralKind::Tab, '\t'),
+            'n' => special(ast::SpecialLiteralKind::LineFeed, '\n'),
+            'r' => special(ast::SpecialLiteralKind::CarriageReturn, '\r'),
+            'v' => special(ast::SpecialLiteralKind::VerticalTab, '\x0B'),
+            ' ' if self.ignore_whitespace() => {
+                special(ast::SpecialLiteralKind::Space, ' ')
+            }
+            'A' => Ok(Primitive::Assertion(ast::Assertion {
+                span: span,
+                kind: ast::AssertionKind::StartText,
+            })),
+            'z' => Ok(Primitive::Assertion(ast::Assertion {
+                span: span,
+                kind: ast::AssertionKind::EndText,
+            })),
+            'b' => Ok(Primitive::Assertion(ast::Assertion {
+                span: span,
+                kind: ast::AssertionKind::WordBoundary,
+            })),
+            'B' => Ok(Primitive::Assertion(ast::Assertion {
+                span: span,
+                kind: ast::AssertionKind::NotWordBoundary,
+            })),
+            _ => Err(self.error(span, ast::ErrorKind::EscapeUnrecognized)),
+        }
+    }
+
+    /// Parse an octal representation of a Unicode codepoint up to 3 digits
+    /// long. This expects the parser to be positioned at the first octal
+    /// digit and advances the parser to the first character immediately
+    /// following the octal number. This also assumes that parsing octal
+    /// escapes is enabled.
+    ///
+    /// Assuming the preconditions are met, this routine can never fail.
+    fn parse_octal(&self) -> ast::Literal {
+        use std::char;
+        use std::u32;
+
+        assert!(self.parser().octal);
+        assert!('0' <= self.char() && self.char() <= '7');
+        let start = self.pos();
+        // Parse up to two more digits.
+        while
+            self.bump() &&
+            '0' <= self.char() && self.char() <= '7' &&
+            self.pos().offset - start.offset <= 2
+        {}
+        let end = self.pos();
+        let octal = &self.pattern()[start.offset..end.offset];
+        // Parsing the octal should never fail since the above guarantees a
+        // valid number.
+        let codepoint =
+            u32::from_str_radix(octal, 8).expect("valid octal number");
+        // The max value for 3 digit octal is 0777 = 511 and [0, 511] has no
+        // invalid Unicode scalar values.
+        let c = char::from_u32(codepoint).expect("Unicode scalar value");
+        ast::Literal {
+            span: Span::new(start, end),
+            kind: ast::LiteralKind::Octal,
+            c: c,
+        }
+    }
+
+    /// Parse a hex representation of a Unicode codepoint. This handles both
+    /// hex notations, i.e., `\xFF` and `\x{FFFF}`. This expects the parser to
+    /// be positioned at the `x`, `u` or `U` prefix. The parser is advanced to
+    /// the first character immediately following the hexadecimal literal.
+    fn parse_hex(&self) -> Result<ast::Literal> {
+        assert!(self.char() == 'x'
+                || self.char() == 'u'
+                || self.char() == 'U');
+
+        let hex_kind = match self.char() {
+            'x' => ast::HexLiteralKind::X,
+            'u' => ast::HexLiteralKind::UnicodeShort,
+            _ => ast::HexLiteralKind::UnicodeLong,
+        };
+        if !self.bump_and_bump_space() {
+            return Err(self.error(
+                self.span(),
+                ast::ErrorKind::EscapeUnexpectedEof,
+            ));
+        }
+        if self.char() == '{' {
+            self.parse_hex_brace(hex_kind)
+        } else {
+            self.parse_hex_digits(hex_kind)
+        }
+    }
+
+    /// Parse an N-digit hex representation of a Unicode codepoint. This
+    /// expects the parser to be positioned at the first digit and will advance
+    /// the parser to the first character immediately following the escape
+    /// sequence.
+    ///
+    /// The number of digits given must be 2 (for `\xNN`), 4 (for `\uNNNN`)
+    /// or 8 (for `\UNNNNNNNN`).
+    fn parse_hex_digits(
+        &self,
+        kind: ast::HexLiteralKind,
+    ) -> Result<ast::Literal> {
+        use std::char;
+        use std::u32;
+
+        let mut scratch = self.parser().scratch.borrow_mut();
+        scratch.clear();
+
+        let start = self.pos();
+        for i in 0..kind.digits() {
+            if i > 0 && !self.bump_and_bump_space() {
+                return Err(self.error(
+                    self.span(),
+                    ast::ErrorKind::EscapeUnexpectedEof,
+                ));
+            }
+            if !is_hex(self.char()) {
+                return Err(self.error(
+                    self.span_char(),
+                    ast::ErrorKind::EscapeHexInvalidDigit,
+                ));
+            }
+            scratch.push(self.char());
+        }
+        // The final bump just moves the parser past the literal, which may
+        // be EOF.
+        self.bump_and_bump_space();
+        let end = self.pos();
+        let hex = scratch.as_str();
+        match u32::from_str_radix(hex, 16).ok().and_then(char::from_u32) {
+            None => Err(self.error(
+                Span::new(start, end),
+                ast::ErrorKind::EscapeHexInvalid,
+            )),
+            Some(c) => Ok(ast::Literal {
+                span: Span::new(start, end),
+                kind: ast::LiteralKind::HexFixed(kind),
+                c: c,
+            }),
+        }
+    }
+
+    /// Parse a hex representation of any Unicode scalar value. This expects
+    /// the parser to be positioned at the opening brace `{` and will advance
+    /// the parser to the first character following the closing brace `}`.
+    fn parse_hex_brace(
+        &self,
+        kind: ast::HexLiteralKind,
+    ) -> Result<ast::Literal> {
+        use std::char;
+        use std::u32;
+
+        let mut scratch = self.parser().scratch.borrow_mut();
+        scratch.clear();
+
+        let brace_pos = self.pos();
+        let start = self.span_char().end;
+        while self.bump_and_bump_space() && self.char() != '}' {
+            if !is_hex(self.char()) {
+                return Err(self.error(
+                    self.span_char(),
+                    ast::ErrorKind::EscapeHexInvalidDigit,
+                ));
+            }
+            scratch.push(self.char());
+        }
+        if self.is_eof() {
+            return Err(self.error(
+                Span::new(brace_pos, self.pos()),
+                ast::ErrorKind::EscapeUnexpectedEof,
+            ));
+        }
+        let end = self.pos();
+        let hex = scratch.as_str();
+        assert_eq!(self.char(), '}');
+        self.bump_and_bump_space();
+
+        if hex.is_empty() {
+            return Err(self.error(
+                Span::new(brace_pos, self.pos()),
+                ast::ErrorKind::EscapeHexEmpty,
+            ));
+        }
+        match u32::from_str_radix(hex, 16).ok().and_then(char::from_u32) {
+            None => Err(self.error(
+                Span::new(start, end),
+                ast::ErrorKind::EscapeHexInvalid,
+            )),
+            Some(c) => Ok(ast::Literal {
+                span: Span::new(start, self.pos()),
+                kind: ast::LiteralKind::HexBrace(kind),
+                c: c,
+            }),
+        }
+    }
+
+    /// Parse a decimal number into a u32 while trimming leading and trailing
+    /// whitespace.
+    ///
+    /// This expects the parser to be positioned at the first position where
+    /// a decimal digit could occur. This will advance the parser to the byte
+    /// immediately following the last contiguous decimal digit.
+    ///
+    /// If no decimal digit could be found or if there was a problem parsing
+    /// the complete set of digits into a u32, then an error is returned.
+    fn parse_decimal(&self) -> Result<u32> {
+        let mut scratch = self.parser().scratch.borrow_mut();
+        scratch.clear();
+
+        while !self.is_eof() && self.char().is_whitespace() {
+            self.bump();
+        }
+        let start = self.pos();
+        while !self.is_eof() && '0' <= self.char() && self.char() <= '9' {
+            scratch.push(self.char());
+            self.bump_and_bump_space();
+        }
+        let span = Span::new(start, self.pos());
+        while !self.is_eof() && self.char().is_whitespace() {
+            self.bump_and_bump_space();
+        }
+        let digits = scratch.as_str();
+        if digits.is_empty() {
+            return Err(self.error(span, ast::ErrorKind::DecimalEmpty));
+        }
+        match u32::from_str_radix(digits, 10).ok() {
+            Some(n) => Ok(n),
+            None => Err(self.error(span, ast::ErrorKind::DecimalInvalid)),
+        }
+    }
+
+    /// Parse a standard character class consisting primarily of characters or
+    /// character ranges, but can also contain nested character classes of
+    /// any type (sans `.`).
+    ///
+    /// This assumes the parser is positioned at the opening `[`. If parsing
+    /// is successful, then the parser is advanced to the position immediately
+    /// following the closing `]`.
+    fn parse_set_class(&self) -> Result<ast::Class> {
+        assert_eq!(self.char(), '[');
+
+        let mut union = ast::ClassSetUnion {
+            span: self.span(),
+            items: vec![],
+        };
+        loop {
+            self.bump_space();
+            if self.is_eof() {
+                return Err(self.unclosed_class_error());
+            }
+            match self.char() {
+                '[' => {
+                    // If we've already parsed the opening bracket, then
+                    // attempt to treat this as the beginning of an ASCII
+                    // class. If ASCII class parsing fails, then the parser
+                    // backs up to `[`.
+                    if !self.parser().stack_class.borrow().is_empty() {
+                        if let Some(cls) = self.maybe_parse_ascii_class() {
+                            union.push(ast::ClassSetItem::Ascii(cls));
+                            continue;
+                        }
+                    }
+                    union = self.push_class_open(union)?;
+                }
+                ']' => {
+                    match self.pop_class(union)? {
+                        Either::Left(nested_union) => { union = nested_union; }
+                        Either::Right(class) => return Ok(class),
+                    }
+                }
+                '&' if self.peek() == Some('&') => {
+                    assert!(self.bump_if("&&"));
+                    union = self.push_class_op(
+                        ast::ClassSetBinaryOpKind::Intersection, union);
+                }
+                '-' if self.peek() == Some('-') => {
+                    assert!(self.bump_if("--"));
+                    union = self.push_class_op(
+                        ast::ClassSetBinaryOpKind::Difference, union);
+                }
+                '~' if self.peek() == Some('~') => {
+                    assert!(self.bump_if("~~"));
+                    union = self.push_class_op(
+                        ast::ClassSetBinaryOpKind::SymmetricDifference, union);
+                }
+                _ => {
+                    union.push(self.parse_set_class_range()?);
+                }
+            }
+        }
+    }
+
+    /// Parse a single primitive item in a character class set. The item to
+    /// be parsed can either be one of a simple literal character, a range
+    /// between two simple literal characters or a "primitive" character
+    /// class like \w or \p{Greek}.
+    ///
+    /// If an invalid escape is found, or if a character class is found where
+    /// a simple literal is expected (e.g., in a range), then an error is
+    /// returned.
+    fn parse_set_class_range(&self) -> Result<ast::ClassSetItem> {
+        let prim1 = self.parse_set_class_item()?;
+        self.bump_space();
+        if self.is_eof() {
+            return Err(self.unclosed_class_error());
+        }
+        // If the next char isn't a `-`, then we don't have a range.
+        // There are two exceptions. If the char after a `-` is a `]`, then
+        // `-` is interpreted as a literal `-`. Alternatively, if the char
+        // after a `-` is a `-`, then `--` corresponds to a "difference"
+        // operation.
+        if self.char() != '-'
+            || self.peek_space() == Some(']')
+            || self.peek_space() == Some('-')
+        {
+            return prim1.into_class_set_item(self);
+        }
+        // OK, now we're parsing a range, so bump past the `-` and parse the
+        // second half of the range.
+        if !self.bump_and_bump_space() {
+            return Err(self.unclosed_class_error());
+        }
+        let prim2 = self.parse_set_class_item()?;
+        let range = ast::ClassSetRange {
+            span: Span::new(prim1.span().start, prim2.span().end),
+            start: prim1.into_class_literal(self)?,
+            end: prim2.into_class_literal(self)?,
+        };
+        if !range.is_valid() {
+            return Err(self.error(
+                range.span,
+                ast::ErrorKind::ClassRangeInvalid,
+            ));
+        }
+        Ok(ast::ClassSetItem::Range(range))
+    }
+
+    /// Parse a single item in a character class as a primitive, where the
+    /// primitive either consists of a verbatim literal or a single escape
+    /// sequence.
+    ///
+    /// This assumes the parser is positioned at the beginning of a primitive,
+    /// and advances the parser to the first position after the primitive if
+    /// successful.
+    ///
+    /// Note that it is the caller's responsibility to report an error if an
+    /// illegal primitive was parsed.
+    fn parse_set_class_item(&self) -> Result<Primitive> {
+        if self.char() == '\\' {
+            self.parse_escape()
+        } else {
+            let x = Primitive::Literal(ast::Literal {
+                span: self.span_char(),
+                kind: ast::LiteralKind::Verbatim,
+                c: self.char(),
+            });
+            self.bump();
+            Ok(x)
+        }
+    }
+
+    /// Parses the opening of a character class set. This includes the opening
+    /// bracket along with `^` if present to indicate negation. This also
+    /// starts parsing the opening set of unioned items if applicable, since
+    /// there are special rules applied to certain characters in the opening
+    /// of a character class. For example, `[^]]` is the class of all
+    /// characters not equal to `]`. (`]` would need to be escaped in any other
+    /// position.) Similarly for `-`.
+    ///
+    /// In all cases, the op inside the returned `ast::ClassBracketed` is an
+    /// empty union. This empty union should be replaced with the actual item
+    /// when it is popped from the parser's stack.
+    ///
+    /// This assumes the parser is positioned at the opening `[` and advances
+    /// the parser to the first non-special byte of the character class.
+    ///
+    /// An error is returned if EOF is found.
+    fn parse_set_class_open(
+        &self,
+    ) -> Result<(ast::ClassBracketed, ast::ClassSetUnion)> {
+        assert_eq!(self.char(), '[');
+        let start = self.pos();
+        if !self.bump_and_bump_space() {
+            return Err(self.error(
+                Span::new(start, self.pos()),
+                ast::ErrorKind::ClassUnclosed,
+            ));
+        }
+
+        let negated =
+            if self.char() != '^' {
+                false
+            } else {
+                if !self.bump_and_bump_space() {
+                    return Err(self.error(
+                        Span::new(start, self.pos()),
+                        ast::ErrorKind::ClassUnclosed,
+                    ));
+                }
+                true
+            };
+        // Accept any number of `-` as literal `-`.
+        let mut union = ast::ClassSetUnion {
+            span: self.span(),
+            items: vec![],
+        };
+        while self.char() == '-' {
+            union.push(ast::ClassSetItem::Literal(ast::Literal {
+                span: self.span_char(),
+                kind: ast::LiteralKind::Verbatim,
+                c: '-',
+            }));
+            if !self.bump_and_bump_space() {
+                return Err(self.error(
+                    Span::new(start, self.pos()),
+                    ast::ErrorKind::ClassUnclosed,
+                ));
+            }
+        }
+        // If `]` is the *first* char in a set, then interpret it as a literal
+        // `]`. That is, an empty class is impossible to write.
+        if union.items.is_empty() && self.char() == ']' {
+            union.push(ast::ClassSetItem::Literal(ast::Literal {
+                span: self.span_char(),
+                kind: ast::LiteralKind::Verbatim,
+                c: ']',
+            }));
+            if !self.bump_and_bump_space() {
+                return Err(self.error(
+                    Span::new(start, self.pos()),
+                    ast::ErrorKind::ClassUnclosed,
+                ));
+            }
+        }
+        let set = ast::ClassBracketed {
+            span: Span::new(start, self.pos()),
+            negated: negated,
+            kind: ast::ClassSet::union(ast::ClassSetUnion {
+                span: Span::new(union.span.start, union.span.start),
+                items: vec![],
+            }),
+        };
+        Ok((set, union))
+    }
+
+    /// Attempt to parse an ASCII character class, e.g., `[:alnum:]`.
+    ///
+    /// This assumes the parser is positioned at the opening `[`.
+    ///
+    /// If no valid ASCII character class could be found, then this does not
+    /// advance the parser and `None` is returned. Otherwise, the parser is
+    /// advanced to the first byte following the closing `]` and the
+    /// corresponding ASCII class is returned.
+    fn maybe_parse_ascii_class(&self) -> Option<ast::ClassAscii> {
+        // ASCII character classes are interesting from a parsing perspective
+        // because parsing cannot fail with any interesting error. For example,
+        // in order to use an ASCII character class, it must be enclosed in
+        // double brackets, e.g., `[[:alnum:]]`. Alternatively, you might think
+        // of it as "ASCII character characters have the syntax `[:NAME:]`
+        // which can only appear within character brackets." This means that
+        // things like `[[:lower:]A]` are legal constructs.
+        //
+        // However, if one types an incorrect ASCII character class, e.g.,
+        // `[[:loower:]]`, then we treat that as a normal nested character
+        // class containing the characters `:elorw`. One might argue that we
+        // should return an error instead since the repeated colons give away
+        // the intent to write an ASCII class. But what if the user typed
+        // `[[:lower]]` instead? How can we tell that was intended to be an
+        // ASCII class and not just a normal nested class?
+        //
+        // Reasonable people can probably disagree over this, but for better
+        // or worse, we implement semantics that never fails at the expense
+        // of better failure modes.
+        assert_eq!(self.char(), '[');
+        // If parsing fails, then we back up the parser to this starting point.
+        let start = self.pos();
+        let mut negated = false;
+        if !self.bump() || self.char() != ':' {
+            self.parser().pos.set(start);
+            return None;
+        }
+        if !self.bump() {
+            self.parser().pos.set(start);
+            return None;
+        }
+        if self.char() == '^' {
+            negated = true;
+            if !self.bump() {
+                self.parser().pos.set(start);
+                return None;
+            }
+        }
+        let name_start = self.offset();
+        while self.char() != ':' && self.bump() {}
+        if self.is_eof() {
+            self.parser().pos.set(start);
+            return None;
+        }
+        let name = &self.pattern()[name_start..self.offset()];
+        if !self.bump_if(":]") {
+            self.parser().pos.set(start);
+            return None;
+        }
+        let kind = match ast::ClassAsciiKind::from_name(name) {
+            Some(kind) => kind,
+            None => {
+                self.parser().pos.set(start);
+                return None;
+            }
+        };
+        Some(ast::ClassAscii {
+            span: Span::new(start, self.pos()),
+            kind: kind,
+            negated: negated,
+        })
+    }
+
+    /// Parse a Unicode class in either the single character notation, `\pN`
+    /// or the multi-character bracketed notation, `\p{Greek}`. This assumes
+    /// the parser is positioned at the `p` (or `P` for negation) and will
+    /// advance the parser to the character immediately following the class.
+    ///
+    /// Note that this does not check whether the class name is valid or not.
+    fn parse_unicode_class(&self) -> Result<ast::ClassUnicode> {
+        assert!(self.char() == 'p' || self.char() == 'P');
+
+        let mut scratch = self.parser().scratch.borrow_mut();
+        scratch.clear();
+
+        let negated = self.char() == 'P';
+        if !self.bump_and_bump_space() {
+            return Err(self.error(
+                self.span(),
+                ast::ErrorKind::EscapeUnexpectedEof,
+            ));
+        }
+        let (start, kind) =
+            if self.char() == '{' {
+                let start = self.span_char().end;
+                while self.bump_and_bump_space() && self.char() != '}' {
+                    scratch.push(self.char());
+                }
+                if self.is_eof() {
+                    return Err(self.error(
+                        self.span(),
+                        ast::ErrorKind::EscapeUnexpectedEof,
+                    ));
+                }
+                assert_eq!(self.char(), '}');
+                self.bump();
+
+                let name = scratch.as_str();
+                if let Some(i) = name.find("!=") {
+                    (start, ast::ClassUnicodeKind::NamedValue {
+                        op: ast::ClassUnicodeOpKind::NotEqual,
+                        name: name[..i].to_string(),
+                        value: name[i+2..].to_string(),
+                    })
+                } else if let Some(i) = name.find(':') {
+                    (start, ast::ClassUnicodeKind::NamedValue {
+                        op: ast::ClassUnicodeOpKind::Colon,
+                        name: name[..i].to_string(),
+                        value: name[i+1..].to_string(),
+                    })
+                } else if let Some(i) = name.find('=') {
+                    (start, ast::ClassUnicodeKind::NamedValue {
+                        op: ast::ClassUnicodeOpKind::Equal,
+                        name: name[..i].to_string(),
+                        value: name[i+1..].to_string(),
+                    })
+                } else {
+                    (start, ast::ClassUnicodeKind::Named(name.to_string()))
+                }
+            } else {
+                let start = self.pos();
+                let c = self.char();
+                self.bump_and_bump_space();
+                let kind = ast::ClassUnicodeKind::OneLetter(c);
+                (start, kind)
+            };
+        Ok(ast::ClassUnicode {
+            span: Span::new(start, self.pos()),
+            negated: negated,
+            kind: kind,
+        })
+    }
+
+    /// Parse a Perl character class, e.g., `\d` or `\W`. This assumes the
+    /// parser is currently at a valid character class name and will be
+    /// advanced to the character immediately following the class.
+    fn parse_perl_class(&self) -> ast::ClassPerl {
+        let c = self.char();
+        let span = self.span_char();
+        self.bump();
+        let (negated, kind) = match c {
+            'd' => (false, ast::ClassPerlKind::Digit),
+            'D' => (true, ast::ClassPerlKind::Digit),
+            's' => (false, ast::ClassPerlKind::Space),
+            'S' => (true, ast::ClassPerlKind::Space),
+            'w' => (false, ast::ClassPerlKind::Word),
+            'W' => (true, ast::ClassPerlKind::Word),
+            c => panic!("expected valid Perl class but got '{}'", c),
+        };
+        ast::ClassPerl { span: span, kind: kind, negated: negated }
+    }
+}
+
+/// A type that traverses a fully parsed Ast and checks whether its depth
+/// exceeds the specified nesting limit. If it does, then an error is returned.
+#[derive(Debug)]
+struct NestLimiter<'p, 's: 'p, P: 'p + 's> {
+    /// The parser that is checking the nest limit.
+    p: &'p ParserI<'s, P>,
+    /// The current depth while walking an Ast.
+    depth: u32,
+}
+
+impl<'p, 's, P: Borrow<Parser>> NestLimiter<'p, 's, P> {
+    fn new(p: &'p ParserI<'s, P>) -> NestLimiter<'p, 's, P> {
+        NestLimiter { p: p, depth: 0 }
+    }
+
+    fn check(self, ast: &Ast) -> Result<()> {
+        ast::visit(ast, self)
+    }
+
+    fn increment_depth(&mut self, span: &Span) -> Result<()> {
+        let new = self.depth.checked_add(1).ok_or_else(|| self.p.error(
+            span.clone(),
+            ast::ErrorKind::NestLimitExceeded(::std::u32::MAX),
+        ))?;
+        let limit = self.p.parser().nest_limit;
+        if new > limit {
+            return Err(self.p.error(
+                span.clone(),
+                ast::ErrorKind::NestLimitExceeded(limit),
+            ));
+        }
+        self.depth = new;
+        Ok(())
+    }
+
+    fn decrement_depth(&mut self) {
+        // Assuming the correctness of the visitor, this should never drop
+        // below 0.
+        self.depth = self.depth.checked_sub(1).unwrap();
+    }
+}
+
+impl<'p, 's, P: Borrow<Parser>> ast::Visitor for NestLimiter<'p, 's, P> {
+    type Output = ();
+    type Err = ast::Error;
+
+    fn finish(self) -> Result<()> {
+        Ok(())
+    }
+
+    fn visit_pre(&mut self, ast: &Ast) -> Result<()> {
+        let span = match *ast {
+            Ast::Empty(_)
+            | Ast::Flags(_)
+            | Ast::Literal(_)
+            | Ast::Dot(_)
+            | Ast::Assertion(_)
+            | Ast::Class(ast::Class::Unicode(_))
+            | Ast::Class(ast::Class::Perl(_)) => {
+                // These are all base cases, so we don't increment depth.
+                return Ok(());
+            }
+            Ast::Class(ast::Class::Bracketed(ref x)) => &x.span,
+            Ast::Repetition(ref x) => &x.span,
+            Ast::Group(ref x) => &x.span,
+            Ast::Alternation(ref x) => &x.span,
+            Ast::Concat(ref x) => &x.span,
+        };
+        self.increment_depth(span)
+    }
+
+    fn visit_post(&mut self, ast: &Ast) -> Result<()> {
+        match *ast {
+            Ast::Empty(_)
+            | Ast::Flags(_)
+            | Ast::Literal(_)
+            | Ast::Dot(_)
+            | Ast::Assertion(_)
+            | Ast::Class(ast::Class::Unicode(_))
+            | Ast::Class(ast::Class::Perl(_)) => {
+                // These are all base cases, so we don't decrement depth.
+                Ok(())
+            }
+            Ast::Class(ast::Class::Bracketed(_))
+            | Ast::Repetition(_)
+            | Ast::Group(_)
+            | Ast::Alternation(_)
+            | Ast::Concat(_) => {
+                self.decrement_depth();
+                Ok(())
+            }
+        }
+    }
+
+    fn visit_class_set_item_pre(
+        &mut self,
+        ast: &ast::ClassSetItem,
+    ) -> Result<()> {
+        let span = match *ast {
+            ast::ClassSetItem::Empty(_)
+            | ast::ClassSetItem::Literal(_)
+            | ast::ClassSetItem::Range(_)
+            | ast::ClassSetItem::Ascii(_)
+            | ast::ClassSetItem::Unicode(_)
+            | ast::ClassSetItem::Perl(_) => {
+                // These are all base cases, so we don't increment depth.
+                return Ok(());
+            }
+            ast::ClassSetItem::Bracketed(ref x) => &x.span,
+            ast::ClassSetItem::Union(ref x) => &x.span,
+        };
+        self.increment_depth(span)
+    }
+
+    fn visit_class_set_item_post(
+        &mut self,
+        ast: &ast::ClassSetItem,
+    ) -> Result<()> {
+        match *ast {
+            ast::ClassSetItem::Empty(_)
+            | ast::ClassSetItem::Literal(_)
+            | ast::ClassSetItem::Range(_)
+            | ast::ClassSetItem::Ascii(_)
+            | ast::ClassSetItem::Unicode(_)
+            | ast::ClassSetItem::Perl(_) => {
+                // These are all base cases, so we don't decrement depth.
+                Ok(())
+            }
+            ast::ClassSetItem::Bracketed(_)
+            | ast::ClassSetItem::Union(_) => {
+                self.decrement_depth();
+                Ok(())
+            }
+        }
+    }
+
+    fn visit_class_set_binary_op_pre(
+        &mut self,
+        ast: &ast::ClassSetBinaryOp,
+    ) -> Result<()> {
+        self.increment_depth(&ast.span)
+    }
+
+    fn visit_class_set_binary_op_post(
+        &mut self,
+        _ast: &ast::ClassSetBinaryOp,
+    ) -> Result<()> {
+        self.decrement_depth();
+        Ok(())
+    }
+}
+
+/// When the result is an error, transforms the ast::ErrorKind from the source
+/// Result into another one. This function is used to return clearer error
+/// messages when possible.
+fn specialize_err<T>(
+    result: Result<T>,
+    from: ast::ErrorKind,
+    to: ast::ErrorKind,
+) -> Result<T> {
+    if let Err(e) = result {
+        if e.kind == from {
+            Err(ast::Error {
+                kind: to,
+                pattern: e.pattern,
+                span: e.span,
+            })
+        } else {
+            Err(e)
+        }
+    } else {
+        result
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::ops::Range;
+
+    use ast::{self, Ast, Position, Span};
+    use super::{Parser, ParserI, ParserBuilder, Primitive};
+
+    // Our own assert_eq, which has slightly better formatting (but honestly
+    // still kind of crappy).
+    macro_rules! assert_eq {
+        ($left:expr, $right:expr) => ({
+            match (&$left, &$right) {
+                (left_val, right_val) => {
+                    if !(*left_val == *right_val) {
+                        panic!("assertion failed: `(left == right)`\n\n\
+                               left:  `{:?}`\nright: `{:?}`\n\n",
+                               left_val, right_val)
+                    }
+                }
+            }
+        });
+    }
+
+    // We create these errors to compare with real ast::Errors in the tests.
+    // We define equality between TestError and ast::Error to disregard the
+    // pattern string in ast::Error, which is annoying to provide in tests.
+    #[derive(Clone, Debug)]
+    struct TestError {
+        span: Span,
+        kind: ast::ErrorKind,
+    }
+
+    impl PartialEq<ast::Error> for TestError {
+        fn eq(&self, other: &ast::Error) -> bool {
+            self.span == other.span && self.kind == other.kind
+        }
+    }
+
+    impl PartialEq<TestError> for ast::Error {
+        fn eq(&self, other: &TestError) -> bool {
+            self.span == other.span && self.kind == other.kind
+        }
+    }
+
+    fn s(str: &str) -> String {
+        str.to_string()
+    }
+
+    fn parser(pattern: &str) -> ParserI<Parser> {
+        ParserI::new(Parser::new(), pattern)
+    }
+
+    fn parser_octal(pattern: &str) -> ParserI<Parser> {
+        let parser = ParserBuilder::new().octal(true).build();
+        ParserI::new(parser, pattern)
+    }
+
+    fn parser_nest_limit(pattern: &str, nest_limit: u32) -> ParserI<Parser> {
+        let p = ParserBuilder::new().nest_limit(nest_limit).build();
+        ParserI::new(p, pattern)
+    }
+
+    fn parser_ignore_whitespace(pattern: &str) -> ParserI<Parser> {
+        let p = ParserBuilder::new().ignore_whitespace(true).build();
+        ParserI::new(p, pattern)
+    }
+
+    /// Short alias for creating a new span.
+    fn nspan(start: Position, end: Position) -> Span {
+        Span::new(start, end)
+    }
+
+    /// Short alias for creating a new position.
+    fn npos(offset: usize, line: usize, column: usize) -> Position {
+        Position::new(offset, line, column)
+    }
+
+    /// Create a new span from the given offset range. This assumes a single
+    /// line and sets the columns based on the offsets. i.e., This only works
+    /// out of the box for ASCII, which is fine for most tests.
+    fn span(range: Range<usize>) -> Span {
+        let start = Position::new(range.start, 1, range.start + 1);
+        let end = Position::new(range.end, 1, range.end + 1);
+        Span::new(start, end)
+    }
+
+    /// Create a new span for the corresponding byte range in the given string.
+    fn span_range(subject: &str, range: Range<usize>) -> Span {
+        let start = Position {
+            offset: range.start,
+            line: 1 + subject[..range.start].matches('\n').count(),
+            column: 1 + subject[..range.start]
+                .chars()
+                .rev()
+                .position(|c| c == '\n')
+                .unwrap_or(subject[..range.start].chars().count()),
+        };
+        let end = Position {
+            offset: range.end,
+            line: 1 + subject[..range.end].matches('\n').count(),
+            column: 1 + subject[..range.end]
+                .chars()
+                .rev()
+                .position(|c| c == '\n')
+                .unwrap_or(subject[..range.end].chars().count()),
+        };
+        Span::new(start, end)
+    }
+
+    /// Create a verbatim literal starting at the given position.
+    fn lit(c: char, start: usize) -> Ast {
+        lit_with(c, span(start..start + c.len_utf8()))
+    }
+
+    /// Create a punctuation literal starting at the given position.
+    fn punct_lit(c: char, span: Span) -> Ast {
+        Ast::Literal(ast::Literal {
+            span: span,
+            kind: ast::LiteralKind::Punctuation,
+            c: c,
+        })
+    }
+
+    /// Create a verbatim literal with the given span.
+    fn lit_with(c: char, span: Span) -> Ast {
+        Ast::Literal(ast::Literal {
+            span: span,
+            kind: ast::LiteralKind::Verbatim,
+            c: c,
+        })
+    }
+
+    /// Create a concatenation with the given range.
+    fn concat(range: Range<usize>, asts: Vec<Ast>) -> Ast {
+        concat_with(span(range), asts)
+    }
+
+    /// Create a concatenation with the given span.
+    fn concat_with(span: Span, asts: Vec<Ast>) -> Ast {
+        Ast::Concat(ast::Concat { span: span, asts: asts })
+    }
+
+    /// Create an alternation with the given span.
+    fn alt(range: Range<usize>, asts: Vec<Ast>) -> Ast {
+        Ast::Alternation(ast::Alternation { span: span(range), asts: asts })
+    }
+
+    /// Create a capturing group with the given span.
+    fn group(range: Range<usize>, index: u32, ast: Ast) -> Ast {
+        Ast::Group(ast::Group {
+            span: span(range),
+            kind: ast::GroupKind::CaptureIndex(index),
+            ast: Box::new(ast),
+        })
+    }
+
+    /// Create an ast::SetFlags.
+    ///
+    /// The given pattern should be the full pattern string. The range given
+    /// should correspond to the byte offsets where the flag set occurs.
+    ///
+    /// If negated is true, then the set is interpreted as beginning with a
+    /// negation.
+    fn flag_set(
+        pat: &str,
+        range: Range<usize>,
+        flag: ast::Flag,
+        negated: bool,
+    ) -> Ast {
+        let mut items = vec![
+            ast::FlagsItem {
+                span: span_range(pat, (range.end - 2)..(range.end - 1)),
+                kind: ast::FlagsItemKind::Flag(flag),
+            },
+        ];
+        if negated {
+            items.insert(0, ast::FlagsItem {
+                span: span_range(pat, (range.start + 2)..(range.end - 2)),
+                kind: ast::FlagsItemKind::Negation,
+            });
+        }
+        Ast::Flags(ast::SetFlags {
+            span: span_range(pat, range.clone()),
+            flags: ast::Flags {
+                span: span_range(pat, (range.start + 2)..(range.end - 1)),
+                items: items,
+            },
+        })
+    }
+
+    #[test]
+    fn parse_nest_limit() {
+        // A nest limit of 0 still allows some types of regexes.
+        assert_eq!(
+            parser_nest_limit("", 0).parse(),
+            Ok(Ast::Empty(span(0..0))));
+        assert_eq!(
+            parser_nest_limit("a", 0).parse(),
+            Ok(lit('a', 0)));
+
+        // Test repetition operations, which require one level of nesting.
+        assert_eq!(
+            parser_nest_limit("a+", 0).parse().unwrap_err(),
+            TestError {
+                span: span(0..2),
+                kind: ast::ErrorKind::NestLimitExceeded(0),
+            });
+        assert_eq!(
+            parser_nest_limit("a+", 1).parse(),
+            Ok(Ast::Repetition(ast::Repetition {
+                span: span(0..2),
+                op: ast::RepetitionOp {
+                    span: span(1..2),
+                    kind: ast::RepetitionKind::OneOrMore,
+                },
+                greedy: true,
+                ast: Box::new(lit('a', 0)),
+            })));
+        assert_eq!(
+            parser_nest_limit("(a)+", 1).parse().unwrap_err(),
+            TestError {
+                span: span(0..3),
+                kind: ast::ErrorKind::NestLimitExceeded(1),
+            });
+        assert_eq!(
+            parser_nest_limit("a+*", 1).parse().unwrap_err(),
+            TestError {
+                span: span(0..2),
+                kind: ast::ErrorKind::NestLimitExceeded(1),
+            });
+        assert_eq!(
+            parser_nest_limit("a+*", 2).parse(),
+            Ok(Ast::Repetition(ast::Repetition {
+                span: span(0..3),
+                op: ast::RepetitionOp {
+                    span: span(2..3),
+                    kind: ast::RepetitionKind::ZeroOrMore,
+                },
+                greedy: true,
+                ast: Box::new(Ast::Repetition(ast::Repetition {
+                    span: span(0..2),
+                    op: ast::RepetitionOp {
+                        span: span(1..2),
+                        kind: ast::RepetitionKind::OneOrMore,
+                    },
+                    greedy: true,
+                    ast: Box::new(lit('a', 0)),
+                })),
+            })));
+
+        // Test concatenations. A concatenation requires one level of nesting.
+        assert_eq!(
+            parser_nest_limit("ab", 0).parse().unwrap_err(),
+            TestError {
+                span: span(0..2),
+                kind: ast::ErrorKind::NestLimitExceeded(0),
+            });
+        assert_eq!(
+            parser_nest_limit("ab", 1).parse(),
+            Ok(concat(0..2, vec![lit('a', 0), lit('b', 1)])));
+        assert_eq!(
+            parser_nest_limit("abc", 1).parse(),
+            Ok(concat(0..3, vec![lit('a', 0), lit('b', 1), lit('c', 2)])));
+
+        // Test alternations. An alternation requires one level of nesting.
+        assert_eq!(
+            parser_nest_limit("a|b", 0).parse().unwrap_err(),
+            TestError {
+                span: span(0..3),
+                kind: ast::ErrorKind::NestLimitExceeded(0),
+            });
+        assert_eq!(
+            parser_nest_limit("a|b", 1).parse(),
+            Ok(alt(0..3, vec![lit('a', 0), lit('b', 2)])));
+        assert_eq!(
+            parser_nest_limit("a|b|c", 1).parse(),
+            Ok(alt(0..5, vec![lit('a', 0), lit('b', 2), lit('c', 4)])));
+
+        // Test character classes. Classes form their own mini-recursive
+        // syntax!
+        assert_eq!(
+            parser_nest_limit("[a]", 0).parse().unwrap_err(),
+            TestError {
+                span: span(0..3),
+                kind: ast::ErrorKind::NestLimitExceeded(0),
+            });
+        assert_eq!(
+            parser_nest_limit("[a]", 1).parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..3),
+                negated: false,
+                kind: ast::ClassSet::Item(
+                    ast::ClassSetItem::Literal(ast::Literal {
+                        span: span(1..2),
+                        kind: ast::LiteralKind::Verbatim,
+                        c: 'a',
+                    })
+                ),
+            }))));
+        assert_eq!(
+            parser_nest_limit("[ab]", 1).parse().unwrap_err(),
+            TestError {
+                span: span(1..3),
+                kind: ast::ErrorKind::NestLimitExceeded(1),
+            });
+        assert_eq!(
+            parser_nest_limit("[ab[cd]]", 2).parse().unwrap_err(),
+            TestError {
+                span: span(3..7),
+                kind: ast::ErrorKind::NestLimitExceeded(2),
+            });
+        assert_eq!(
+            parser_nest_limit("[ab[cd]]", 3).parse().unwrap_err(),
+            TestError {
+                span: span(4..6),
+                kind: ast::ErrorKind::NestLimitExceeded(3),
+            });
+        assert_eq!(
+            parser_nest_limit("[a--b]", 1).parse().unwrap_err(),
+            TestError {
+                span: span(1..5),
+                kind: ast::ErrorKind::NestLimitExceeded(1),
+            });
+        assert_eq!(
+            parser_nest_limit("[a--bc]", 2).parse().unwrap_err(),
+            TestError {
+                span: span(4..6),
+                kind: ast::ErrorKind::NestLimitExceeded(2),
+            });
+    }
+
+    #[test]
+    fn parse_comments() {
+        let pat = "(?x)
+# This is comment 1.
+foo # This is comment 2.
+  # This is comment 3.
+bar
+# This is comment 4.";
+        let astc = parser(pat).parse_with_comments().unwrap();
+        assert_eq!(
+            astc.ast,
+            concat_with(span_range(pat, 0..pat.len()), vec![
+                flag_set(pat, 0..4, ast::Flag::IgnoreWhitespace, false),
+                lit_with('f', span_range(pat, 26..27)),
+                lit_with('o', span_range(pat, 27..28)),
+                lit_with('o', span_range(pat, 28..29)),
+                lit_with('b', span_range(pat, 74..75)),
+                lit_with('a', span_range(pat, 75..76)),
+                lit_with('r', span_range(pat, 76..77)),
+            ]));
+        assert_eq!(astc.comments, vec![
+            ast::Comment {
+                span: span_range(pat, 5..26),
+                comment: s(" This is comment 1."),
+            },
+            ast::Comment {
+                span: span_range(pat, 30..51),
+                comment: s(" This is comment 2."),
+            },
+            ast::Comment {
+                span: span_range(pat, 53..74),
+                comment: s(" This is comment 3."),
+            },
+            ast::Comment {
+                span: span_range(pat, 78..98),
+                comment: s(" This is comment 4."),
+            },
+        ]);
+    }
+
+    #[test]
+    fn parse_holistic() {
+        assert_eq!(
+            parser("]").parse(),
+            Ok(lit(']', 0)));
+        assert_eq!(
+            parser(r"\\\.\+\*\?\(\)\|\[\]\{\}\^\$\#\&\-\~").parse(),
+            Ok(concat(0..36, vec![
+                punct_lit('\\', span(0..2)),
+                punct_lit('.', span(2..4)),
+                punct_lit('+', span(4..6)),
+                punct_lit('*', span(6..8)),
+                punct_lit('?', span(8..10)),
+                punct_lit('(', span(10..12)),
+                punct_lit(')', span(12..14)),
+                punct_lit('|', span(14..16)),
+                punct_lit('[', span(16..18)),
+                punct_lit(']', span(18..20)),
+                punct_lit('{', span(20..22)),
+                punct_lit('}', span(22..24)),
+                punct_lit('^', span(24..26)),
+                punct_lit('$', span(26..28)),
+                punct_lit('#', span(28..30)),
+                punct_lit('&', span(30..32)),
+                punct_lit('-', span(32..34)),
+                punct_lit('~', span(34..36)),
+            ])));
+    }
+
+    #[test]
+    fn parse_ignore_whitespace() {
+        // Test that basic whitespace insensitivity works.
+        let pat = "(?x)a b";
+        assert_eq!(
+            parser(pat).parse(),
+            Ok(concat_with(nspan(npos(0, 1, 1), npos(7, 1, 8)), vec![
+                flag_set(pat, 0..4, ast::Flag::IgnoreWhitespace, false),
+                lit_with('a', nspan(npos(4, 1, 5), npos(5, 1, 6))),
+                lit_with('b', nspan(npos(6, 1, 7), npos(7, 1, 8))),
+            ])));
+
+        // Test that we can toggle whitespace insensitivity.
+        let pat = "(?x)a b(?-x)a b";
+        assert_eq!(
+            parser(pat).parse(),
+            Ok(concat_with(nspan(npos(0, 1, 1), npos(15, 1, 16)), vec![
+                flag_set(pat, 0..4, ast::Flag::IgnoreWhitespace, false),
+                lit_with('a', nspan(npos(4, 1, 5), npos(5, 1, 6))),
+                lit_with('b', nspan(npos(6, 1, 7), npos(7, 1, 8))),
+                flag_set(pat, 7..12, ast::Flag::IgnoreWhitespace, true),
+                lit_with('a', nspan(npos(12, 1, 13), npos(13, 1, 14))),
+                lit_with(' ', nspan(npos(13, 1, 14), npos(14, 1, 15))),
+                lit_with('b', nspan(npos(14, 1, 15), npos(15, 1, 16))),
+            ])));
+
+        // Test that nesting whitespace insensitive flags works.
+        let pat = "a (?x:a )a ";
+        assert_eq!(
+            parser(pat).parse(),
+            Ok(concat_with(span_range(pat, 0..11), vec![
+                lit_with('a', span_range(pat, 0..1)),
+                lit_with(' ', span_range(pat, 1..2)),
+                Ast::Group(ast::Group {
+                    span: span_range(pat, 2..9),
+                    kind: ast::GroupKind::NonCapturing(ast::Flags {
+                        span: span_range(pat, 4..5),
+                        items: vec![
+                            ast::FlagsItem {
+                                span: span_range(pat, 4..5),
+                                kind: ast::FlagsItemKind::Flag(
+                                    ast::Flag::IgnoreWhitespace),
+                            },
+                        ],
+                    }),
+                    ast: Box::new(lit_with('a', span_range(pat, 6..7))),
+                }),
+                lit_with('a', span_range(pat, 9..10)),
+                lit_with(' ', span_range(pat, 10..11)),
+            ])));
+
+        // Test that whitespace after an opening paren is insignificant.
+        let pat = "(?x)( ?P<foo> a )";
+        assert_eq!(
+            parser(pat).parse(),
+            Ok(concat_with(span_range(pat, 0..pat.len()), vec![
+                flag_set(pat, 0..4, ast::Flag::IgnoreWhitespace, false),
+                Ast::Group(ast::Group {
+                    span: span_range(pat, 4..pat.len()),
+                    kind: ast::GroupKind::CaptureName(ast::CaptureName {
+                        span: span_range(pat, 9..12),
+                        name: s("foo"),
+                        index: 1,
+                    }),
+                    ast: Box::new(lit_with('a', span_range(pat, 14..15))),
+                }),
+            ])));
+        let pat = "(?x)(  a )";
+        assert_eq!(
+            parser(pat).parse(),
+            Ok(concat_with(span_range(pat, 0..pat.len()), vec![
+                flag_set(pat, 0..4, ast::Flag::IgnoreWhitespace, false),
+                Ast::Group(ast::Group {
+                    span: span_range(pat, 4..pat.len()),
+                    kind: ast::GroupKind::CaptureIndex(1),
+                    ast: Box::new(lit_with('a', span_range(pat, 7..8))),
+                }),
+            ])));
+        let pat = "(?x)(  ?:  a )";
+        assert_eq!(
+            parser(pat).parse(),
+            Ok(concat_with(span_range(pat, 0..pat.len()), vec![
+                flag_set(pat, 0..4, ast::Flag::IgnoreWhitespace, false),
+                Ast::Group(ast::Group {
+                    span: span_range(pat, 4..pat.len()),
+                    kind: ast::GroupKind::NonCapturing(ast::Flags {
+                        span: span_range(pat, 8..8),
+                        items: vec![],
+                    }),
+                    ast: Box::new(lit_with('a', span_range(pat, 11..12))),
+                }),
+            ])));
+        let pat = r"(?x)\x { 53 }";
+        assert_eq!(
+            parser(pat).parse(),
+            Ok(concat_with(span_range(pat, 0..pat.len()), vec![
+                flag_set(pat, 0..4, ast::Flag::IgnoreWhitespace, false),
+                Ast::Literal(ast::Literal {
+                    span: span(4..13),
+                    kind: ast::LiteralKind::HexBrace(ast::HexLiteralKind::X),
+                    c: 'S',
+                }),
+            ])));
+
+        // Test that whitespace after an escape is OK.
+        let pat = r"(?x)\ ";
+        assert_eq!(
+            parser(pat).parse(),
+            Ok(concat_with(span_range(pat, 0..pat.len()), vec![
+                flag_set(pat, 0..4, ast::Flag::IgnoreWhitespace, false),
+                Ast::Literal(ast::Literal {
+                    span: span_range(pat, 4..6),
+                    kind: ast::LiteralKind::Special(
+                        ast::SpecialLiteralKind::Space),
+                    c: ' ',
+                }),
+            ])));
+        // ... but only when `x` mode is enabled.
+        let pat = r"\ ";
+        assert_eq!(
+            parser(pat).parse().unwrap_err(),
+            TestError {
+                span: span_range(pat, 0..2),
+                kind: ast::ErrorKind::EscapeUnrecognized,
+            });
+    }
+
+    #[test]
+    fn parse_newlines() {
+        let pat = ".\n.";
+        assert_eq!(
+            parser(pat).parse(),
+            Ok(concat_with(span_range(pat, 0..3), vec![
+                Ast::Dot(span_range(pat, 0..1)),
+                lit_with('\n', span_range(pat, 1..2)),
+                Ast::Dot(span_range(pat, 2..3)),
+            ])));
+
+        let pat = "foobar\nbaz\nquux\n";
+        assert_eq!(
+            parser(pat).parse(),
+            Ok(concat_with(span_range(pat, 0..pat.len()), vec![
+                lit_with('f', nspan(npos(0, 1, 1), npos(1, 1, 2))),
+                lit_with('o', nspan(npos(1, 1, 2), npos(2, 1, 3))),
+                lit_with('o', nspan(npos(2, 1, 3), npos(3, 1, 4))),
+                lit_with('b', nspan(npos(3, 1, 4), npos(4, 1, 5))),
+                lit_with('a', nspan(npos(4, 1, 5), npos(5, 1, 6))),
+                lit_with('r', nspan(npos(5, 1, 6), npos(6, 1, 7))),
+                lit_with('\n', nspan(npos(6, 1, 7), npos(7, 2, 1))),
+                lit_with('b', nspan(npos(7, 2, 1), npos(8, 2, 2))),
+                lit_with('a', nspan(npos(8, 2, 2), npos(9, 2, 3))),
+                lit_with('z', nspan(npos(9, 2, 3), npos(10, 2, 4))),
+                lit_with('\n', nspan(npos(10, 2, 4), npos(11, 3, 1))),
+                lit_with('q', nspan(npos(11, 3, 1), npos(12, 3, 2))),
+                lit_with('u', nspan(npos(12, 3, 2), npos(13, 3, 3))),
+                lit_with('u', nspan(npos(13, 3, 3), npos(14, 3, 4))),
+                lit_with('x', nspan(npos(14, 3, 4), npos(15, 3, 5))),
+                lit_with('\n', nspan(npos(15, 3, 5), npos(16, 4, 1))),
+            ])));
+    }
+
+    #[test]
+    fn parse_uncounted_repetition() {
+        assert_eq!(
+            parser(r"a*").parse(),
+            Ok(Ast::Repetition(ast::Repetition {
+                span: span(0..2),
+                op: ast::RepetitionOp {
+                    span: span(1..2),
+                    kind: ast::RepetitionKind::ZeroOrMore,
+                },
+                greedy: true,
+                ast: Box::new(lit('a', 0)),
+            })));
+        assert_eq!(
+            parser(r"a+").parse(),
+            Ok(Ast::Repetition(ast::Repetition {
+                span: span(0..2),
+                op: ast::RepetitionOp {
+                    span: span(1..2),
+                    kind: ast::RepetitionKind::OneOrMore,
+                },
+                greedy: true,
+                ast: Box::new(lit('a', 0)),
+            })));
+
+        assert_eq!(
+            parser(r"a?").parse(),
+            Ok(Ast::Repetition(ast::Repetition {
+                span: span(0..2),
+                op: ast::RepetitionOp {
+                    span: span(1..2),
+                    kind: ast::RepetitionKind::ZeroOrOne,
+                },
+                greedy: true,
+                ast: Box::new(lit('a', 0)),
+            })));
+        assert_eq!(
+            parser(r"a??").parse(),
+            Ok(Ast::Repetition(ast::Repetition {
+                span: span(0..3),
+                op: ast::RepetitionOp {
+                    span: span(1..3),
+                    kind: ast::RepetitionKind::ZeroOrOne,
+                },
+                greedy: false,
+                ast: Box::new(lit('a', 0)),
+            })));
+        assert_eq!(
+            parser(r"a?").parse(),
+            Ok(Ast::Repetition(ast::Repetition {
+                span: span(0..2),
+                op: ast::RepetitionOp {
+                    span: span(1..2),
+                    kind: ast::RepetitionKind::ZeroOrOne,
+                },
+                greedy: true,
+                ast: Box::new(lit('a', 0)),
+            })));
+        assert_eq!(
+            parser(r"a?b").parse(),
+            Ok(concat(0..3, vec![
+                Ast::Repetition(ast::Repetition {
+                    span: span(0..2),
+                    op: ast::RepetitionOp {
+                        span: span(1..2),
+                        kind: ast::RepetitionKind::ZeroOrOne,
+                    },
+                    greedy: true,
+                    ast: Box::new(lit('a', 0)),
+                }),
+                lit('b', 2),
+            ])));
+        assert_eq!(
+            parser(r"a??b").parse(),
+            Ok(concat(0..4, vec![
+                Ast::Repetition(ast::Repetition {
+                    span: span(0..3),
+                    op: ast::RepetitionOp {
+                        span: span(1..3),
+                        kind: ast::RepetitionKind::ZeroOrOne,
+                    },
+                    greedy: false,
+                    ast: Box::new(lit('a', 0)),
+                }),
+                lit('b', 3),
+            ])));
+        assert_eq!(
+            parser(r"ab?").parse(),
+            Ok(concat(0..3, vec![
+                lit('a', 0),
+                Ast::Repetition(ast::Repetition {
+                    span: span(1..3),
+                    op: ast::RepetitionOp {
+                        span: span(2..3),
+                        kind: ast::RepetitionKind::ZeroOrOne,
+                    },
+                    greedy: true,
+                    ast: Box::new(lit('b', 1)),
+                }),
+            ])));
+        assert_eq!(
+            parser(r"(ab)?").parse(),
+            Ok(Ast::Repetition(ast::Repetition {
+                span: span(0..5),
+                op: ast::RepetitionOp {
+                    span: span(4..5),
+                    kind: ast::RepetitionKind::ZeroOrOne,
+                },
+                greedy: true,
+                ast: Box::new(group(0..4, 1, concat(1..3, vec![
+                    lit('a', 1),
+                    lit('b', 2),
+                ]))),
+            })));
+        assert_eq!(
+            parser(r"|a?").parse(),
+            Ok(alt(0..3, vec![
+                Ast::Empty(span(0..0)),
+                Ast::Repetition(ast::Repetition {
+                    span: span(1..3),
+                    op: ast::RepetitionOp {
+                        span: span(2..3),
+                        kind: ast::RepetitionKind::ZeroOrOne,
+                    },
+                    greedy: true,
+                    ast: Box::new(lit('a', 1)),
+                }),
+            ])));
+
+        assert_eq!(
+            parser(r"*").parse().unwrap_err(),
+            TestError {
+                span: span(0..0),
+                kind: ast::ErrorKind::RepetitionMissing,
+            });
+        assert_eq!(
+            parser(r"(?i)*").parse().unwrap_err(),
+            TestError {
+                span: span(4..4),
+                kind: ast::ErrorKind::RepetitionMissing,
+            });
+        assert_eq!(
+            parser(r"(*)").parse().unwrap_err(),
+            TestError {
+                span: span(1..1),
+                kind: ast::ErrorKind::RepetitionMissing,
+            });
+        assert_eq!(
+            parser(r"(?:?)").parse().unwrap_err(),
+            TestError {
+                span: span(3..3),
+                kind: ast::ErrorKind::RepetitionMissing,
+            });
+        assert_eq!(
+            parser(r"+").parse().unwrap_err(),
+            TestError {
+                span: span(0..0),
+                kind: ast::ErrorKind::RepetitionMissing,
+            });
+        assert_eq!(
+            parser(r"?").parse().unwrap_err(),
+            TestError {
+                span: span(0..0),
+                kind: ast::ErrorKind::RepetitionMissing,
+            });
+        assert_eq!(
+            parser(r"(?)").parse().unwrap_err(),
+            TestError {
+                span: span(1..1),
+                kind: ast::ErrorKind::RepetitionMissing,
+            });
+        assert_eq!(
+            parser(r"|*").parse().unwrap_err(),
+            TestError {
+                span: span(1..1),
+                kind: ast::ErrorKind::RepetitionMissing,
+            });
+        assert_eq!(
+            parser(r"|+").parse().unwrap_err(),
+            TestError {
+                span: span(1..1),
+                kind: ast::ErrorKind::RepetitionMissing,
+            });
+        assert_eq!(
+            parser(r"|?").parse().unwrap_err(),
+            TestError {
+                span: span(1..1),
+                kind: ast::ErrorKind::RepetitionMissing,
+            });
+    }
+
+    #[test]
+    fn parse_counted_repetition() {
+        assert_eq!(
+            parser(r"a{5}").parse(),
+            Ok(Ast::Repetition(ast::Repetition {
+                span: span(0..4),
+                op: ast::RepetitionOp {
+                    span: span(1..4),
+                    kind: ast::RepetitionKind::Range(
+                        ast::RepetitionRange::Exactly(5)),
+                },
+                greedy: true,
+                ast: Box::new(lit('a', 0)),
+            })));
+        assert_eq!(
+            parser(r"a{5,}").parse(),
+            Ok(Ast::Repetition(ast::Repetition {
+                span: span(0..5),
+                op: ast::RepetitionOp {
+                    span: span(1..5),
+                    kind: ast::RepetitionKind::Range(
+                        ast::RepetitionRange::AtLeast(5)),
+                },
+                greedy: true,
+                ast: Box::new(lit('a', 0)),
+            })));
+        assert_eq!(
+            parser(r"a{5,9}").parse(),
+            Ok(Ast::Repetition(ast::Repetition {
+                span: span(0..6),
+                op: ast::RepetitionOp {
+                    span: span(1..6),
+                    kind: ast::RepetitionKind::Range(
+                        ast::RepetitionRange::Bounded(5, 9)),
+                },
+                greedy: true,
+                ast: Box::new(lit('a', 0)),
+            })));
+        assert_eq!(
+            parser(r"a{5}?").parse(),
+            Ok(Ast::Repetition(ast::Repetition {
+                span: span(0..5),
+                op: ast::RepetitionOp {
+                    span: span(1..5),
+                    kind: ast::RepetitionKind::Range(
+                        ast::RepetitionRange::Exactly(5)),
+                },
+                greedy: false,
+                ast: Box::new(lit('a', 0)),
+            })));
+        assert_eq!(
+            parser(r"ab{5}").parse(),
+            Ok(concat(0..5, vec![
+                lit('a', 0),
+                Ast::Repetition(ast::Repetition {
+                    span: span(1..5),
+                    op: ast::RepetitionOp {
+                        span: span(2..5),
+                        kind: ast::RepetitionKind::Range(
+                            ast::RepetitionRange::Exactly(5)),
+                    },
+                    greedy: true,
+                    ast: Box::new(lit('b', 1)),
+                }),
+            ])));
+        assert_eq!(
+            parser(r"ab{5}c").parse(),
+            Ok(concat(0..6, vec![
+                lit('a', 0),
+                Ast::Repetition(ast::Repetition {
+                    span: span(1..5),
+                    op: ast::RepetitionOp {
+                        span: span(2..5),
+                        kind: ast::RepetitionKind::Range(
+                            ast::RepetitionRange::Exactly(5)),
+                    },
+                    greedy: true,
+                    ast: Box::new(lit('b', 1)),
+                }),
+                lit('c', 5),
+            ])));
+
+        assert_eq!(
+            parser(r"a{ 5 }").parse(),
+            Ok(Ast::Repetition(ast::Repetition {
+                span: span(0..6),
+                op: ast::RepetitionOp {
+                    span: span(1..6),
+                    kind: ast::RepetitionKind::Range(
+                        ast::RepetitionRange::Exactly(5)),
+                },
+                greedy: true,
+                ast: Box::new(lit('a', 0)),
+            })));
+        assert_eq!(
+            parser(r"a{ 5 , 9 }").parse(),
+            Ok(Ast::Repetition(ast::Repetition {
+                span: span(0..10),
+                op: ast::RepetitionOp {
+                    span: span(1..10),
+                    kind: ast::RepetitionKind::Range(
+                        ast::RepetitionRange::Bounded(5, 9)),
+                },
+                greedy: true,
+                ast: Box::new(lit('a', 0)),
+            })));
+        assert_eq!(
+            parser_ignore_whitespace(r"a{5,9} ?").parse(),
+            Ok(Ast::Repetition(ast::Repetition {
+                span: span(0..8),
+                op: ast::RepetitionOp {
+                    span: span(1..8),
+                    kind: ast::RepetitionKind::Range(
+                        ast::RepetitionRange::Bounded(5, 9)),
+                },
+                greedy: false,
+                ast: Box::new(lit('a', 0)),
+            })));
+
+        assert_eq!(
+            parser(r"(?i){0}").parse().unwrap_err(),
+            TestError {
+                span: span(4..4),
+                kind: ast::ErrorKind::RepetitionMissing,
+            });
+        assert_eq!(
+            parser(r"(?m){1,1}").parse().unwrap_err(),
+            TestError {
+                span: span(4..4),
+                kind: ast::ErrorKind::RepetitionMissing,
+            });
+        assert_eq!(
+            parser(r"a{]}").parse().unwrap_err(),
+            TestError {
+                span: span(2..2),
+                kind: ast::ErrorKind::RepetitionCountDecimalEmpty,
+            });
+        assert_eq!(
+            parser(r"a{1,]}").parse().unwrap_err(),
+            TestError {
+                span: span(4..4),
+                kind: ast::ErrorKind::RepetitionCountDecimalEmpty,
+            });
+        assert_eq!(
+            parser(r"a{").parse().unwrap_err(),
+            TestError {
+                span: span(1..2),
+                kind: ast::ErrorKind::RepetitionCountUnclosed,
+            });
+        assert_eq!(
+            parser(r"a{}").parse().unwrap_err(),
+            TestError {
+                span: span(2..2),
+                kind: ast::ErrorKind::RepetitionCountDecimalEmpty,
+            });
+        assert_eq!(
+            parser(r"a{a").parse().unwrap_err(),
+            TestError {
+                span: span(2..2),
+                kind: ast::ErrorKind::RepetitionCountDecimalEmpty,
+            });
+        assert_eq!(
+            parser(r"a{9999999999}").parse().unwrap_err(),
+            TestError {
+                span: span(2..12),
+                kind: ast::ErrorKind::DecimalInvalid,
+            });
+        assert_eq!(
+            parser(r"a{9").parse().unwrap_err(),
+            TestError {
+                span: span(1..3),
+                kind: ast::ErrorKind::RepetitionCountUnclosed,
+            });
+        assert_eq!(
+            parser(r"a{9,a").parse().unwrap_err(),
+            TestError {
+                span: span(4..4),
+                kind: ast::ErrorKind::RepetitionCountDecimalEmpty,
+            });
+        assert_eq!(
+            parser(r"a{9,9999999999}").parse().unwrap_err(),
+            TestError {
+                span: span(4..14),
+                kind: ast::ErrorKind::DecimalInvalid,
+            });
+        assert_eq!(
+            parser(r"a{9,").parse().unwrap_err(),
+            TestError {
+                span: span(1..4),
+                kind: ast::ErrorKind::RepetitionCountUnclosed,
+            });
+        assert_eq!(
+            parser(r"a{9,11").parse().unwrap_err(),
+            TestError {
+                span: span(1..6),
+                kind: ast::ErrorKind::RepetitionCountUnclosed,
+            });
+        assert_eq!(
+            parser(r"a{2,1}").parse().unwrap_err(),
+            TestError {
+                span: span(1..6),
+                kind: ast::ErrorKind::RepetitionCountInvalid,
+            });
+        assert_eq!(
+            parser(r"{5}").parse().unwrap_err(),
+            TestError {
+                span: span(0..0),
+                kind: ast::ErrorKind::RepetitionMissing,
+            });
+        assert_eq!(
+            parser(r"|{5}").parse().unwrap_err(),
+            TestError {
+                span: span(1..1),
+                kind: ast::ErrorKind::RepetitionMissing,
+            });
+    }
+
+    #[test]
+    fn parse_alternate() {
+        assert_eq!(
+            parser(r"a|b").parse(),
+            Ok(Ast::Alternation(ast::Alternation {
+                span: span(0..3),
+                asts: vec![lit('a', 0), lit('b', 2)],
+            })));
+        assert_eq!(
+            parser(r"(a|b)").parse(),
+            Ok(group(0..5, 1, Ast::Alternation(ast::Alternation {
+                span: span(1..4),
+                asts: vec![lit('a', 1), lit('b', 3)],
+            }))));
+
+        assert_eq!(
+            parser(r"a|b|c").parse(),
+            Ok(Ast::Alternation(ast::Alternation {
+                span: span(0..5),
+                asts: vec![lit('a', 0), lit('b', 2), lit('c', 4)],
+            })));
+        assert_eq!(
+            parser(r"ax|by|cz").parse(),
+            Ok(Ast::Alternation(ast::Alternation {
+                span: span(0..8),
+                asts: vec![
+                    concat(0..2, vec![lit('a', 0), lit('x', 1)]),
+                    concat(3..5, vec![lit('b', 3), lit('y', 4)]),
+                    concat(6..8, vec![lit('c', 6), lit('z', 7)]),
+                ],
+            })));
+        assert_eq!(
+            parser(r"(ax|by|cz)").parse(),
+            Ok(group(0..10, 1, Ast::Alternation(ast::Alternation {
+                span: span(1..9),
+                asts: vec![
+                    concat(1..3, vec![lit('a', 1), lit('x', 2)]),
+                    concat(4..6, vec![lit('b', 4), lit('y', 5)]),
+                    concat(7..9, vec![lit('c', 7), lit('z', 8)]),
+                ],
+            }))));
+        assert_eq!(
+            parser(r"(ax|(by|(cz)))").parse(),
+            Ok(group(0..14, 1, alt(1..13, vec![
+                concat(1..3, vec![lit('a', 1), lit('x', 2)]),
+                group(4..13, 2, alt(5..12, vec![
+                    concat(5..7, vec![lit('b', 5), lit('y', 6)]),
+                    group(8..12, 3, concat(9..11, vec![
+                        lit('c', 9),
+                        lit('z', 10),
+                    ])),
+                ])),
+            ]))));
+
+        assert_eq!(
+            parser(r"|").parse(), Ok(alt(0..1, vec![
+                Ast::Empty(span(0..0)), Ast::Empty(span(1..1)),
+            ])));
+        assert_eq!(
+            parser(r"||").parse(), Ok(alt(0..2, vec![
+                Ast::Empty(span(0..0)),
+                Ast::Empty(span(1..1)),
+                Ast::Empty(span(2..2)),
+            ])));
+        assert_eq!(
+            parser(r"a|").parse(), Ok(alt(0..2, vec![
+                lit('a', 0), Ast::Empty(span(2..2)),
+            ])));
+        assert_eq!(
+            parser(r"|a").parse(), Ok(alt(0..2, vec![
+                Ast::Empty(span(0..0)), lit('a', 1),
+            ])));
+
+        assert_eq!(
+            parser(r"(|)").parse(), Ok(group(0..3, 1, alt(1..2, vec![
+                Ast::Empty(span(1..1)), Ast::Empty(span(2..2)),
+            ]))));
+        assert_eq!(
+            parser(r"(a|)").parse(), Ok(group(0..4, 1, alt(1..3, vec![
+                lit('a', 1), Ast::Empty(span(3..3)),
+            ]))));
+        assert_eq!(
+            parser(r"(|a)").parse(), Ok(group(0..4, 1, alt(1..3, vec![
+                Ast::Empty(span(1..1)), lit('a', 2),
+            ]))));
+
+        assert_eq!(
+            parser(r"a|b)").parse().unwrap_err(),
+            TestError {
+                span: span(3..4),
+                kind: ast::ErrorKind::GroupUnopened,
+            });
+        assert_eq!(
+            parser(r"(a|b").parse().unwrap_err(),
+            TestError {
+                span: span(0..1),
+                kind: ast::ErrorKind::GroupUnclosed,
+            });
+    }
+
+    #[test]
+    fn parse_unsupported_lookaround() {
+        assert_eq!(
+            parser(r"(?=a)").parse().unwrap_err(),
+            TestError {
+                span: span(0..3),
+                kind: ast::ErrorKind::UnsupportedLookAround,
+            });
+        assert_eq!(
+            parser(r"(?!a)").parse().unwrap_err(),
+            TestError {
+                span: span(0..3),
+                kind: ast::ErrorKind::UnsupportedLookAround,
+            });
+        assert_eq!(
+            parser(r"(?<=a)").parse().unwrap_err(),
+            TestError {
+                span: span(0..4),
+                kind: ast::ErrorKind::UnsupportedLookAround,
+            });
+        assert_eq!(
+            parser(r"(?<!a)").parse().unwrap_err(),
+            TestError {
+                span: span(0..4),
+                kind: ast::ErrorKind::UnsupportedLookAround,
+            });
+    }
+
+    #[test]
+    fn parse_group() {
+        assert_eq!(parser("(?i)").parse(), Ok(Ast::Flags(ast::SetFlags {
+            span: span(0..4),
+            flags: ast::Flags {
+                span: span(2..3),
+                items: vec![ast::FlagsItem {
+                    span: span(2..3),
+                    kind: ast::FlagsItemKind::Flag(ast::Flag::CaseInsensitive),
+                }],
+            },
+        })));
+        assert_eq!(parser("(?iU)").parse(), Ok(Ast::Flags(ast::SetFlags {
+            span: span(0..5),
+            flags: ast::Flags {
+                span: span(2..4),
+                items: vec![
+                    ast::FlagsItem {
+                        span: span(2..3),
+                        kind: ast::FlagsItemKind::Flag(
+                            ast::Flag::CaseInsensitive),
+                    },
+                    ast::FlagsItem {
+                        span: span(3..4),
+                        kind: ast::FlagsItemKind::Flag(ast::Flag::SwapGreed),
+                    },
+                ],
+            },
+        })));
+        assert_eq!(parser("(?i-U)").parse(), Ok(Ast::Flags(ast::SetFlags {
+            span: span(0..6),
+            flags: ast::Flags {
+                span: span(2..5),
+                items: vec![
+                    ast::FlagsItem {
+                        span: span(2..3),
+                        kind: ast::FlagsItemKind::Flag(
+                            ast::Flag::CaseInsensitive),
+                    },
+                    ast::FlagsItem {
+                        span: span(3..4),
+                        kind: ast::FlagsItemKind::Negation,
+                    },
+                    ast::FlagsItem {
+                        span: span(4..5),
+                        kind: ast::FlagsItemKind::Flag(ast::Flag::SwapGreed),
+                    },
+                ],
+            },
+        })));
+
+        assert_eq!(parser("()").parse(), Ok(Ast::Group(ast::Group {
+            span: span(0..2),
+            kind: ast::GroupKind::CaptureIndex(1),
+            ast: Box::new(Ast::Empty(span(1..1))),
+        })));
+        assert_eq!(parser("(a)").parse(), Ok(Ast::Group(ast::Group {
+            span: span(0..3),
+            kind: ast::GroupKind::CaptureIndex(1),
+            ast: Box::new(lit('a', 1)),
+        })));
+        assert_eq!(parser("(())").parse(), Ok(Ast::Group(ast::Group {
+            span: span(0..4),
+            kind: ast::GroupKind::CaptureIndex(1),
+            ast: Box::new(Ast::Group(ast::Group {
+                span: span(1..3),
+                kind: ast::GroupKind::CaptureIndex(2),
+                ast: Box::new(Ast::Empty(span(2..2))),
+            })),
+        })));
+
+        assert_eq!(parser("(?:a)").parse(), Ok(Ast::Group(ast::Group {
+            span: span(0..5),
+            kind: ast::GroupKind::NonCapturing(ast::Flags {
+                span: span(2..2),
+                items: vec![],
+            }),
+            ast: Box::new(lit('a', 3)),
+        })));
+
+        assert_eq!(parser("(?i:a)").parse(), Ok(Ast::Group(ast::Group {
+            span: span(0..6),
+            kind: ast::GroupKind::NonCapturing(ast::Flags {
+                span: span(2..3),
+                items: vec![
+                    ast::FlagsItem {
+                        span: span(2..3),
+                        kind: ast::FlagsItemKind::Flag(
+                            ast::Flag::CaseInsensitive),
+                    },
+                ],
+            }),
+            ast: Box::new(lit('a', 4)),
+        })));
+        assert_eq!(parser("(?i-U:a)").parse(), Ok(Ast::Group(ast::Group {
+            span: span(0..8),
+            kind: ast::GroupKind::NonCapturing(ast::Flags {
+                span: span(2..5),
+                items: vec![
+                    ast::FlagsItem {
+                        span: span(2..3),
+                        kind: ast::FlagsItemKind::Flag(
+                            ast::Flag::CaseInsensitive),
+                    },
+                    ast::FlagsItem {
+                        span: span(3..4),
+                        kind: ast::FlagsItemKind::Negation,
+                    },
+                    ast::FlagsItem {
+                        span: span(4..5),
+                        kind: ast::FlagsItemKind::Flag(ast::Flag::SwapGreed),
+                    },
+                ],
+            }),
+            ast: Box::new(lit('a', 6)),
+        })));
+
+        assert_eq!(
+            parser("(").parse().unwrap_err(),
+            TestError {
+                span: span(0..1),
+                kind: ast::ErrorKind::GroupUnclosed,
+            });
+        assert_eq!(
+            parser("(?").parse().unwrap_err(),
+            TestError {
+                span: span(0..1),
+                kind: ast::ErrorKind::GroupUnclosed,
+            });
+        assert_eq!(
+            parser("(?P").parse().unwrap_err(),
+            TestError {
+                span: span(2..3),
+                kind: ast::ErrorKind::FlagUnrecognized,
+            });
+        assert_eq!(
+            parser("(?P<").parse().unwrap_err(),
+            TestError {
+                span: span(4..4),
+                kind: ast::ErrorKind::GroupNameUnexpectedEof,
+            });
+        assert_eq!(
+            parser("(a").parse().unwrap_err(),
+            TestError {
+                span: span(0..1),
+                kind: ast::ErrorKind::GroupUnclosed,
+            });
+        assert_eq!(
+            parser("(()").parse().unwrap_err(),
+            TestError {
+                span: span(0..1),
+                kind: ast::ErrorKind::GroupUnclosed,
+            });
+        assert_eq!(
+            parser(")").parse().unwrap_err(),
+            TestError {
+                span: span(0..1),
+                kind: ast::ErrorKind::GroupUnopened,
+            });
+        assert_eq!(
+            parser("a)").parse().unwrap_err(),
+            TestError {
+                span: span(1..2),
+                kind: ast::ErrorKind::GroupUnopened,
+            });
+    }
+
+    #[test]
+    fn parse_capture_name() {
+        assert_eq!(parser("(?P<a>z)").parse(), Ok(Ast::Group(ast::Group {
+            span: span(0..8),
+            kind: ast::GroupKind::CaptureName(ast::CaptureName {
+                span: span(4..5),
+                name: s("a"),
+                index: 1,
+            }),
+            ast: Box::new(lit('z', 6)),
+        })));
+        assert_eq!(parser("(?P<abc>z)").parse(), Ok(Ast::Group(ast::Group {
+            span: span(0..10),
+            kind: ast::GroupKind::CaptureName(ast::CaptureName {
+                span: span(4..7),
+                name: s("abc"),
+                index: 1,
+            }),
+            ast: Box::new(lit('z', 8)),
+        })));
+
+        assert_eq!(
+            parser("(?P<").parse().unwrap_err(),
+            TestError {
+                span: span(4..4),
+                kind: ast::ErrorKind::GroupNameUnexpectedEof,
+            });
+        assert_eq!(
+            parser("(?P<>z)").parse().unwrap_err(),
+            TestError {
+                span: span(4..4),
+                kind: ast::ErrorKind::GroupNameEmpty,
+            });
+        assert_eq!(
+            parser("(?P<a").parse().unwrap_err(),
+            TestError {
+                span: span(5..5),
+                kind: ast::ErrorKind::GroupNameUnexpectedEof,
+            });
+        assert_eq!(
+            parser("(?P<ab").parse().unwrap_err(),
+            TestError {
+                span: span(6..6),
+                kind: ast::ErrorKind::GroupNameUnexpectedEof,
+            });
+        assert_eq!(
+            parser("(?P<0a").parse().unwrap_err(),
+            TestError {
+                span: span(4..5),
+                kind: ast::ErrorKind::GroupNameInvalid,
+            });
+        assert_eq!(
+            parser("(?P<~").parse().unwrap_err(),
+            TestError {
+                span: span(4..5),
+                kind: ast::ErrorKind::GroupNameInvalid,
+            });
+        assert_eq!(
+            parser("(?P<abc~").parse().unwrap_err(),
+            TestError {
+                span: span(7..8),
+                kind: ast::ErrorKind::GroupNameInvalid,
+            });
+        assert_eq!(
+            parser("(?P<a>y)(?P<a>z)").parse().unwrap_err(),
+            TestError {
+                span: span(12..13),
+                kind: ast::ErrorKind::GroupNameDuplicate {
+                    original: span(4..5),
+                },
+            });
+    }
+
+    #[test]
+    fn parse_flags() {
+        assert_eq!(parser("i:").parse_flags(), Ok(ast::Flags {
+            span: span(0..1),
+            items: vec![ast::FlagsItem {
+                span: span(0..1),
+                kind: ast::FlagsItemKind::Flag(ast::Flag::CaseInsensitive),
+            }],
+        }));
+        assert_eq!(parser("i)").parse_flags(), Ok(ast::Flags {
+            span: span(0..1),
+            items: vec![ast::FlagsItem {
+                span: span(0..1),
+                kind: ast::FlagsItemKind::Flag(ast::Flag::CaseInsensitive),
+            }],
+        }));
+
+        assert_eq!(parser("isU:").parse_flags(), Ok(ast::Flags {
+            span: span(0..3),
+            items: vec![
+                ast::FlagsItem {
+                    span: span(0..1),
+                    kind: ast::FlagsItemKind::Flag(ast::Flag::CaseInsensitive),
+                },
+                ast::FlagsItem {
+                    span: span(1..2),
+                    kind: ast::FlagsItemKind::Flag(
+                        ast::Flag::DotMatchesNewLine),
+                },
+                ast::FlagsItem {
+                    span: span(2..3),
+                    kind: ast::FlagsItemKind::Flag(ast::Flag::SwapGreed),
+                },
+            ],
+        }));
+
+        assert_eq!(parser("-isU:").parse_flags(), Ok(ast::Flags {
+            span: span(0..4),
+            items: vec![
+                ast::FlagsItem {
+                    span: span(0..1),
+                    kind: ast::FlagsItemKind::Negation,
+                },
+                ast::FlagsItem {
+                    span: span(1..2),
+                    kind: ast::FlagsItemKind::Flag(ast::Flag::CaseInsensitive),
+                },
+                ast::FlagsItem {
+                    span: span(2..3),
+                    kind: ast::FlagsItemKind::Flag(
+                        ast::Flag::DotMatchesNewLine),
+                },
+                ast::FlagsItem {
+                    span: span(3..4),
+                    kind: ast::FlagsItemKind::Flag(ast::Flag::SwapGreed),
+                },
+            ],
+        }));
+        assert_eq!(parser("i-sU:").parse_flags(), Ok(ast::Flags {
+            span: span(0..4),
+            items: vec![
+                ast::FlagsItem {
+                    span: span(0..1),
+                    kind: ast::FlagsItemKind::Flag(ast::Flag::CaseInsensitive),
+                },
+                ast::FlagsItem {
+                    span: span(1..2),
+                    kind: ast::FlagsItemKind::Negation,
+                },
+                ast::FlagsItem {
+                    span: span(2..3),
+                    kind: ast::FlagsItemKind::Flag(
+                        ast::Flag::DotMatchesNewLine),
+                },
+                ast::FlagsItem {
+                    span: span(3..4),
+                    kind: ast::FlagsItemKind::Flag(ast::Flag::SwapGreed),
+                },
+            ],
+        }));
+
+        assert_eq!(
+            parser("isU").parse_flags().unwrap_err(),
+            TestError {
+                span: span(3..3),
+                kind: ast::ErrorKind::FlagUnexpectedEof,
+            });
+        assert_eq!(
+            parser("isUa:").parse_flags().unwrap_err(),
+            TestError {
+                span: span(3..4),
+                kind: ast::ErrorKind::FlagUnrecognized,
+            });
+        assert_eq!(
+            parser("isUi:").parse_flags().unwrap_err(),
+            TestError {
+                span: span(3..4),
+                kind: ast::ErrorKind::FlagDuplicate {
+                    original: span(0..1),
+                },
+            });
+        assert_eq!(
+            parser("i-sU-i:").parse_flags().unwrap_err(),
+            TestError {
+                span: span(4..5),
+                kind: ast::ErrorKind::FlagRepeatedNegation {
+                    original: span(1..2),
+                },
+            });
+        assert_eq!(
+            parser("-)").parse_flags().unwrap_err(),
+            TestError {
+                span: span(0..1),
+                kind: ast::ErrorKind::FlagDanglingNegation,
+            });
+        assert_eq!(
+            parser("i-)").parse_flags().unwrap_err(),
+            TestError {
+                span: span(1..2),
+                kind: ast::ErrorKind::FlagDanglingNegation,
+            });
+        assert_eq!(
+            parser("iU-)").parse_flags().unwrap_err(),
+            TestError {
+                span: span(2..3),
+                kind: ast::ErrorKind::FlagDanglingNegation,
+            });
+    }
+
+    #[test]
+    fn parse_flag() {
+        assert_eq!(parser("i").parse_flag(), Ok(ast::Flag::CaseInsensitive));
+        assert_eq!(parser("m").parse_flag(), Ok(ast::Flag::MultiLine));
+        assert_eq!(parser("s").parse_flag(), Ok(ast::Flag::DotMatchesNewLine));
+        assert_eq!(parser("U").parse_flag(), Ok(ast::Flag::SwapGreed));
+        assert_eq!(parser("u").parse_flag(), Ok(ast::Flag::Unicode));
+        assert_eq!(parser("x").parse_flag(), Ok(ast::Flag::IgnoreWhitespace));
+
+        assert_eq!(
+            parser("a").parse_flag().unwrap_err(),
+            TestError {
+                span: span(0..1),
+                kind: ast::ErrorKind::FlagUnrecognized,
+            });
+        assert_eq!(
+            parser("☃").parse_flag().unwrap_err(),
+            TestError {
+                span: span_range("☃", 0..3),
+                kind: ast::ErrorKind::FlagUnrecognized,
+            });
+    }
+
+    #[test]
+    fn parse_primitive_non_escape() {
+        assert_eq!(
+            parser(r".").parse_primitive(),
+            Ok(Primitive::Dot(span(0..1))));
+        assert_eq!(
+            parser(r"^").parse_primitive(),
+            Ok(Primitive::Assertion(ast::Assertion {
+                span: span(0..1),
+                kind: ast::AssertionKind::StartLine,
+            })));
+        assert_eq!(
+            parser(r"$").parse_primitive(),
+            Ok(Primitive::Assertion(ast::Assertion {
+                span: span(0..1),
+                kind: ast::AssertionKind::EndLine,
+            })));
+
+        assert_eq!(
+            parser(r"a").parse_primitive(),
+            Ok(Primitive::Literal(ast::Literal {
+                span: span(0..1),
+                kind: ast::LiteralKind::Verbatim,
+                c: 'a',
+            })));
+        assert_eq!(
+            parser(r"|").parse_primitive(),
+            Ok(Primitive::Literal(ast::Literal {
+                span: span(0..1),
+                kind: ast::LiteralKind::Verbatim,
+                c: '|',
+            })));
+        assert_eq!(
+            parser(r"☃").parse_primitive(),
+            Ok(Primitive::Literal(ast::Literal {
+                span: span_range("☃", 0..3),
+                kind: ast::LiteralKind::Verbatim,
+                c: '☃',
+            })));
+    }
+
+    #[test]
+    fn parse_escape() {
+        assert_eq!(
+            parser(r"\|").parse_primitive(),
+            Ok(Primitive::Literal(ast::Literal {
+                span: span(0..2),
+                kind: ast::LiteralKind::Punctuation,
+                c: '|',
+            })));
+        let specials = &[
+            (r"\a", '\x07', ast::SpecialLiteralKind::Bell),
+            (r"\f", '\x0C', ast::SpecialLiteralKind::FormFeed),
+            (r"\t", '\t', ast::SpecialLiteralKind::Tab),
+            (r"\n", '\n', ast::SpecialLiteralKind::LineFeed),
+            (r"\r", '\r', ast::SpecialLiteralKind::CarriageReturn),
+            (r"\v", '\x0B', ast::SpecialLiteralKind::VerticalTab),
+        ];
+        for &(pat, c, ref kind) in specials {
+            assert_eq!(
+                parser(pat).parse_primitive(),
+                Ok(Primitive::Literal(ast::Literal {
+                    span: span(0..2),
+                    kind: ast::LiteralKind::Special(kind.clone()),
+                    c: c,
+                })));
+        }
+        assert_eq!(
+            parser(r"\A").parse_primitive(),
+            Ok(Primitive::Assertion(ast::Assertion {
+                span: span(0..2),
+                kind: ast::AssertionKind::StartText,
+            })));
+        assert_eq!(
+            parser(r"\z").parse_primitive(),
+            Ok(Primitive::Assertion(ast::Assertion {
+                span: span(0..2),
+                kind: ast::AssertionKind::EndText,
+            })));
+        assert_eq!(
+            parser(r"\b").parse_primitive(),
+            Ok(Primitive::Assertion(ast::Assertion {
+                span: span(0..2),
+                kind: ast::AssertionKind::WordBoundary,
+            })));
+        assert_eq!(
+            parser(r"\B").parse_primitive(),
+            Ok(Primitive::Assertion(ast::Assertion {
+                span: span(0..2),
+                kind: ast::AssertionKind::NotWordBoundary,
+            })));
+
+        assert_eq!(
+            parser(r"\").parse_escape().unwrap_err(),
+            TestError {
+                span: span(0..1),
+                kind: ast::ErrorKind::EscapeUnexpectedEof,
+            });
+        assert_eq!(
+            parser(r"\y").parse_escape().unwrap_err(),
+            TestError {
+                span: span(0..2),
+                kind: ast::ErrorKind::EscapeUnrecognized,
+            });
+    }
+
+    #[test]
+    fn parse_unsupported_backreference() {
+        assert_eq!(
+            parser(r"\0").parse_escape().unwrap_err(),
+            TestError {
+                span: span(0..2),
+                kind: ast::ErrorKind::UnsupportedBackreference,
+            });
+        assert_eq!(
+            parser(r"\9").parse_escape().unwrap_err(),
+            TestError {
+                span: span(0..2),
+                kind: ast::ErrorKind::UnsupportedBackreference,
+            });
+    }
+
+    #[test]
+    fn parse_octal() {
+        for i in 0..511 {
+            let pat = format!(r"\{:o}", i);
+            assert_eq!(
+                parser_octal(&pat).parse_escape(),
+                Ok(Primitive::Literal(ast::Literal {
+                    span: span(0..pat.len()),
+                    kind: ast::LiteralKind::Octal,
+                    c: ::std::char::from_u32(i).unwrap(),
+                })));
+        }
+        assert_eq!(
+            parser_octal(r"\778").parse_escape(),
+            Ok(Primitive::Literal(ast::Literal {
+                span: span(0..3),
+                kind: ast::LiteralKind::Octal,
+                c: '?',
+            })));
+        assert_eq!(
+            parser_octal(r"\7777").parse_escape(),
+            Ok(Primitive::Literal(ast::Literal {
+                span: span(0..4),
+                kind: ast::LiteralKind::Octal,
+                c: '\u{01FF}',
+            })));
+        assert_eq!(
+            parser_octal(r"\778").parse(),
+            Ok(Ast::Concat(ast::Concat {
+                span: span(0..4),
+                asts: vec![
+                    Ast::Literal(ast::Literal {
+                        span: span(0..3),
+                        kind: ast::LiteralKind::Octal,
+                        c: '?',
+                    }),
+                    Ast::Literal(ast::Literal {
+                        span: span(3..4),
+                        kind: ast::LiteralKind::Verbatim,
+                        c: '8',
+                    }),
+                ],
+            })));
+        assert_eq!(
+            parser_octal(r"\7777").parse(),
+            Ok(Ast::Concat(ast::Concat {
+                span: span(0..5),
+                asts: vec![
+                    Ast::Literal(ast::Literal {
+                        span: span(0..4),
+                        kind: ast::LiteralKind::Octal,
+                        c: '\u{01FF}',
+                    }),
+                    Ast::Literal(ast::Literal {
+                        span: span(4..5),
+                        kind: ast::LiteralKind::Verbatim,
+                        c: '7',
+                    }),
+                ],
+            })));
+
+        assert_eq!(
+            parser_octal(r"\8").parse_escape().unwrap_err(),
+            TestError {
+                span: span(0..2),
+                kind: ast::ErrorKind::EscapeUnrecognized,
+            });
+    }
+
+    #[test]
+    fn parse_hex_two() {
+        for i in 0..256 {
+            let pat = format!(r"\x{:02x}", i);
+            assert_eq!(
+                parser(&pat).parse_escape(),
+                Ok(Primitive::Literal(ast::Literal {
+                    span: span(0..pat.len()),
+                    kind: ast::LiteralKind::HexFixed(ast::HexLiteralKind::X),
+                    c: ::std::char::from_u32(i).unwrap(),
+                })));
+        }
+
+        assert_eq!(
+            parser(r"\xF").parse_escape().unwrap_err(),
+            TestError {
+                span: span(3..3),
+                kind: ast::ErrorKind::EscapeUnexpectedEof,
+            });
+        assert_eq!(
+            parser(r"\xG").parse_escape().unwrap_err(),
+            TestError {
+                span: span(2..3),
+                kind: ast::ErrorKind::EscapeHexInvalidDigit,
+            });
+        assert_eq!(
+            parser(r"\xFG").parse_escape().unwrap_err(),
+            TestError {
+                span: span(3..4),
+                kind: ast::ErrorKind::EscapeHexInvalidDigit,
+            });
+    }
+
+    #[test]
+    fn parse_hex_four() {
+        for i in 0..65536 {
+            let c = match ::std::char::from_u32(i) {
+                None => continue,
+                Some(c) => c,
+            };
+            let pat = format!(r"\u{:04x}", i);
+            assert_eq!(
+                parser(&pat).parse_escape(),
+                Ok(Primitive::Literal(ast::Literal {
+                    span: span(0..pat.len()),
+                    kind: ast::LiteralKind::HexFixed(
+                        ast::HexLiteralKind::UnicodeShort),
+                    c: c,
+                })));
+        }
+
+        assert_eq!(
+            parser(r"\uF").parse_escape().unwrap_err(),
+            TestError {
+                span: span(3..3),
+                kind: ast::ErrorKind::EscapeUnexpectedEof,
+            });
+        assert_eq!(
+            parser(r"\uG").parse_escape().unwrap_err(),
+            TestError {
+                span: span(2..3),
+                kind: ast::ErrorKind::EscapeHexInvalidDigit,
+            });
+        assert_eq!(
+            parser(r"\uFG").parse_escape().unwrap_err(),
+            TestError {
+                span: span(3..4),
+                kind: ast::ErrorKind::EscapeHexInvalidDigit,
+            });
+        assert_eq!(
+            parser(r"\uFFG").parse_escape().unwrap_err(),
+            TestError {
+                span: span(4..5),
+                kind: ast::ErrorKind::EscapeHexInvalidDigit,
+            });
+        assert_eq!(
+            parser(r"\uFFFG").parse_escape().unwrap_err(),
+            TestError {
+                span: span(5..6),
+                kind: ast::ErrorKind::EscapeHexInvalidDigit,
+            });
+        assert_eq!(
+            parser(r"\uD800").parse_escape().unwrap_err(),
+            TestError {
+                span: span(2..6),
+                kind: ast::ErrorKind::EscapeHexInvalid,
+            });
+    }
+
+    #[test]
+    fn parse_hex_eight() {
+        for i in 0..65536 {
+            let c = match ::std::char::from_u32(i) {
+                None => continue,
+                Some(c) => c,
+            };
+            let pat = format!(r"\U{:08x}", i);
+            assert_eq!(
+                parser(&pat).parse_escape(),
+                Ok(Primitive::Literal(ast::Literal {
+                    span: span(0..pat.len()),
+                    kind: ast::LiteralKind::HexFixed(
+                        ast::HexLiteralKind::UnicodeLong),
+                    c: c,
+                })));
+        }
+
+        assert_eq!(
+            parser(r"\UF").parse_escape().unwrap_err(),
+            TestError {
+                span: span(3..3),
+                kind: ast::ErrorKind::EscapeUnexpectedEof,
+            });
+        assert_eq!(
+            parser(r"\UG").parse_escape().unwrap_err(),
+            TestError {
+                span: span(2..3),
+                kind: ast::ErrorKind::EscapeHexInvalidDigit,
+            });
+        assert_eq!(
+            parser(r"\UFG").parse_escape().unwrap_err(),
+            TestError {
+                span: span(3..4),
+                kind: ast::ErrorKind::EscapeHexInvalidDigit,
+            });
+        assert_eq!(
+            parser(r"\UFFG").parse_escape().unwrap_err(),
+            TestError {
+                span: span(4..5),
+                kind: ast::ErrorKind::EscapeHexInvalidDigit,
+            });
+        assert_eq!(
+            parser(r"\UFFFG").parse_escape().unwrap_err(),
+            TestError {
+                span: span(5..6),
+                kind: ast::ErrorKind::EscapeHexInvalidDigit,
+            });
+        assert_eq!(
+            parser(r"\UFFFFG").parse_escape().unwrap_err(),
+            TestError {
+                span: span(6..7),
+                kind: ast::ErrorKind::EscapeHexInvalidDigit,
+            });
+        assert_eq!(
+            parser(r"\UFFFFFG").parse_escape().unwrap_err(),
+            TestError {
+                span: span(7..8),
+                kind: ast::ErrorKind::EscapeHexInvalidDigit,
+            });
+        assert_eq!(
+            parser(r"\UFFFFFFG").parse_escape().unwrap_err(),
+            TestError {
+                span: span(8..9),
+                kind: ast::ErrorKind::EscapeHexInvalidDigit,
+            });
+        assert_eq!(
+            parser(r"\UFFFFFFFG").parse_escape().unwrap_err(),
+            TestError {
+                span: span(9..10),
+                kind: ast::ErrorKind::EscapeHexInvalidDigit,
+            });
+    }
+
+    #[test]
+    fn parse_hex_brace() {
+        assert_eq!(
+            parser(r"\u{26c4}").parse_escape(),
+            Ok(Primitive::Literal(ast::Literal {
+                span: span(0..8),
+                kind: ast::LiteralKind::HexBrace(
+                    ast::HexLiteralKind::UnicodeShort),
+                c: '⛄',
+            })));
+        assert_eq!(
+            parser(r"\U{26c4}").parse_escape(),
+            Ok(Primitive::Literal(ast::Literal {
+                span: span(0..8),
+                kind: ast::LiteralKind::HexBrace(
+                    ast::HexLiteralKind::UnicodeLong),
+                c: '⛄',
+            })));
+        assert_eq!(
+            parser(r"\x{26c4}").parse_escape(),
+            Ok(Primitive::Literal(ast::Literal {
+                span: span(0..8),
+                kind: ast::LiteralKind::HexBrace(ast::HexLiteralKind::X),
+                c: '⛄',
+            })));
+        assert_eq!(
+            parser(r"\x{26C4}").parse_escape(),
+            Ok(Primitive::Literal(ast::Literal {
+                span: span(0..8),
+                kind: ast::LiteralKind::HexBrace(ast::HexLiteralKind::X),
+                c: '⛄',
+            })));
+        assert_eq!(
+            parser(r"\x{10fFfF}").parse_escape(),
+            Ok(Primitive::Literal(ast::Literal {
+                span: span(0..10),
+                kind: ast::LiteralKind::HexBrace(ast::HexLiteralKind::X),
+                c: '\u{10FFFF}',
+            })));
+
+        assert_eq!(
+            parser(r"\x").parse_escape().unwrap_err(),
+            TestError {
+                span: span(2..2),
+                kind: ast::ErrorKind::EscapeUnexpectedEof,
+            });
+        assert_eq!(
+            parser(r"\x{").parse_escape().unwrap_err(),
+            TestError {
+                span: span(2..3),
+                kind: ast::ErrorKind::EscapeUnexpectedEof,
+            });
+        assert_eq!(
+            parser(r"\x{FF").parse_escape().unwrap_err(),
+            TestError {
+                span: span(2..5),
+                kind: ast::ErrorKind::EscapeUnexpectedEof,
+            });
+        assert_eq!(
+            parser(r"\x{}").parse_escape().unwrap_err(),
+            TestError {
+                span: span(2..4),
+                kind: ast::ErrorKind::EscapeHexEmpty,
+            });
+        assert_eq!(
+            parser(r"\x{FGF}").parse_escape().unwrap_err(),
+            TestError {
+                span: span(4..5),
+                kind: ast::ErrorKind::EscapeHexInvalidDigit,
+            });
+        assert_eq!(
+            parser(r"\x{FFFFFF}").parse_escape().unwrap_err(),
+            TestError {
+                span: span(3..9),
+                kind: ast::ErrorKind::EscapeHexInvalid,
+            });
+        assert_eq!(
+            parser(r"\x{D800}").parse_escape().unwrap_err(),
+            TestError {
+                span: span(3..7),
+                kind: ast::ErrorKind::EscapeHexInvalid,
+            });
+        assert_eq!(
+            parser(r"\x{FFFFFFFFF}").parse_escape().unwrap_err(),
+            TestError {
+                span: span(3..12),
+                kind: ast::ErrorKind::EscapeHexInvalid,
+            });
+    }
+
+    #[test]
+    fn parse_decimal() {
+        assert_eq!(parser("123").parse_decimal(), Ok(123));
+        assert_eq!(parser("0").parse_decimal(), Ok(0));
+        assert_eq!(parser("01").parse_decimal(), Ok(1));
+
+        assert_eq!(
+            parser("-1").parse_decimal().unwrap_err(),
+            TestError {
+                span: span(0..0),
+                kind: ast::ErrorKind::DecimalEmpty,
+            });
+        assert_eq!(
+            parser("").parse_decimal().unwrap_err(),
+            TestError {
+                span: span(0..0),
+                kind: ast::ErrorKind::DecimalEmpty,
+            });
+        assert_eq!(
+            parser("9999999999").parse_decimal().unwrap_err(),
+            TestError {
+                span: span(0..10),
+                kind: ast::ErrorKind::DecimalInvalid,
+            });
+    }
+
+    #[test]
+    fn parse_set_class() {
+        fn union(span: Span, items: Vec<ast::ClassSetItem>) -> ast::ClassSet {
+            ast::ClassSet::union(ast::ClassSetUnion {
+                span: span,
+                items: items,
+            })
+        }
+
+        fn intersection(
+            span: Span,
+            lhs: ast::ClassSet,
+            rhs: ast::ClassSet,
+        ) -> ast::ClassSet {
+            ast::ClassSet::BinaryOp(ast::ClassSetBinaryOp {
+                span: span,
+                kind: ast::ClassSetBinaryOpKind::Intersection,
+                lhs: Box::new(lhs),
+                rhs: Box::new(rhs),
+            })
+        }
+
+        fn difference(
+            span: Span,
+            lhs: ast::ClassSet,
+            rhs: ast::ClassSet,
+        ) -> ast::ClassSet {
+            ast::ClassSet::BinaryOp(ast::ClassSetBinaryOp {
+                span: span,
+                kind: ast::ClassSetBinaryOpKind::Difference,
+                lhs: Box::new(lhs),
+                rhs: Box::new(rhs),
+            })
+        }
+
+        fn symdifference(
+            span: Span,
+            lhs: ast::ClassSet,
+            rhs: ast::ClassSet,
+        ) -> ast::ClassSet {
+            ast::ClassSet::BinaryOp(ast::ClassSetBinaryOp {
+                span: span,
+                kind: ast::ClassSetBinaryOpKind::SymmetricDifference,
+                lhs: Box::new(lhs),
+                rhs: Box::new(rhs),
+            })
+        }
+
+        fn itemset(item: ast::ClassSetItem) -> ast::ClassSet {
+            ast::ClassSet::Item(item)
+        }
+
+        fn item_ascii(cls: ast::ClassAscii) -> ast::ClassSetItem {
+            ast::ClassSetItem::Ascii(cls)
+        }
+
+        fn item_unicode(cls: ast::ClassUnicode) -> ast::ClassSetItem {
+            ast::ClassSetItem::Unicode(cls)
+        }
+
+        fn item_perl(cls: ast::ClassPerl) -> ast::ClassSetItem {
+            ast::ClassSetItem::Perl(cls)
+        }
+
+        fn item_bracket(cls: ast::ClassBracketed) -> ast::ClassSetItem {
+            ast::ClassSetItem::Bracketed(Box::new(cls))
+        }
+
+        fn lit(span: Span, c: char) -> ast::ClassSetItem {
+            ast::ClassSetItem::Literal(ast::Literal {
+                span: span,
+                kind: ast::LiteralKind::Verbatim,
+                c: c,
+            })
+        }
+
+        fn empty(span: Span) -> ast::ClassSetItem {
+            ast::ClassSetItem::Empty(span)
+        }
+
+        fn range(span: Span, start: char, end: char) -> ast::ClassSetItem {
+            let pos1 = Position {
+                offset: span.start.offset + start.len_utf8(),
+                column: span.start.column + 1,
+                ..span.start
+            };
+            let pos2 = Position {
+                offset: span.end.offset - end.len_utf8(),
+                column: span.end.column - 1,
+                ..span.end
+            };
+            ast::ClassSetItem::Range(ast::ClassSetRange {
+                span: span,
+                start: ast::Literal {
+                    span: Span { end: pos1, ..span },
+                    kind: ast::LiteralKind::Verbatim,
+                    c: start,
+                },
+                end: ast::Literal {
+                    span: Span { start: pos2, ..span },
+                    kind: ast::LiteralKind::Verbatim,
+                    c: end,
+                },
+            })
+        }
+
+        fn alnum(span: Span, negated: bool) -> ast::ClassAscii {
+            ast::ClassAscii {
+                span: span,
+                kind: ast::ClassAsciiKind::Alnum,
+                negated: negated,
+            }
+        }
+
+        fn lower(span: Span, negated: bool) -> ast::ClassAscii {
+            ast::ClassAscii {
+                span: span,
+                kind: ast::ClassAsciiKind::Lower,
+                negated: negated,
+            }
+        }
+
+        assert_eq!(
+            parser("[[:alnum:]]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..11),
+                negated: false,
+                kind: itemset(item_ascii(alnum(span(1..10), false))),
+            }))));
+        assert_eq!(
+            parser("[[[:alnum:]]]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..13),
+                negated: false,
+                kind: itemset(item_bracket(ast::ClassBracketed {
+                    span: span(1..12),
+                    negated: false,
+                    kind: itemset(item_ascii(alnum(span(2..11), false))),
+                })),
+            }))));
+        assert_eq!(
+            parser("[[:alnum:]&&[:lower:]]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..22),
+                negated: false,
+                kind: intersection(
+                    span(1..21),
+                    itemset(item_ascii(alnum(span(1..10), false))),
+                    itemset(item_ascii(lower(span(12..21), false))),
+                ),
+            }))));
+        assert_eq!(
+            parser("[[:alnum:]--[:lower:]]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..22),
+                negated: false,
+                kind: difference(
+                    span(1..21),
+                    itemset(item_ascii(alnum(span(1..10), false))),
+                    itemset(item_ascii(lower(span(12..21), false))),
+                ),
+            }))));
+        assert_eq!(
+            parser("[[:alnum:]~~[:lower:]]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..22),
+                negated: false,
+                kind: symdifference(
+                    span(1..21),
+                    itemset(item_ascii(alnum(span(1..10), false))),
+                    itemset(item_ascii(lower(span(12..21), false))),
+                ),
+            }))));
+
+        assert_eq!(
+            parser("[a]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..3),
+                negated: false,
+                kind: itemset(lit(span(1..2), 'a')),
+            }))));
+        assert_eq!(
+            parser(r"[a\]]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..5),
+                negated: false,
+                kind: union(span(1..4), vec![
+                    lit(span(1..2), 'a'),
+                    ast::ClassSetItem::Literal(ast::Literal {
+                        span: span(2..4),
+                        kind: ast::LiteralKind::Punctuation,
+                        c: ']',
+                    }),
+                ]),
+            }))));
+        assert_eq!(
+            parser(r"[a\-z]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..6),
+                negated: false,
+                kind: union(span(1..5), vec![
+                    lit(span(1..2), 'a'),
+                    ast::ClassSetItem::Literal(ast::Literal {
+                        span: span(2..4),
+                        kind: ast::LiteralKind::Punctuation,
+                        c: '-',
+                    }),
+                    lit(span(4..5), 'z'),
+                ]),
+            }))));
+        assert_eq!(
+            parser("[ab]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..4),
+                negated: false,
+                kind: union(span(1..3), vec![
+                    lit(span(1..2), 'a'),
+                    lit(span(2..3), 'b'),
+                ]),
+            }))));
+        assert_eq!(
+            parser("[a-]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..4),
+                negated: false,
+                kind: union(span(1..3), vec![
+                    lit(span(1..2), 'a'),
+                    lit(span(2..3), '-'),
+                ]),
+            }))));
+        assert_eq!(
+            parser("[-a]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..4),
+                negated: false,
+                kind: union(span(1..3), vec![
+                    lit(span(1..2), '-'),
+                    lit(span(2..3), 'a'),
+                ]),
+            }))));
+        assert_eq!(
+            parser(r"[\pL]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..5),
+                negated: false,
+                kind: itemset(item_unicode(ast::ClassUnicode {
+                    span: span(1..4),
+                    negated: false,
+                    kind: ast::ClassUnicodeKind::OneLetter('L'),
+                })),
+            }))));
+        assert_eq!(
+            parser(r"[\w]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..4),
+                negated: false,
+                kind: itemset(item_perl(ast::ClassPerl {
+                    span: span(1..3),
+                    kind: ast::ClassPerlKind::Word,
+                    negated: false,
+                })),
+            }))));
+        assert_eq!(
+            parser(r"[a\wz]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..6),
+                negated: false,
+                kind: union(span(1..5), vec![
+                    lit(span(1..2), 'a'),
+                    item_perl(ast::ClassPerl {
+                        span: span(2..4),
+                        kind: ast::ClassPerlKind::Word,
+                        negated: false,
+                    }),
+                    lit(span(4..5), 'z'),
+                ]),
+            }))));
+
+        assert_eq!(
+            parser("[a-z]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..5),
+                negated: false,
+                kind: itemset(range(span(1..4), 'a', 'z')),
+            }))));
+        assert_eq!(
+            parser("[a-cx-z]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..8),
+                negated: false,
+                kind: union(span(1..7), vec![
+                    range(span(1..4), 'a', 'c'),
+                    range(span(4..7), 'x', 'z'),
+                ]),
+            }))));
+        assert_eq!(
+            parser(r"[\w&&a-cx-z]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..12),
+                negated: false,
+                kind: intersection(
+                    span(1..11),
+                    itemset(item_perl(ast::ClassPerl {
+                        span: span(1..3),
+                        kind: ast::ClassPerlKind::Word,
+                        negated: false,
+                    })),
+                    union(span(5..11), vec![
+                        range(span(5..8), 'a', 'c'),
+                        range(span(8..11), 'x', 'z'),
+                    ]),
+                ),
+            }))));
+        assert_eq!(
+            parser(r"[a-cx-z&&\w]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..12),
+                negated: false,
+                kind: intersection(
+                    span(1..11),
+                    union(span(1..7), vec![
+                        range(span(1..4), 'a', 'c'),
+                        range(span(4..7), 'x', 'z'),
+                    ]),
+                    itemset(item_perl(ast::ClassPerl {
+                        span: span(9..11),
+                        kind: ast::ClassPerlKind::Word,
+                        negated: false,
+                    })),
+                ),
+            }))));
+        assert_eq!(
+            parser(r"[a--b--c]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..9),
+                negated: false,
+                kind: difference(
+                    span(1..8),
+                    difference(
+                        span(1..5),
+                        itemset(lit(span(1..2), 'a')),
+                        itemset(lit(span(4..5), 'b')),
+                    ),
+                    itemset(lit(span(7..8), 'c')),
+                ),
+            }))));
+        assert_eq!(
+            parser(r"[a~~b~~c]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..9),
+                negated: false,
+                kind: symdifference(
+                    span(1..8),
+                    symdifference(
+                        span(1..5),
+                        itemset(lit(span(1..2), 'a')),
+                        itemset(lit(span(4..5), 'b')),
+                    ),
+                    itemset(lit(span(7..8), 'c')),
+                ),
+            }))));
+        assert_eq!(
+            parser(r"[\^&&^]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..7),
+                negated: false,
+                kind: intersection(
+                    span(1..6),
+                    itemset(ast::ClassSetItem::Literal(ast::Literal {
+                        span: span(1..3),
+                        kind: ast::LiteralKind::Punctuation,
+                        c: '^',
+                    })),
+                    itemset(lit(span(5..6), '^')),
+                ),
+            }))));
+        assert_eq!(
+            parser(r"[\&&&&]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..7),
+                negated: false,
+                kind: intersection(
+                    span(1..6),
+                    itemset(ast::ClassSetItem::Literal(ast::Literal {
+                        span: span(1..3),
+                        kind: ast::LiteralKind::Punctuation,
+                        c: '&',
+                    })),
+                    itemset(lit(span(5..6), '&')),
+                ),
+            }))));
+        assert_eq!(
+            parser(r"[&&&&]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..6),
+                negated: false,
+                kind: intersection(
+                    span(1..5),
+                    intersection(
+                        span(1..3),
+                        itemset(empty(span(1..1))),
+                        itemset(empty(span(3..3))),
+                    ),
+                    itemset(empty(span(5..5))),
+                ),
+            }))));
+
+        let pat = "[☃-⛄]";
+        assert_eq!(
+            parser(pat).parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span_range(pat, 0..9),
+                negated: false,
+                kind: itemset(ast::ClassSetItem::Range(ast::ClassSetRange {
+                    span: span_range(pat, 1..8),
+                    start: ast::Literal {
+                        span: span_range(pat, 1..4),
+                        kind: ast::LiteralKind::Verbatim,
+                        c: '☃',
+                    },
+                    end: ast::Literal {
+                        span: span_range(pat, 5..8),
+                        kind: ast::LiteralKind::Verbatim,
+                        c: '⛄',
+                    },
+                })),
+            }))));
+
+        assert_eq!(
+            parser(r"[]]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..3),
+                negated: false,
+                kind: itemset(lit(span(1..2), ']')),
+            }))));
+        assert_eq!(
+            parser(r"[]\[]").parse(),
+            Ok(Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                span: span(0..5),
+                negated: false,
+                kind: union(span(1..4), vec![
+                    lit(span(1..2), ']'),
+                    ast::ClassSetItem::Literal(ast::Literal  {
+                        span: span(2..4),
+                        kind: ast::LiteralKind::Punctuation,
+                        c: '[',
+                    }),
+                ]),
+            }))));
+        assert_eq!(
+            parser(r"[\[]]").parse(),
+            Ok(concat(0..5, vec![
+                Ast::Class(ast::Class::Bracketed(ast::ClassBracketed {
+                    span: span(0..4),
+                    negated: false,
+                    kind: itemset(ast::ClassSetItem::Literal(ast::Literal  {
+                        span: span(1..3),
+                        kind: ast::LiteralKind::Punctuation,
+                        c: '[',
+                    })),
+                })),
+                Ast::Literal(ast::Literal {
+                    span: span(4..5),
+                    kind: ast::LiteralKind::Verbatim,
+                    c: ']',
+                }),
+            ])));
+
+        assert_eq!(
+            parser("[").parse().unwrap_err(),
+            TestError {
+                span: span(0..1),
+                kind: ast::ErrorKind::ClassUnclosed,
+            });
+        assert_eq!(
+            parser("[[").parse().unwrap_err(),
+            TestError {
+                span: span(1..2),
+                kind: ast::ErrorKind::ClassUnclosed,
+            });
+        assert_eq!(
+            parser("[[-]").parse().unwrap_err(),
+            TestError {
+                span: span(0..1),
+                kind: ast::ErrorKind::ClassUnclosed,
+            });
+        assert_eq!(
+            parser("[[[:alnum:]").parse().unwrap_err(),
+            TestError {
+                span: span(1..2),
+                kind: ast::ErrorKind::ClassUnclosed,
+            });
+        assert_eq!(
+            parser(r"[\b]").parse().unwrap_err(),
+            TestError {
+                span: span(1..3),
+                kind: ast::ErrorKind::ClassEscapeInvalid,
+            });
+        assert_eq!(
+            parser(r"[\w-a]").parse().unwrap_err(),
+            TestError {
+                span: span(1..3),
+                kind: ast::ErrorKind::ClassRangeLiteral,
+            });
+        assert_eq!(
+            parser(r"[a-\w]").parse().unwrap_err(),
+            TestError {
+                span: span(3..5),
+                kind: ast::ErrorKind::ClassRangeLiteral,
+            });
+        assert_eq!(
+            parser(r"[z-a]").parse().unwrap_err(),
+            TestError {
+                span: span(1..4),
+                kind: ast::ErrorKind::ClassRangeInvalid,
+            });
+
+        assert_eq!(
+            parser_ignore_whitespace("[a ").parse().unwrap_err(),
+            TestError {
+                span: span(0..1),
+                kind: ast::ErrorKind::ClassUnclosed,
+            });
+        assert_eq!(
+            parser_ignore_whitespace("[a- ").parse().unwrap_err(),
+            TestError {
+                span: span(0..1),
+                kind: ast::ErrorKind::ClassUnclosed,
+            });
+    }
+
+    #[test]
+    fn parse_set_class_open() {
+        assert_eq!(
+            parser("[a]").parse_set_class_open(), {
+                let set = ast::ClassBracketed {
+                    span: span(0..1),
+                    negated: false,
+                    kind: ast::ClassSet::union(ast::ClassSetUnion {
+                        span: span(1..1),
+                        items: vec![],
+                    }),
+                };
+                let union = ast::ClassSetUnion {
+                    span: span(1..1),
+                    items: vec![],
+                };
+                Ok((set, union))
+            });
+        assert_eq!(
+            parser_ignore_whitespace("[   a]").parse_set_class_open(), {
+                let set = ast::ClassBracketed {
+                    span: span(0..4),
+                    negated: false,
+                    kind: ast::ClassSet::union(ast::ClassSetUnion {
+                        span: span(4..4),
+                        items: vec![],
+                    }),
+                };
+                let union = ast::ClassSetUnion {
+                    span: span(4..4),
+                    items: vec![],
+                };
+                Ok((set, union))
+            });
+        assert_eq!(
+            parser("[^a]").parse_set_class_open(), {
+                let set = ast::ClassBracketed {
+                    span: span(0..2),
+                    negated: true,
+                    kind: ast::ClassSet::union(ast::ClassSetUnion {
+                        span: span(2..2),
+                        items: vec![],
+                    }),
+                };
+                let union = ast::ClassSetUnion {
+                    span: span(2..2),
+                    items: vec![],
+                };
+                Ok((set, union))
+            });
+        assert_eq!(
+            parser_ignore_whitespace("[ ^ a]").parse_set_class_open(), {
+                let set = ast::ClassBracketed {
+                    span: span(0..4),
+                    negated: true,
+                    kind: ast::ClassSet::union(ast::ClassSetUnion {
+                        span: span(4..4),
+                        items: vec![],
+                    }),
+                };
+                let union = ast::ClassSetUnion {
+                    span: span(4..4),
+                    items: vec![],
+                };
+                Ok((set, union))
+            });
+        assert_eq!(
+            parser("[-a]").parse_set_class_open(), {
+                let set = ast::ClassBracketed {
+                    span: span(0..2),
+                    negated: false,
+                    kind: ast::ClassSet::union(ast::ClassSetUnion {
+                        span: span(1..1),
+                        items: vec![],
+                    }),
+                };
+                let union = ast::ClassSetUnion {
+                    span: span(1..2),
+                    items: vec![
+                        ast::ClassSetItem::Literal(ast::Literal {
+                            span: span(1..2),
+                            kind: ast::LiteralKind::Verbatim,
+                            c: '-',
+                        }),
+                    ],
+                };
+                Ok((set, union))
+            });
+        assert_eq!(
+            parser_ignore_whitespace("[ - a]").parse_set_class_open(), {
+                let set = ast::ClassBracketed {
+                    span: span(0..4),
+                    negated: false,
+                    kind: ast::ClassSet::union(ast::ClassSetUnion {
+                        span: span(2..2),
+                        items: vec![],
+                    }),
+                };
+                let union = ast::ClassSetUnion {
+                    span: span(2..3),
+                    items: vec![
+                        ast::ClassSetItem::Literal(ast::Literal {
+                            span: span(2..3),
+                            kind: ast::LiteralKind::Verbatim,
+                            c: '-',
+                        }),
+                    ],
+                };
+                Ok((set, union))
+            });
+        assert_eq!(
+            parser("[^-a]").parse_set_class_open(), {
+                let set = ast::ClassBracketed {
+                    span: span(0..3),
+                    negated: true,
+                    kind: ast::ClassSet::union(ast::ClassSetUnion {
+                        span: span(2..2),
+                        items: vec![],
+                    }),
+                };
+                let union = ast::ClassSetUnion {
+                    span: span(2..3),
+                    items: vec![
+                        ast::ClassSetItem::Literal(ast::Literal {
+                            span: span(2..3),
+                            kind: ast::LiteralKind::Verbatim,
+                            c: '-',
+                        }),
+                    ],
+                };
+                Ok((set, union))
+            });
+        assert_eq!(
+            parser("[--a]").parse_set_class_open(), {
+                let set = ast::ClassBracketed {
+                    span: span(0..3),
+                    negated: false,
+                    kind: ast::ClassSet::union(ast::ClassSetUnion {
+                        span: span(1..1),
+                        items: vec![],
+                    }),
+                };
+                let union = ast::ClassSetUnion {
+                    span: span(1..3),
+                    items: vec![
+                        ast::ClassSetItem::Literal(ast::Literal {
+                            span: span(1..2),
+                            kind: ast::LiteralKind::Verbatim,
+                            c: '-',
+                        }),
+                        ast::ClassSetItem::Literal(ast::Literal {
+                            span: span(2..3),
+                            kind: ast::LiteralKind::Verbatim,
+                            c: '-',
+                        }),
+                    ],
+                };
+                Ok((set, union))
+            });
+        assert_eq!(
+            parser("[]a]").parse_set_class_open(), {
+                let set = ast::ClassBracketed {
+                    span: span(0..2),
+                    negated: false,
+                    kind: ast::ClassSet::union(ast::ClassSetUnion {
+                        span: span(1..1),
+                        items: vec![],
+                    }),
+                };
+                let union = ast::ClassSetUnion {
+                    span: span(1..2),
+                    items: vec![
+                        ast::ClassSetItem::Literal(ast::Literal {
+                            span: span(1..2),
+                            kind: ast::LiteralKind::Verbatim,
+                            c: ']',
+                        }),
+                    ],
+                };
+                Ok((set, union))
+            });
+        assert_eq!(
+            parser_ignore_whitespace("[ ] a]").parse_set_class_open(), {
+                let set = ast::ClassBracketed {
+                    span: span(0..4),
+                    negated: false,
+                    kind: ast::ClassSet::union(ast::ClassSetUnion {
+                        span: span(2..2),
+                        items: vec![],
+                    }),
+                };
+                let union = ast::ClassSetUnion {
+                    span: span(2..3),
+                    items: vec![
+                        ast::ClassSetItem::Literal(ast::Literal {
+                            span: span(2..3),
+                            kind: ast::LiteralKind::Verbatim,
+                            c: ']',
+                        }),
+                    ],
+                };
+                Ok((set, union))
+            });
+        assert_eq!(
+            parser("[^]a]").parse_set_class_open(), {
+                let set = ast::ClassBracketed {
+                    span: span(0..3),
+                    negated: true,
+                    kind: ast::ClassSet::union(ast::ClassSetUnion {
+                        span: span(2..2),
+                        items: vec![],
+                    }),
+                };
+                let union = ast::ClassSetUnion {
+                    span: span(2..3),
+                    items: vec![
+                        ast::ClassSetItem::Literal(ast::Literal {
+                            span: span(2..3),
+                            kind: ast::LiteralKind::Verbatim,
+                            c: ']',
+                        }),
+                    ],
+                };
+                Ok((set, union))
+            });
+        assert_eq!(
+            parser("[-]a]").parse_set_class_open(), {
+                let set = ast::ClassBracketed {
+                    span: span(0..2),
+                    negated: false,
+                    kind: ast::ClassSet::union(ast::ClassSetUnion {
+                        span: span(1..1),
+                        items: vec![],
+                    }),
+                };
+                let union = ast::ClassSetUnion {
+                    span: span(1..2),
+                    items: vec![
+                        ast::ClassSetItem::Literal(ast::Literal {
+                            span: span(1..2),
+                            kind: ast::LiteralKind::Verbatim,
+                            c: '-',
+                        }),
+                    ],
+                };
+                Ok((set, union))
+            });
+
+        assert_eq!(
+            parser("[").parse_set_class_open().unwrap_err(),
+            TestError {
+                span: span(0..1),
+                kind: ast::ErrorKind::ClassUnclosed,
+            });
+        assert_eq!(
+            parser_ignore_whitespace("[    ")
+            .parse_set_class_open()
+            .unwrap_err(),
+            TestError {
+                span: span(0..5),
+                kind: ast::ErrorKind::ClassUnclosed,
+            });
+        assert_eq!(
+            parser("[^").parse_set_class_open().unwrap_err(),
+            TestError {
+                span: span(0..2),
+                kind: ast::ErrorKind::ClassUnclosed,
+            });
+        assert_eq!(
+            parser("[]").parse_set_class_open().unwrap_err(),
+            TestError {
+                span: span(0..2),
+                kind: ast::ErrorKind::ClassUnclosed,
+            });
+        assert_eq!(
+            parser("[-").parse_set_class_open().unwrap_err(),
+            TestError {
+                span: span(0..2),
+                kind: ast::ErrorKind::ClassUnclosed,
+            });
+        assert_eq!(
+            parser("[--").parse_set_class_open().unwrap_err(),
+            TestError {
+                span: span(0..3),
+                kind: ast::ErrorKind::ClassUnclosed,
+            });
+    }
+
+    #[test]
+    fn maybe_parse_ascii_class() {
+        assert_eq!(
+            parser(r"[:alnum:]").maybe_parse_ascii_class(),
+            Some(ast::ClassAscii {
+                span: span(0..9),
+                kind: ast::ClassAsciiKind::Alnum,
+                negated: false,
+            }));
+        assert_eq!(
+            parser(r"[:alnum:]A").maybe_parse_ascii_class(),
+            Some(ast::ClassAscii {
+                span: span(0..9),
+                kind: ast::ClassAsciiKind::Alnum,
+                negated: false,
+            }));
+        assert_eq!(
+            parser(r"[:^alnum:]").maybe_parse_ascii_class(),
+            Some(ast::ClassAscii {
+                span: span(0..10),
+                kind: ast::ClassAsciiKind::Alnum,
+                negated: true,
+            }));
+
+        let p = parser(r"[:");
+        assert_eq!(p.maybe_parse_ascii_class(), None);
+        assert_eq!(p.offset(), 0);
+
+        let p = parser(r"[:^");
+        assert_eq!(p.maybe_parse_ascii_class(), None);
+        assert_eq!(p.offset(), 0);
+
+        let p = parser(r"[^:alnum:]");
+        assert_eq!(p.maybe_parse_ascii_class(), None);
+        assert_eq!(p.offset(), 0);
+
+        let p = parser(r"[:alnnum:]");
+        assert_eq!(p.maybe_parse_ascii_class(), None);
+        assert_eq!(p.offset(), 0);
+
+        let p = parser(r"[:alnum]");
+        assert_eq!(p.maybe_parse_ascii_class(), None);
+        assert_eq!(p.offset(), 0);
+
+        let p = parser(r"[:alnum:");
+        assert_eq!(p.maybe_parse_ascii_class(), None);
+        assert_eq!(p.offset(), 0);
+    }
+
+    #[test]
+    fn parse_unicode_class() {
+        assert_eq!(
+            parser(r"\pN").parse_escape(),
+            Ok(Primitive::Unicode(ast::ClassUnicode {
+                span: span(0..3),
+                negated: false,
+                kind: ast::ClassUnicodeKind::OneLetter('N'),
+            })));
+        assert_eq!(
+            parser(r"\PN").parse_escape(),
+            Ok(Primitive::Unicode(ast::ClassUnicode {
+                span: span(0..3),
+                negated: true,
+                kind: ast::ClassUnicodeKind::OneLetter('N'),
+            })));
+        assert_eq!(
+            parser(r"\p{N}").parse_escape(),
+            Ok(Primitive::Unicode(ast::ClassUnicode {
+                span: span(0..5),
+                negated: false,
+                kind: ast::ClassUnicodeKind::Named(s("N")),
+            })));
+        assert_eq!(
+            parser(r"\P{N}").parse_escape(),
+            Ok(Primitive::Unicode(ast::ClassUnicode {
+                span: span(0..5),
+                negated: true,
+                kind: ast::ClassUnicodeKind::Named(s("N")),
+            })));
+        assert_eq!(
+            parser(r"\p{Greek}").parse_escape(),
+            Ok(Primitive::Unicode(ast::ClassUnicode {
+                span: span(0..9),
+                negated: false,
+                kind: ast::ClassUnicodeKind::Named(s("Greek")),
+            })));
+
+        assert_eq!(
+            parser(r"\p{scx:Katakana}").parse_escape(),
+            Ok(Primitive::Unicode(ast::ClassUnicode {
+                span: span(0..16),
+                negated: false,
+                kind: ast::ClassUnicodeKind::NamedValue {
+                    op: ast::ClassUnicodeOpKind::Colon,
+                    name: s("scx"),
+                    value: s("Katakana"),
+                },
+            })));
+        assert_eq!(
+            parser(r"\p{scx=Katakana}").parse_escape(),
+            Ok(Primitive::Unicode(ast::ClassUnicode {
+                span: span(0..16),
+                negated: false,
+                kind: ast::ClassUnicodeKind::NamedValue {
+                    op: ast::ClassUnicodeOpKind::Equal,
+                    name: s("scx"),
+                    value: s("Katakana"),
+                },
+            })));
+        assert_eq!(
+            parser(r"\p{scx!=Katakana}").parse_escape(),
+            Ok(Primitive::Unicode(ast::ClassUnicode {
+                span: span(0..17),
+                negated: false,
+                kind: ast::ClassUnicodeKind::NamedValue {
+                    op: ast::ClassUnicodeOpKind::NotEqual,
+                    name: s("scx"),
+                    value: s("Katakana"),
+                },
+            })));
+
+        assert_eq!(
+            parser(r"\p{:}").parse_escape(),
+            Ok(Primitive::Unicode(ast::ClassUnicode {
+                span: span(0..5),
+                negated: false,
+                kind: ast::ClassUnicodeKind::NamedValue {
+                    op: ast::ClassUnicodeOpKind::Colon,
+                    name: s(""),
+                    value: s(""),
+                },
+            })));
+        assert_eq!(
+            parser(r"\p{=}").parse_escape(),
+            Ok(Primitive::Unicode(ast::ClassUnicode {
+                span: span(0..5),
+                negated: false,
+                kind: ast::ClassUnicodeKind::NamedValue {
+                    op: ast::ClassUnicodeOpKind::Equal,
+                    name: s(""),
+                    value: s(""),
+                },
+            })));
+        assert_eq!(
+            parser(r"\p{!=}").parse_escape(),
+            Ok(Primitive::Unicode(ast::ClassUnicode {
+                span: span(0..6),
+                negated: false,
+                kind: ast::ClassUnicodeKind::NamedValue {
+                    op: ast::ClassUnicodeOpKind::NotEqual,
+                    name: s(""),
+                    value: s(""),
+                },
+            })));
+
+        assert_eq!(
+            parser(r"\p").parse_escape().unwrap_err(),
+            TestError {
+                span: span(2..2),
+                kind: ast::ErrorKind::EscapeUnexpectedEof,
+            });
+        assert_eq!(
+            parser(r"\p{").parse_escape().unwrap_err(),
+            TestError {
+                span: span(3..3),
+                kind: ast::ErrorKind::EscapeUnexpectedEof,
+            });
+        assert_eq!(
+            parser(r"\p{N").parse_escape().unwrap_err(),
+            TestError {
+                span: span(4..4),
+                kind: ast::ErrorKind::EscapeUnexpectedEof,
+            });
+        assert_eq!(
+            parser(r"\p{Greek").parse_escape().unwrap_err(),
+            TestError {
+                span: span(8..8),
+                kind: ast::ErrorKind::EscapeUnexpectedEof,
+            });
+
+        assert_eq!(
+            parser(r"\pNz").parse(),
+            Ok(Ast::Concat(ast::Concat {
+                span: span(0..4),
+                asts: vec![
+                    Ast::Class(ast::Class::Unicode(ast::ClassUnicode {
+                        span: span(0..3),
+                        negated: false,
+                        kind: ast::ClassUnicodeKind::OneLetter('N'),
+                    })),
+                    Ast::Literal(ast::Literal {
+                        span: span(3..4),
+                        kind: ast::LiteralKind::Verbatim,
+                        c: 'z',
+                    }),
+                ],
+            })));
+        assert_eq!(
+            parser(r"\p{Greek}z").parse(),
+            Ok(Ast::Concat(ast::Concat {
+                span: span(0..10),
+                asts: vec![
+                    Ast::Class(ast::Class::Unicode(ast::ClassUnicode {
+                        span: span(0..9),
+                        negated: false,
+                        kind: ast::ClassUnicodeKind::Named(s("Greek")),
+                    })),
+                    Ast::Literal(ast::Literal {
+                        span: span(9..10),
+                        kind: ast::LiteralKind::Verbatim,
+                        c: 'z',
+                    }),
+                ],
+            })));
+    }
+
+    #[test]
+    fn parse_perl_class() {
+        assert_eq!(
+            parser(r"\d").parse_escape(),
+            Ok(Primitive::Perl(ast::ClassPerl {
+                span: span(0..2),
+                kind: ast::ClassPerlKind::Digit,
+                negated: false,
+            })));
+        assert_eq!(
+            parser(r"\D").parse_escape(),
+            Ok(Primitive::Perl(ast::ClassPerl {
+                span: span(0..2),
+                kind: ast::ClassPerlKind::Digit,
+                negated: true,
+            })));
+        assert_eq!(
+            parser(r"\s").parse_escape(),
+            Ok(Primitive::Perl(ast::ClassPerl {
+                span: span(0..2),
+                kind: ast::ClassPerlKind::Space,
+                negated: false,
+            })));
+        assert_eq!(
+            parser(r"\S").parse_escape(),
+            Ok(Primitive::Perl(ast::ClassPerl {
+                span: span(0..2),
+                kind: ast::ClassPerlKind::Space,
+                negated: true,
+            })));
+        assert_eq!(
+            parser(r"\w").parse_escape(),
+            Ok(Primitive::Perl(ast::ClassPerl {
+                span: span(0..2),
+                kind: ast::ClassPerlKind::Word,
+                negated: false,
+            })));
+        assert_eq!(
+            parser(r"\W").parse_escape(),
+            Ok(Primitive::Perl(ast::ClassPerl {
+                span: span(0..2),
+                kind: ast::ClassPerlKind::Word,
+                negated: true,
+            })));
+
+        assert_eq!(
+            parser(r"\d").parse(),
+            Ok(Ast::Class(ast::Class::Perl(ast::ClassPerl {
+                span: span(0..2),
+                kind: ast::ClassPerlKind::Digit,
+                negated: false,
+            }))));
+        assert_eq!(
+            parser(r"\dz").parse(),
+            Ok(Ast::Concat(ast::Concat {
+                span: span(0..3),
+                asts: vec![
+                    Ast::Class(ast::Class::Perl(ast::ClassPerl {
+                        span: span(0..2),
+                        kind: ast::ClassPerlKind::Digit,
+                        negated: false,
+                    })),
+                    Ast::Literal(ast::Literal {
+                        span: span(2..3),
+                        kind: ast::LiteralKind::Verbatim,
+                        c: 'z',
+                    }),
+                ],
+            })));
+    }
+
+    // This tests a bug fix where the nest limit checker wasn't decrementing
+    // its depth during post-traversal, which causes long regexes to trip
+    // the default limit too aggressively.
+    #[test]
+    fn regression_454_nest_too_big() {
+        let pattern = r#"
+        2(?:
+          [45]\d{3}|
+          7(?:
+            1[0-267]|
+            2[0-289]|
+            3[0-29]|
+            4[01]|
+            5[1-3]|
+            6[013]|
+            7[0178]|
+            91
+          )|
+          8(?:
+            0[125]|
+            [139][1-6]|
+            2[0157-9]|
+            41|
+            6[1-35]|
+            7[1-5]|
+            8[1-8]|
+            90
+          )|
+          9(?:
+            0[0-2]|
+            1[0-4]|
+            2[568]|
+            3[3-6]|
+            5[5-7]|
+            6[0167]|
+            7[15]|
+            8[0146-9]
+          )
+        )\d{4}
+        "#;
+        assert!(parser_nest_limit(pattern, 50).parse().is_ok());
+    }
+
+    // This tests that we treat a trailing `-` in a character class as a
+    // literal `-` even when whitespace mode is enabled and there is whitespace
+    // after the trailing `-`.
+    #[test]
+    fn regression_455_trailing_dash_ignore_whitespace() {
+        assert!(parser("(?x)[ / - ]").parse().is_ok());
+        assert!(parser("(?x)[ a - ]").parse().is_ok());
+        assert!(parser("(?x)[
+            a
+            - ]
+        ").parse().is_ok());
+        assert!(parser("(?x)[
+            a # wat
+            - ]
+        ").parse().is_ok());
+
+        assert!(parser("(?x)[ / -").parse().is_err());
+        assert!(parser("(?x)[ / - ").parse().is_err());
+        assert!(parser("(?x)[
+            / -
+        ").parse().is_err());
+        assert!(parser("(?x)[
+            / - # wat
+        ").parse().is_err());
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/ast/print.rs.html b/target/doc/src/regex_syntax/ast/print.rs.html new file mode 100644 index 0000000..f4cd34b --- /dev/null +++ b/target/doc/src/regex_syntax/ast/print.rs.html @@ -0,0 +1,1175 @@ +print.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+This module provides a regular expression printer for `Ast`.
+*/
+
+use std::fmt;
+
+use ast::{self, Ast};
+use ast::visitor::{self, Visitor};
+
+/// A builder for constructing a printer.
+///
+/// Note that since a printer doesn't have any configuration knobs, this type
+/// remains unexported.
+#[derive(Clone, Debug)]
+struct PrinterBuilder {
+    _priv: (),
+}
+
+impl Default for PrinterBuilder {
+    fn default() -> PrinterBuilder {
+        PrinterBuilder::new()
+    }
+}
+
+impl PrinterBuilder {
+    fn new() -> PrinterBuilder {
+        PrinterBuilder {
+            _priv: (),
+        }
+    }
+
+    fn build(&self) -> Printer {
+        Printer {
+            _priv: (),
+        }
+    }
+}
+
+/// A printer for a regular expression abstract syntax tree.
+///
+/// A printer converts an abstract syntax tree (AST) to a regular expression
+/// pattern string. This particular printer uses constant stack space and heap
+/// space proportional to the size of the AST.
+///
+/// This printer will not necessarily preserve the original formatting of the
+/// regular expression pattern string. For example, all whitespace and comments
+/// are ignored.
+#[derive(Debug)]
+pub struct Printer {
+    _priv: (),
+}
+
+impl Printer {
+    /// Create a new printer.
+    pub fn new() -> Printer {
+        PrinterBuilder::new().build()
+    }
+
+    /// Print the given `Ast` to the given writer. The writer must implement
+    /// `fmt::Write`. Typical implementations of `fmt::Write` that can be used
+    /// here are a `fmt::Formatter` (which is available in `fmt::Display`
+    /// implementations) or a `&mut String`.
+    pub fn print<W: fmt::Write>(&mut self, ast: &Ast, wtr: W) -> fmt::Result {
+        visitor::visit(ast, Writer { printer: self, wtr: wtr })
+    }
+}
+
+#[derive(Debug)]
+struct Writer<'p, W> {
+    printer: &'p mut Printer,
+    wtr: W,
+}
+
+impl<'p, W: fmt::Write> Visitor for Writer<'p, W> {
+    type Output = ();
+    type Err = fmt::Error;
+
+    fn finish(self) -> fmt::Result {
+        Ok(())
+    }
+
+    fn visit_pre(&mut self, ast: &Ast) -> fmt::Result {
+        match *ast {
+            Ast::Group(ref x) => self.fmt_group_pre(x),
+            Ast::Class(ast::Class::Bracketed(ref x)) => {
+                self.fmt_class_bracketed_pre(x)
+            }
+            _ => Ok(())
+        }
+    }
+
+    fn visit_post(&mut self, ast: &Ast) -> fmt::Result {
+        use ast::Class;
+
+        match *ast {
+            Ast::Empty(_) => Ok(()),
+            Ast::Flags(ref x) => self.fmt_set_flags(x),
+            Ast::Literal(ref x) => self.fmt_literal(x),
+            Ast::Dot(_) => self.wtr.write_str("."),
+            Ast::Assertion(ref x) => self.fmt_assertion(x),
+            Ast::Class(Class::Perl(ref x)) => self.fmt_class_perl(x),
+            Ast::Class(Class::Unicode(ref x)) => self.fmt_class_unicode(x),
+            Ast::Class(Class::Bracketed(ref x)) => {
+                self.fmt_class_bracketed_post(x)
+            }
+            Ast::Repetition(ref x) => self.fmt_repetition(x),
+            Ast::Group(ref x) => self.fmt_group_post(x),
+            Ast::Alternation(_) => Ok(()),
+            Ast::Concat(_) => Ok(()),
+        }
+    }
+
+    fn visit_alternation_in(&mut self) -> fmt::Result {
+        self.wtr.write_str("|")
+    }
+
+    fn visit_class_set_item_pre(
+        &mut self,
+        ast: &ast::ClassSetItem,
+    ) -> Result<(), Self::Err> {
+        match *ast {
+            ast::ClassSetItem::Bracketed(ref x) => {
+                self.fmt_class_bracketed_pre(x)
+            }
+            _ => Ok(()),
+        }
+    }
+
+    fn visit_class_set_item_post(
+        &mut self,
+        ast: &ast::ClassSetItem,
+    ) -> Result<(), Self::Err> {
+        use ast::ClassSetItem::*;
+
+        match *ast {
+            Empty(_) => Ok(()),
+            Literal(ref x) => self.fmt_literal(x),
+            Range(ref x) => {
+                self.fmt_literal(&x.start)?;
+                self.wtr.write_str("-")?;
+                self.fmt_literal(&x.end)?;
+                Ok(())
+            }
+            Ascii(ref x) => self.fmt_class_ascii(x),
+            Unicode(ref x) => self.fmt_class_unicode(x),
+            Perl(ref x) => self.fmt_class_perl(x),
+            Bracketed(ref x) => self.fmt_class_bracketed_post(x),
+            Union(_) => Ok(()),
+        }
+    }
+
+    fn visit_class_set_binary_op_in(
+        &mut self,
+        ast: &ast::ClassSetBinaryOp,
+    ) -> Result<(), Self::Err> {
+        self.fmt_class_set_binary_op_kind(&ast.kind)
+    }
+}
+
+impl<'p, W: fmt::Write> Writer<'p, W> {
+    fn fmt_group_pre(&mut self, ast: &ast::Group) -> fmt::Result {
+        use ast::GroupKind::*;
+        match ast.kind {
+            CaptureIndex(_) => self.wtr.write_str("("),
+            CaptureName(ref x) => {
+                self.wtr.write_str("(?P<")?;
+                self.wtr.write_str(&x.name)?;
+                self.wtr.write_str(">")?;
+                Ok(())
+            }
+            NonCapturing(ref flags) => {
+                self.wtr.write_str("(?")?;
+                self.fmt_flags(flags)?;
+                self.wtr.write_str(":")?;
+                Ok(())
+            }
+        }
+    }
+
+    fn fmt_group_post(&mut self, _ast: &ast::Group) -> fmt::Result {
+        self.wtr.write_str(")")
+    }
+
+    fn fmt_repetition(&mut self, ast: &ast::Repetition) -> fmt::Result {
+        use ast::RepetitionKind::*;
+        match ast.op.kind {
+            ZeroOrOne if ast.greedy => self.wtr.write_str("?"),
+            ZeroOrOne => self.wtr.write_str("??"),
+            ZeroOrMore if ast.greedy => self.wtr.write_str("*"),
+            ZeroOrMore => self.wtr.write_str("*?"),
+            OneOrMore if ast.greedy => self.wtr.write_str("+"),
+            OneOrMore => self.wtr.write_str("+?"),
+            Range(ref x) => {
+                self.fmt_repetition_range(x)?;
+                if !ast.greedy {
+                    self.wtr.write_str("?")?;
+                }
+                Ok(())
+            }
+        }
+    }
+
+    fn fmt_repetition_range(
+        &mut self,
+        ast: &ast::RepetitionRange,
+    ) -> fmt::Result {
+        use ast::RepetitionRange::*;
+        match *ast {
+            Exactly(x) => write!(self.wtr, "{{{}}}", x),
+            AtLeast(x) => write!(self.wtr, "{{{},}}", x),
+            Bounded(x, y) => write!(self.wtr, "{{{},{}}}", x, y),
+        }
+    }
+
+    fn fmt_literal(&mut self, ast: &ast::Literal) -> fmt::Result {
+        use ast::LiteralKind::*;
+
+        match ast.kind {
+            Verbatim => self.wtr.write_char(ast.c),
+            Punctuation => write!(self.wtr, r"\{}", ast.c),
+            Octal => write!(self.wtr, r"\{:o}", ast.c as u32),
+            HexFixed(ast::HexLiteralKind::X) => {
+                write!(self.wtr, r"\x{:02X}", ast.c as u32)
+            }
+            HexFixed(ast::HexLiteralKind::UnicodeShort) => {
+                write!(self.wtr, r"\u{:04X}", ast.c as u32)
+            }
+            HexFixed(ast::HexLiteralKind::UnicodeLong) => {
+                write!(self.wtr, r"\U{:08X}", ast.c as u32)
+            }
+            HexBrace(ast::HexLiteralKind::X) => {
+                write!(self.wtr, r"\x{{{:X}}}", ast.c as u32)
+            }
+            HexBrace(ast::HexLiteralKind::UnicodeShort) => {
+                write!(self.wtr, r"\u{{{:X}}}", ast.c as u32)
+            }
+            HexBrace(ast::HexLiteralKind::UnicodeLong) => {
+                write!(self.wtr, r"\U{{{:X}}}", ast.c as u32)
+            }
+            Special(ast::SpecialLiteralKind::Bell) => {
+                self.wtr.write_str(r"\a")
+            }
+            Special(ast::SpecialLiteralKind::FormFeed) => {
+                self.wtr.write_str(r"\f")
+            }
+            Special(ast::SpecialLiteralKind::Tab) => {
+                self.wtr.write_str(r"\t")
+            }
+            Special(ast::SpecialLiteralKind::LineFeed) => {
+                self.wtr.write_str(r"\n")
+            }
+            Special(ast::SpecialLiteralKind::CarriageReturn) => {
+                self.wtr.write_str(r"\r")
+            }
+            Special(ast::SpecialLiteralKind::VerticalTab) => {
+                self.wtr.write_str(r"\v")
+            }
+            Special(ast::SpecialLiteralKind::Space) => {
+                self.wtr.write_str(r"\ ")
+            }
+        }
+    }
+
+    fn fmt_assertion(&mut self, ast: &ast::Assertion) -> fmt::Result {
+        use ast::AssertionKind::*;
+        match ast.kind {
+            StartLine => self.wtr.write_str("^"),
+            EndLine => self.wtr.write_str("$"),
+            StartText => self.wtr.write_str(r"\A"),
+            EndText => self.wtr.write_str(r"\z"),
+            WordBoundary => self.wtr.write_str(r"\b"),
+            NotWordBoundary => self.wtr.write_str(r"\B"),
+        }
+    }
+
+    fn fmt_set_flags(&mut self, ast: &ast::SetFlags) -> fmt::Result {
+        self.wtr.write_str("(?")?;
+        self.fmt_flags(&ast.flags)?;
+        self.wtr.write_str(")")?;
+        Ok(())
+    }
+
+    fn fmt_flags(&mut self, ast: &ast::Flags) -> fmt::Result {
+        use ast::{Flag, FlagsItemKind};
+
+        for item in &ast.items {
+            match item.kind {
+                FlagsItemKind::Negation => self.wtr.write_str("-"),
+                FlagsItemKind::Flag(ref flag) => {
+                    match *flag {
+                        Flag::CaseInsensitive => self.wtr.write_str("i"),
+                        Flag::MultiLine => self.wtr.write_str("m"),
+                        Flag::DotMatchesNewLine => self.wtr.write_str("s"),
+                        Flag::SwapGreed => self.wtr.write_str("U"),
+                        Flag::Unicode => self.wtr.write_str("u"),
+                        Flag::IgnoreWhitespace => self.wtr.write_str("x"),
+                    }
+                }
+            }?;
+        }
+        Ok(())
+    }
+
+    fn fmt_class_bracketed_pre(
+        &mut self,
+        ast: &ast::ClassBracketed,
+    ) -> fmt::Result {
+        if ast.negated {
+            self.wtr.write_str("[^")
+        } else {
+            self.wtr.write_str("[")
+        }
+    }
+
+    fn fmt_class_bracketed_post(
+        &mut self,
+        _ast: &ast::ClassBracketed,
+    ) -> fmt::Result {
+        self.wtr.write_str("]")
+    }
+
+    fn fmt_class_set_binary_op_kind(
+        &mut self,
+        ast: &ast::ClassSetBinaryOpKind,
+    ) -> fmt::Result {
+        use ast::ClassSetBinaryOpKind::*;
+        match *ast {
+            Intersection => self.wtr.write_str("&&"),
+            Difference => self.wtr.write_str("--"),
+            SymmetricDifference => self.wtr.write_str("~~"),
+        }
+    }
+
+    fn fmt_class_perl(&mut self, ast: &ast::ClassPerl) -> fmt::Result {
+        use ast::ClassPerlKind::*;
+        match ast.kind {
+            Digit if ast.negated => self.wtr.write_str(r"\D"),
+            Digit => self.wtr.write_str(r"\d"),
+            Space if ast.negated => self.wtr.write_str(r"\S"),
+            Space => self.wtr.write_str(r"\s"),
+            Word if ast.negated => self.wtr.write_str(r"\W"),
+            Word => self.wtr.write_str(r"\w"),
+        }
+    }
+
+    fn fmt_class_ascii(&mut self, ast: &ast::ClassAscii) -> fmt::Result {
+        use ast::ClassAsciiKind::*;
+        match ast.kind {
+            Alnum if ast.negated => self.wtr.write_str("[:^alnum:]"),
+            Alnum => self.wtr.write_str("[:alnum:]"),
+            Alpha if ast.negated => self.wtr.write_str("[:^alpha:]"),
+            Alpha => self.wtr.write_str("[:alpha:]"),
+            Ascii if ast.negated => self.wtr.write_str("[:^ascii:]"),
+            Ascii => self.wtr.write_str("[:ascii:]"),
+            Blank if ast.negated => self.wtr.write_str("[:^blank:]"),
+            Blank => self.wtr.write_str("[:blank:]"),
+            Cntrl if ast.negated => self.wtr.write_str("[:^cntrl:]"),
+            Cntrl => self.wtr.write_str("[:cntrl:]"),
+            Digit if ast.negated => self.wtr.write_str("[:^digit:]"),
+            Digit => self.wtr.write_str("[:digit:]"),
+            Graph if ast.negated => self.wtr.write_str("[:^graph:]"),
+            Graph => self.wtr.write_str("[:graph:]"),
+            Lower if ast.negated => self.wtr.write_str("[:^lower:]"),
+            Lower => self.wtr.write_str("[:lower:]"),
+            Print if ast.negated => self.wtr.write_str("[:^print:]"),
+            Print => self.wtr.write_str("[:print:]"),
+            Punct if ast.negated => self.wtr.write_str("[:^punct:]"),
+            Punct => self.wtr.write_str("[:punct:]"),
+            Space if ast.negated => self.wtr.write_str("[:^space:]"),
+            Space => self.wtr.write_str("[:space:]"),
+            Upper if ast.negated => self.wtr.write_str("[:^upper:]"),
+            Upper => self.wtr.write_str("[:upper:]"),
+            Word if ast.negated => self.wtr.write_str("[:^word:]"),
+            Word => self.wtr.write_str("[:word:]"),
+            Xdigit if ast.negated => self.wtr.write_str("[:^xdigit:]"),
+            Xdigit => self.wtr.write_str("[:xdigit:]"),
+        }
+    }
+
+    fn fmt_class_unicode(&mut self, ast: &ast::ClassUnicode) -> fmt::Result {
+        use ast::ClassUnicodeKind::*;
+        use ast::ClassUnicodeOpKind::*;
+
+        if ast.negated {
+            self.wtr.write_str(r"\P")?;
+        } else {
+            self.wtr.write_str(r"\p")?;
+        }
+        match ast.kind {
+            OneLetter(c) => self.wtr.write_char(c),
+            Named(ref x) => write!(self.wtr, "{{{}}}", x),
+            NamedValue { op: Equal, ref name, ref value } => {
+                write!(self.wtr, "{{{}={}}}", name, value)
+            }
+            NamedValue { op: Colon, ref name, ref value } => {
+                write!(self.wtr, "{{{}:{}}}", name, value)
+            }
+            NamedValue { op: NotEqual, ref name, ref value } => {
+                write!(self.wtr, "{{{}!={}}}", name, value)
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use ast::parse::ParserBuilder;
+    use super::Printer;
+
+    fn roundtrip(given: &str) {
+        roundtrip_with(|b| b, given);
+    }
+
+    fn roundtrip_with<F>(mut f: F, given: &str)
+    where F: FnMut(&mut ParserBuilder) -> &mut ParserBuilder
+    {
+        let mut builder = ParserBuilder::new();
+        f(&mut builder);
+        let ast = builder.build().parse(given).unwrap();
+
+        let mut printer = Printer::new();
+        let mut dst = String::new();
+        printer.print(&ast, &mut dst).unwrap();
+        assert_eq!(given, dst);
+    }
+
+    #[test]
+    fn print_literal() {
+        roundtrip("a");
+        roundtrip(r"\[");
+        roundtrip_with(|b| b.octal(true), r"\141");
+        roundtrip(r"\x61");
+        roundtrip(r"\x7F");
+        roundtrip(r"\u0061");
+        roundtrip(r"\U00000061");
+        roundtrip(r"\x{61}");
+        roundtrip(r"\x{7F}");
+        roundtrip(r"\u{61}");
+        roundtrip(r"\U{61}");
+
+        roundtrip(r"\a");
+        roundtrip(r"\f");
+        roundtrip(r"\t");
+        roundtrip(r"\n");
+        roundtrip(r"\r");
+        roundtrip(r"\v");
+        roundtrip(r"(?x)\ ");
+    }
+
+    #[test]
+    fn print_dot() {
+        roundtrip(".");
+    }
+
+    #[test]
+    fn print_concat() {
+        roundtrip("ab");
+        roundtrip("abcde");
+        roundtrip("a(bcd)ef");
+    }
+
+    #[test]
+    fn print_alternation() {
+        roundtrip("a|b");
+        roundtrip("a|b|c|d|e");
+        roundtrip("|a|b|c|d|e");
+        roundtrip("|a|b|c|d|e|");
+        roundtrip("a(b|c|d)|e|f");
+    }
+
+    #[test]
+    fn print_assertion() {
+        roundtrip(r"^");
+        roundtrip(r"$");
+        roundtrip(r"\A");
+        roundtrip(r"\z");
+        roundtrip(r"\b");
+        roundtrip(r"\B");
+    }
+
+    #[test]
+    fn print_repetition() {
+        roundtrip("a?");
+        roundtrip("a??");
+        roundtrip("a*");
+        roundtrip("a*?");
+        roundtrip("a+");
+        roundtrip("a+?");
+        roundtrip("a{5}");
+        roundtrip("a{5}?");
+        roundtrip("a{5,}");
+        roundtrip("a{5,}?");
+        roundtrip("a{5,10}");
+        roundtrip("a{5,10}?");
+    }
+
+    #[test]
+    fn print_flags() {
+        roundtrip("(?i)");
+        roundtrip("(?-i)");
+        roundtrip("(?s-i)");
+        roundtrip("(?-si)");
+        roundtrip("(?siUmux)");
+    }
+
+    #[test]
+    fn print_group() {
+        roundtrip("(?i:a)");
+        roundtrip("(?P<foo>a)");
+        roundtrip("(a)");
+    }
+
+    #[test]
+    fn print_class() {
+        roundtrip(r"[abc]");
+        roundtrip(r"[a-z]");
+        roundtrip(r"[^a-z]");
+        roundtrip(r"[a-z0-9]");
+        roundtrip(r"[-a-z0-9]");
+        roundtrip(r"[-a-z0-9]");
+        roundtrip(r"[a-z0-9---]");
+        roundtrip(r"[a-z&&m-n]");
+        roundtrip(r"[[a-z&&m-n]]");
+        roundtrip(r"[a-z--m-n]");
+        roundtrip(r"[a-z~~m-n]");
+        roundtrip(r"[a-z[0-9]]");
+        roundtrip(r"[a-z[^0-9]]");
+
+        roundtrip(r"\d");
+        roundtrip(r"\D");
+        roundtrip(r"\s");
+        roundtrip(r"\S");
+        roundtrip(r"\w");
+        roundtrip(r"\W");
+
+        roundtrip(r"[[:alnum:]]");
+        roundtrip(r"[[:^alnum:]]");
+        roundtrip(r"[[:alpha:]]");
+        roundtrip(r"[[:^alpha:]]");
+        roundtrip(r"[[:ascii:]]");
+        roundtrip(r"[[:^ascii:]]");
+        roundtrip(r"[[:blank:]]");
+        roundtrip(r"[[:^blank:]]");
+        roundtrip(r"[[:cntrl:]]");
+        roundtrip(r"[[:^cntrl:]]");
+        roundtrip(r"[[:digit:]]");
+        roundtrip(r"[[:^digit:]]");
+        roundtrip(r"[[:graph:]]");
+        roundtrip(r"[[:^graph:]]");
+        roundtrip(r"[[:lower:]]");
+        roundtrip(r"[[:^lower:]]");
+        roundtrip(r"[[:print:]]");
+        roundtrip(r"[[:^print:]]");
+        roundtrip(r"[[:punct:]]");
+        roundtrip(r"[[:^punct:]]");
+        roundtrip(r"[[:space:]]");
+        roundtrip(r"[[:^space:]]");
+        roundtrip(r"[[:upper:]]");
+        roundtrip(r"[[:^upper:]]");
+        roundtrip(r"[[:word:]]");
+        roundtrip(r"[[:^word:]]");
+        roundtrip(r"[[:xdigit:]]");
+        roundtrip(r"[[:^xdigit:]]");
+
+        roundtrip(r"\pL");
+        roundtrip(r"\PL");
+        roundtrip(r"\p{L}");
+        roundtrip(r"\P{L}");
+        roundtrip(r"\p{X=Y}");
+        roundtrip(r"\P{X=Y}");
+        roundtrip(r"\p{X:Y}");
+        roundtrip(r"\P{X:Y}");
+        roundtrip(r"\p{X!=Y}");
+        roundtrip(r"\P{X!=Y}");
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/ast/visitor.rs.html b/target/doc/src/regex_syntax/ast/visitor.rs.html new file mode 100644 index 0000000..5fac64d --- /dev/null +++ b/target/doc/src/regex_syntax/ast/visitor.rs.html @@ -0,0 +1,1117 @@ +visitor.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::fmt;
+
+use ast::{self, Ast};
+
+/// A trait for visiting an abstract syntax tree (AST) in depth first order.
+///
+/// The principle aim of this trait is to enable callers to perform case
+/// analysis on an abstract syntax tree without necessarily using recursion.
+/// In particular, this permits callers to do case analysis with constant stack
+/// usage, which can be important since the size of an abstract syntax tree
+/// may be proportional to end user input.
+///
+/// Typical usage of this trait involves providing an implementation and then
+/// running it using the [`visit`](fn.visit.html) function.
+///
+/// Note that the abstract syntax tree for a regular expression is quite
+/// complex. Unless you specifically need it, you might be able to use the
+/// much simpler
+/// [high-level intermediate representation](../hir/struct.Hir.html)
+/// and its
+/// [corresponding `Visitor` trait](../hir/trait.Visitor.html)
+/// instead.
+pub trait Visitor {
+    /// The result of visiting an AST.
+    type Output;
+    /// An error that visiting an AST might return.
+    type Err;
+
+    /// All implementors of `Visitor` must provide a `finish` method, which
+    /// yields the result of visiting the AST or an error.
+    fn finish(self) -> Result<Self::Output, Self::Err>;
+
+    /// This method is called before beginning traversal of the AST.
+    fn start(&mut self) {}
+
+    /// This method is called on an `Ast` before descending into child `Ast`
+    /// nodes.
+    fn visit_pre(&mut self, _ast: &Ast) -> Result<(), Self::Err> {
+        Ok(())
+    }
+
+    /// This method is called on an `Ast` after descending all of its child
+    /// `Ast` nodes.
+    fn visit_post(&mut self, _ast: &Ast) -> Result<(), Self::Err> {
+        Ok(())
+    }
+
+    /// This method is called between child nodes of an
+    /// [`Alternation`](struct.Alternation.html).
+    fn visit_alternation_in(&mut self) -> Result<(), Self::Err> {
+        Ok(())
+    }
+
+    /// This method is called on every
+    /// [`ClassSetItem`](enum.ClassSetItem.html)
+    /// before descending into child nodes.
+    fn visit_class_set_item_pre(
+        &mut self,
+        _ast: &ast::ClassSetItem,
+    ) -> Result<(), Self::Err> {
+        Ok(())
+    }
+
+    /// This method is called on every
+    /// [`ClassSetItem`](enum.ClassSetItem.html)
+    /// after descending into child nodes.
+    fn visit_class_set_item_post(
+        &mut self,
+        _ast: &ast::ClassSetItem,
+    ) -> Result<(), Self::Err> {
+        Ok(())
+    }
+
+    /// This method is called on every
+    /// [`ClassSetBinaryOp`](struct.ClassSetBinaryOp.html)
+    /// before descending into child nodes.
+    fn visit_class_set_binary_op_pre(
+        &mut self,
+        _ast: &ast::ClassSetBinaryOp,
+    ) -> Result<(), Self::Err> {
+        Ok(())
+    }
+
+    /// This method is called on every
+    /// [`ClassSetBinaryOp`](struct.ClassSetBinaryOp.html)
+    /// after descending into child nodes.
+    fn visit_class_set_binary_op_post(
+        &mut self,
+        _ast: &ast::ClassSetBinaryOp,
+    ) -> Result<(), Self::Err> {
+        Ok(())
+    }
+
+    /// This method is called between the left hand and right hand child nodes
+    /// of a [`ClassSetBinaryOp`](struct.ClassSetBinaryOp.html).
+    fn visit_class_set_binary_op_in(
+        &mut self,
+        _ast: &ast::ClassSetBinaryOp,
+    ) -> Result<(), Self::Err> {
+        Ok(())
+    }
+}
+
+/// Executes an implementation of `Visitor` in constant stack space.
+///
+/// This function will visit every node in the given `Ast` while calling the
+/// appropriate methods provided by the
+/// [`Visitor`](trait.Visitor.html) trait.
+///
+/// The primary use case for this method is when one wants to perform case
+/// analysis over an `Ast` without using a stack size proportional to the depth
+/// of the `Ast`. Namely, this method will instead use constant stack size, but
+/// will use heap space proportional to the size of the `Ast`. This may be
+/// desirable in cases where the size of `Ast` is proportional to end user
+/// input.
+///
+/// If the visitor returns an error at any point, then visiting is stopped and
+/// the error is returned.
+pub fn visit<V: Visitor>(ast: &Ast, visitor: V) -> Result<V::Output, V::Err> {
+    HeapVisitor::new().visit(ast, visitor)
+}
+
+/// HeapVisitor visits every item in an `Ast` recursively using constant stack
+/// size and a heap size proportional to the size of the `Ast`.
+struct HeapVisitor<'a> {
+    /// A stack of `Ast` nodes. This is roughly analogous to the call stack
+    /// used in a typical recursive visitor.
+    stack: Vec<(&'a Ast, Frame<'a>)>,
+    /// Similar to the `Ast` stack above, but is used only for character
+    /// classes. In particular, character classes embed their own mini
+    /// recursive syntax.
+    stack_class: Vec<(ClassInduct<'a>, ClassFrame<'a>)>,
+}
+
+/// Represents a single stack frame while performing structural induction over
+/// an `Ast`.
+enum Frame<'a> {
+    /// A stack frame allocated just before descending into a repetition
+    /// operator's child node.
+    Repetition(&'a ast::Repetition),
+    /// A stack frame allocated just before descending into a group's child
+    /// node.
+    Group(&'a ast::Group),
+    /// The stack frame used while visiting every child node of a concatenation
+    /// of expressions.
+    Concat {
+        /// The child node we are currently visiting.
+        head: &'a Ast,
+        /// The remaining child nodes to visit (which may be empty).
+        tail: &'a [Ast],
+    },
+    /// The stack frame used while visiting every child node of an alternation
+    /// of expressions.
+    Alternation {
+        /// The child node we are currently visiting.
+        head: &'a Ast,
+        /// The remaining child nodes to visit (which may be empty).
+        tail: &'a [Ast],
+    },
+}
+
+/// Represents a single stack frame while performing structural induction over
+/// a character class.
+enum ClassFrame<'a> {
+    /// The stack frame used while visiting every child node of a union of
+    /// character class items.
+    Union {
+        /// The child node we are currently visiting.
+        head: &'a ast::ClassSetItem,
+        /// The remaining child nodes to visit (which may be empty).
+        tail: &'a [ast::ClassSetItem],
+    },
+    /// The stack frame used while a binary class operation.
+    Binary {
+        op: &'a ast::ClassSetBinaryOp,
+    },
+    /// A stack frame allocated just before descending into a binary operator's
+    /// left hand child node.
+    BinaryLHS {
+        op: &'a ast::ClassSetBinaryOp,
+        lhs: &'a ast::ClassSet,
+        rhs: &'a ast::ClassSet,
+    },
+    /// A stack frame allocated just before descending into a binary operator's
+    /// right hand child node.
+    BinaryRHS {
+        op: &'a ast::ClassSetBinaryOp,
+        rhs: &'a ast::ClassSet,
+    },
+}
+
+/// A representation of the inductive step when performing structural induction
+/// over a character class.
+///
+/// Note that there is no analogous explicit type for the inductive step for
+/// `Ast` nodes because the inductive step is just an `Ast`. For character
+/// classes, the inductive step can produce one of two possible child nodes:
+/// an item or a binary operation. (An item cannot be a binary operation
+/// because that would imply binary operations can be unioned in the concrete
+/// syntax, which is not possible.)
+enum ClassInduct<'a> {
+    Item(&'a ast::ClassSetItem),
+    BinaryOp(&'a ast::ClassSetBinaryOp),
+}
+
+impl<'a> HeapVisitor<'a> {
+    fn new() -> HeapVisitor<'a> {
+        HeapVisitor { stack: vec![], stack_class: vec![] }
+    }
+
+    fn visit<V: Visitor>(
+        &mut self,
+        mut ast: &'a Ast,
+        mut visitor: V,
+    ) -> Result<V::Output, V::Err> {
+        self.stack.clear();
+        self.stack_class.clear();
+
+        visitor.start();
+        loop {
+            visitor.visit_pre(ast)?;
+            if let Some(x) = self.induct(ast, &mut visitor)? {
+                let child = x.child();
+                self.stack.push((ast, x));
+                ast = child;
+                continue;
+            }
+            // No induction means we have a base case, so we can post visit
+            // it now.
+            visitor.visit_post(ast)?;
+
+            // At this point, we now try to pop our call stack until it is
+            // either empty or we hit another inductive case.
+            loop {
+                let (post_ast, frame) = match self.stack.pop() {
+                    None => return visitor.finish(),
+                    Some((post_ast, frame)) => (post_ast, frame),
+                };
+                // If this is a concat/alternate, then we might have additional
+                // inductive steps to process.
+                if let Some(x) = self.pop(frame) {
+                    if let Frame::Alternation {..} = x {
+                        visitor.visit_alternation_in()?;
+                    }
+                    ast = x.child();
+                    self.stack.push((post_ast, x));
+                    break;
+                }
+                // Otherwise, we've finished visiting all the child nodes for
+                // this AST, so we can post visit it now.
+                visitor.visit_post(post_ast)?;
+            }
+        }
+    }
+
+    /// Build a stack frame for the given AST if one is needed (which occurs if
+    /// and only if there are child nodes in the AST). Otherwise, return None.
+    ///
+    /// If this visits a class, then the underlying visitor implementation may
+    /// return an error which will be passed on here.
+    fn induct<V: Visitor>(
+        &mut self,
+        ast: &'a Ast,
+        visitor: &mut V,
+    ) -> Result<Option<Frame<'a>>, V::Err> {
+        Ok(match *ast {
+            Ast::Class(ast::Class::Bracketed(ref x)) => {
+                self.visit_class(x, visitor)?;
+                None
+            }
+            Ast::Repetition(ref x) => Some(Frame::Repetition(x)),
+            Ast::Group(ref x) => Some(Frame::Group(x)),
+            Ast::Concat(ref x) if x.asts.is_empty() => None,
+            Ast::Concat(ref x) => {
+                Some(Frame::Concat {
+                    head: &x.asts[0],
+                    tail: &x.asts[1..],
+                })
+            }
+            Ast::Alternation(ref x) if x.asts.is_empty() => None,
+            Ast::Alternation(ref x) => {
+                Some(Frame::Alternation {
+                    head: &x.asts[0],
+                    tail: &x.asts[1..],
+                })
+            }
+            _ => None,
+        })
+    }
+
+    /// Pops the given frame. If the frame has an additional inductive step,
+    /// then return it, otherwise return `None`.
+    fn pop(&self, induct: Frame<'a>) -> Option<Frame<'a>> {
+        match induct {
+            Frame::Repetition(_) => None,
+            Frame::Group(_) => None,
+            Frame::Concat { tail, .. } => {
+                if tail.is_empty() {
+                    None
+                } else {
+                    Some(Frame::Concat {
+                        head: &tail[0],
+                        tail: &tail[1..],
+                    })
+                }
+            }
+            Frame::Alternation { tail, .. } => {
+                if tail.is_empty() {
+                    None
+                } else {
+                    Some(Frame::Alternation {
+                        head: &tail[0],
+                        tail: &tail[1..],
+                    })
+                }
+            }
+        }
+    }
+
+    fn visit_class<V: Visitor>(
+        &mut self,
+        ast: &'a ast::ClassBracketed,
+        visitor: &mut V,
+    ) -> Result<(), V::Err> {
+        let mut ast = ClassInduct::from_bracketed(ast);
+        loop {
+            self.visit_class_pre(&ast, visitor)?;
+            if let Some(x) = self.induct_class(&ast) {
+                let child = x.child();
+                self.stack_class.push((ast, x));
+                ast = child;
+                continue;
+            }
+            self.visit_class_post(&ast, visitor)?;
+
+            // At this point, we now try to pop our call stack until it is
+            // either empty or we hit another inductive case.
+            loop {
+                let (post_ast, frame) = match self.stack_class.pop() {
+                    None => return Ok(()),
+                    Some((post_ast, frame)) => (post_ast, frame),
+                };
+                // If this is a union or a binary op, then we might have
+                // additional inductive steps to process.
+                if let Some(x) = self.pop_class(frame) {
+                    if let ClassFrame::BinaryRHS { ref op, .. } = x {
+                        visitor.visit_class_set_binary_op_in(op)?;
+                    }
+                    ast = x.child();
+                    self.stack_class.push((post_ast, x));
+                    break;
+                }
+                // Otherwise, we've finished visiting all the child nodes for
+                // this class node, so we can post visit it now.
+                self.visit_class_post(&post_ast, visitor)?;
+            }
+        }
+    }
+
+    /// Call the appropriate `Visitor` methods given an inductive step.
+    fn visit_class_pre<V: Visitor>(
+        &self,
+        ast: &ClassInduct<'a>,
+        visitor: &mut V,
+    ) -> Result<(), V::Err> {
+        match *ast {
+            ClassInduct::Item(item) => {
+                visitor.visit_class_set_item_pre(item)?;
+            }
+            ClassInduct::BinaryOp(op) => {
+                visitor.visit_class_set_binary_op_pre(op)?;
+            }
+        }
+        Ok(())
+    }
+
+    /// Call the appropriate `Visitor` methods given an inductive step.
+    fn visit_class_post<V: Visitor>(
+        &self,
+        ast: &ClassInduct<'a>,
+        visitor: &mut V,
+    ) -> Result<(), V::Err> {
+        match *ast {
+            ClassInduct::Item(item) => {
+                visitor.visit_class_set_item_post(item)?;
+            }
+            ClassInduct::BinaryOp(op) => {
+                visitor.visit_class_set_binary_op_post(op)?;
+            }
+        }
+        Ok(())
+    }
+
+    /// Build a stack frame for the given class node if one is needed (which
+    /// occurs if and only if there are child nodes). Otherwise, return None.
+    fn induct_class(
+        &self,
+        ast: &ClassInduct<'a>,
+    ) -> Option<ClassFrame<'a>> {
+        match *ast {
+            ClassInduct::Item(&ast::ClassSetItem::Bracketed(ref x)) => {
+                match x.kind {
+                    ast::ClassSet::Item(ref item) => {
+                        Some(ClassFrame::Union {
+                            head: item,
+                            tail: &[],
+                        })
+                    }
+                    ast::ClassSet::BinaryOp(ref op) => {
+                        Some(ClassFrame::Binary { op: op })
+                    }
+                }
+            }
+            ClassInduct::Item(&ast::ClassSetItem::Union(ref x)) => {
+                if x.items.is_empty() {
+                    None
+                } else {
+                    Some(ClassFrame::Union {
+                        head: &x.items[0],
+                        tail: &x.items[1..],
+                    })
+                }
+            }
+            ClassInduct::BinaryOp(op) => {
+                Some(ClassFrame::BinaryLHS {
+                    op: op,
+                    lhs: &op.lhs,
+                    rhs: &op.rhs,
+                })
+            }
+            _ => None,
+        }
+    }
+
+    /// Pops the given frame. If the frame has an additional inductive step,
+    /// then return it, otherwise return `None`.
+    fn pop_class(&self, induct: ClassFrame<'a>) -> Option<ClassFrame<'a>> {
+        match induct {
+            ClassFrame::Union { tail, .. } => {
+                if tail.is_empty() {
+                    None
+                } else {
+                    Some(ClassFrame::Union {
+                        head: &tail[0],
+                        tail: &tail[1..],
+                    })
+                }
+            }
+            ClassFrame::Binary {..} => None,
+            ClassFrame::BinaryLHS { op, rhs, .. } => {
+                Some(ClassFrame::BinaryRHS {
+                    op: op,
+                    rhs: rhs,
+                })
+            }
+            ClassFrame::BinaryRHS {..} => None,
+        }
+    }
+}
+
+impl<'a> Frame<'a> {
+    /// Perform the next inductive step on this frame and return the next
+    /// child AST node to visit.
+    fn child(&self) -> &'a Ast {
+        match *self {
+            Frame::Repetition(rep) => &rep.ast,
+            Frame::Group(group) => &group.ast,
+            Frame::Concat { head, .. } => head,
+            Frame::Alternation { head, .. } => head,
+        }
+    }
+}
+
+impl<'a> ClassFrame<'a> {
+    /// Perform the next inductive step on this frame and return the next
+    /// child class node to visit.
+    fn child(&self) -> ClassInduct<'a> {
+        match *self {
+            ClassFrame::Union { head, .. } => ClassInduct::Item(head),
+            ClassFrame::Binary { op, .. } => ClassInduct::BinaryOp(op),
+            ClassFrame::BinaryLHS { ref lhs, .. } => {
+                ClassInduct::from_set(lhs)
+            }
+            ClassFrame::BinaryRHS { ref rhs, .. } => {
+                ClassInduct::from_set(rhs)
+            }
+        }
+    }
+}
+
+impl<'a> ClassInduct<'a> {
+    fn from_bracketed(ast: &'a ast::ClassBracketed) -> ClassInduct<'a> {
+        ClassInduct::from_set(&ast.kind)
+    }
+
+    fn from_set(ast: &'a ast::ClassSet) -> ClassInduct<'a> {
+        match *ast {
+            ast::ClassSet::Item(ref item) => ClassInduct::Item(item),
+            ast::ClassSet::BinaryOp(ref op) => ClassInduct::BinaryOp(op),
+        }
+    }
+}
+
+impl<'a> fmt::Debug for ClassFrame<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let x = match *self {
+            ClassFrame::Union{..} => "Union",
+            ClassFrame::Binary{..} => "Binary",
+            ClassFrame::BinaryLHS{..} => "BinaryLHS",
+            ClassFrame::BinaryRHS{..} => "BinaryRHS",
+        };
+        write!(f, "{}", x)
+    }
+}
+
+impl<'a> fmt::Debug for ClassInduct<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let x = match *self {
+            ClassInduct::Item(it) => {
+                match *it {
+                    ast::ClassSetItem::Empty(_) => "Item(Empty)",
+                    ast::ClassSetItem::Literal(_) => "Item(Literal)",
+                    ast::ClassSetItem::Range(_) => "Item(Range)",
+                    ast::ClassSetItem::Ascii(_) => "Item(Ascii)",
+                    ast::ClassSetItem::Perl(_) => "Item(Perl)",
+                    ast::ClassSetItem::Unicode(_) => "Item(Unicode)",
+                    ast::ClassSetItem::Bracketed(_) => "Item(Bracketed)",
+                    ast::ClassSetItem::Union(_) => "Item(Union)",
+                }
+            }
+            ClassInduct::BinaryOp(it) => {
+                match it.kind {
+                    ast::ClassSetBinaryOpKind::Intersection => {
+                        "BinaryOp(Intersection)"
+                    }
+                    ast::ClassSetBinaryOpKind::Difference => {
+                        "BinaryOp(Difference)"
+                    }
+                    ast::ClassSetBinaryOpKind::SymmetricDifference => {
+                        "BinaryOp(SymmetricDifference)"
+                    }
+                }
+            }
+        };
+        write!(f, "{}", x)
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/either.rs.html b/target/doc/src/regex_syntax/either.rs.html new file mode 100644 index 0000000..580d3ec --- /dev/null +++ b/target/doc/src/regex_syntax/either.rs.html @@ -0,0 +1,19 @@ +either.rs.html -- source
1
+2
+3
+4
+5
+6
+7
+8
+
+/// A simple binary sum type.
+///
+/// This is occasionally useful in an ad hoc fashion.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum Either<Left, Right> {
+    Left(Left),
+    Right(Right),
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/error.rs.html b/target/doc/src/regex_syntax/error.rs.html new file mode 100644 index 0000000..ebf67f1 --- /dev/null +++ b/target/doc/src/regex_syntax/error.rs.html @@ -0,0 +1,643 @@ +error.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+
+use std::cmp;
+use std::error;
+use std::fmt;
+use std::result;
+
+use ast;
+use hir;
+
+/// A type alias for dealing with errors returned by this crate.
+pub type Result<T> = result::Result<T, Error>;
+
+/// This error type encompasses any error that can be returned by this crate.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum Error {
+    /// An error that occurred while translating concrete syntax into abstract
+    /// syntax (AST).
+    Parse(ast::Error),
+    /// An error that occurred while translating abstract syntax into a high
+    /// level intermediate representation (HIR).
+    Translate(hir::Error),
+    /// Hints that destructuring should not be exhaustive.
+    ///
+    /// This enum may grow additional variants, so this makes sure clients
+    /// don't count on exhaustive matching. (Otherwise, adding a new variant
+    /// could break existing code.)
+    #[doc(hidden)]
+    __Nonexhaustive,
+}
+
+impl From<ast::Error> for Error {
+    fn from(err: ast::Error) -> Error {
+        Error::Parse(err)
+    }
+}
+
+impl From<hir::Error> for Error {
+    fn from(err: hir::Error) -> Error {
+        Error::Translate(err)
+    }
+}
+
+impl error::Error for Error {
+    fn description(&self) -> &str {
+        match *self {
+            Error::Parse(ref x) => x.description(),
+            Error::Translate(ref x) => x.description(),
+            _ => unreachable!(),
+        }
+    }
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            Error::Parse(ref x) => x.fmt(f),
+            Error::Translate(ref x) => x.fmt(f),
+            _ => unreachable!(),
+        }
+    }
+}
+
+/// A helper type for formatting nice error messages.
+///
+/// This type is responsible for reporting regex parse errors in a nice human
+/// readable format. Most of its complexity is from interspersing notational
+/// markers pointing out the position where an error occurred.
+#[derive(Debug)]
+pub struct Formatter<'e, E: 'e> {
+    /// The original regex pattern in which the error occurred.
+    pattern: &'e str,
+    /// The error kind. It must impl fmt::Display.
+    err: &'e E,
+    /// The primary span of the error.
+    span: &'e ast::Span,
+    /// An auxiliary and optional span, in case the error needs to point to
+    /// two locations (e.g., when reporting a duplicate capture group name).
+    aux_span: Option<&'e ast::Span>,
+}
+
+impl<'e> From<&'e ast::Error> for Formatter<'e, ast::ErrorKind> {
+    fn from(err: &'e ast::Error) -> Self {
+        Formatter {
+            pattern: err.pattern(),
+            err: err.kind(),
+            span: err.span(),
+            aux_span: err.auxiliary_span(),
+        }
+    }
+}
+
+impl<'e> From<&'e hir::Error> for Formatter<'e, hir::ErrorKind> {
+    fn from(err: &'e hir::Error) -> Self {
+        Formatter {
+            pattern: err.pattern(),
+            err: err.kind(),
+            span: err.span(),
+            aux_span: None,
+        }
+    }
+}
+
+impl<'e, E: fmt::Display> fmt::Display for Formatter<'e, E> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let spans = Spans::from_formatter(self);
+        if self.pattern.contains('\n') {
+            let divider = repeat_char('~', 79);
+
+            writeln!(f, "regex parse error:")?;
+            writeln!(f, "{}", divider)?;
+            let notated = spans.notate();
+            write!(f, "{}", notated)?;
+            writeln!(f, "{}", divider)?;
+            // If we have error spans that cover multiple lines, then we just
+            // note the line numbers.
+            if !spans.multi_line.is_empty() {
+                let mut notes = vec![];
+                for span in &spans.multi_line {
+                    notes.push(format!(
+                        "on line {} (column {}) through line {} (column {})",
+                        span.start.line, span.start.column,
+                        span.end.line, span.end.column - 1));
+                }
+                writeln!(f, "{}", notes.join("\n"))?;
+            }
+            write!(f, "error: {}", self.err)?;
+        } else {
+            writeln!(f, "regex parse error:")?;
+            let notated = Spans::from_formatter(self).notate();
+            write!(f, "{}", notated)?;
+            write!(f, "error: {}", self.err)?;
+        }
+        Ok(())
+    }
+}
+
+/// This type represents an arbitrary number of error spans in a way that makes
+/// it convenient to notate the regex pattern. ("Notate" means "point out
+/// exactly where the error occurred in the regex pattern.")
+///
+/// Technically, we can only ever have two spans given our current error
+/// structure. However, after toiling with a specific algorithm for handling
+/// two spans, it became obvious that an algorithm to handle an arbitrary
+/// number of spans was actually much simpler.
+struct Spans<'p> {
+    /// The original regex pattern string.
+    pattern: &'p str,
+    /// The total width that should be used for line numbers. The width is
+    /// used for left padding the line numbers for alignment.
+    ///
+    /// A value of `0` means line numbers should not be displayed. That is,
+    /// the pattern is itself only one line.
+    line_number_width: usize,
+    /// All error spans that occur on a single line. This sequence always has
+    /// length equivalent to the number of lines in `pattern`, where the index
+    /// of the sequence represents a line number, starting at `0`. The spans
+    /// in each line are sorted in ascending order.
+    by_line: Vec<Vec<ast::Span>>,
+    /// All error spans that occur over one or more lines. That is, the start
+    /// and end position of the span have different line numbers. The spans are
+    /// sorted in ascending order.
+    multi_line: Vec<ast::Span>,
+}
+
+impl<'p> Spans<'p> {
+    /// Build a sequence of spans from a formatter.
+    fn from_formatter<'e, E: fmt::Display>(
+        fmter: &'p Formatter<'e, E>,
+    ) -> Spans<'p> {
+        let mut line_count = fmter.pattern.lines().count();
+        // If the pattern ends with a `\n` literal, then our line count is
+        // off by one, since a span can occur immediately after the last `\n`,
+        // which is consider to be an additional line.
+        if fmter.pattern.ends_with('\n') {
+            line_count += 1;
+        }
+        let line_number_width =
+            if line_count <= 1 {
+                0
+            } else {
+                line_count.to_string().len()
+            };
+        let mut spans = Spans {
+            pattern: &fmter.pattern,
+            line_number_width: line_number_width,
+            by_line: vec![vec![]; line_count],
+            multi_line: vec![],
+        };
+        spans.add(fmter.span.clone());
+        if let Some(span) = fmter.aux_span {
+            spans.add(span.clone());
+        }
+        spans
+    }
+
+    /// Add the given span to this sequence, putting it in the right place.
+    fn add(&mut self, span: ast::Span) {
+        // This is grossly inefficient since we sort after each add, but right
+        // now, we only ever add two spans at most.
+        if span.is_one_line() {
+            let i = span.start.line - 1; // because lines are 1-indexed
+            self.by_line[i].push(span);
+            self.by_line[i].sort();
+        } else {
+            self.multi_line.push(span);
+            self.multi_line.sort();
+        }
+    }
+
+    /// Notate the pattern string with carents (`^`) pointing at each span
+    /// location. This only applies to spans that occur within a single line.
+    fn notate(&self) -> String {
+        let mut notated = String::new();
+        for (i, line) in self.pattern.lines().enumerate() {
+            if self.line_number_width > 0 {
+                notated.push_str(&self.left_pad_line_number(i + 1));
+                notated.push_str(": ");
+            } else {
+                notated.push_str("    ");
+            }
+            notated.push_str(line);
+            notated.push('\n');
+            if let Some(notes) = self.notate_line(i) {
+                notated.push_str(&notes);
+                notated.push('\n');
+            }
+        }
+        notated
+    }
+
+    /// Return notes for the line indexed at `i` (zero-based). If there are no
+    /// spans for the given line, then `None` is returned. Otherwise, an
+    /// appropriately space padded string with correctly positioned `^` is
+    /// returned, accounting for line numbers.
+    fn notate_line(&self, i: usize) -> Option<String> {
+        let spans = &self.by_line[i];
+        if spans.is_empty() {
+            return None;
+        }
+        let mut notes = String::new();
+        for _ in 0..self.line_number_padding() {
+            notes.push(' ');
+        }
+        let mut pos = 0;
+        for span in spans {
+            for _ in pos..(span.start.column - 1) {
+                notes.push(' ');
+                pos += 1;
+            }
+            let note_len = span.end.column.saturating_sub(span.start.column);
+            for _ in 0..cmp::max(1, note_len) {
+                notes.push('^');
+                pos += 1;
+            }
+        }
+        Some(notes)
+    }
+
+    /// Left pad the given line number with spaces such that it is aligned with
+    /// other line numbers.
+    fn left_pad_line_number(&self, n: usize) -> String {
+        let n = n.to_string();
+        let pad = self.line_number_width.checked_sub(n.len()).unwrap();
+        let mut result = repeat_char(' ', pad);
+        result.push_str(&n);
+        result
+    }
+
+    /// Return the line number padding beginning at the start of each line of
+    /// the pattern.
+    ///
+    /// If the pattern is only one line, then this returns a fixed padding
+    /// for visual indentation.
+    fn line_number_padding(&self) -> usize {
+        if self.line_number_width == 0 {
+            4
+        } else {
+            2 + self.line_number_width
+        }
+    }
+}
+
+fn repeat_char(c: char, count: usize) -> String {
+    ::std::iter::repeat(c).take(count).collect()
+}
+
+#[cfg(test)]
+mod tests {
+    use ast::parse::Parser;
+
+    fn assert_panic_message(pattern: &str, expected_msg: &str) -> () {
+        let result = Parser::new().parse(pattern);
+        match result {
+            Ok(_) => {
+                panic!("regex should not have parsed");
+            }
+            Err(err) => {
+                assert_eq!(err.to_string(), expected_msg.trim());
+            }
+        }
+    }
+
+    // See: https://github.com/rust-lang/regex/issues/464
+    #[test]
+    fn regression_464() {
+        let err = Parser::new().parse("a{\n").unwrap_err();
+        // This test checks that the error formatter doesn't panic.
+        assert!(!err.to_string().is_empty());
+    }
+
+    // See: https://github.com/rust-lang/regex/issues/545
+    #[test]
+    fn repetition_quantifier_expects_a_valid_decimal() {
+        assert_panic_message(r"\\u{[^}]*}", r#"
+regex parse error:
+    \\u{[^}]*}
+        ^
+error: repetition quantifier expects a valid decimal
+"#);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/hir/interval.rs.html b/target/doc/src/regex_syntax/hir/interval.rs.html new file mode 100644 index 0000000..7b57234 --- /dev/null +++ b/target/doc/src/regex_syntax/hir/interval.rs.html @@ -0,0 +1,983 @@ +interval.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+
+use std::char;
+use std::cmp;
+use std::fmt::Debug;
+use std::slice;
+use std::u8;
+
+// This module contains an *internal* implementation of interval sets.
+//
+// The primary invariant that interval sets guards is canonical ordering. That
+// is, every interval set contains an ordered sequence of intervals where
+// no two intervals are overlapping or adjacent. While this invariant is
+// occasionally broken within the implementation, it should be impossible for
+// callers to observe it.
+//
+// Since case folding (as implemented below) breaks that invariant, we roll
+// that into this API even though it is a little out of place in an otherwise
+// generic interval set.
+//
+// Some of the implementation complexity here is a result of me wanting to
+// preserve the sequential representation without using additional memory.
+// In many cases, we do use linear extra memory, but it is at most 2x and it
+// is amortized. If we relaxed the memory requirements, this implementation
+// could become much simpler. The extra memory is honestly probably OK, but
+// character classes (especially of the Unicode variety) can become quite
+// large, and it would be nice to keep regex compilation snappy even in debug
+// builds. (In the past, I have been careless with this area of code and it has
+// caused slow regex compilations in debug mode, so this isn't entirely
+// unwarranted.)
+//
+// Tests on this are relegated to the public API of HIR in src/hir.rs.
+
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct IntervalSet<I> {
+    ranges: Vec<I>,
+}
+
+impl<I: Interval> IntervalSet<I> {
+    /// Create a new set from a sequence of intervals. Each interval is
+    /// specified as a pair of bounds, where both bounds are inclusive.
+    ///
+    /// The given ranges do not need to be in any specific order, and ranges
+    /// may overlap.
+    pub fn new<T: IntoIterator<Item=I>>(intervals: T) -> IntervalSet<I> {
+        let mut set = IntervalSet { ranges: intervals.into_iter().collect() };
+        set.canonicalize();
+        set
+    }
+
+    /// Add a new interval to this set.
+    pub fn push(&mut self, interval: I) {
+        // TODO: This could be faster. e.g., Push the interval such that
+        // it preserves canonicalization.
+        self.ranges.push(interval);
+        self.canonicalize();
+    }
+
+    /// Return an iterator over all intervals in this set.
+    ///
+    /// The iterator yields intervals in ascending order.
+    pub fn iter(&self) -> IntervalSetIter<I> {
+        IntervalSetIter(self.ranges.iter())
+    }
+
+    /// Return an immutable slice of intervals in this set.
+    ///
+    /// The sequence returned is in canonical ordering.
+    pub fn intervals(&self) -> &[I] {
+        &self.ranges
+    }
+
+    /// Expand this interval set 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`.
+    pub fn case_fold_simple(&mut self) {
+        let len = self.ranges.len();
+        for i in 0..len {
+            let range = self.ranges[i];
+            range.case_fold_simple(&mut self.ranges);
+        }
+        self.canonicalize();
+    }
+
+    /// Union this set with the given set, in place.
+    pub fn union(&mut self, other: &IntervalSet<I>) {
+        // This could almost certainly be done more efficiently.
+        self.ranges.extend(&other.ranges);
+        self.canonicalize();
+    }
+
+    /// Intersect this set with the given set, in place.
+    pub fn intersect(&mut self, other: &IntervalSet<I>) {
+        if self.ranges.is_empty() {
+            return;
+        }
+        if other.ranges.is_empty() {
+            self.ranges.clear();
+            return;
+        }
+
+        // There should be a way to do this in-place with constant memory,
+        // but I couldn't figure out a simple way to do it. So just append
+        // the intersection to the end of this range, and then drain it before
+        // we're done.
+        let drain_end = self.ranges.len();
+
+        let mut ita = (0..drain_end).into_iter();
+        let mut itb = (0..other.ranges.len()).into_iter();
+        let mut a = ita.next().unwrap();
+        let mut b = itb.next().unwrap();
+        loop {
+            if let Some(ab) = self.ranges[a].intersect(&other.ranges[b]) {
+                self.ranges.push(ab);
+            }
+            let (it, aorb) =
+                if self.ranges[a].upper() < other.ranges[b].upper() {
+                    (&mut ita, &mut a)
+                } else {
+                    (&mut itb, &mut b)
+                };
+            match it.next() {
+                Some(v) => *aorb = v,
+                None => break,
+            }
+        }
+        self.ranges.drain(..drain_end);
+    }
+
+    /// Subtract the given set from this set, in place.
+    pub fn difference(&mut self, other: &IntervalSet<I>) {
+        if self.ranges.is_empty() || other.ranges.is_empty() {
+            return;
+        }
+
+        // This algorithm is (to me) surprisingly complex. A search of the
+        // interwebs indicate that this is a potentially interesting problem.
+        // Folks seem to suggest interval or segment trees, but I'd like to
+        // avoid the overhead (both runtime and conceptual) of that.
+        //
+        // The following is basically my Shitty First Draft. Therefore, in
+        // order to grok it, you probably need to read each line carefully.
+        // Simplifications are most welcome!
+        //
+        // Remember, we can assume the canonical format invariant here, which
+        // says that all ranges are sorted, not overlapping and not adjacent in
+        // each class.
+        let drain_end = self.ranges.len();
+        let (mut a, mut b) = (0, 0);
+    'LOOP:
+        while a < drain_end && b < other.ranges.len() {
+            // Basically, the easy cases are when neither range overlaps with
+            // each other. If the `b` range is less than our current `a`
+            // range, then we can skip it and move on.
+            if other.ranges[b].upper() < self.ranges[a].lower() {
+                b += 1;
+                continue;
+            }
+            // ... similarly for the `a` range. If it's less than the smallest
+            // `b` range, then we can add it as-is.
+            if self.ranges[a].upper() < other.ranges[b].lower() {
+                let range = self.ranges[a];
+                self.ranges.push(range);
+                a += 1;
+                continue;
+            }
+            // Otherwise, we have overlapping ranges.
+            assert!(!self.ranges[a].is_intersection_empty(&other.ranges[b]));
+
+            // This part is tricky and was non-obvious to me without looking
+            // at explicit examples (see the tests). The trickiness stems from
+            // two things: 1) subtracting a range from another range could
+            // yield two ranges and 2) after subtracting a range, it's possible
+            // that future ranges can have an impact. The loop below advances
+            // the `b` ranges until they can't possible impact the current
+            // range.
+            //
+            // For example, if our `a` range is `a-t` and our next three `b`
+            // ranges are `a-c`, `g-i`, `r-t` and `x-z`, then we need to apply
+            // subtraction three times before moving on to the next `a` range.
+            let mut range = self.ranges[a];
+            while b < other.ranges.len()
+                && !range.is_intersection_empty(&other.ranges[b])
+            {
+                let old_range = range;
+                range = match range.difference(&other.ranges[b]) {
+                    (None, None) => {
+                        // We lost the entire range, so move on to the next
+                        // without adding this one.
+                        a += 1;
+                        continue 'LOOP;
+                    }
+                    (Some(range1), None) | (None, Some(range1)) => range1,
+                    (Some(range1), Some(range2)) => {
+                        self.ranges.push(range1);
+                        range2
+                    }
+                };
+                // It's possible that the `b` range has more to contribute
+                // here. In particular, if it is greater than the original
+                // range, then it might impact the next `a` range *and* it
+                // has impacted the current `a` range as much as possible,
+                // so we can quit. We don't bump `b` so that the next `a`
+                // range can apply it.
+                if other.ranges[b].upper() > old_range.upper() {
+                    break;
+                }
+                // Otherwise, the next `b` range might apply to the current
+                // `a` range.
+                b += 1;
+            }
+            self.ranges.push(range);
+            a += 1;
+        }
+        while a < drain_end {
+            let range = self.ranges[a];
+            self.ranges.push(range);
+            a += 1;
+        }
+        self.ranges.drain(..drain_end);
+    }
+
+    /// Compute the symmetric difference of the two sets, in place.
+    ///
+    /// This computes the symmetric difference of two interval sets. This
+    /// removes all elements in this set that are also in the given set,
+    /// but also adds all elements from the given set that aren't in this
+    /// set. That is, the set will contain all elements in either set,
+    /// but will not contain any elements that are in both sets.
+    pub fn symmetric_difference(&mut self, other: &IntervalSet<I>) {
+        // TODO(burntsushi): Fix this so that it amortizes allocation.
+        let mut intersection = self.clone();
+        intersection.intersect(other);
+        self.union(other);
+        self.difference(&intersection);
+    }
+
+    /// Negate this interval set.
+    ///
+    /// For all `x` where `x` is any element, if `x` was in this set, then it
+    /// will not be in this set after negation.
+    pub fn negate(&mut self) {
+        if self.ranges.is_empty() {
+            let (min, max) = (I::Bound::min_value(), I::Bound::max_value());
+            self.ranges.push(I::create(min, max));
+            return;
+        }
+
+        // There should be a way to do this in-place with constant memory,
+        // but I couldn't figure out a simple way to do it. So just append
+        // the negation to the end of this range, and then drain it before
+        // we're done.
+        let drain_end = self.ranges.len();
+
+        // We do checked arithmetic below because of the canonical ordering
+        // invariant.
+        if self.ranges[0].lower() > I::Bound::min_value() {
+            let upper = self.ranges[0].lower().decrement();
+            self.ranges.push(I::create(I::Bound::min_value(), upper));
+        }
+        for i in 1..drain_end {
+            let lower = self.ranges[i - 1].upper().increment();
+            let upper = self.ranges[i].lower().decrement();
+            self.ranges.push(I::create(lower, upper));
+        }
+        if self.ranges[drain_end - 1].upper() < I::Bound::max_value() {
+            let lower = self.ranges[drain_end - 1].upper().increment();
+            self.ranges.push(I::create(lower, I::Bound::max_value()));
+        }
+        self.ranges.drain(..drain_end);
+    }
+
+    /// Converts this set into a canonical ordering.
+    fn canonicalize(&mut self) {
+        if self.is_canonical() {
+            return;
+        }
+        self.ranges.sort();
+        assert!(!self.ranges.is_empty());
+
+        // Is there a way to do this in-place with constant memory? I couldn't
+        // figure out a way to do it. So just append the canonicalization to
+        // the end of this range, and then drain it before we're done.
+        let drain_end = self.ranges.len();
+        for oldi in 0..drain_end {
+            // If we've added at least one new range, then check if we can
+            // merge this range in the previously added range.
+            if self.ranges.len() > drain_end {
+                let (last, rest) = self.ranges.split_last_mut().unwrap();
+                if let Some(union) = last.union(&rest[oldi]) {
+                    *last = union;
+                    continue;
+                }
+            }
+            let range = self.ranges[oldi];
+            self.ranges.push(range);
+        }
+        self.ranges.drain(..drain_end);
+    }
+
+    /// Returns true if and only if this class is in a canonical ordering.
+    fn is_canonical(&self) -> bool {
+        for pair in self.ranges.windows(2) {
+            if pair[0] >= pair[1] {
+                return false;
+            }
+            if pair[0].is_contiguous(&pair[1]) {
+                return false;
+            }
+        }
+        true
+    }
+}
+
+/// An iterator over intervals.
+#[derive(Debug)]
+pub struct IntervalSetIter<'a, I: 'a>(slice::Iter<'a, I>);
+
+impl<'a, I> Iterator for IntervalSetIter<'a, I> {
+    type Item = &'a I;
+
+    fn next(&mut self) -> Option<&'a I> {
+        self.0.next()
+    }
+}
+
+pub trait Interval:
+    Clone + Copy + Debug + Default + Eq + PartialEq + PartialOrd + Ord
+{
+    type Bound: Bound;
+
+    fn lower(&self) -> Self::Bound;
+    fn upper(&self) -> Self::Bound;
+    fn set_lower(&mut self, bound: Self::Bound);
+    fn set_upper(&mut self, bound: Self::Bound);
+    fn case_fold_simple(&self, intervals: &mut Vec<Self>);
+
+    /// Create a new interval.
+    fn create(lower: Self::Bound, upper: Self::Bound) -> Self {
+        let mut int = Self::default();
+        if lower <= upper {
+            int.set_lower(lower);
+            int.set_upper(upper);
+        } else {
+            int.set_lower(upper);
+            int.set_upper(lower);
+        }
+        int
+    }
+
+    /// Union the given overlapping range into this range.
+    ///
+    /// If the two ranges aren't contiguous, then this returns `None`.
+    fn union(&self, other: &Self) -> Option<Self> {
+        if !self.is_contiguous(other) {
+            return None;
+        }
+        let lower = cmp::min(self.lower(), other.lower());
+        let upper = cmp::max(self.upper(), other.upper());
+        Some(Self::create(lower, upper))
+    }
+
+    /// Intersect this range with the given range and return the result.
+    ///
+    /// If the intersection is empty, then this returns `None`.
+    fn intersect(&self, other: &Self) -> Option<Self> {
+        let lower = cmp::max(self.lower(), other.lower());
+        let upper = cmp::min(self.upper(), other.upper());
+        if lower <= upper {
+            Some(Self::create(lower, upper))
+        } else {
+            None
+        }
+    }
+
+    /// Subtract the given range from this range and return the resulting
+    /// ranges.
+    ///
+    /// If subtraction would result in an empty range, then no ranges are
+    /// returned.
+    fn difference(&self, other: &Self) -> (Option<Self>, Option<Self>) {
+        if self.is_subset(other) {
+            return (None, None);
+        }
+        if self.is_intersection_empty(other) {
+            return (Some(self.clone()), None);
+        }
+        let add_lower = other.lower() > self.lower();
+        let add_upper = other.upper() < self.upper();
+        // We know this because !self.is_subset(other) and the ranges have
+        // a non-empty intersection.
+        assert!(add_lower || add_upper);
+        let mut ret = (None, None);
+        if add_lower {
+            let upper = other.lower().decrement();
+            ret.0 = Some(Self::create(self.lower(), upper));
+        }
+        if add_upper {
+            let lower = other.upper().increment();
+            let range = Self::create(lower, self.upper());
+            if ret.0.is_none() {
+                ret.0 = Some(range);
+            } else {
+                ret.1 = Some(range);
+            }
+        }
+        ret
+    }
+
+    /// Compute the symmetric difference the given range from this range. This
+    /// returns the union of the two ranges minus its intersection.
+    fn symmetric_difference(
+        &self,
+        other: &Self,
+    ) -> (Option<Self>, Option<Self>) {
+        let union = match self.union(other) {
+            None => return (Some(self.clone()), Some(other.clone())),
+            Some(union) => union,
+        };
+        let intersection = match self.intersect(other) {
+            None => return (Some(self.clone()), Some(other.clone())),
+            Some(intersection) => intersection,
+        };
+        union.difference(&intersection)
+    }
+
+    /// Returns true if and only if the two ranges are contiguous. Two ranges
+    /// are contiguous if and only if the ranges are either overlapping or
+    /// adjacent.
+    fn is_contiguous(&self, other: &Self) -> bool {
+        let lower1 = self.lower().as_u32();
+        let upper1 = self.upper().as_u32();
+        let lower2 = other.lower().as_u32();
+        let upper2 = other.upper().as_u32();
+        cmp::max(lower1, lower2) <= cmp::min(upper1, upper2).saturating_add(1)
+    }
+
+    /// Returns true if and only if the intersection of this range and the
+    /// other range is empty.
+    fn is_intersection_empty(&self, other: &Self) -> bool {
+        let (lower1, upper1) = (self.lower(), self.upper());
+        let (lower2, upper2) = (other.lower(), other.upper());
+        cmp::max(lower1, lower2) > cmp::min(upper1, upper2)
+    }
+
+    /// Returns true if and only if this range is a subset of the other range.
+    fn is_subset(&self, other: &Self) -> bool {
+        let (lower1, upper1) = (self.lower(), self.upper());
+        let (lower2, upper2) = (other.lower(), other.upper());
+        (lower2 <= lower1 && lower1 <= upper2)
+        && (lower2 <= upper1 && upper1 <= upper2)
+    }
+}
+
+pub trait Bound: Copy + Clone + Debug + Eq + PartialEq + PartialOrd + Ord {
+    fn min_value() -> Self;
+    fn max_value() -> Self;
+    fn as_u32(self) -> u32;
+    fn increment(self) -> Self;
+    fn decrement(self) -> Self;
+}
+
+impl Bound for u8 {
+    fn min_value() -> Self { u8::MIN }
+    fn max_value() -> Self { u8::MAX }
+    fn as_u32(self) -> u32 { self as u32 }
+    fn increment(self) -> Self { self.checked_add(1).unwrap() }
+    fn decrement(self) -> Self { self.checked_sub(1).unwrap() }
+}
+
+impl Bound for char {
+    fn min_value() -> Self { '\x00' }
+    fn max_value() -> Self { '\u{10FFFF}' }
+    fn as_u32(self) -> u32 { self as u32 }
+
+    fn increment(self) -> Self {
+        match self {
+            '\u{D7FF}' => '\u{E000}',
+            c => char::from_u32((c as u32).checked_add(1).unwrap()).unwrap(),
+        }
+    }
+
+    fn decrement(self) -> Self {
+        match self {
+            '\u{E000}' => '\u{D7FF}',
+            c => char::from_u32((c as u32).checked_sub(1).unwrap()).unwrap(),
+        }
+    }
+}
+
+// Tests for interval sets are written in src/hir.rs against the public API.
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/hir/literal/mod.rs.html b/target/doc/src/regex_syntax/hir/literal/mod.rs.html new file mode 100644 index 0000000..a5bc7f5 --- /dev/null +++ b/target/doc/src/regex_syntax/hir/literal/mod.rs.html @@ -0,0 +1,3105 @@ +mod.rs.html -- source
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+Provides routines for extracting literal prefixes and suffixes from an `Hir`.
+*/
+
+use std::cmp;
+use std::fmt;
+use std::iter;
+use std::mem;
+use std::ops;
+
+use hir::{self, Hir, HirKind};
+
+/// A set of literal byte strings extracted from a regular expression.
+///
+/// Every member of the set is a `Literal`, which is represented by a
+/// `Vec<u8>`. (Notably, it may contain invalid UTF-8.) Every member is
+/// said to be either *complete* or *cut*. A complete literal means that
+/// it extends until the beginning (or end) of the regular expression. In
+/// some circumstances, this can be used to indicate a match in the regular
+/// expression.
+///
+/// A key aspect of literal extraction is knowing when to stop. It is not
+/// feasible to blindly extract all literals from a regular expression, even if
+/// there are finitely many. For example, the regular expression `[0-9]{10}`
+/// has `10^10` distinct literals. For this reason, literal extraction is
+/// bounded to some low number by default using heuristics, but the limits can
+/// be tweaked.
+///
+/// **WARNING**: Literal extraction uses stack space proportional to the size
+/// of the `Hir` expression. At some point, this drawback will be eliminated.
+/// To protect yourself, set a reasonable
+/// [`nest_limit` on your `Parser`](../../struct.ParserBuilder.html#method.nest_limit).
+/// This is done for you by default.
+#[derive(Clone, Eq, PartialEq)]
+pub struct Literals {
+    lits: Vec<Literal>,
+    limit_size: usize,
+    limit_class: usize,
+}
+
+/// A single member of a set of literals extracted from a regular expression.
+///
+/// This type has `Deref` and `DerefMut` impls to `Vec<u8>` so that all slice
+/// and `Vec` operations are available.
+#[derive(Clone, Eq, Ord)]
+pub struct Literal {
+    v: Vec<u8>,
+    cut: bool,
+}
+
+impl Literals {
+    /// Returns a new empty set of literals using default limits.
+    pub fn empty() -> Literals {
+        Literals {
+            lits: vec![],
+            limit_size: 250,
+            limit_class: 10,
+        }
+    }
+
+    /// Returns a set of literal prefixes extracted from the given `Hir`.
+    pub fn prefixes(expr: &Hir) -> Literals {
+        let mut lits = Literals::empty();
+        lits.union_prefixes(expr);
+        lits
+    }
+
+    /// Returns a set of literal suffixes extracted from the given `Hir`.
+    pub fn suffixes(expr: &Hir) -> Literals {
+        let mut lits = Literals::empty();
+        lits.union_suffixes(expr);
+        lits
+    }
+
+    /// Get the approximate size limit (in bytes) of this set.
+    pub fn limit_size(&self) -> usize {
+        self.limit_size
+    }
+
+    /// Set the approximate size limit (in bytes) of this set.
+    ///
+    /// If extracting a literal would put the set over this limit, then
+    /// extraction stops.
+    ///
+    /// The new limits will only apply to additions to this set. Existing
+    /// members remain unchanged, even if the set exceeds the new limit.
+    pub fn set_limit_size(&mut self, size: usize) -> &mut Literals {
+        self.limit_size = size;
+        self
+    }
+
+    /// Get the character class size limit for this set.
+    pub fn limit_class(&self) -> usize {
+        self.limit_class
+    }
+
+    /// Limits the size of character(or byte) classes considered.
+    ///
+    /// A value of `0` prevents all character classes from being considered.
+    ///
+    /// This limit also applies to case insensitive literals, since each
+    /// character in the case insensitive literal is converted to a class, and
+    /// then case folded.
+    ///
+    /// The new limits will only apply to additions to this set. Existing
+    /// members remain unchanged, even if the set exceeds the new limit.
+    pub fn set_limit_class(&mut self, size: usize) -> &mut Literals {
+        self.limit_class = size;
+        self
+    }
+
+    /// Returns the set of literals as a slice. Its order is unspecified.
+    pub fn literals(&self) -> &[Literal] {
+        &self.lits
+    }
+
+    /// Returns the length of the smallest literal.
+    ///
+    /// Returns None is there are no literals in the set.
+    pub fn min_len(&self) -> Option<usize> {
+        let mut min = None;
+        for lit in &self.lits {
+            match min {
+                None => min = Some(lit.len()),
+                Some(m) if lit.len() < m => min = Some(lit.len()),
+                _ => {}
+            }
+        }
+        min
+    }
+
+    /// Returns true if all members in this set are complete.
+    pub fn all_complete(&self) -> bool {
+        !self.lits.is_empty() && self.lits.iter().all(|l| !l.is_cut())
+    }
+
+    /// Returns true if any member in this set is complete.
+    pub fn any_complete(&self) -> bool {
+        self.lits.iter().any(|lit| !lit.is_cut())
+    }
+
+    /// Returns true if this set contains an empty literal.
+    pub fn contains_empty(&self) -> bool {
+        self.lits.iter().any(|lit| lit.is_empty())
+    }
+
+    /// Returns true if this set is empty or if all of its members is empty.
+    pub fn is_empty(&self) -> bool {
+        self.lits.is_empty() || self.lits.iter().all(|lit| lit.is_empty())
+    }
+
+    /// Returns a new empty set of literals using this set's limits.
+    pub fn to_empty(&self) -> Literals {
+        let mut lits = Literals::empty();
+        lits.set_limit_size(self.limit_size)
+            .set_limit_class(self.limit_class);
+        lits
+    }
+
+    /// Returns the longest common prefix of all members in this set.
+    pub fn longest_common_prefix(&self) -> &[u8] {
+        if self.is_empty() {
+            return &[];
+        }
+        let lit0 = &*self.lits[0];
+        let mut len = lit0.len();
+        for lit in &self.lits[1..] {
+            len = cmp::min(
+                len,
+                lit.iter()
+                   .zip(lit0)
+                   .take_while(|&(a, b)| a == b)
+                   .count());
+        }
+        &self.lits[0][..len]
+    }
+
+    /// Returns the longest common suffix of all members in this set.
+    pub fn longest_common_suffix(&self) -> &[u8] {
+        if self.is_empty() {
+            return &[];
+        }
+        let lit0 = &*self.lits[0];
+        let mut len = lit0.len();
+        for lit in &self.lits[1..] {
+            len = cmp::min(
+                len,
+                lit.iter()
+                   .rev()
+                   .zip(lit0.iter().rev())
+                   .take_while(|&(a, b)| a == b)
+                   .count());
+        }
+        &self.lits[0][self.lits[0].len() - len..]
+    }
+
+    /// Returns a new set of literals with the given number of bytes trimmed
+    /// from the suffix of each literal.
+    ///
+    /// If any literal would be cut out completely by trimming, then None is
+    /// returned.
+    ///
+    /// Any duplicates that are created as a result of this transformation are
+    /// removed.
+    pub fn trim_suffix(&self, num_bytes: usize) -> Option<Literals> {
+        if self.min_len().map(|len| len <= num_bytes).unwrap_or(true) {
+            return None;
+        }
+        let mut new = self.to_empty();
+        for mut lit in self.lits.iter().cloned() {
+            let new_len = lit.len() - num_bytes;
+            lit.truncate(new_len);
+            lit.cut();
+            new.lits.push(lit);
+        }
+        new.lits.sort();
+        new.lits.dedup();
+        Some(new)
+    }
+
+    /// Returns a new set of prefixes of this set of literals that are
+    /// guaranteed to be unambiguous.
+    ///
+    /// Any substring match with a member of the set is returned is guaranteed
+    /// to never overlap with a substring match of another member of the set
+    /// at the same starting position.
+    ///
+    /// Given any two members of the returned set, neither is a substring of
+    /// the other.
+    pub fn unambiguous_prefixes(&self) -> Literals {
+        if self.lits.is_empty() {
+            return self.to_empty();
+        }
+        let mut old: Vec<Literal> = self.lits.iter().cloned().collect();
+        let mut new = self.to_empty();
+    'OUTER:
+        while let Some(mut candidate) = old.pop() {
+            if candidate.is_empty() {
+                continue;
+            }
+            if new.lits.is_empty() {
+                new.lits.push(candidate);
+                continue;
+            }
+            for lit2 in &mut new.lits {
+                if lit2.is_empty() {
+                    continue;
+                }
+                if &candidate == lit2 {
+                    // If the literal is already in the set, then we can
+                    // just drop it. But make sure that cut literals are
+                    // infectious!
+                    candidate.cut = candidate.cut || lit2.cut;
+                    lit2.cut = candidate.cut;
+                    continue 'OUTER;
+                }
+                if candidate.len() < lit2.len() {
+                    if let Some(i) = position(&candidate, &lit2) {
+                        candidate.cut();
+                        let mut lit3 = lit2.clone();
+                        lit3.truncate(i);
+                        lit3.cut();
+                        old.push(lit3);
+                        lit2.clear();
+                    }
+                } else {
+                    if let Some(i) = position(&lit2, &candidate) {
+                        lit2.cut();
+                        let mut new_candidate = candidate.clone();
+                        new_candidate.truncate(i);
+                        new_candidate.cut();
+                        old.push(new_candidate);
+                        candidate.clear();
+                    }
+                }
+                // Oops, the candidate is already represented in the set.
+                if candidate.is_empty() {
+                    continue 'OUTER;
+                }
+            }
+            new.lits.push(candidate);
+        }
+        new.lits.retain(|lit| !lit.is_empty());
+        new.lits.sort();
+        new.lits.dedup();
+        new
+    }
+
+    /// Returns a new set of suffixes of this set of literals that are
+    /// guaranteed to be unambiguous.
+    ///
+    /// Any substring match with a member of the set is returned is guaranteed
+    /// to never overlap with a substring match of another member of the set
+    /// at the same ending position.
+    ///
+    /// Given any two members of the returned set, neither is a substring of
+    /// the other.
+    pub fn unambiguous_suffixes(&self) -> Literals {
+        // This is a touch wasteful...
+        let mut lits = self.clone();
+        lits.reverse();
+        let mut unamb = lits.unambiguous_prefixes();
+        unamb.reverse();
+        unamb
+    }
+
+    /// Unions the prefixes from the given expression to this set.
+    ///
+    /// If prefixes could not be added (for example, this set would exceed its
+    /// size limits or the set of prefixes from `expr` includes the empty
+    /// string), then false is returned.
+    ///
+    /// Note that prefix literals extracted from `expr` are said to be complete
+    /// if and only if the literal extends from the beginning of `expr` to the
+    /// end of `expr`.
+    pub fn union_prefixes(&mut self, expr: &Hir) -> bool {
+        let mut lits = self.to_empty();
+        prefixes(expr, &mut lits);
+        !lits.is_empty() && !lits.contains_empty() && self.union(lits)
+    }
+
+    /// Unions the suffixes from the given expression to this set.
+    ///
+    /// If suffixes could not be added (for example, this set would exceed its
+    /// size limits or the set of suffixes from `expr` includes the empty
+    /// string), then false is returned.
+    ///
+    /// Note that prefix literals extracted from `expr` are said to be complete
+    /// if and only if the literal extends from the end of `expr` to the
+    /// beginning of `expr`.
+    pub fn union_suffixes(&mut self, expr: &Hir) -> bool {
+        let mut lits = self.to_empty();
+        suffixes(expr, &mut lits);
+        lits.reverse();
+        !lits.is_empty() && !lits.contains_empty() && self.union(lits)
+    }
+
+    /// Unions this set with another set.
+    ///
+    /// If the union would cause the set to exceed its limits, then the union
+    /// is skipped and it returns false. Otherwise, if the union succeeds, it
+    /// returns true.
+    pub fn union(&mut self, lits: Literals) -> bool {
+        if self.num_bytes() + lits.num_bytes() > self.limit_size {
+            return false;
+        }
+        if lits.is_empty() {
+            self.lits.push(Literal::empty());
+        } else {
+            self.lits.extend(lits.lits);
+        }
+        true
+    }
+
+    /// Extends this set with another set.
+    ///
+    /// The set of literals is extended via a cross product.
+    ///
+    /// If a cross product would cause this set to exceed its limits, then the
+    /// cross product is skipped and it returns false. Otherwise, if the cross
+    /// product succeeds, it returns true.
+    pub fn cross_product(&mut self, lits: &Literals) -> bool {
+        if lits.is_empty() {
+            return true;
+        }
+        // Check that we make sure we stay in our limits.
+        let mut size_after;
+        if self.is_empty() || !self.any_complete() {
+            size_after = self.num_bytes();
+            for lits_lit in lits.literals() {
+                size_after += lits_lit.len();
+            }
+        } else {
+            size_after = self.lits.iter().fold(0, |accum, lit| {
+                accum + if lit.is_cut() { lit.len() } else { 0 }
+            });
+            for lits_lit in lits.literals() {
+                for self_lit in self.literals() {
+                    if !self_lit.is_cut() {
+                        size_after += self_lit.len() + lits_lit.len();
+                    }
+                }
+            }
+        }
+        if size_after > self.limit_size {
+            return false;
+        }
+
+        let mut base = self.remove_complete();
+        if base.is_empty() {
+            base = vec![Literal::empty()];
+        }
+        for lits_lit in lits.literals() {
+            for mut self_lit in base.clone() {
+                self_lit.extend(&**lits_lit);
+                self_lit.cut = lits_lit.cut;
+                self.lits.push(self_lit);
+            }
+        }
+        true
+    }
+
+    /// Extends each literal in this set with the bytes given.
+    ///
+    /// If the set is empty, then the given literal is added to the set.
+    ///
+    /// If adding any number of bytes to all members of this set causes a limit
+    /// to be exceeded, then no bytes are added and false is returned. If a
+    /// prefix of `bytes` can be fit into this set, then it is used and all
+    /// resulting literals are cut.
+    pub fn cross_add(&mut self, bytes: &[u8]) -> bool {
+        // N.B. This could be implemented by simply calling cross_product with
+        // a literal set containing just `bytes`, but we can be smarter about
+        // taking shorter prefixes of `bytes` if they'll fit.
+        if bytes.is_empty() {
+            return true;
+        }
+        if self.lits.is_empty() {
+            let i = cmp::min(self.limit_size, bytes.len());
+            self.lits.push(Literal::new(bytes[..i].to_owned()));
+            self.lits[0].cut = i < bytes.len();
+            return !self.lits[0].is_cut();
+        }
+        let size = self.num_bytes();
+        if size + self.lits.len() >= self.limit_size {
+            return false;
+        }
+        let mut i = 1;
+        while size + (i * self.lits.len()) <= self.limit_size
+            && i < bytes.len() {
+            i += 1;
+        }
+        for lit in &mut self.lits {
+            if !lit.is_cut() {
+                lit.extend(&bytes[..i]);
+                if i < bytes.len() {
+                    lit.cut();
+                }
+            }
+        }
+        true
+    }
+
+    /// Adds the given literal to this set.
+    ///
+    /// Returns false if adding this literal would cause the class to be too
+    /// big.
+    pub fn add(&mut self, lit: Literal) -> bool {
+        if self.num_bytes() + lit.len() > self.limit_size {
+            return false;
+        }
+        self.lits.push(lit);
+        true
+    }
+
+    /// Extends each literal in this set with the character class given.
+    ///
+    /// Returns false if the character class was too big to add.
+    pub fn add_char_class(&mut self, cls: &hir::ClassUnicode) -> bool {
+        self._add_char_class(cls, false)
+    }
+
+    /// Extends each literal in this set with the character class given,
+    /// writing the bytes of each character in reverse.
+    ///
+    /// Returns false if the character class was too big to add.
+    fn add_char_class_reverse(&mut self, cls: &hir::ClassUnicode) -> bool {
+        self._add_char_class(cls, true)
+    }
+
+    fn _add_char_class(
+        &mut self,
+        cls: &hir::ClassUnicode,
+        reverse: bool,
+    ) -> bool {
+        use std::char;
+
+        if self.class_exceeds_limits(cls_char_count(cls)) {
+            return false;
+        }
+        let mut base = self.remove_complete();
+        if base.is_empty() {
+            base = vec![Literal::empty()];
+        }
+        for r in cls.iter() {
+            let (s, e) = (r.start as u32, r.end as u32 + 1);
+            for c in (s..e).filter_map(char::from_u32) {
+                for mut lit in base.clone() {
+                    let mut bytes = c.to_string().into_bytes();
+                    if reverse {
+                        bytes.reverse();
+                    }
+                    lit.extend(&bytes);
+                    self.lits.push(lit);
+                }
+            }
+        }
+        true
+    }
+
+    /// Extends each literal in this set with the byte class given.
+    ///
+    /// Returns false if the byte class was too big to add.
+    pub fn add_byte_class(&mut self, cls: &hir::ClassBytes) -> bool {
+        if self.class_exceeds_limits(cls_byte_count(cls)) {
+            return false;
+        }
+        let mut base = self.remove_complete();
+        if base.is_empty() {
+            base = vec![Literal::empty()];
+        }
+        for r in cls.iter() {
+            let (s, e) = (r.start as u32, r.end as u32 + 1);
+            for b in (s..e).map(|b| b as u8) {
+                for mut lit in base.clone() {
+                    lit.push(b);
+                    self.lits.push(lit);
+                }
+            }
+        }
+        true
+    }
+
+    /// Cuts every member of this set. When a member is cut, it can never
+    /// be extended.
+    pub fn cut(&mut self) {
+        for lit in &mut self.lits {
+            lit.cut();
+        }
+    }
+
+    /// Reverses all members in place.
+    pub fn reverse(&mut self) {
+        for lit in &mut self.lits {
+            lit.reverse();
+        }
+    }
+
+    /// Clears this set of all members.
+    pub fn clear(&mut self) {
+        self.lits.clear();
+    }
+
+    /// Pops all complete literals out of this set.
+    fn remove_complete(&mut self) -> Vec<Literal> {
+        let mut base = vec![];
+        for lit in mem::replace(&mut self.lits, vec![]) {
+            if lit.is_cut() {
+                self.lits.push(lit);
+            } else {
+                base.push(lit);
+            }
+        }
+        base
+    }
+
+    /// Returns the total number of bytes in this set.
+    fn num_bytes(&self) -> usize {
+        self.lits.iter().fold(0, |accum, lit| accum + lit.len())
+    }
+
+    /// Returns true if a character class with the given size would cause this
+    /// set to exceed its limits.
+    ///
+    /// The size given should correspond to the number of items in the class.
+    fn class_exceeds_limits(&self, size: usize) -> bool {
+        if size > self.limit_class {
+            return true;
+        }
+        // This is an approximation since codepoints in a char class can encode
+        // to 1-4 bytes.
+        let new_byte_count =
+            if self.lits.is_empty() {
+                size
+            } else {
+                self.lits
+                    .iter()
+                    .fold(0, |accum, lit| {
+                        accum + if lit.is_cut() {
+                            // If the literal is cut, then we'll never add
+                            // anything to it, so don't count it.
+                            0
+                        } else {
+                            (lit.len() + 1) * size
+                        }
+                    })
+            };
+        new_byte_count > self.limit_size
+    }
+}
+
+fn prefixes(expr: &Hir, lits: &mut Literals) {
+    match *expr.kind() {
+        HirKind::Literal(hir::Literal::Unicode(c)) => {
+            let mut buf = [0; 4];
+            lits.cross_add(c.encode_utf8(&mut buf).as_bytes());
+        }
+        HirKind::Literal(hir::Literal::Byte(b)) => {
+            lits.cross_add(&[b]);
+        }
+        HirKind::Class(hir::Class::Unicode(ref cls)) => {
+            if !lits.add_char_class(cls) {
+                lits.cut();
+            }
+        }
+        HirKind::Class(hir::Class::Bytes(ref cls)) => {
+            if !lits.add_byte_class(cls) {
+                lits.cut();
+            }
+        }
+        HirKind::Group(hir::Group { ref hir, .. }) => {
+            prefixes(&**hir, lits);
+        }
+        HirKind::Repetition(ref x) => {
+            match x.kind {
+                hir::RepetitionKind::ZeroOrOne => {
+                    repeat_zero_or_one_literals(&x.hir, lits, prefixes);
+                }
+                hir::RepetitionKind::ZeroOrMore => {
+                    repeat_zero_or_more_literals(&x.hir, lits, prefixes);
+                }
+                hir::RepetitionKind::OneOrMore => {
+                    repeat_one_or_more_literals(&x.hir, lits, prefixes);
+                }
+                hir::RepetitionKind::Range(ref rng) => {
+                    let (min, max) = match *rng {
+                        hir::RepetitionRange::Exactly(m) => {
+                            (m, Some(m))
+                        }
+                        hir::RepetitionRange::AtLeast(m) => {
+                            (m, None)
+                        }
+                        hir::RepetitionRange::Bounded(m, n) => {
+                            (m, Some(n))
+                        }
+                    };
+                    repeat_range_literals(
+                        &x.hir, min, max, x.greedy, lits, prefixes)
+                }
+            }
+        }
+        HirKind::Concat(ref es) if es.is_empty() => {}
+        HirKind::Concat(ref es) if es.len() == 1 => prefixes(&es[0], lits),
+        HirKind::Concat(ref es) => {
+            for e in es {
+                if let HirKind::Anchor(hir::Anchor::StartText) = *e.kind() {
+                    if !lits.is_empty() {
+                        lits.cut();
+                        break;
+                    }
+                    lits.add(Literal::empty());
+                    continue;
+                }
+                let mut lits2 = lits.to_empty();
+                prefixes(e, &mut lits2);
+                if !lits.cross_product(&lits2) || !lits2.any_complete() {
+                    // If this expression couldn't yield any literal that
+                    // could be extended, then we need to quit. Since we're
+                    // short-circuiting, we also need to freeze every member.
+                    lits.cut();
+                    break;
+                }
+            }
+        }
+        HirKind::Alternation(ref es) => {
+            alternate_literals(es, lits, prefixes);
+        }
+        _ => lits.cut(),
+    }
+}
+
+fn suffixes(expr: &Hir, lits: &mut Literals) {
+    match *expr.kind() {
+        HirKind::Literal(hir::Literal::Unicode(c)) => {
+            let mut buf = [0u8; 4];
+            let i = c.encode_utf8(&mut buf).len();
+            let buf = &mut buf[..i];
+            buf.reverse();
+            lits.cross_add(buf);
+        }
+        HirKind::Literal(hir::Literal::Byte(b)) => {
+            lits.cross_add(&[b]);
+        }
+        HirKind::Class(hir::Class::Unicode(ref cls)) => {
+            if !lits.add_char_class_reverse(cls) {
+                lits.cut();
+            }
+        }
+        HirKind::Class(hir::Class::Bytes(ref cls)) => {
+            if !lits.add_byte_class(cls) {
+                lits.cut();
+            }
+        }
+        HirKind::Group(hir::Group { ref hir, .. }) => {
+            suffixes(&**hir, lits);
+        }
+        HirKind::Repetition(ref x) => {
+            match x.kind {
+                hir::RepetitionKind::ZeroOrOne => {
+                    repeat_zero_or_one_literals(&x.hir, lits, suffixes);
+                }
+                hir::RepetitionKind::ZeroOrMore => {
+                    repeat_zero_or_more_literals(&x.hir, lits, suffixes);
+                }
+                hir::RepetitionKind::OneOrMore => {
+                    repeat_one_or_more_literals(&x.hir, lits, suffixes);
+                }
+                hir::RepetitionKind::Range(ref rng) => {
+                    let (min, max) = match *rng {
+                        hir::RepetitionRange::Exactly(m) => {
+                            (m, Some(m))
+                        }
+                        hir::RepetitionRange::AtLeast(m) => {
+                            (m, None)
+                        }
+                        hir::RepetitionRange::Bounded(m, n) => {
+                            (m, Some(n))
+                        }
+                    };
+                    repeat_range_literals(
+                        &x.hir, min, max, x.greedy, lits, suffixes)
+                }
+            }
+        }
+        HirKind::Concat(ref es) if es.is_empty() => {}
+        HirKind::Concat(ref es) if es.len() == 1 => suffixes(&es[0], lits),
+        HirKind::Concat(ref es) => {
+            for e in es.iter().rev() {
+                if let HirKind::Anchor(hir::Anchor::EndText) = *e.kind() {
+                    if !lits.is_empty() {
+                        lits.cut();
+                        break;
+                    }
+                    lits.add(Literal::empty());
+                    continue;
+                }
+                let mut lits2 = lits.to_empty();
+                suffixes(e, &mut lits2);
+                if !lits.cross_product(&lits2) || !lits2.any_complete() {
+                    // If this expression couldn't yield any literal that
+                    // could be extended, then we need to quit. Since we're
+                    // short-circuiting, we also need to freeze every member.
+                    lits.cut();
+                    break;
+                }
+            }
+        }
+        HirKind::Alternation(ref es) => {
+            alternate_literals(es, lits, suffixes);
+        }
+        _ => lits.cut(),
+    }
+}
+
+fn repeat_zero_or_one_literals<F: FnMut(&Hir, &mut Literals)>(
+    e: &Hir,
+    lits: &mut Literals,
+    mut f: F,
+) {
+    let (mut lits2, mut lits3) = (lits.clone(), lits.to_empty());
+    lits3.set_limit_size(lits.limit_size() / 2);
+    f(e, &mut lits3);
+
+    if lits3.is_empty() || !lits2.cross_product(&lits3) {
+        lits.cut();
+        return;
+    }
+    lits2.add(Literal::empty());
+    if !lits.union(lits2) {
+        lits.cut();
+    }
+}
+
+fn repeat_zero_or_more_literals<F: FnMut(&Hir, &mut Literals)>(
+    e: &Hir,
+    lits: &mut Literals,
+    mut f: F,
+) {
+    let (mut lits2, mut lits3) = (lits.clone(), lits.to_empty());
+    lits3.set_limit_size(lits.limit_size() / 2);
+    f(e, &mut lits3);
+
+    if lits3.is_empty() || !lits2.cross_product(&lits3) {
+        lits.cut();
+        return;
+    }
+    lits2.cut();
+    lits2.add(Literal::empty());
+    if !lits.union(lits2) {
+        lits.cut();
+    }
+}
+
+fn repeat_one_or_more_literals<F: FnMut(&Hir, &mut Literals)>(
+    e: &Hir,
+    lits: &mut Literals,
+    mut f: F,
+) {
+    f(e, lits);
+    lits.cut();
+}
+
+fn repeat_range_literals<F: FnMut(&Hir, &mut Literals)>(
+    e: &Hir,
+    min: u32,
+    max: Option<u32>,
+    greedy: bool,
+    lits: &mut Literals,
+    mut f: F,
+) {
+    if min == 0 {
+        // This is a bit conservative. If `max` is set, then we could
+        // treat this as a finite set of alternations. For now, we
+        // just treat it as `e*`.
+        f(&Hir::repetition(hir::Repetition {
+            kind: hir::RepetitionKind::ZeroOrMore,
+            greedy: greedy,
+            hir: Box::new(e.clone()),
+        }), lits);
+    } else {
+        if min > 0 {
+            let n = cmp::min(lits.limit_size, min as usize);
+            let es = iter::repeat(e.clone()).take(n).collect();
+            f(&Hir::concat(es), lits);
+            if n < min as usize || lits.contains_empty() {
+                lits.cut();
+            }
+        }
+        if max.map_or(true, |max| min < max) {
+            lits.cut();
+        }
+    }
+}
+
+fn alternate_literals<F: FnMut(&Hir, &mut Literals)>(
+    es: &[Hir],
+    lits: &mut Literals,
+    mut f: F,
+) {
+    let mut lits2 = lits.to_empty();
+    for e in es {
+        let mut lits3 = lits.to_empty();
+        lits3.set_limit_size(lits.limit_size() / 5);
+        f(e, &mut lits3);
+        if lits3.is_empty() || !lits2.union(lits3) {
+            // If we couldn't find suffixes for *any* of the
+            // alternates, then the entire alternation has to be thrown
+            // away and any existing members must be frozen. Similarly,
+            // if the union couldn't complete, stop and freeze.
+            lits.cut();
+            return;
+        }
+    }
+    if !lits.cross_product(&lits2) {
+        lits.cut();
+    }
+}
+
+impl fmt::Debug for Literals {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Literals")
+         .field("lits", &self.lits)
+         .field("limit_size", &self.limit_size)
+         .field("limit_class", &self.limit_class)
+         .finish()
+    }
+}
+
+impl Literal {
+    /// Returns a new complete literal with the bytes given.
+    pub fn new(bytes: Vec<u8>) -> Literal {
+        Literal { v: bytes, cut: false }
+    }
+
+    /// Returns a new complete empty literal.
+    pub fn empty() -> Literal {
+        Literal { v: vec![], cut: false }
+    }
+
+    /// Returns true if this literal was "cut."
+    pub fn is_cut(&self) -> bool {
+        self.cut
+    }
+
+    /// Cuts this literal.
+    pub fn cut(&mut self) {
+        self.cut = true;
+    }
+}
+
+impl PartialEq for Literal {
+    fn eq(&self, other: &Literal) -> bool {
+        self.v == other.v
+    }
+}
+
+impl PartialOrd for Literal {
+    fn partial_cmp(&self, other: &Literal) -> Option<cmp::Ordering> {
+        self.v.partial_cmp(&other.v)
+    }
+}
+
+impl fmt::Debug for Literal {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        if self.is_cut() {
+            write!(f, "Cut({})", escape_unicode(&self.v))
+        } else {
+            write!(f, "Complete({})", escape_unicode(&self.v))
+        }
+    }
+}
+
+impl AsRef<[u8]> for Literal {
+    fn as_ref(&self) -> &[u8] { &self.v }
+}
+
+impl ops::Deref for Literal {
+    type Target = Vec<u8>;
+    fn deref(&self) -> &Vec<u8> { &self.v }
+}
+
+impl ops::DerefMut for Literal {
+    fn deref_mut(&mut self) -> &mut Vec<u8> { &mut self.v }
+}
+
+fn position(needle: &[u8], mut haystack: &[u8]) -> Option<usize> {
+    let mut i = 0;
+    while haystack.len() >= needle.len() {
+        if needle == &haystack[..needle.len()] {
+            return Some(i);
+        }
+        i += 1;
+        haystack = &haystack[1..];
+    }
+    None
+}
+
+fn escape_unicode(bytes: &[u8]) -> String {
+    let show = match ::std::str::from_utf8(bytes) {
+        Ok(v) => v.to_string(),
+        Err(_) => escape_bytes(bytes),
+    };
+    let mut space_escaped = String::new();
+    for c in show.chars() {
+        if c.is_whitespace() {
+            let escaped = if c as u32 <= 0x7F {
+                escape_byte(c as u8)
+            } else {
+                if c as u32 <= 0xFFFF {
+                    format!(r"\u{{{:04x}}}", c as u32)
+                } else {
+                    format!(r"\U{{{:08x}}}", c as u32)
+                }
+            };
+            space_escaped.push_str(&escaped);
+        } else {
+            space_escaped.push(c);
+        }
+    }
+    space_escaped
+}
+
+fn escape_bytes(bytes: &[u8]) -> String {
+    let mut s = String::new();
+    for &b in bytes {
+        s.push_str(&escape_byte(b));
+    }
+    s
+}
+
+fn escape_byte(byte: u8) -> String {
+    use std::ascii::escape_default;
+
+    let escaped: Vec<u8> = escape_default(byte).collect();
+    String::from_utf8_lossy(&escaped).into_owned()
+}
+
+fn cls_char_count(cls: &hir::ClassUnicode) -> usize {
+    cls.iter()
+        .map(|&r| 1 + (r.end as u32) - (r.start as u32))
+        .sum::<u32>() as usize
+}
+
+fn cls_byte_count(cls: &hir::ClassBytes) -> usize {
+    cls.iter()
+        .map(|&r| 1 + (r.end as u32) - (r.start as u32))
+        .sum::<u32>() as usize
+}
+
+#[cfg(test)]
+mod tests {
+    use std::fmt;
+
+    use ParserBuilder;
+    use hir::Hir;
+    use super::{Literals, Literal, escape_bytes};
+
+    // To make test failures easier to read.
+    #[derive(Debug, Eq, PartialEq)]
+    struct Bytes(Vec<ULiteral>);
+    #[derive(Debug, Eq, PartialEq)]
+    struct Unicode(Vec<ULiteral>);
+
+    fn escape_lits(blits: &[Literal]) -> Vec<ULiteral> {
+        let mut ulits = vec![];
+        for blit in blits {
+            ulits.push(ULiteral {
+                v: escape_bytes(&blit),
+                cut: blit.is_cut(),
+            });
+        }
+        ulits
+    }
+
+    fn create_lits<I: IntoIterator<Item=Literal>>(it: I) -> Literals {
+        Literals {
+            lits: it.into_iter().collect(),
+            limit_size: 0,
+            limit_class: 0,
+        }
+    }
+
+    // Needs to be pub for 1.3?
+    #[derive(Clone, Eq, PartialEq)]
+    pub struct ULiteral {
+        v: String,
+        cut: bool,
+    }
+
+    impl ULiteral {
+        fn is_cut(&self) -> bool { self.cut }
+    }
+
+    impl fmt::Debug for ULiteral {
+        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+            if self.is_cut() {
+                write!(f, "Cut({})", self.v)
+            } else {
+                write!(f, "Complete({})", self.v)
+            }
+        }
+    }
+
+    impl PartialEq<Literal> for ULiteral {
+        fn eq(&self, other: &Literal) -> bool {
+            self.v.as_bytes() == &*other.v && self.is_cut() == other.is_cut()
+        }
+    }
+
+    impl PartialEq<ULiteral> for Literal {
+        fn eq(&self, other: &ULiteral) -> bool {
+            &*self.v == other.v.as_bytes() && self.is_cut() == other.is_cut()
+        }
+    }
+
+    #[allow(non_snake_case)]
+    fn C(s: &'static str) -> ULiteral {
+        ULiteral { v: s.to_owned(), cut: true }
+    }
+    #[allow(non_snake_case)]
+    fn M(s: &'static str) -> ULiteral {
+        ULiteral { v: s.to_owned(), cut: false }
+    }
+
+    fn prefixes(lits: &mut Literals, expr: &Hir) {
+        lits.union_prefixes(expr);
+    }
+
+    fn suffixes(lits: &mut Literals, expr: &Hir) {
+        lits.union_suffixes(expr);
+    }
+
+    macro_rules! assert_lit_eq {
+        ($which:ident, $got_lits:expr, $($expected_lit:expr),*) => {{
+            let expected: Vec<ULiteral> = vec![$($expected_lit),*];
+            let lits = $got_lits;
+            assert_eq!(
+                $which(expected.clone()),
+                $which(escape_lits(lits.literals())));
+            assert_eq!(
+                !expected.is_empty() && expected.iter().all(|l| !l.is_cut()),
+                lits.all_complete());
+            assert_eq!(
+                expected.iter().any(|l| !l.is_cut()),
+                lits.any_complete());
+        }};
+    }
+
+    macro_rules! test_lit {
+        ($name:ident, $which:ident, $re:expr) => {
+            test_lit!($name, $which, $re,);
+        };
+        ($name:ident, $which:ident, $re:expr, $($lit:expr),*) => {
+            #[test]
+            fn $name() {
+                let expr = ParserBuilder::new()
+                    .build()
+                    .parse($re)
+                    .unwrap();
+                let lits = Literals::$which(&expr);
+                assert_lit_eq!(Unicode, lits, $($lit),*);
+
+                let expr = ParserBuilder::new()
+                    .allow_invalid_utf8(true)
+                    .unicode(false)
+                    .build()
+                    .parse($re)
+                    .unwrap();
+                let lits = Literals::$which(&expr);
+                assert_lit_eq!(Bytes, lits, $($lit),*);
+            }
+        };
+    }
+
+    // ************************************************************************
+    // Tests for prefix literal extraction.
+    // ************************************************************************
+
+    // Elementary tests.
+    test_lit!(pfx_one_lit1, prefixes, "a", M("a"));
+    test_lit!(pfx_one_lit2, prefixes, "abc", M("abc"));
+    test_lit!(pfx_one_lit3, prefixes, "(?u)☃", M("\\xe2\\x98\\x83"));
+    test_lit!(pfx_one_lit4, prefixes, "(?ui)☃", M("\\xe2\\x98\\x83"));
+    test_lit!(pfx_class1, prefixes, "[1-4]",
+              M("1"), M("2"), M("3"), M("4"));
+    test_lit!(pfx_class2, prefixes, "(?u)[☃Ⅰ]",
+              M("\\xe2\\x85\\xa0"), M("\\xe2\\x98\\x83"));
+    test_lit!(pfx_class3, prefixes, "(?ui)[☃Ⅰ]",
+              M("\\xe2\\x85\\xa0"), M("\\xe2\\x85\\xb0"),
+              M("\\xe2\\x98\\x83"));
+    test_lit!(pfx_one_lit_casei1, prefixes, "(?i)a",
+              M("A"), M("a"));
+    test_lit!(pfx_one_lit_casei2, prefixes, "(?i)abc",
+              M("ABC"), M("aBC"), M("AbC"), M("abC"),
+              M("ABc"), M("aBc"), M("Abc"), M("abc"));
+    test_lit!(pfx_group1, prefixes, "(a)", M("a"));
+    test_lit!(pfx_rep_zero_or_one1, prefixes, "a?");
+    test_lit!(pfx_rep_zero_or_one2, prefixes, "(?:abc)?");
+    test_lit!(pfx_rep_zero_or_more1, prefixes, "a*");
+    test_lit!(pfx_rep_zero_or_more2, prefixes, "(?:abc)*");
+    test_lit!(pfx_rep_one_or_more1, prefixes, "a+", C("a"));
+    test_lit!(pfx_rep_one_or_more2, prefixes, "(?:abc)+", C("abc"));
+    test_lit!(pfx_rep_nested_one_or_more, prefixes, "(?:a+)+", C("a"));
+    test_lit!(pfx_rep_range1, prefixes, "a{0}");
+    test_lit!(pfx_rep_range2, prefixes, "a{0,}");
+    test_lit!(pfx_rep_range3, prefixes, "a{0,1}");
+    test_lit!(pfx_rep_range4, prefixes, "a{1}", M("a"));
+    test_lit!(pfx_rep_range5, prefixes, "a{2}", M("aa"));
+    test_lit!(pfx_rep_range6, prefixes, "a{1,2}", C("a"));
+    test_lit!(pfx_rep_range7, prefixes, "a{2,3}", C("aa"));
+
+    // Test regexes with concatenations.
+    test_lit!(pfx_cat1, prefixes, "(?:a)(?:b)", M("ab"));
+    test_lit!(pfx_cat2, prefixes, "[ab]z", M("az"), M("bz"));
+    test_lit!(pfx_cat3, prefixes, "(?i)[ab]z",
+              M("AZ"), M("BZ"), M("aZ"), M("bZ"),
+              M("Az"), M("Bz"), M("az"), M("bz"));
+    test_lit!(pfx_cat4, prefixes, "[ab][yz]",
+              M("ay"), M("by"), M("az"), M("bz"));
+    test_lit!(pfx_cat5, prefixes, "a*b", C("a"), M("b"));
+    test_lit!(pfx_cat6, prefixes, "a*b*c", C("a"), C("b"), M("c"));
+    test_lit!(pfx_cat7, prefixes, "a*b*c+", C("a"), C("b"), C("c"));
+    test_lit!(pfx_cat8, prefixes, "a*b+c", C("a"), C("b"));
+    test_lit!(pfx_cat9, prefixes, "a*b+c*", C("a"), C("b"));
+    test_lit!(pfx_cat10, prefixes, "ab*", C("ab"), M("a"));
+    test_lit!(pfx_cat11, prefixes, "ab*c", C("ab"), M("ac"));
+    test_lit!(pfx_cat12, prefixes, "ab+", C("ab"));
+    test_lit!(pfx_cat13, prefixes, "ab+c", C("ab"));
+    test_lit!(pfx_cat14, prefixes, "a^", C("a"));
+    test_lit!(pfx_cat15, prefixes, "$a");
+    test_lit!(pfx_cat16, prefixes, r"ab*c", C("ab"), M("ac"));
+    test_lit!(pfx_cat17, prefixes, r"ab+c", C("ab"));
+    test_lit!(pfx_cat18, prefixes, r"z*azb", C("z"), M("azb"));
+    test_lit!(pfx_cat19, prefixes, "a.z", C("a"));
+
+    // Test regexes with alternations.
+    test_lit!(pfx_alt1, prefixes, "a|b", M("a"), M("b"));
+    test_lit!(pfx_alt2, prefixes, "[1-3]|b", M("1"), M("2"), M("3"), M("b"));
+    test_lit!(pfx_alt3, prefixes, "y(?:a|b)z", M("yaz"), M("ybz"));
+    test_lit!(pfx_alt4, prefixes, "a|b*");
+    test_lit!(pfx_alt5, prefixes, "a|b+", M("a"), C("b"));
+    test_lit!(pfx_alt6, prefixes, "a|(?:b|c*)");
+    test_lit!(pfx_alt7, prefixes, "(a|b)*c|(a|ab)*c",
+              C("a"), C("b"), M("c"), C("a"), C("ab"), M("c"));
+    test_lit!(pfx_alt8, prefixes, "a*b|c", C("a"), M("b"), M("c"));
+
+    // Test regexes with empty assertions.
+    test_lit!(pfx_empty1, prefixes, "^a", M("a"));
+    test_lit!(pfx_empty2, prefixes, "a${2}", C("a"));
+    test_lit!(pfx_empty3, prefixes, "^abc", M("abc"));
+    test_lit!(pfx_empty4, prefixes, "(?:^abc)|(?:^z)", M("abc"), M("z"));
+
+    // Make sure some curious regexes have no prefixes.
+    test_lit!(pfx_nothing1, prefixes, ".");
+    test_lit!(pfx_nothing2, prefixes, "(?s).");
+    test_lit!(pfx_nothing3, prefixes, "^");
+    test_lit!(pfx_nothing4, prefixes, "$");
+    test_lit!(pfx_nothing6, prefixes, "(?m)$");
+    test_lit!(pfx_nothing7, prefixes, r"\b");
+    test_lit!(pfx_nothing8, prefixes, r"\B");
+
+    // Test a few regexes that defeat any prefix literal detection.
+    test_lit!(pfx_defeated1, prefixes, ".a");
+    test_lit!(pfx_defeated2, prefixes, "(?s).a");
+    test_lit!(pfx_defeated3, prefixes, "a*b*c*");
+    test_lit!(pfx_defeated4, prefixes, "a|.");
+    test_lit!(pfx_defeated5, prefixes, ".|a");
+    test_lit!(pfx_defeated6, prefixes, "a|^");
+    test_lit!(pfx_defeated7, prefixes, ".(?:a(?:b)(?:c))");
+    test_lit!(pfx_defeated8, prefixes, "$a");
+    test_lit!(pfx_defeated9, prefixes, "(?m)$a");
+    test_lit!(pfx_defeated10, prefixes, r"\ba");
+    test_lit!(pfx_defeated11, prefixes, r"\Ba");
+    test_lit!(pfx_defeated12, prefixes, "^*a");
+    test_lit!(pfx_defeated13, prefixes, "^+a");
+
+    test_lit!(
+        pfx_crazy1,
+        prefixes,
+        r"M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]",
+        C("Mo\\'am"), C("Mu\\'am"), C("Moam"), C("Muam"));
+
+    // ************************************************************************
+    // Tests for quiting prefix literal search.
+    // ************************************************************************
+
+    macro_rules! test_exhausted {
+        ($name:ident, $which:ident, $re:expr) => {
+            test_exhausted!($name, $which, $re,);
+        };
+        ($name:ident, $which:ident, $re:expr, $($lit:expr),*) => {
+            #[test]
+            fn $name() {
+                let expr = ParserBuilder::new()
+                    .build()
+                    .parse($re)
+                    .unwrap();
+                let mut lits = Literals::empty();
+                lits.set_limit_size(20).set_limit_class(10);
+                $which(&mut lits, &expr);
+                assert_lit_eq!(Unicode, lits, $($lit),*);
+
+                let expr = ParserBuilder::new()
+                    .allow_invalid_utf8(true)
+                    .unicode(false)
+                    .build()
+                    .parse($re)
+                    .unwrap();
+                let mut lits = Literals::empty();
+                lits.set_limit_size(20).set_limit_class(10);
+                $which(&mut lits, &expr);
+                assert_lit_eq!(Bytes, lits, $($lit),*);
+            }
+        };
+    }
+
+    // These test use a much lower limit than the default so that we can
+    // write test cases of reasonable size.
+    test_exhausted!(pfx_exhausted1, prefixes, "[a-z]");
+    test_exhausted!(pfx_exhausted2, prefixes, "[a-z]*A");
+    test_exhausted!(pfx_exhausted3, prefixes, "A[a-z]Z", C("A"));
+    test_exhausted!(pfx_exhausted4, prefixes, "(?i)foobar",
+                    C("FO"), C("fO"), C("Fo"), C("fo"));
+    test_exhausted!(pfx_exhausted5, prefixes, "(?:ab){100}",
+                    C("abababababababababab"));
+    test_exhausted!(pfx_exhausted6, prefixes, "(?:(?:ab){100})*cd",
+                    C("ababababab"), M("cd"));
+    test_exhausted!(pfx_exhausted7, prefixes, "z(?:(?:ab){100})*cd",
+                    C("zababababab"), M("zcd"));
+    test_exhausted!(pfx_exhausted8, prefixes, "aaaaaaaaaaaaaaaaaaaaz",
+                    C("aaaaaaaaaaaaaaaaaaaa"));
+
+    // ************************************************************************
+    // Tests for suffix literal extraction.
+    // ************************************************************************
+
+    // Elementary tests.
+    test_lit!(sfx_one_lit1, suffixes, "a", M("a"));
+    test_lit!(sfx_one_lit2, suffixes, "abc", M("abc"));
+    test_lit!(sfx_one_lit3, suffixes, "(?u)☃", M("\\xe2\\x98\\x83"));
+    test_lit!(sfx_one_lit4, suffixes, "(?ui)☃", M("\\xe2\\x98\\x83"));
+    test_lit!(sfx_class1, suffixes, "[1-4]",
+              M("1"), M("2"), M("3"), M("4"));
+    test_lit!(sfx_class2, suffixes, "(?u)[☃Ⅰ]",
+              M("\\xe2\\x85\\xa0"), M("\\xe2\\x98\\x83"));
+    test_lit!(sfx_class3, suffixes, "(?ui)[☃Ⅰ]",
+              M("\\xe2\\x85\\xa0"), M("\\xe2\\x85\\xb0"),
+              M("\\xe2\\x98\\x83"));
+    test_lit!(sfx_one_lit_casei1, suffixes, "(?i)a",
+              M("A"), M("a"));
+    test_lit!(sfx_one_lit_casei2, suffixes, "(?i)abc",
+              M("ABC"), M("ABc"), M("AbC"), M("Abc"),
+              M("aBC"), M("aBc"), M("abC"), M("abc"));
+    test_lit!(sfx_group1, suffixes, "(a)", M("a"));
+    test_lit!(sfx_rep_zero_or_one1, suffixes, "a?");
+    test_lit!(sfx_rep_zero_or_one2, suffixes, "(?:abc)?");
+    test_lit!(sfx_rep_zero_or_more1, suffixes, "a*");
+    test_lit!(sfx_rep_zero_or_more2, suffixes, "(?:abc)*");
+    test_lit!(sfx_rep_one_or_more1, suffixes, "a+", C("a"));
+    test_lit!(sfx_rep_one_or_more2, suffixes, "(?:abc)+", C("abc"));
+    test_lit!(sfx_rep_nested_one_or_more, suffixes, "(?:a+)+", C("a"));
+    test_lit!(sfx_rep_range1, suffixes, "a{0}");
+    test_lit!(sfx_rep_range2, suffixes, "a{0,}");
+    test_lit!(sfx_rep_range3, suffixes, "a{0,1}");
+    test_lit!(sfx_rep_range4, suffixes, "a{1}", M("a"));
+    test_lit!(sfx_rep_range5, suffixes, "a{2}", M("aa"));
+    test_lit!(sfx_rep_range6, suffixes, "a{1,2}", C("a"));
+    test_lit!(sfx_rep_range7, suffixes, "a{2,3}", C("aa"));
+
+    // Test regexes with concatenations.
+    test_lit!(sfx_cat1, suffixes, "(?:a)(?:b)", M("ab"));
+    test_lit!(sfx_cat2, suffixes, "[ab]z", M("az"), M("bz"));
+    test_lit!(sfx_cat3, suffixes, "(?i)[ab]z",
+              M("AZ"), M("Az"), M("BZ"), M("Bz"),
+              M("aZ"), M("az"), M("bZ"), M("bz"));
+    test_lit!(sfx_cat4, suffixes, "[ab][yz]",
+              M("ay"), M("az"), M("by"), M("bz"));
+    test_lit!(sfx_cat5, suffixes, "a*b", C("ab"), M("b"));
+    test_lit!(sfx_cat6, suffixes, "a*b*c", C("bc"), C("ac"), M("c"));
+    test_lit!(sfx_cat7, suffixes, "a*b*c+", C("c"));
+    test_lit!(sfx_cat8, suffixes, "a*b+c", C("bc"));
+    test_lit!(sfx_cat9, suffixes, "a*b+c*", C("c"), C("b"));
+    test_lit!(sfx_cat10, suffixes, "ab*", C("b"), M("a"));
+    test_lit!(sfx_cat11, suffixes, "ab*c", C("bc"), M("ac"));
+    test_lit!(sfx_cat12, suffixes, "ab+", C("b"));
+    test_lit!(sfx_cat13, suffixes, "ab+c", C("bc"));
+    test_lit!(sfx_cat14, suffixes, "a^");
+    test_lit!(sfx_cat15, suffixes, "$a", C("a"));
+    test_lit!(sfx_cat16, suffixes, r"ab*c", C("bc"), M("ac"));
+    test_lit!(sfx_cat17, suffixes, r"ab+c", C("bc"));
+    test_lit!(sfx_cat18, suffixes, r"z*azb", C("zazb"), M("azb"));
+    test_lit!(sfx_cat19, suffixes, "a.z", C("z"));
+
+    // Test regexes with alternations.
+    test_lit!(sfx_alt1, suffixes, "a|b", M("a"), M("b"));
+    test_lit!(sfx_alt2, suffixes, "[1-3]|b", M("1"), M("2"), M("3"), M("b"));
+    test_lit!(sfx_alt3, suffixes, "y(?:a|b)z", M("yaz"), M("ybz"));
+    test_lit!(sfx_alt4, suffixes, "a|b*");
+    test_lit!(sfx_alt5, suffixes, "a|b+", M("a"), C("b"));
+    test_lit!(sfx_alt6, suffixes, "a|(?:b|c*)");
+    test_lit!(sfx_alt7, suffixes, "(a|b)*c|(a|ab)*c",
+              C("ac"), C("bc"), M("c"), C("ac"), C("abc"), M("c"));
+    test_lit!(sfx_alt8, suffixes, "a*b|c", C("ab"), M("b"), M("c"));
+
+    // Test regexes with empty assertions.
+    test_lit!(sfx_empty1, suffixes, "a$", M("a"));
+    test_lit!(sfx_empty2, suffixes, "${2}a", C("a"));
+
+    // Make sure some curious regexes have no suffixes.
+    test_lit!(sfx_nothing1, suffixes, ".");
+    test_lit!(sfx_nothing2, suffixes, "(?s).");
+    test_lit!(sfx_nothing3, suffixes, "^");
+    test_lit!(sfx_nothing4, suffixes, "$");
+    test_lit!(sfx_nothing6, suffixes, "(?m)$");
+    test_lit!(sfx_nothing7, suffixes, r"\b");
+    test_lit!(sfx_nothing8, suffixes, r"\B");
+
+    // Test a few regexes that defeat any suffix literal detection.
+    test_lit!(sfx_defeated1, suffixes, "a.");
+    test_lit!(sfx_defeated2, suffixes, "(?s)a.");
+    test_lit!(sfx_defeated3, suffixes, "a*b*c*");
+    test_lit!(sfx_defeated4, suffixes, "a|.");
+    test_lit!(sfx_defeated5, suffixes, ".|a");
+    test_lit!(sfx_defeated6, suffixes, "a|^");
+    test_lit!(sfx_defeated7, suffixes, "(?:a(?:b)(?:c)).");
+    test_lit!(sfx_defeated8, suffixes, "a^");
+    test_lit!(sfx_defeated9, suffixes, "(?m)a$");
+    test_lit!(sfx_defeated10, suffixes, r"a\b");
+    test_lit!(sfx_defeated11, suffixes, r"a\B");
+    test_lit!(sfx_defeated12, suffixes, "a^*");
+    test_lit!(sfx_defeated13, suffixes, "a^+");
+
+    // These test use a much lower limit than the default so that we can
+    // write test cases of reasonable size.
+    test_exhausted!(sfx_exhausted1, suffixes, "[a-z]");
+    test_exhausted!(sfx_exhausted2, suffixes, "A[a-z]*");
+    test_exhausted!(sfx_exhausted3, suffixes, "A[a-z]Z", C("Z"));
+    test_exhausted!(sfx_exhausted4, suffixes, "(?i)foobar",
+                    C("AR"), C("Ar"), C("aR"), C("ar"));
+    test_exhausted!(sfx_exhausted5, suffixes, "(?:ab){100}",
+                    C("abababababababababab"));
+    test_exhausted!(sfx_exhausted6, suffixes, "cd(?:(?:ab){100})*",
+                    C("ababababab"), M("cd"));
+    test_exhausted!(sfx_exhausted7, suffixes, "cd(?:(?:ab){100})*z",
+                    C("abababababz"), M("cdz"));
+    test_exhausted!(sfx_exhausted8, suffixes, "zaaaaaaaaaaaaaaaaaaaa",
+                    C("aaaaaaaaaaaaaaaaaaaa"));
+
+    // ************************************************************************
+    // Tests for generating unambiguous literal sets.
+    // ************************************************************************
+
+    macro_rules! test_unamb {
+        ($name:ident, $given:expr, $expected:expr) => {
+            #[test]
+            fn $name() {
+                let given: Vec<Literal> =
+                    $given
+                    .into_iter()
+                    .map(|ul| {
+                        let cut = ul.is_cut();
+                        Literal { v: ul.v.into_bytes(), cut: cut }
+                    })
+                    .collect();
+                let lits = create_lits(given);
+                let got = lits.unambiguous_prefixes();
+                assert_eq!($expected, escape_lits(got.literals()));
+            }
+        };
+    }
+
+    test_unamb!(unambiguous1, vec![M("z"), M("azb")], vec![C("a"), C("z")]);
+    test_unamb!(unambiguous2,
+                vec![M("zaaaaaa"), M("aa")], vec![C("aa"), C("z")]);
+    test_unamb!(unambiguous3,
+                vec![M("Sherlock"), M("Watson")],
+                vec![M("Sherlock"), M("Watson")]);
+    test_unamb!(unambiguous4, vec![M("abc"), M("bc")], vec![C("a"), C("bc")]);
+    test_unamb!(unambiguous5, vec![M("bc"), M("abc")], vec![C("a"), C("bc")]);
+    test_unamb!(unambiguous6, vec![M("a"), M("aa")], vec![C("a")]);
+    test_unamb!(unambiguous7, vec![M("aa"), M("a")], vec![C("a")]);
+    test_unamb!(unambiguous8, vec![M("ab"), M("a")], vec![C("a")]);
+    test_unamb!(unambiguous9,
+                vec![M("ac"), M("bc"), M("c"), M("ac"), M("abc"), M("c")],
+                vec![C("a"), C("b"), C("c")]);
+    test_unamb!(unambiguous10,
+                vec![M("Mo'"), M("Mu'"), M("Mo"), M("Mu")],
+                vec![C("Mo"), C("Mu")]);
+    test_unamb!(unambiguous11,
+                vec![M("zazb"), M("azb")], vec![C("a"), C("z")]);
+    test_unamb!(unambiguous12, vec![M("foo"), C("foo")], vec![C("foo")]);
+    test_unamb!(unambiguous13,
+                vec![M("ABCX"), M("CDAX"), M("BCX")],
+                vec![C("A"), C("BCX"), C("CD")]);
+    test_unamb!(unambiguous14,
+                vec![M("IMGX"), M("MVIX"), M("MGX"), M("DSX")],
+                vec![M("DSX"), C("I"), C("MGX"), C("MV")]);
+    test_unamb!(unambiguous15,
+                vec![M("IMG_"), M("MG_"), M("CIMG")],
+                vec![C("C"), C("I"), C("MG_")]);
+
+
+    // ************************************************************************
+    // Tests for suffix trimming.
+    // ************************************************************************
+    macro_rules! test_trim {
+        ($name:ident, $trim:expr, $given:expr, $expected:expr) => {
+            #[test]
+            fn $name() {
+                let given: Vec<Literal> =
+                    $given
+                    .into_iter()
+                    .map(|ul| {
+                        let cut = ul.is_cut();
+                        Literal { v: ul.v.into_bytes(), cut: cut }
+                    })
+                    .collect();
+                let lits = create_lits(given);
+                let got = lits.trim_suffix($trim).unwrap();
+                assert_eq!($expected, escape_lits(got.literals()));
+            }
+        }
+    }
+
+    test_trim!(trim1, 1, vec![M("ab"), M("yz")], vec![C("a"), C("y")]);
+    test_trim!(trim2, 1, vec![M("abc"), M("abd")], vec![C("ab")]);
+    test_trim!(trim3, 2, vec![M("abc"), M("abd")], vec![C("a")]);
+    test_trim!(trim4, 2, vec![M("abc"), M("ghij")], vec![C("a"), C("gh")]);
+
+    // ************************************************************************
+    // Tests for longest common prefix.
+    // ************************************************************************
+
+    macro_rules! test_lcp {
+        ($name:ident, $given:expr, $expected:expr) => {
+            #[test]
+            fn $name() {
+                let given: Vec<Literal> =
+                    $given
+                    .into_iter()
+                    .map(|s: &str| Literal {
+                        v: s.to_owned().into_bytes(),
+                        cut: false,
+                    })
+                    .collect();
+                let lits = create_lits(given);
+                let got = lits.longest_common_prefix();
+                assert_eq!($expected, escape_bytes(got));
+            }
+        };
+    }
+
+    test_lcp!(lcp1, vec!["a"], "a");
+    test_lcp!(lcp2, vec![], "");
+    test_lcp!(lcp3, vec!["a", "b"], "");
+    test_lcp!(lcp4, vec!["ab", "ab"], "ab");
+    test_lcp!(lcp5, vec!["ab", "a"], "a");
+    test_lcp!(lcp6, vec!["a", "ab"], "a");
+    test_lcp!(lcp7, vec!["ab", "b"], "");
+    test_lcp!(lcp8, vec!["b", "ab"], "");
+    test_lcp!(lcp9, vec!["foobar", "foobaz"], "fooba");
+    test_lcp!(lcp10, vec!["foobar", "foobaz", "a"], "");
+    test_lcp!(lcp11, vec!["a", "foobar", "foobaz"], "");
+    test_lcp!(lcp12, vec!["foo", "flub", "flab", "floo"], "f");
+
+    // ************************************************************************
+    // Tests for longest common suffix.
+    // ************************************************************************
+
+    macro_rules! test_lcs {
+        ($name:ident, $given:expr, $expected:expr) => {
+            #[test]
+            fn $name() {
+                let given: Vec<Literal> =
+                    $given
+                    .into_iter()
+                    .map(|s: &str| Literal {
+                        v: s.to_owned().into_bytes(),
+                        cut: false,
+                    })
+                    .collect();
+                let lits = create_lits(given);
+                let got = lits.longest_common_suffix();
+                assert_eq!($expected, escape_bytes(got));
+            }
+        };
+    }
+
+    test_lcs!(lcs1, vec!["a"], "a");
+    test_lcs!(lcs2, vec![], "");
+    test_lcs!(lcs3, vec!["a", "b"], "");
+    test_lcs!(lcs4, vec!["ab", "ab"], "ab");
+    test_lcs!(lcs5, vec!["ab", "a"], "");
+    test_lcs!(lcs6, vec!["a", "ab"], "");
+    test_lcs!(lcs7, vec!["ab", "b"], "b");
+    test_lcs!(lcs8, vec!["b", "ab"], "b");
+    test_lcs!(lcs9, vec!["barfoo", "bazfoo"], "foo");
+    test_lcs!(lcs10, vec!["barfoo", "bazfoo", "a"], "");
+    test_lcs!(lcs11, vec!["a", "barfoo", "bazfoo"], "");
+    test_lcs!(lcs12, vec!["flub", "bub", "boob", "dub"], "b");
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/hir/mod.rs.html b/target/doc/src/regex_syntax/hir/mod.rs.html new file mode 100644 index 0000000..54babcc --- /dev/null +++ b/target/doc/src/regex_syntax/hir/mod.rs.html @@ -0,0 +1,4387 @@ +mod.rs.html -- source
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+2035
+2036
+2037
+2038
+2039
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2047
+2048
+2049
+2050
+2051
+2052
+2053
+2054
+2055
+2056
+2057
+2058
+2059
+2060
+2061
+2062
+2063
+2064
+2065
+2066
+2067
+2068
+2069
+2070
+2071
+2072
+2073
+2074
+2075
+2076
+2077
+2078
+2079
+2080
+2081
+2082
+2083
+2084
+2085
+2086
+2087
+2088
+2089
+2090
+2091
+2092
+2093
+2094
+2095
+2096
+2097
+2098
+2099
+2100
+2101
+2102
+2103
+2104
+2105
+2106
+2107
+2108
+2109
+2110
+2111
+2112
+2113
+2114
+2115
+2116
+2117
+2118
+2119
+2120
+2121
+2122
+2123
+2124
+2125
+2126
+2127
+2128
+2129
+2130
+2131
+2132
+2133
+2134
+2135
+2136
+2137
+2138
+2139
+2140
+2141
+2142
+2143
+2144
+2145
+2146
+2147
+2148
+2149
+2150
+2151
+2152
+2153
+2154
+2155
+2156
+2157
+2158
+2159
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
+2178
+2179
+2180
+2181
+2182
+2183
+2184
+2185
+2186
+2187
+2188
+2189
+2190
+2191
+2192
+
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+Defines a high-level intermediate representation for regular expressions.
+*/
+use std::char;
+use std::cmp;
+use std::error;
+use std::fmt;
+use std::u8;
+
+use ast::Span;
+use hir::interval::{Interval, IntervalSet, IntervalSetIter};
+use unicode;
+
+pub use hir::visitor::{Visitor, visit};
+
+mod interval;
+pub mod literal;
+pub mod print;
+pub mod translate;
+mod visitor;
+
+/// An error that can occur while translating an `Ast` to a `Hir`.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Error {
+    /// The kind of error.
+    kind: ErrorKind,
+    /// The original pattern that the translator's Ast was parsed from. Every
+    /// span in an error is a valid range into this string.
+    pattern: String,
+    /// The span of this error, derived from the Ast given to the translator.
+    span: Span,
+}
+
+impl Error {
+    /// Return the type of this error.
+    pub fn kind(&self) -> &ErrorKind {
+        &self.kind
+    }
+
+    /// The original pattern string in which this error occurred.
+    ///
+    /// Every span reported by this error is reported in terms of this string.
+    pub fn pattern(&self) -> &str {
+        &self.pattern
+    }
+
+    /// Return the span at which this error occurred.
+    pub fn span(&self) -> &Span {
+        &self.span
+    }
+}
+
+/// The type of an error that occurred while building an `Hir`.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum ErrorKind {
+    /// This error occurs when a Unicode feature is used when Unicode
+    /// support is disabled. For example `(?-u:\pL)` would trigger this error.
+    UnicodeNotAllowed,
+    /// This error occurs when translating a pattern that could match a byte
+    /// sequence that isn't UTF-8 and `allow_invalid_utf8` was disabled.
+    InvalidUtf8,
+    /// This occurs when an unrecognized Unicode property name could not
+    /// be found.
+    UnicodePropertyNotFound,
+    /// This occurs when an unrecognized Unicode property value could not
+    /// be found.
+    UnicodePropertyValueNotFound,
+    /// This occurs when the translator attempts to construct a character class
+    /// that is empty.
+    ///
+    /// Note that this restriction in the translator may be removed in the
+    /// future.
+    EmptyClassNotAllowed,
+    /// Hints that destructuring should not be exhaustive.
+    ///
+    /// This enum may grow additional variants, so this makes sure clients
+    /// don't count on exhaustive matching. (Otherwise, adding a new variant
+    /// could break existing code.)
+    #[doc(hidden)]
+    __Nonexhaustive,
+}
+
+impl ErrorKind {
+    fn description(&self) -> &str {
+        use self::ErrorKind::*;
+        match *self {
+            UnicodeNotAllowed => "Unicode not allowed here",
+            InvalidUtf8 => "pattern can match invalid UTF-8",
+            UnicodePropertyNotFound => "Unicode property not found",
+            UnicodePropertyValueNotFound => "Unicode property value not found",
+            EmptyClassNotAllowed => "empty character classes are not allowed",
+            _ => unreachable!(),
+        }
+    }
+}
+
+impl error::Error for Error {
+    fn description(&self) -> &str {
+        self.kind.description()
+    }
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        ::error::Formatter::from(self).fmt(f)
+    }
+}
+
+impl fmt::Display for ErrorKind {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.write_str(self.description())
+    }
+}
+
+/// A high-level intermediate representation (HIR) for a regular expression.
+///
+/// The HIR of a regular expression represents an intermediate step between its
+/// abstract syntax (a structured description of the concrete syntax) and
+/// compiled byte codes. 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 "compile away" 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]`).
+///
+/// If the HIR was produced by a translator that disallows invalid UTF-8, then
+/// the HIR is guaranteed to match UTF-8 exclusively.
+///
+/// This type defines its own destructor that uses constant stack space and
+/// heap space proportional to the size of the HIR.
+///
+/// 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 "concatenations
+///    always consist of two or more sub-expressions."
+/// 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 text.
+///
+/// Also, an `Hir`'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`.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Hir {
+    /// The underlying HIR kind.
+    kind: HirKind,
+    /// Analysis info about this HIR, computed during construction.
+    info: HirInfo,
+}
+
+/// The kind of an arbitrary `Hir` expression.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum HirKind {
+    /// The empty regular expression, which matches everything, including the
+    /// empty string.
+    Empty,
+    /// A single literal character that matches exactly this character.
+    Literal(Literal),
+    /// 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.
+    Class(Class),
+    /// An anchor assertion. An anchor assertion match always has zero length.
+    Anchor(Anchor),
+    /// A word boundary assertion, which may or may not be Unicode aware. A
+    /// word boundary assertion match always has zero length.
+    WordBoundary(WordBoundary),
+    /// A repetition operation applied to a child expression.
+    Repetition(Repetition),
+    /// A possibly capturing group, which contains a child expression.
+    Group(Group),
+    /// A concatenation of expressions. A concatenation always has at least two
+    /// child expressions.
+    ///
+    /// A concatenation matches only if each of its child expression matches
+    /// one after the other.
+    Concat(Vec<Hir>),
+    /// An alternation of expressions. An alternation always has at least two
+    /// child expressions.
+    ///
+    /// An alternation matches only if at least one of its child expression
+    /// matches. If multiple expressions match, then the leftmost is preferred.
+    Alternation(Vec<Hir>),
+}
+
+impl Hir {
+    /// Returns a reference to the underlying HIR kind.
+    pub fn kind(&self) -> &HirKind {
+        &self.kind
+    }
+
+    /// Consumes ownership of this HIR expression and returns its underlying
+    /// `HirKind`.
+    pub fn into_kind(mut self) -> HirKind {
+        use std::mem;
+        mem::replace(&mut self.kind, HirKind::Empty)
+    }
+
+    /// Returns an empty HIR expression.
+    ///
+    /// An empty HIR expression always matches, including the empty string.
+    pub fn empty() -> Hir {
+        let mut info = HirInfo::new();
+        info.set_always_utf8(true);
+        info.set_all_assertions(true);
+        info.set_anchored_start(false);
+        info.set_anchored_end(false);
+        info.set_line_anchored_start(false);
+        info.set_line_anchored_end(false);
+        info.set_any_anchored_start(false);
+        info.set_any_anchored_end(false);
+        info.set_match_empty(true);
+        info.set_literal(true);
+        info.set_alternation_literal(true);
+        Hir {
+            kind: HirKind::Empty,
+            info: info,
+        }
+    }
+
+    /// Creates a literal HIR expression.
+    ///
+    /// If the given literal has a `Byte` variant with an ASCII byte, then this
+    /// method panics. This enforces the invariant that `Byte` variants are
+    /// only used to express matching of invalid UTF-8.
+    pub fn literal(lit: Literal) -> Hir {
+        if let Literal::Byte(b) = lit {
+            assert!(b > 0x7F);
+        }
+
+        let mut info = HirInfo::new();
+        info.set_always_utf8(lit.is_unicode());
+        info.set_all_assertions(false);
+        info.set_anchored_start(false);
+        info.set_anchored_end(false);
+        info.set_line_anchored_start(false);
+        info.set_line_anchored_end(false);
+        info.set_any_anchored_start(false);
+        info.set_any_anchored_end(false);
+        info.set_match_empty(false);
+        info.set_literal(true);
+        info.set_alternation_literal(true);
+        Hir {
+            kind: HirKind::Literal(lit),
+            info: info,
+        }
+    }
+
+    /// Creates a class HIR expression.
+    pub fn class(class: Class) -> Hir {
+        let mut info = HirInfo::new();
+        info.set_always_utf8(class.is_always_utf8());
+        info.set_all_assertions(false);
+        info.set_anchored_start(false);
+        info.set_anchored_end(false);
+        info.set_line_anchored_start(false);
+        info.set_line_anchored_end(false);
+        info.set_any_anchored_start(false);
+        info.set_any_anchored_end(false);
+        info.set_match_empty(false);
+        info.set_literal(false);
+        info.set_alternation_literal(false);
+        Hir {
+            kind: HirKind::Class(class),
+            info: info,
+        }
+    }
+
+    /// Creates an anchor assertion HIR expression.
+    pub fn anchor(anchor: Anchor) -> Hir {
+        let mut info = HirInfo::new();
+        info.set_always_utf8(true);
+        info.set_all_assertions(true);
+        info.set_anchored_start(false);
+        info.set_anchored_end(false);
+        info.set_line_anchored_start(false);
+        info.set_line_anchored_end(false);
+        info.set_any_anchored_start(false);
+        info.set_any_anchored_end(false);
+        info.set_match_empty(true);
+        info.set_literal(false);
+        info.set_alternation_literal(false);
+        if let Anchor::StartText = anchor {
+            info.set_anchored_start(true);
+            info.set_line_anchored_start(true);
+            info.set_any_anchored_start(true);
+        }
+        if let Anchor::EndText = anchor {
+            info.set_anchored_end(true);
+            info.set_line_anchored_end(true);
+            info.set_any_anchored_end(true);
+        }
+        if let Anchor::StartLine = anchor {
+            info.set_line_anchored_start(true);
+        }
+        if let Anchor::EndLine = anchor {
+            info.set_line_anchored_end(true);
+        }
+        Hir {
+            kind: HirKind::Anchor(anchor),
+            info: info,
+        }
+    }
+
+    /// Creates a word boundary assertion HIR expression.
+    pub fn word_boundary(word_boundary: WordBoundary) -> Hir {
+        let mut info = HirInfo::new();
+        info.set_always_utf8(true);
+        info.set_all_assertions(true);
+        info.set_anchored_start(false);
+        info.set_anchored_end(false);
+        info.set_line_anchored_start(false);
+        info.set_line_anchored_end(false);
+        info.set_any_anchored_start(false);
+        info.set_any_anchored_end(false);
+        info.set_literal(false);
+        info.set_alternation_literal(false);
+        // A negated word boundary matches the empty string, but a normal
+        // word boundary does not!
+        info.set_match_empty(word_boundary.is_negated());
+        // Negated ASCII word boundaries can match invalid UTF-8.
+        if let WordBoundary::AsciiNegate = word_boundary {
+            info.set_always_utf8(false);
+        }
+        Hir {
+            kind: HirKind::WordBoundary(word_boundary),
+            info: info,
+        }
+    }
+
+    /// Creates a repetition HIR expression.
+    pub fn repetition(rep: Repetition) -> Hir {
+        let mut info = HirInfo::new();
+        info.set_always_utf8(rep.hir.is_always_utf8());
+        info.set_all_assertions(rep.hir.is_all_assertions());
+        // If this operator can match the empty string, then it can never
+        // be anchored.
+        info.set_anchored_start(
+            !rep.is_match_empty() && rep.hir.is_anchored_start()
+        );
+        info.set_anchored_end(
+            !rep.is_match_empty() && rep.hir.is_anchored_end()
+        );
+        info.set_line_anchored_start(
+            !rep.is_match_empty() && rep.hir.is_anchored_start()
+        );
+        info.set_line_anchored_end(
+            !rep.is_match_empty() && rep.hir.is_anchored_end()
+        );
+        info.set_any_anchored_start(rep.hir.is_any_anchored_start());
+        info.set_any_anchored_end(rep.hir.is_any_anchored_end());
+        info.set_match_empty(rep.is_match_empty() || rep.hir.is_match_empty());
+        info.set_literal(false);
+        info.set_alternation_literal(false);
+        Hir {
+            kind: HirKind::Repetition(rep),
+            info: info,
+        }
+    }
+
+    /// Creates a group HIR expression.
+    pub fn group(group: Group) -> Hir {
+        let mut info = HirInfo::new();
+        info.set_always_utf8(group.hir.is_always_utf8());
+        info.set_all_assertions(group.hir.is_all_assertions());
+        info.set_anchored_start(group.hir.is_anchored_start());
+        info.set_anchored_end(group.hir.is_anchored_end());
+        info.set_line_anchored_start(group.hir.is_line_anchored_start());
+        info.set_line_anchored_end(group.hir.is_line_anchored_end());
+        info.set_any_anchored_start(group.hir.is_any_anchored_start());
+        info.set_any_anchored_end(group.hir.is_any_anchored_end());
+        info.set_match_empty(group.hir.is_match_empty());
+        info.set_literal(false);
+        info.set_alternation_literal(false);
+        Hir {
+            kind: HirKind::Group(group),
+            info: info,
+        }
+    }
+
+    /// Returns the concatenation of the given expressions.
+    ///
+    /// This flattens the concatenation as appropriate.
+    pub fn concat(mut exprs: Vec<Hir>) -> Hir {
+        match exprs.len() {
+            0 => Hir::empty(),
+            1 => { exprs.pop().unwrap() }
+            _ => {
+                let mut info = HirInfo::new();
+                info.set_always_utf8(true);
+                info.set_all_assertions(true);
+                info.set_any_anchored_start(false);
+                info.set_any_anchored_end(false);
+                info.set_match_empty(true);
+                info.set_literal(true);
+                info.set_alternation_literal(true);
+
+                // Some attributes require analyzing all sub-expressions.
+                for e in &exprs {
+                    let x = info.is_always_utf8() && e.is_always_utf8();
+                    info.set_always_utf8(x);
+
+                    let x = info.is_all_assertions() && e.is_all_assertions();
+                    info.set_all_assertions(x);
+
+                    let x =
+                        info.is_any_anchored_start()
+                        || e.is_any_anchored_start();
+                    info.set_any_anchored_start(x);
+
+                    let x =
+                        info.is_any_anchored_end()
+                        || e.is_any_anchored_end();
+                    info.set_any_anchored_end(x);
+
+                    let x = info.is_match_empty() && e.is_match_empty();
+                    info.set_match_empty(x);
+
+                    let x = info.is_literal() && e.is_literal();
+                    info.set_literal(x);
+
+                    let x =
+                        info.is_alternation_literal()
+                        && e.is_alternation_literal();
+                    info.set_alternation_literal(x);
+                }
+                // Anchored attributes require something slightly more
+                // sophisticated. Normally, WLOG, to determine whether an
+                // expression is anchored to the start, we'd only need to check
+                // the first expression of a concatenation. However,
+                // expressions like `$\b^` are still anchored to the start,
+                // but the first expression in the concatenation *isn't*
+                // anchored to the start. So the "first" expression to look at
+                // is actually one that is either not an assertion or is
+                // specifically the StartText assertion.
+                info.set_anchored_start(
+                    exprs.iter()
+                        .take_while(|e| {
+                            e.is_anchored_start() || e.is_all_assertions()
+                        })
+                        .any(|e| {
+                            e.is_anchored_start()
+                        }));
+                // Similarly for the end anchor, but in reverse.
+                info.set_anchored_end(
+                    exprs.iter()
+                        .rev()
+                        .take_while(|e| {
+                            e.is_anchored_end() || e.is_all_assertions()
+                        })
+                        .any(|e| {
+                            e.is_anchored_end()
+                        }));
+                // Repeat the process for line anchors.
+                info.set_line_anchored_start(
+                    exprs.iter()
+                        .take_while(|e| {
+                            e.is_line_anchored_start() || e.is_all_assertions()
+                        })
+                        .any(|e| {
+                            e.is_line_anchored_start()
+                        }));
+                info.set_line_anchored_end(
+                    exprs.iter()
+                        .rev()
+                        .take_while(|e| {
+                            e.is_line_anchored_end() || e.is_all_assertions()
+                        })
+                        .any(|e| {
+                            e.is_line_anchored_end()
+                        }));
+                Hir {
+                    kind: HirKind::Concat(exprs),
+                    info: info,
+                }
+            }
+        }
+    }
+
+    /// Returns the alternation of the given expressions.
+    ///
+    /// This flattens the alternation as appropriate.
+    pub fn alternation(mut exprs: Vec<Hir>) -> Hir {
+        match exprs.len() {
+            0 => Hir::empty(),
+            1 => exprs.pop().unwrap(),
+            _ => {
+                let mut info = HirInfo::new();
+                info.set_always_utf8(true);
+                info.set_all_assertions(true);
+                info.set_anchored_start(true);
+                info.set_anchored_end(true);
+                info.set_line_anchored_start(true);
+                info.set_line_anchored_end(true);
+                info.set_any_anchored_start(false);
+                info.set_any_anchored_end(false);
+                info.set_match_empty(false);
+                info.set_literal(false);
+                info.set_alternation_literal(true);
+
+                // Some attributes require analyzing all sub-expressions.
+                for e in &exprs {
+                    let x = info.is_always_utf8() && e.is_always_utf8();
+                    info.set_always_utf8(x);
+
+                    let x = info.is_all_assertions() && e.is_all_assertions();
+                    info.set_all_assertions(x);
+
+                    let x = info.is_anchored_start() && e.is_anchored_start();
+                    info.set_anchored_start(x);
+
+                    let x = info.is_anchored_end() && e.is_anchored_end();
+                    info.set_anchored_end(x);
+
+                    let x = info.is_line_anchored_start()
+                        && e.is_line_anchored_start();
+                    info.set_line_anchored_start(x);
+
+                    let x = info.is_line_anchored_end()
+                        && e.is_line_anchored_end();
+                    info.set_line_anchored_end(x);
+
+                    let x =
+                        info.is_any_anchored_start()
+                        || e.is_any_anchored_start();
+                    info.set_any_anchored_start(x);
+
+                    let x =
+                        info.is_any_anchored_end()
+                        || e.is_any_anchored_end();
+                    info.set_any_anchored_end(x);
+
+                    let x = info.is_match_empty() || e.is_match_empty();
+                    info.set_match_empty(x);
+
+                    let x =
+                        info.is_alternation_literal()
+                        && e.is_literal();
+                    info.set_alternation_literal(x);
+                }
+                Hir {
+                    kind: HirKind::Alternation(exprs),
+                    info: info,
+                }
+            }
+        }
+    }
+
+    /// Build an HIR expression for `.`.
+    ///
+    /// A `.` expression matches any character except for `\n`. To build an
+    /// expression that matches any character, including `\n`, use the `any`
+    /// method.
+    ///
+    /// If `bytes` is `true`, then this assumes characters are limited to a
+    /// single byte.
+    pub fn dot(bytes: bool) -> Hir {
+        if bytes {
+            let mut cls = ClassBytes::empty();
+            cls.push(ClassBytesRange::new(b'\0', b'\x09'));
+            cls.push(ClassBytesRange::new(b'\x0B', b'\xFF'));
+            Hir::class(Class::Bytes(cls))
+        } else {
+            let mut cls = ClassUnicode::empty();
+            cls.push(ClassUnicodeRange::new('\0', '\x09'));
+            cls.push(ClassUnicodeRange::new('\x0B', '\u{10FFFF}'));
+            Hir::class(Class::Unicode(cls))
+        }
+    }
+
+    /// Build an HIR expression for `(?s).`.
+    ///
+    /// A `(?s).` expression matches any character, including `\n`. To build an
+    /// expression that matches any character except for `\n`, then use the
+    /// `dot` method.
+    ///
+    /// If `bytes` is `true`, then this assumes characters are limited to a
+    /// single byte.
+    pub fn any(bytes: bool) -> Hir {
+        if bytes {
+            let mut cls = ClassBytes::empty();
+            cls.push(ClassBytesRange::new(b'\0', b'\xFF'));
+            Hir::class(Class::Bytes(cls))
+        } else {
+            let mut cls = ClassUnicode::empty();
+            cls.push(ClassUnicodeRange::new('\0', '\u{10FFFF}'));
+            Hir::class(Class::Unicode(cls))
+        }
+    }
+
+    /// Return true if and only if this HIR will always match valid UTF-8.
+    ///
+    /// When this returns false, then it is possible for this HIR expression
+    /// to match invalid UTF-8.
+    pub fn is_always_utf8(&self) -> bool {
+        self.info.is_always_utf8()
+    }
+
+    /// Returns true if and only if this entire HIR expression is made up of
+    /// zero-width assertions.
+    ///
+    /// This includes expressions like `^$\b\A\z` and even `((\b)+())*^`, but
+    /// not `^a`.
+    pub fn is_all_assertions(&self) -> bool {
+        self.info.is_all_assertions()
+    }
+
+    /// Return true if and only if this HIR is required to match from the
+    /// beginning of text. This includes expressions like `^foo`, `^(foo|bar)`,
+    /// `^foo|^bar` but not `^foo|bar`.
+    pub fn is_anchored_start(&self) -> bool {
+        self.info.is_anchored_start()
+    }
+
+    /// Return true if and only if this HIR is required to match at the end
+    /// of text. This includes expressions like `foo$`, `(foo|bar)$`,
+    /// `foo$|bar$` but not `foo$|bar`.
+    pub fn is_anchored_end(&self) -> bool {
+        self.info.is_anchored_end()
+    }
+
+    /// Return true if and only if this HIR is required to match from the
+    /// beginning of text or the beginning of a line. This includes expressions
+    /// like `^foo`, `(?m)^foo`, `^(foo|bar)`, `^(foo|bar)`, `(?m)^foo|^bar`
+    /// but not `^foo|bar` or `(?m)^foo|bar`.
+    ///
+    /// Note that if `is_anchored_start` is `true`, then
+    /// `is_line_anchored_start` will also be `true`. The reverse implication
+    /// is not true. For example, `(?m)^foo` is line anchored, but not
+    /// `is_anchored_start`.
+    pub fn is_line_anchored_start(&self) -> bool {
+        self.info.is_line_anchored_start()
+    }
+
+    /// Return true if and only if this HIR is required to match at the
+    /// end of text or the end of a line. This includes expressions like
+    /// `foo$`, `(?m)foo$`, `(foo|bar)$`, `(?m)(foo|bar)$`, `foo$|bar$`,
+    /// `(?m)(foo|bar)$`, but not `foo$|bar` or `(?m)foo$|bar`.
+    ///
+    /// Note that if `is_anchored_end` is `true`, then
+    /// `is_line_anchored_end` will also be `true`. The reverse implication
+    /// is not true. For example, `(?m)foo$` is line anchored, but not
+    /// `is_anchored_end`.
+    pub fn is_line_anchored_end(&self) -> bool {
+        self.info.is_line_anchored_end()
+    }
+
+    /// Return true if and only if this HIR contains any sub-expression that
+    /// is required to match at the beginning of text. Specifically, this
+    /// returns true if the `^` symbol (when multiline mode is disabled) or the
+    /// `\A` escape appear anywhere in the regex.
+    pub fn is_any_anchored_start(&self) -> bool {
+        self.info.is_any_anchored_start()
+    }
+
+    /// Return true if and only if this HIR contains any sub-expression that is
+    /// required to match at the end of text. Specifically, this returns true
+    /// if the `$` symbol (when multiline mode is disabled) or the `\z` escape
+    /// appear anywhere in the regex.
+    pub fn is_any_anchored_end(&self) -> bool {
+        self.info.is_any_anchored_end()
+    }
+
+    /// Return true if and only if the empty string is part of the language
+    /// matched by this regular expression.
+    ///
+    /// This includes `a*`, `a?b*`, `a{0}`, `()`, `()+`, `^$`, `a|b?`, `\B`,
+    /// but not `a`, `a+` or `\b`.
+    pub fn is_match_empty(&self) -> bool {
+        self.info.is_match_empty()
+    }
+
+    /// 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()`
+    /// are not (even though that contain sub-expressions that are literals).
+    pub fn is_literal(&self) -> bool {
+        self.info.is_literal()
+    }
+
+    /// 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 alternaiton
+    /// literals, but `f+`, `(foo)`, `foo()`
+    /// are not (even though that contain sub-expressions that are literals).
+    pub fn is_alternation_literal(&self) -> bool {
+        self.info.is_alternation_literal()
+    }
+}
+
+impl HirKind {
+    /// Return true if and only if this HIR is the empty regular expression.
+    ///
+    /// Note that this is not defined inductively. That is, it only tests if
+    /// this kind is the `Empty` variant. To get the inductive definition,
+    /// use the `is_match_empty` method on [`Hir`](struct.Hir.html).
+    pub fn is_empty(&self) -> bool {
+        match *self {
+            HirKind::Empty => true,
+            _ => false,
+        }
+    }
+
+    /// Returns true if and only if this kind has any (including possibly
+    /// empty) subexpressions.
+    pub fn has_subexprs(&self) -> bool {
+        match *self {
+            HirKind::Empty
+            | HirKind::Literal(_)
+            | HirKind::Class(_)
+            | HirKind::Anchor(_)
+            | HirKind::WordBoundary(_) => false,
+            HirKind::Group(_)
+            | HirKind::Repetition(_)
+            | HirKind::Concat(_)
+            | HirKind::Alternation(_) => true,
+        }
+    }
+}
+
+/// 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`.
+impl fmt::Display for Hir {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        use hir::print::Printer;
+        Printer::new().print(self, f)
+    }
+}
+
+/// The high-level intermediate representation of a literal.
+///
+/// A literal corresponds to a single character, where a character is either
+/// defined by a Unicode scalar value or an arbitrary byte. Unicode characters
+/// are preferred whenever possible. In particular, a `Byte` variant is only
+/// ever produced when it could match invalid UTF-8.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum Literal {
+    /// A single character represented by a Unicode scalar value.
+    Unicode(char),
+    /// A single character represented by an arbitrary byte.
+    Byte(u8),
+}
+
+impl Literal {
+    /// Returns true if and only if this literal corresponds to a Unicode
+    /// scalar value.
+    pub fn is_unicode(&self) -> bool {
+        match *self {
+            Literal::Unicode(_) => true,
+            Literal::Byte(b) if b <= 0x7F => true,
+            Literal::Byte(_) => false,
+        }
+    }
+}
+
+/// 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 unlike [`Literal`](enum.Literal.html), a `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.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum Class {
+    /// A set of characters represented by Unicode scalar values.
+    Unicode(ClassUnicode),
+    /// A set of characters represented by arbitrary bytes (one byte per
+    /// character).
+    Bytes(ClassBytes),
+}
+
+impl Class {
+    /// 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`.
+    pub fn case_fold_simple(&mut self) {
+        match *self {
+            Class::Unicode(ref mut x) => x.case_fold_simple(),
+            Class::Bytes(ref mut x) => x.case_fold_simple(),
+        }
+    }
+
+    /// Negate this character class in place.
+    ///
+    /// After completion, this character class will contain precisely the
+    /// characters that weren't previously in the class.
+    pub fn negate(&mut self) {
+        match *self {
+            Class::Unicode(ref mut x) => x.negate(),
+            Class::Bytes(ref mut x) => x.negate(),
+        }
+    }
+
+    /// 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.
+    pub fn is_always_utf8(&self) -> bool {
+        match *self {
+            Class::Unicode(_) => true,
+            Class::Bytes(ref x) => x.is_all_ascii(),
+        }
+    }
+}
+
+/// A set of characters represented by Unicode scalar values.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct ClassUnicode {
+    set: IntervalSet<ClassUnicodeRange>,
+}
+
+impl ClassUnicode {
+    /// 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.
+    pub fn new<I>(ranges: I) -> ClassUnicode
+    where I: IntoIterator<Item=ClassUnicodeRange>
+    {
+        ClassUnicode { set: IntervalSet::new(ranges) }
+    }
+
+    /// Create a new class with no ranges.
+    pub fn empty() -> ClassUnicode {
+        ClassUnicode::new(vec![])
+    }
+
+    /// Add a new range to this set.
+    pub fn push(&mut self, range: ClassUnicodeRange) {
+        self.set.push(range);
+    }
+
+    /// Return an iterator over all ranges in this class.
+    ///
+    /// The iterator yields ranges in ascending order.
+    pub fn iter(&self) -> ClassUnicodeIter {
+        ClassUnicodeIter(self.set.iter())
+    }
+
+    /// Return the underlying ranges as a slice.
+    pub fn ranges(&self) -> &[ClassUnicodeRange] {
+        self.set.intervals()
+    }
+
+    /// Expand this character class such that it contains all case folded
+    /// characters, according to Unicode's "simple" 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`.
+    pub fn case_fold_simple(&mut self) {
+        self.set.case_fold_simple();
+    }
+
+    /// 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.
+    pub fn negate(&mut self) {
+        self.set.negate();
+    }
+
+    /// Union this character class with the given character class, in place.
+    pub fn union(&mut self, other: &ClassUnicode) {
+        self.set.union(&other.set);
+    }
+
+    /// Intersect this character class with the given character class, in
+    /// place.
+    pub fn intersect(&mut self, other: &ClassUnicode) {
+        self.set.intersect(&other.set);
+    }
+
+    /// Subtract the given character class from this character class, in place.
+    pub fn difference(&mut self, other: &ClassUnicode) {
+        self.set.difference(&other.set);
+    }
+
+    /// 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'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.
+    pub fn symmetric_difference(&mut self, other: &ClassUnicode) {
+        self.set.symmetric_difference(&other.set);
+    }
+}
+
+/// An iterator over all ranges in a Unicode character class.
+///
+/// The lifetime `'a` refers to the lifetime of the underlying class.
+#[derive(Debug)]
+pub struct ClassUnicodeIter<'a>(IntervalSetIter<'a, ClassUnicodeRange>);
+
+impl<'a> Iterator for ClassUnicodeIter<'a> {
+    type Item = &'a ClassUnicodeRange;
+
+    fn next(&mut self) -> Option<&'a ClassUnicodeRange> {
+        self.0.next()
+    }
+}
+
+/// 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.
+#[derive(Clone, Copy, Default, Eq, PartialEq, PartialOrd, Ord)]
+pub struct ClassUnicodeRange {
+    start: char,
+    end: char,
+}
+
+impl fmt::Debug for ClassUnicodeRange {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let start =
+            if !self.start.is_whitespace() && !self.start.is_control() {
+                self.start.to_string()
+            } else {
+                format!("0x{:X}", self.start as u32)
+            };
+        let end =
+            if !self.end.is_whitespace() && !self.end.is_control() {
+                self.end.to_string()
+            } else {
+                format!("0x{:X}", self.end as u32)
+            };
+        f.debug_struct("ClassUnicodeRange")
+         .field("start", &start)
+         .field("end", &end)
+         .finish()
+    }
+}
+
+impl Interval for ClassUnicodeRange {
+    type Bound = char;
+
+    #[inline] fn lower(&self) -> char { self.start }
+    #[inline] fn upper(&self) -> char { self.end }
+    #[inline] fn set_lower(&mut self, bound: char) { self.start = bound; }
+    #[inline] fn set_upper(&mut self, bound: char) { self.end = bound; }
+
+    /// 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.
+    fn case_fold_simple(&self, ranges: &mut Vec<ClassUnicodeRange>) {
+        if !unicode::contains_simple_case_mapping(self.start, self.end) {
+            return;
+        }
+        let start = self.start as u32;
+        let end = (self.end as u32).saturating_add(1);
+        let mut next_simple_cp = None;
+        for cp in (start..end).filter_map(char::from_u32) {
+            if next_simple_cp.map_or(false, |next| cp < next) {
+                continue;
+            }
+            let it = match unicode::simple_fold(cp) {
+                Ok(it) => it,
+                Err(next) => {
+                    next_simple_cp = next;
+                    continue;
+                }
+            };
+            for cp_folded in it {
+                ranges.push(ClassUnicodeRange::new(cp_folded, cp_folded));
+            }
+        }
+    }
+}
+
+impl ClassUnicodeRange {
+    /// 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 <= end`.
+    pub fn new(start: char, end: char) -> ClassUnicodeRange {
+        ClassUnicodeRange::create(start, end)
+    }
+
+    /// Return the start of this range.
+    ///
+    /// The start of a range is always less than or equal to the end of the
+    /// range.
+    pub fn start(&self) -> char {
+        self.start
+    }
+
+    /// Return the end of this range.
+    ///
+    /// The end of a range is always greater than or equal to the start of the
+    /// range.
+    pub fn end(&self) -> char {
+        self.end
+    }
+}
+
+/// A set of characters represented by arbitrary bytes (where one byte
+/// corresponds to one character).
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct ClassBytes {
+    set: IntervalSet<ClassBytesRange>,
+}
+
+impl ClassBytes {
+    /// 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.
+    pub fn new<I>(ranges: I) -> ClassBytes
+    where I: IntoIterator<Item=ClassBytesRange>
+    {
+        ClassBytes { set: IntervalSet::new(ranges) }
+    }
+
+    /// Create a new class with no ranges.
+    pub fn empty() -> ClassBytes {
+        ClassBytes::new(vec![])
+    }
+
+    /// Add a new range to this set.
+    pub fn push(&mut self, range: ClassBytesRange) {
+        self.set.push(range);
+    }
+
+    /// Return an iterator over all ranges in this class.
+    ///
+    /// The iterator yields ranges in ascending order.
+    pub fn iter(&self) -> ClassBytesIter {
+        ClassBytesIter(self.set.iter())
+    }
+
+    /// Return the underlying ranges as a slice.
+    pub fn ranges(&self) -> &[ClassBytesRange] {
+        self.set.intervals()
+    }
+
+    /// 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`.
+    pub fn case_fold_simple(&mut self) {
+        self.set.case_fold_simple();
+    }
+
+    /// 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.
+    pub fn negate(&mut self) {
+        self.set.negate();
+    }
+
+    /// Union this byte class with the given byte class, in place.
+    pub fn union(&mut self, other: &ClassBytes) {
+        self.set.union(&other.set);
+    }
+
+    /// Intersect this byte class with the given byte class, in place.
+    pub fn intersect(&mut self, other: &ClassBytes) {
+        self.set.intersect(&other.set);
+    }
+
+    /// Subtract the given byte class from this byte class, in place.
+    pub fn difference(&mut self, other: &ClassBytes) {
+        self.set.difference(&other.set);
+    }
+
+    /// 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'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.
+    pub fn symmetric_difference(&mut self, other: &ClassBytes) {
+        self.set.symmetric_difference(&other.set);
+    }
+
+    /// 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.
+    pub fn is_all_ascii(&self) -> bool {
+        self.set.intervals().last().map_or(true, |r| r.end <= 0x7F)
+    }
+}
+
+/// An iterator over all ranges in a byte character class.
+///
+/// The lifetime `'a` refers to the lifetime of the underlying class.
+#[derive(Debug)]
+pub struct ClassBytesIter<'a>(IntervalSetIter<'a, ClassBytesRange>);
+
+impl<'a> Iterator for ClassBytesIter<'a> {
+    type Item = &'a ClassBytesRange;
+
+    fn next(&mut self) -> Option<&'a ClassBytesRange> {
+        self.0.next()
+    }
+}
+
+/// 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.
+#[derive(Clone, Copy, Default, Eq, PartialEq, PartialOrd, Ord)]
+pub struct ClassBytesRange {
+    start: u8,
+    end: u8,
+}
+
+impl Interval for ClassBytesRange {
+    type Bound = u8;
+
+    #[inline] fn lower(&self) -> u8 { self.start }
+    #[inline] fn upper(&self) -> u8 { self.end }
+    #[inline] fn set_lower(&mut self, bound: u8) { self.start = bound; }
+    #[inline] fn set_upper(&mut self, bound: u8) { self.end = bound; }
+
+    /// 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.
+    fn case_fold_simple(&self, ranges: &mut Vec<ClassBytesRange>) {
+        if !ClassBytesRange::new(b'a', b'z').is_intersection_empty(self) {
+            let lower = cmp::max(self.start, b'a');
+            let upper = cmp::min(self.end, b'z');
+            ranges.push(ClassBytesRange::new(lower - 32, upper - 32));
+        }
+        if !ClassBytesRange::new(b'A', b'Z').is_intersection_empty(self) {
+            let lower = cmp::max(self.start, b'A');
+            let upper = cmp::min(self.end, b'Z');
+            ranges.push(ClassBytesRange::new(lower + 32, upper + 32));
+        }
+    }
+}
+
+impl ClassBytesRange {
+    /// 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 <= end`.
+    pub fn new(start: u8, end: u8) -> ClassBytesRange {
+        ClassBytesRange::create(start, end)
+    }
+
+    /// Return the start of this range.
+    ///
+    /// The start of a range is always less than or equal to the end of the
+    /// range.
+    pub fn start(&self) -> u8 {
+        self.start
+    }
+
+    /// Return the end of this range.
+    ///
+    /// The end of a range is always greater than or equal to the start of the
+    /// range.
+    pub fn end(&self) -> u8 {
+        self.end
+    }
+}
+
+impl fmt::Debug for ClassBytesRange {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let mut debug = f.debug_struct("ClassBytesRange");
+        if self.start <= 0x7F {
+            debug.field("start", &(self.start as char));
+        } else {
+            debug.field("start", &self.start);
+        }
+        if self.end <= 0x7F {
+            debug.field("end", &(self.end as char));
+        } else {
+            debug.field("end", &self.end);
+        }
+        debug.finish()
+    }
+}
+
+/// The high-level intermediate representation for an anchor assertion.
+///
+/// A matching anchor assertion is always zero-length.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum Anchor {
+    /// 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.
+    StartLine,
+    /// 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.
+    EndLine,
+    /// Match the beginning of text. Specifically, this matches at the starting
+    /// position of the input.
+    StartText,
+    /// Match the end of text. Specifically, this matches at the ending
+    /// position of the input.
+    EndText,
+}
+
+/// The high-level intermediate representation for a word-boundary assertion.
+///
+/// A matching word boundary assertion is always zero-length.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum WordBoundary {
+    /// 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.
+    Unicode,
+    /// Match a Unicode-aware negation of a word boundary.
+    UnicodeNegate,
+    /// 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.
+    Ascii,
+    /// Match an ASCII-only negation of a word boundary.
+    AsciiNegate,
+}
+
+impl WordBoundary {
+    /// Returns true if and only if this word boundary assertion is negated.
+    pub fn is_negated(&self) -> bool {
+        match *self {
+            WordBoundary::Unicode |  WordBoundary::Ascii => false,
+            WordBoundary::UnicodeNegate |  WordBoundary::AsciiNegate => true,
+        }
+    }
+}
+
+/// The high-level intermediate representation for a group.
+///
+/// This represents one of three possible group types:
+///
+/// 1. A non-capturing group (e.g., `(?:expr)`).
+/// 2. A capturing group (e.g., `(expr)`).
+/// 3. A named capturing group (e.g., `(?P<name>expr)`).
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Group {
+    /// The kind of this group. If it is a capturing group, then the kind
+    /// contains the capture group index (and the name, if it is a named
+    /// group).
+    pub kind: GroupKind,
+    /// The expression inside the capturing group, which may be empty.
+    pub hir: Box<Hir>,
+}
+
+/// The kind of group.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum GroupKind {
+    /// A normal unnamed capturing group.
+    ///
+    /// The value is the capture index of the group.
+    CaptureIndex(u32),
+    /// A named capturing group.
+    CaptureName {
+        /// The name of the group.
+        name: String,
+        /// The capture index of the group.
+        index: u32,
+    },
+    /// A non-capturing group.
+    NonCapturing,
+}
+
+/// The high-level intermediate representation of a repetition operator.
+///
+/// A repetition operator permits the repetition of an arbitrary
+/// sub-expression.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Repetition {
+    /// The kind of this repetition operator.
+    pub kind: RepetitionKind,
+    /// 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` "ungreedy" flag.
+    pub greedy: bool,
+    /// The expression being repeated.
+    pub hir: Box<Hir>,
+}
+
+impl Repetition {
+    /// Returns true if and only if this repetition operator makes it possible
+    /// to match the empty string.
+    ///
+    /// Note that this is not defined inductively. For example, while `a*`
+    /// will report `true`, `()+` will not, even though `()` matches the empty
+    /// string and one or more occurrences of something that matches the empty
+    /// string will always match the empty string. In order to get the
+    /// inductive definition, see the corresponding method on
+    /// [`Hir`](struct.Hir.html).
+    pub fn is_match_empty(&self) -> bool {
+        match self.kind {
+            RepetitionKind::ZeroOrOne => true,
+            RepetitionKind::ZeroOrMore => true,
+            RepetitionKind::OneOrMore => false,
+            RepetitionKind::Range(RepetitionRange::Exactly(m)) => m == 0,
+            RepetitionKind::Range(RepetitionRange::AtLeast(m)) => m == 0,
+            RepetitionKind::Range(RepetitionRange::Bounded(m, _)) => m == 0,
+        }
+    }
+}
+
+/// The kind of a repetition operator.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum RepetitionKind {
+    /// Matches a sub-expression zero or one times.
+    ZeroOrOne,
+    /// Matches a sub-expression zero or more times.
+    ZeroOrMore,
+    /// Matches a sub-expression one or more times.
+    OneOrMore,
+    /// Matches a sub-expression within a bounded range of times.
+    Range(RepetitionRange),
+}
+
+/// The kind of a counted repetition operator.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum RepetitionRange {
+    /// Matches a sub-expression exactly this many times.
+    Exactly(u32),
+    /// Matches a sub-expression at least this many times.
+    AtLeast(u32),
+    /// Matches a sub-expression at least `m` times and at most `n` times.
+    Bounded(u32, u32),
+}
+
+/// 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`.
+impl Drop for Hir {
+    fn drop(&mut self) {
+        use std::mem;
+
+        match *self.kind() {
+            HirKind::Empty
+            | HirKind::Literal(_)
+            | HirKind::Class(_)
+            | HirKind::Anchor(_)
+            | HirKind::WordBoundary(_) => return,
+            HirKind::Group(ref x) if !x.hir.kind.has_subexprs() => return,
+            HirKind::Repetition(ref x) if !x.hir.kind.has_subexprs() => return,
+            HirKind::Concat(ref x) if x.is_empty() => return,
+            HirKind::Alternation(ref x) if x.is_empty() => return,
+            _ => {}
+        }
+
+        let mut stack = vec![mem::replace(self, Hir::empty())];
+        while let Some(mut expr) = stack.pop() {
+            match expr.kind {
+                HirKind::Empty
+                | HirKind::Literal(_)
+                | HirKind::Class(_)
+                | HirKind::Anchor(_)
+                | HirKind::WordBoundary(_) => {}
+                HirKind::Group(ref mut x) => {
+                    stack.push(mem::replace(&mut x.hir, Hir::empty()));
+                }
+                HirKind::Repetition(ref mut x) => {
+                    stack.push(mem::replace(&mut x.hir, Hir::empty()));
+                }
+                HirKind::Concat(ref mut x) => {
+                    stack.extend(x.drain(..));
+                }
+                HirKind::Alternation(ref mut x) => {
+                    stack.extend(x.drain(..));
+                }
+            }
+        }
+    }
+}
+
+/// A type that documents various attributes of an HIR expression.
+///
+/// These attributes are typically defined inductively on the HIR.
+#[derive(Clone, Debug, Eq, PartialEq)]
+struct HirInfo {
+    /// Represent yes/no questions by a bitfield to conserve space, since
+    /// this is included in every HIR expression.
+    ///
+    /// If more attributes need to be added, it is OK to increase the size of
+    /// this as appropriate.
+    bools: u16,
+}
+
+// A simple macro for defining bitfield accessors/mutators.
+macro_rules! define_bool {
+    ($bit:expr, $is_fn_name:ident, $set_fn_name:ident) => {
+        fn $is_fn_name(&self) -> bool {
+            self.bools & (0b1 << $bit) > 0
+        }
+
+        fn $set_fn_name(&mut self, yes: bool) {
+            if yes {
+                self.bools |= 1 << $bit;
+            } else {
+                self.bools &= !(1 << $bit);
+            }
+        }
+    }
+}
+
+impl HirInfo {
+    fn new() -> HirInfo {
+        HirInfo {
+            bools: 0,
+        }
+    }
+
+    define_bool!(0, is_always_utf8, set_always_utf8);
+    define_bool!(1, is_all_assertions, set_all_assertions);
+    define_bool!(2, is_anchored_start, set_anchored_start);
+    define_bool!(3, is_anchored_end, set_anchored_end);
+    define_bool!(4, is_line_anchored_start, set_line_anchored_start);
+    define_bool!(5, is_line_anchored_end, set_line_anchored_end);
+    define_bool!(6, is_any_anchored_start, set_any_anchored_start);
+    define_bool!(7, is_any_anchored_end, set_any_anchored_end);
+    define_bool!(8, is_match_empty, set_match_empty);
+    define_bool!(9, is_literal, set_literal);
+    define_bool!(10, is_alternation_literal, set_alternation_literal);
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    fn uclass(ranges: &[(char, char)]) -> ClassUnicode {
+        let ranges: Vec<ClassUnicodeRange> = ranges
+            .iter()
+            .map(|&(s, e)| ClassUnicodeRange::new(s, e))
+            .collect();
+        ClassUnicode::new(ranges)
+    }
+
+    fn bclass(ranges: &[(u8, u8)]) -> ClassBytes {
+        let ranges: Vec<ClassBytesRange> = ranges
+            .iter()
+            .map(|&(s, e)| ClassBytesRange::new(s, e))
+            .collect();
+        ClassBytes::new(ranges)
+    }
+
+    fn uranges(cls: &ClassUnicode) -> Vec<(char, char)> {
+        cls.iter().map(|x| (x.start(), x.end())).collect()
+    }
+
+    fn ucasefold(cls: &ClassUnicode) -> ClassUnicode {
+        let mut cls_ = cls.clone();
+        cls_.case_fold_simple();
+        cls_
+    }
+
+    fn uunion(cls1: &ClassUnicode, cls2: &ClassUnicode) -> ClassUnicode {
+        let mut cls_ = cls1.clone();
+        cls_.union(cls2);
+        cls_
+    }
+
+    fn uintersect(cls1: &ClassUnicode, cls2: &ClassUnicode) -> ClassUnicode {
+        let mut cls_ = cls1.clone();
+        cls_.intersect(cls2);
+        cls_
+    }
+
+    fn udifference(cls1: &ClassUnicode, cls2: &ClassUnicode) -> ClassUnicode {
+        let mut cls_ = cls1.clone();
+        cls_.difference(cls2);
+        cls_
+    }
+
+    fn usymdifference(cls1: &ClassUnicode, cls2: &ClassUnicode) -> ClassUnicode {
+        let mut cls_ = cls1.clone();
+        cls_.symmetric_difference(cls2);
+        cls_
+    }
+
+    fn unegate(cls: &ClassUnicode) -> ClassUnicode {
+        let mut cls_ = cls.clone();
+        cls_.negate();
+        cls_
+    }
+
+    fn branges(cls: &ClassBytes) -> Vec<(u8, u8)> {
+        cls.iter().map(|x| (x.start(), x.end())).collect()
+    }
+
+    fn bcasefold(cls: &ClassBytes) -> ClassBytes {
+        let mut cls_ = cls.clone();
+        cls_.case_fold_simple();
+        cls_
+    }
+
+    fn bunion(cls1: &ClassBytes, cls2: &ClassBytes) -> ClassBytes {
+        let mut cls_ = cls1.clone();
+        cls_.union(cls2);
+        cls_
+    }
+
+    fn bintersect(cls1: &ClassBytes, cls2: &ClassBytes) -> ClassBytes {
+        let mut cls_ = cls1.clone();
+        cls_.intersect(cls2);
+        cls_
+    }
+
+    fn bdifference(cls1: &ClassBytes, cls2: &ClassBytes) -> ClassBytes {
+        let mut cls_ = cls1.clone();
+        cls_.difference(cls2);
+        cls_
+    }
+
+    fn bsymdifference(cls1: &ClassBytes, cls2: &ClassBytes) -> ClassBytes {
+        let mut cls_ = cls1.clone();
+        cls_.symmetric_difference(cls2);
+        cls_
+    }
+
+    fn bnegate(cls: &ClassBytes) -> ClassBytes {
+        let mut cls_ = cls.clone();
+        cls_.negate();
+        cls_
+    }
+
+    #[test]
+    fn class_range_canonical_unicode() {
+        let range = ClassUnicodeRange::new('\u{00FF}', '\0');
+        assert_eq!('\0', range.start());
+        assert_eq!('\u{00FF}', range.end());
+    }
+
+    #[test]
+    fn class_range_canonical_bytes() {
+        let range = ClassBytesRange::new(b'\xFF', b'\0');
+        assert_eq!(b'\0', range.start());
+        assert_eq!(b'\xFF', range.end());
+    }
+
+    #[test]
+    fn class_canonicalize_unicode() {
+        let cls = uclass(&[('a', 'c'), ('x', 'z')]);
+        let expected = vec![('a', 'c'), ('x', 'z')];
+        assert_eq!(expected, uranges(&cls));
+
+        let cls = uclass(&[('x', 'z'), ('a', 'c')]);
+        let expected = vec![('a', 'c'), ('x', 'z')];
+        assert_eq!(expected, uranges(&cls));
+
+        let cls = uclass(&[('x', 'z'), ('w', 'y')]);
+        let expected = vec![('w', 'z')];
+        assert_eq!(expected, uranges(&cls));
+
+        let cls = uclass(&[
+            ('c', 'f'), ('a', 'g'), ('d', 'j'), ('a', 'c'),
+            ('m', 'p'), ('l', 's'),
+        ]);
+        let expected = vec![('a', 'j'), ('l', 's')];
+        assert_eq!(expected, uranges(&cls));
+
+        let cls = uclass(&[('x', 'z'), ('u', 'w')]);
+        let expected = vec![('u', 'z')];
+        assert_eq!(expected, uranges(&cls));
+
+        let cls = uclass(&[('\x00', '\u{10FFFF}'), ('\x00', '\u{10FFFF}')]);
+        let expected = vec![('\x00', '\u{10FFFF}')];
+        assert_eq!(expected, uranges(&cls));
+
+
+        let cls = uclass(&[('a', 'a'), ('b', 'b')]);
+        let expected = vec![('a', 'b')];
+        assert_eq!(expected, uranges(&cls));
+    }
+
+    #[test]
+    fn class_canonicalize_bytes() {
+        let cls = bclass(&[(b'a', b'c'), (b'x', b'z')]);
+        let expected = vec![(b'a', b'c'), (b'x', b'z')];
+        assert_eq!(expected, branges(&cls));
+
+        let cls = bclass(&[(b'x', b'z'), (b'a', b'c')]);
+        let expected = vec![(b'a', b'c'), (b'x', b'z')];
+        assert_eq!(expected, branges(&cls));
+
+        let cls = bclass(&[(b'x', b'z'), (b'w', b'y')]);
+        let expected = vec![(b'w', b'z')];
+        assert_eq!(expected, branges(&cls));
+
+        let cls = bclass(&[
+            (b'c', b'f'), (b'a', b'g'), (b'd', b'j'), (b'a', b'c'),
+            (b'm', b'p'), (b'l', b's'),
+        ]);
+        let expected = vec![(b'a', b'j'), (b'l', b's')];
+        assert_eq!(expected, branges(&cls));
+
+        let cls = bclass(&[(b'x', b'z'), (b'u', b'w')]);
+        let expected = vec![(b'u', b'z')];
+        assert_eq!(expected, branges(&cls));
+
+        let cls = bclass(&[(b'\x00', b'\xFF'), (b'\x00', b'\xFF')]);
+        let expected = vec![(b'\x00', b'\xFF')];
+        assert_eq!(expected, branges(&cls));
+
+        let cls = bclass(&[(b'a', b'a'), (b'b', b'b')]);
+        let expected = vec![(b'a', b'b')];
+        assert_eq!(expected, branges(&cls));
+    }
+
+    #[test]
+    fn class_case_fold_unicode() {
+        let cls = uclass(&[
+            ('C', 'F'), ('A', 'G'), ('D', 'J'), ('A', 'C'),
+            ('M', 'P'), ('L', 'S'), ('c', 'f'),
+        ]);
+        let expected = uclass(&[
+            ('A', 'J'), ('L', 'S'),
+            ('a', 'j'), ('l', 's'),
+            ('\u{17F}', '\u{17F}'),
+        ]);
+        assert_eq!(expected, ucasefold(&cls));
+
+        let cls = uclass(&[('A', 'Z')]);
+        let expected = uclass(&[
+            ('A', 'Z'), ('a', 'z'),
+            ('\u{17F}', '\u{17F}'),
+            ('\u{212A}', '\u{212A}'),
+        ]);
+        assert_eq!(expected, ucasefold(&cls));
+
+        let cls = uclass(&[('a', 'z')]);
+        let expected = uclass(&[
+            ('A', 'Z'), ('a', 'z'),
+            ('\u{17F}', '\u{17F}'),
+            ('\u{212A}', '\u{212A}'),
+        ]);
+        assert_eq!(expected, ucasefold(&cls));
+
+        let cls = uclass(&[('A', 'A'), ('_', '_')]);
+        let expected = uclass(&[('A', 'A'), ('_', '_'), ('a', 'a')]);
+        assert_eq!(expected, ucasefold(&cls));
+
+        let cls = uclass(&[('A', 'A'), ('=', '=')]);
+        let expected = uclass(&[('=', '='), ('A', 'A'), ('a', 'a')]);
+        assert_eq!(expected, ucasefold(&cls));
+
+        let cls = uclass(&[('\x00', '\x10')]);
+        assert_eq!(cls, ucasefold(&cls));
+
+        let cls = uclass(&[('k', 'k')]);
+        let expected = uclass(&[
+            ('K', 'K'), ('k', 'k'), ('\u{212A}', '\u{212A}'),
+        ]);
+        assert_eq!(expected, ucasefold(&cls));
+
+        let cls = uclass(&[('@', '@')]);
+        assert_eq!(cls, ucasefold(&cls));
+    }
+
+    #[test]
+    fn class_case_fold_bytes() {
+        let cls = bclass(&[
+            (b'C', b'F'), (b'A', b'G'), (b'D', b'J'), (b'A', b'C'),
+            (b'M', b'P'), (b'L', b'S'), (b'c', b'f'),
+        ]);
+        let expected = bclass(&[
+            (b'A', b'J'), (b'L', b'S'),
+            (b'a', b'j'), (b'l', b's'),
+        ]);
+        assert_eq!(expected, bcasefold(&cls));
+
+        let cls = bclass(&[(b'A', b'Z')]);
+        let expected = bclass(&[(b'A', b'Z'), (b'a', b'z')]);
+        assert_eq!(expected, bcasefold(&cls));
+
+        let cls = bclass(&[(b'a', b'z')]);
+        let expected = bclass(&[(b'A', b'Z'), (b'a', b'z')]);
+        assert_eq!(expected, bcasefold(&cls));
+
+        let cls = bclass(&[(b'A', b'A'), (b'_', b'_')]);
+        let expected = bclass(&[(b'A', b'A'), (b'_', b'_'), (b'a', b'a')]);
+        assert_eq!(expected, bcasefold(&cls));
+
+        let cls = bclass(&[(b'A', b'A'), (b'=', b'=')]);
+        let expected = bclass(&[(b'=', b'='), (b'A', b'A'), (b'a', b'a')]);
+        assert_eq!(expected, bcasefold(&cls));
+
+        let cls = bclass(&[(b'\x00', b'\x10')]);
+        assert_eq!(cls, bcasefold(&cls));
+
+        let cls = bclass(&[(b'k', b'k')]);
+        let expected = bclass(&[(b'K', b'K'), (b'k', b'k')]);
+        assert_eq!(expected, bcasefold(&cls));
+
+        let cls = bclass(&[(b'@', b'@')]);
+        assert_eq!(cls, bcasefold(&cls));
+    }
+
+    #[test]
+    fn class_negate_unicode() {
+        let cls = uclass(&[('a', 'a')]);
+        let expected = uclass(&[('\x00', '\x60'), ('\x62', '\u{10FFFF}')]);
+        assert_eq!(expected, unegate(&cls));
+
+        let cls = uclass(&[('a', 'a'), ('b', 'b')]);
+        let expected = uclass(&[('\x00', '\x60'), ('\x63', '\u{10FFFF}')]);
+        assert_eq!(expected, unegate(&cls));
+
+        let cls = uclass(&[('a', 'c'), ('x', 'z')]);
+        let expected = uclass(&[
+            ('\x00', '\x60'), ('\x64', '\x77'), ('\x7B', '\u{10FFFF}'),
+        ]);
+        assert_eq!(expected, unegate(&cls));
+
+        let cls = uclass(&[('\x00', 'a')]);
+        let expected = uclass(&[('\x62', '\u{10FFFF}')]);
+        assert_eq!(expected, unegate(&cls));
+
+        let cls = uclass(&[('a', '\u{10FFFF}')]);
+        let expected = uclass(&[('\x00', '\x60')]);
+        assert_eq!(expected, unegate(&cls));
+
+        let cls = uclass(&[('\x00', '\u{10FFFF}')]);
+        let expected = uclass(&[]);
+        assert_eq!(expected, unegate(&cls));
+
+        let cls = uclass(&[]);
+        let expected = uclass(&[('\x00', '\u{10FFFF}')]);
+        assert_eq!(expected, unegate(&cls));
+
+        let cls = uclass(&[
+            ('\x00', '\u{10FFFD}'), ('\u{10FFFF}', '\u{10FFFF}'),
+        ]);
+        let expected = uclass(&[('\u{10FFFE}', '\u{10FFFE}')]);
+        assert_eq!(expected, unegate(&cls));
+
+        let cls = uclass(&[('\x00', '\u{D7FF}')]);
+        let expected = uclass(&[('\u{E000}', '\u{10FFFF}')]);
+        assert_eq!(expected, unegate(&cls));
+
+        let cls = uclass(&[('\x00', '\u{D7FE}')]);
+        let expected = uclass(&[('\u{D7FF}', '\u{10FFFF}')]);
+        assert_eq!(expected, unegate(&cls));
+
+        let cls = uclass(&[('\u{E000}', '\u{10FFFF}')]);
+        let expected = uclass(&[('\x00', '\u{D7FF}')]);
+        assert_eq!(expected, unegate(&cls));
+
+        let cls = uclass(&[('\u{E001}', '\u{10FFFF}')]);
+        let expected = uclass(&[('\x00', '\u{E000}')]);
+        assert_eq!(expected, unegate(&cls));
+    }
+
+    #[test]
+    fn class_negate_bytes() {
+        let cls = bclass(&[(b'a', b'a')]);
+        let expected = bclass(&[(b'\x00', b'\x60'), (b'\x62', b'\xFF')]);
+        assert_eq!(expected, bnegate(&cls));
+
+        let cls = bclass(&[(b'a', b'a'), (b'b', b'b')]);
+        let expected = bclass(&[(b'\x00', b'\x60'), (b'\x63', b'\xFF')]);
+        assert_eq!(expected, bnegate(&cls));
+
+        let cls = bclass(&[(b'a', b'c'), (b'x', b'z')]);
+        let expected = bclass(&[
+            (b'\x00', b'\x60'), (b'\x64', b'\x77'), (b'\x7B', b'\xFF'),
+        ]);
+        assert_eq!(expected, bnegate(&cls));
+
+        let cls = bclass(&[(b'\x00', b'a')]);
+        let expected = bclass(&[(b'\x62', b'\xFF')]);
+        assert_eq!(expected, bnegate(&cls));
+
+        let cls = bclass(&[(b'a', b'\xFF')]);
+        let expected = bclass(&[(b'\x00', b'\x60')]);
+        assert_eq!(expected, bnegate(&cls));
+
+        let cls = bclass(&[(b'\x00', b'\xFF')]);
+        let expected = bclass(&[]);
+        assert_eq!(expected, bnegate(&cls));
+
+        let cls = bclass(&[]);
+        let expected = bclass(&[(b'\x00', b'\xFF')]);
+        assert_eq!(expected, bnegate(&cls));
+
+        let cls = bclass(&[(b'\x00', b'\xFD'), (b'\xFF', b'\xFF')]);
+        let expected = bclass(&[(b'\xFE', b'\xFE')]);
+        assert_eq!(expected, bnegate(&cls));
+    }
+
+    #[test]
+    fn class_union_unicode() {
+        let cls1 = uclass(&[('a', 'g'), ('m', 't'), ('A', 'C')]);
+        let cls2 = uclass(&[('a', 'z')]);
+        let expected = uclass(&[('a', 'z'), ('A', 'C')]);
+        assert_eq!(expected, uunion(&cls1, &cls2));
+    }
+
+    #[test]
+    fn class_union_bytes() {
+        let cls1 = bclass(&[(b'a', b'g'), (b'm', b't'), (b'A', b'C')]);
+        let cls2 = bclass(&[(b'a', b'z')]);
+        let expected = bclass(&[(b'a', b'z'), (b'A', b'C')]);
+        assert_eq!(expected, bunion(&cls1, &cls2));
+    }
+
+    #[test]
+    fn class_intersect_unicode() {
+        let cls1 = uclass(&[]);
+        let cls2 = uclass(&[('a', 'a')]);
+        let expected = uclass(&[]);
+        assert_eq!(expected, uintersect(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'a')]);
+        let cls2 = uclass(&[('a', 'a')]);
+        let expected = uclass(&[('a', 'a')]);
+        assert_eq!(expected, uintersect(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'a')]);
+        let cls2 = uclass(&[('b', 'b')]);
+        let expected = uclass(&[]);
+        assert_eq!(expected, uintersect(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'a')]);
+        let cls2 = uclass(&[('a', 'c')]);
+        let expected = uclass(&[('a', 'a')]);
+        assert_eq!(expected, uintersect(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'b')]);
+        let cls2 = uclass(&[('a', 'c')]);
+        let expected = uclass(&[('a', 'b')]);
+        assert_eq!(expected, uintersect(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'b')]);
+        let cls2 = uclass(&[('b', 'c')]);
+        let expected = uclass(&[('b', 'b')]);
+        assert_eq!(expected, uintersect(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'b')]);
+        let cls2 = uclass(&[('c', 'd')]);
+        let expected = uclass(&[]);
+        assert_eq!(expected, uintersect(&cls1, &cls2));
+
+        let cls1 = uclass(&[('b', 'c')]);
+        let cls2 = uclass(&[('a', 'd')]);
+        let expected = uclass(&[('b', 'c')]);
+        assert_eq!(expected, uintersect(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'b'), ('d', 'e'), ('g', 'h')]);
+        let cls2 = uclass(&[('a', 'h')]);
+        let expected = uclass(&[('a', 'b'), ('d', 'e'), ('g', 'h')]);
+        assert_eq!(expected, uintersect(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'b'), ('d', 'e'), ('g', 'h')]);
+        let cls2 = uclass(&[('a', 'b'), ('d', 'e'), ('g', 'h')]);
+        let expected = uclass(&[('a', 'b'), ('d', 'e'), ('g', 'h')]);
+        assert_eq!(expected, uintersect(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'b'), ('g', 'h')]);
+        let cls2 = uclass(&[('d', 'e'), ('k', 'l')]);
+        let expected = uclass(&[]);
+        assert_eq!(expected, uintersect(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'b'), ('d', 'e'), ('g', 'h')]);
+        let cls2 = uclass(&[('h', 'h')]);
+        let expected = uclass(&[('h', 'h')]);
+        assert_eq!(expected, uintersect(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'b'), ('e', 'f'), ('i', 'j')]);
+        let cls2 = uclass(&[('c', 'd'), ('g', 'h'), ('k', 'l')]);
+        let expected = uclass(&[]);
+        assert_eq!(expected, uintersect(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'b'), ('c', 'd'), ('e', 'f')]);
+        let cls2 = uclass(&[('b', 'c'), ('d', 'e'), ('f', 'g')]);
+        let expected = uclass(&[('b', 'f')]);
+        assert_eq!(expected, uintersect(&cls1, &cls2));
+    }
+
+    #[test]
+    fn class_intersect_bytes() {
+        let cls1 = bclass(&[]);
+        let cls2 = bclass(&[(b'a', b'a')]);
+        let expected = bclass(&[]);
+        assert_eq!(expected, bintersect(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'a')]);
+        let cls2 = bclass(&[(b'a', b'a')]);
+        let expected = bclass(&[(b'a', b'a')]);
+        assert_eq!(expected, bintersect(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'a')]);
+        let cls2 = bclass(&[(b'b', b'b')]);
+        let expected = bclass(&[]);
+        assert_eq!(expected, bintersect(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'a')]);
+        let cls2 = bclass(&[(b'a', b'c')]);
+        let expected = bclass(&[(b'a', b'a')]);
+        assert_eq!(expected, bintersect(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'b')]);
+        let cls2 = bclass(&[(b'a', b'c')]);
+        let expected = bclass(&[(b'a', b'b')]);
+        assert_eq!(expected, bintersect(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'b')]);
+        let cls2 = bclass(&[(b'b', b'c')]);
+        let expected = bclass(&[(b'b', b'b')]);
+        assert_eq!(expected, bintersect(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'b')]);
+        let cls2 = bclass(&[(b'c', b'd')]);
+        let expected = bclass(&[]);
+        assert_eq!(expected, bintersect(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'b', b'c')]);
+        let cls2 = bclass(&[(b'a', b'd')]);
+        let expected = bclass(&[(b'b', b'c')]);
+        assert_eq!(expected, bintersect(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'b'), (b'd', b'e'), (b'g', b'h')]);
+        let cls2 = bclass(&[(b'a', b'h')]);
+        let expected = bclass(&[(b'a', b'b'), (b'd', b'e'), (b'g', b'h')]);
+        assert_eq!(expected, bintersect(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'b'), (b'd', b'e'), (b'g', b'h')]);
+        let cls2 = bclass(&[(b'a', b'b'), (b'd', b'e'), (b'g', b'h')]);
+        let expected = bclass(&[(b'a', b'b'), (b'd', b'e'), (b'g', b'h')]);
+        assert_eq!(expected, bintersect(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'b'), (b'g', b'h')]);
+        let cls2 = bclass(&[(b'd', b'e'), (b'k', b'l')]);
+        let expected = bclass(&[]);
+        assert_eq!(expected, bintersect(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'b'), (b'd', b'e'), (b'g', b'h')]);
+        let cls2 = bclass(&[(b'h', b'h')]);
+        let expected = bclass(&[(b'h', b'h')]);
+        assert_eq!(expected, bintersect(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'b'), (b'e', b'f'), (b'i', b'j')]);
+        let cls2 = bclass(&[(b'c', b'd'), (b'g', b'h'), (b'k', b'l')]);
+        let expected = bclass(&[]);
+        assert_eq!(expected, bintersect(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'b'), (b'c', b'd'), (b'e', b'f')]);
+        let cls2 = bclass(&[(b'b', b'c'), (b'd', b'e'), (b'f', b'g')]);
+        let expected = bclass(&[(b'b', b'f')]);
+        assert_eq!(expected, bintersect(&cls1, &cls2));
+    }
+
+    #[test]
+    fn class_difference_unicode() {
+        let cls1 = uclass(&[('a', 'a')]);
+        let cls2 = uclass(&[('a', 'a')]);
+        let expected = uclass(&[]);
+        assert_eq!(expected, udifference(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'a')]);
+        let cls2 = uclass(&[]);
+        let expected = uclass(&[('a', 'a')]);
+        assert_eq!(expected, udifference(&cls1, &cls2));
+
+        let cls1 = uclass(&[]);
+        let cls2 = uclass(&[('a', 'a')]);
+        let expected = uclass(&[]);
+        assert_eq!(expected, udifference(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'z')]);
+        let cls2 = uclass(&[('a', 'a')]);
+        let expected = uclass(&[('b', 'z')]);
+        assert_eq!(expected, udifference(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'z')]);
+        let cls2 = uclass(&[('z', 'z')]);
+        let expected = uclass(&[('a', 'y')]);
+        assert_eq!(expected, udifference(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'z')]);
+        let cls2 = uclass(&[('m', 'm')]);
+        let expected = uclass(&[('a', 'l'), ('n', 'z')]);
+        assert_eq!(expected, udifference(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'c'), ('g', 'i'), ('r', 't')]);
+        let cls2 = uclass(&[('a', 'z')]);
+        let expected = uclass(&[]);
+        assert_eq!(expected, udifference(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'c'), ('g', 'i'), ('r', 't')]);
+        let cls2 = uclass(&[('d', 'v')]);
+        let expected = uclass(&[('a', 'c')]);
+        assert_eq!(expected, udifference(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'c'), ('g', 'i'), ('r', 't')]);
+        let cls2 = uclass(&[('b', 'g'), ('s', 'u')]);
+        let expected = uclass(&[('a', 'a'), ('h', 'i'), ('r', 'r')]);
+        assert_eq!(expected, udifference(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'c'), ('g', 'i'), ('r', 't')]);
+        let cls2 = uclass(&[('b', 'd'), ('e', 'g'), ('s', 'u')]);
+        let expected = uclass(&[('a', 'a'), ('h', 'i'), ('r', 'r')]);
+        assert_eq!(expected, udifference(&cls1, &cls2));
+
+        let cls1 = uclass(&[('x', 'z')]);
+        let cls2 = uclass(&[('a', 'c'), ('e', 'g'), ('s', 'u')]);
+        let expected = uclass(&[('x', 'z')]);
+        assert_eq!(expected, udifference(&cls1, &cls2));
+
+        let cls1 = uclass(&[('a', 'z')]);
+        let cls2 = uclass(&[('a', 'c'), ('e', 'g'), ('s', 'u')]);
+        let expected = uclass(&[('d', 'd'), ('h', 'r'), ('v', 'z')]);
+        assert_eq!(expected, udifference(&cls1, &cls2));
+    }
+
+    #[test]
+    fn class_difference_bytes() {
+        let cls1 = bclass(&[(b'a', b'a')]);
+        let cls2 = bclass(&[(b'a', b'a')]);
+        let expected = bclass(&[]);
+        assert_eq!(expected, bdifference(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'a')]);
+        let cls2 = bclass(&[]);
+        let expected = bclass(&[(b'a', b'a')]);
+        assert_eq!(expected, bdifference(&cls1, &cls2));
+
+        let cls1 = bclass(&[]);
+        let cls2 = bclass(&[(b'a', b'a')]);
+        let expected = bclass(&[]);
+        assert_eq!(expected, bdifference(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'z')]);
+        let cls2 = bclass(&[(b'a', b'a')]);
+        let expected = bclass(&[(b'b', b'z')]);
+        assert_eq!(expected, bdifference(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'z')]);
+        let cls2 = bclass(&[(b'z', b'z')]);
+        let expected = bclass(&[(b'a', b'y')]);
+        assert_eq!(expected, bdifference(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'z')]);
+        let cls2 = bclass(&[(b'm', b'm')]);
+        let expected = bclass(&[(b'a', b'l'), (b'n', b'z')]);
+        assert_eq!(expected, bdifference(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'c'), (b'g', b'i'), (b'r', b't')]);
+        let cls2 = bclass(&[(b'a', b'z')]);
+        let expected = bclass(&[]);
+        assert_eq!(expected, bdifference(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'c'), (b'g', b'i'), (b'r', b't')]);
+        let cls2 = bclass(&[(b'd', b'v')]);
+        let expected = bclass(&[(b'a', b'c')]);
+        assert_eq!(expected, bdifference(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'c'), (b'g', b'i'), (b'r', b't')]);
+        let cls2 = bclass(&[(b'b', b'g'), (b's', b'u')]);
+        let expected = bclass(&[(b'a', b'a'), (b'h', b'i'), (b'r', b'r')]);
+        assert_eq!(expected, bdifference(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'c'), (b'g', b'i'), (b'r', b't')]);
+        let cls2 = bclass(&[(b'b', b'd'), (b'e', b'g'), (b's', b'u')]);
+        let expected = bclass(&[(b'a', b'a'), (b'h', b'i'), (b'r', b'r')]);
+        assert_eq!(expected, bdifference(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'x', b'z')]);
+        let cls2 = bclass(&[(b'a', b'c'), (b'e', b'g'), (b's', b'u')]);
+        let expected = bclass(&[(b'x', b'z')]);
+        assert_eq!(expected, bdifference(&cls1, &cls2));
+
+        let cls1 = bclass(&[(b'a', b'z')]);
+        let cls2 = bclass(&[(b'a', b'c'), (b'e', b'g'), (b's', b'u')]);
+        let expected = bclass(&[(b'd', b'd'), (b'h', b'r'), (b'v', b'z')]);
+        assert_eq!(expected, bdifference(&cls1, &cls2));
+    }
+
+    #[test]
+    fn class_symmetric_difference_unicode() {
+        let cls1 = uclass(&[('a', 'm')]);
+        let cls2 = uclass(&[('g', 't')]);
+        let expected = uclass(&[('a', 'f'), ('n', 't')]);
+        assert_eq!(expected, usymdifference(&cls1, &cls2));
+    }
+
+    #[test]
+    fn class_symmetric_difference_bytes() {
+        let cls1 = bclass(&[(b'a', b'm')]);
+        let cls2 = bclass(&[(b'g', b't')]);
+        let expected = bclass(&[(b'a', b'f'), (b'n', b't')]);
+        assert_eq!(expected, bsymdifference(&cls1, &cls2));
+    }
+
+    #[test]
+    #[should_panic]
+    fn hir_byte_literal_non_ascii() {
+        Hir::literal(Literal::Byte(b'a'));
+    }
+
+    // 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.
+    #[test]
+    #[cfg(any(unix, windows))]
+    fn no_stack_overflow_on_drop() {
+        use std::thread;
+
+        let run = || {
+            let mut expr = Hir::empty();
+            for _ in 0..100 {
+                expr = Hir::group(Group {
+                    kind: GroupKind::NonCapturing,
+                    hir: Box::new(expr),
+                });
+                expr = Hir::repetition(Repetition {
+                    kind: RepetitionKind::ZeroOrOne,
+                    greedy: true,
+                    hir: Box::new(expr),
+                });
+
+                expr = Hir {
+                    kind: HirKind::Concat(vec![expr]),
+                    info: HirInfo::new(),
+                };
+                expr = Hir {
+                    kind: HirKind::Alternation(vec![expr]),
+                    info: HirInfo::new(),
+                };
+            }
+            assert!(!expr.kind.is_empty());
+        };
+
+        // We run our test on a thread with a small stack size so we can
+        // force the issue more easily.
+        thread::Builder::new()
+            .stack_size(1<<10)
+            .spawn(run)
+            .unwrap()
+            .join()
+            .unwrap();
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/hir/print.rs.html b/target/doc/src/regex_syntax/hir/print.rs.html new file mode 100644 index 0000000..dac8cf6 --- /dev/null +++ b/target/doc/src/regex_syntax/hir/print.rs.html @@ -0,0 +1,753 @@ +print.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+
+/*!
+This module provides a regular expression printer for `Hir`.
+*/
+
+use std::fmt;
+
+use hir::{self, Hir, HirKind};
+use hir::visitor::{self, Visitor};
+use is_meta_character;
+
+/// A builder for constructing a printer.
+///
+/// Note that since a printer doesn't have any configuration knobs, this type
+/// remains unexported.
+#[derive(Clone, Debug)]
+struct PrinterBuilder {
+    _priv: (),
+}
+
+impl Default for PrinterBuilder {
+    fn default() -> PrinterBuilder {
+        PrinterBuilder::new()
+    }
+}
+
+impl PrinterBuilder {
+    fn new() -> PrinterBuilder {
+        PrinterBuilder {
+            _priv: (),
+        }
+    }
+
+    fn build(&self) -> Printer {
+        Printer {
+            _priv: (),
+        }
+    }
+}
+
+/// A printer for a regular expression's high-level intermediate
+/// representation.
+///
+/// A printer converts a high-level intermediate representation (HIR) to a
+/// regular expression pattern string. This particular printer uses constant
+/// stack space and heap space proportional to the size of the HIR.
+///
+/// Since this printer is only using the HIR, the pattern it prints will likely
+/// not resemble the original pattern at all. For example, a pattern like
+/// `\pL` will have its entire class written out.
+///
+/// The purpose of this printer is to provide a means to mutate an HIR and then
+/// build a regular expression from the result of that mutation. (A regex
+/// library could provide a constructor from this HIR explicitly, but that
+/// creates an unnecessary public coupling between the regex library and this
+/// specific HIR representation.)
+#[derive(Debug)]
+pub struct Printer {
+    _priv: (),
+}
+
+impl Printer {
+    /// Create a new printer.
+    pub fn new() -> Printer {
+        PrinterBuilder::new().build()
+    }
+
+    /// Print the given `Ast` to the given writer. The writer must implement
+    /// `fmt::Write`. Typical implementations of `fmt::Write` that can be used
+    /// here are a `fmt::Formatter` (which is available in `fmt::Display`
+    /// implementations) or a `&mut String`.
+    pub fn print<W: fmt::Write>(&mut self, hir: &Hir, wtr: W) -> fmt::Result {
+        visitor::visit(hir, Writer { printer: self, wtr: wtr })
+    }
+}
+
+#[derive(Debug)]
+struct Writer<'p, W> {
+    printer: &'p mut Printer,
+    wtr: W,
+}
+
+impl<'p, W: fmt::Write> Visitor for Writer<'p, W> {
+    type Output = ();
+    type Err = fmt::Error;
+
+    fn finish(self) -> fmt::Result {
+        Ok(())
+    }
+
+    fn visit_pre(&mut self, hir: &Hir) -> fmt::Result {
+        match *hir.kind() {
+            HirKind::Empty
+            | HirKind::Repetition(_)
+            | HirKind::Concat(_)
+            | HirKind::Alternation(_) => {}
+            HirKind::Literal(hir::Literal::Unicode(c)) => {
+                self.write_literal_char(c)?;
+            }
+            HirKind::Literal(hir::Literal::Byte(b)) => {
+                self.write_literal_byte(b)?;
+            }
+            HirKind::Class(hir::Class::Unicode(ref cls)) => {
+                self.wtr.write_str("[")?;
+                for range in cls.iter() {
+                    if range.start() == range.end() {
+                        self.write_literal_char(range.start())?;
+                    } else {
+                        self.write_literal_char(range.start())?;
+                        self.wtr.write_str("-")?;
+                        self.write_literal_char(range.end())?;
+                    }
+                }
+                self.wtr.write_str("]")?;
+            }
+            HirKind::Class(hir::Class::Bytes(ref cls)) => {
+                self.wtr.write_str("(?-u:[")?;
+                for range in cls.iter() {
+                    if range.start() == range.end() {
+                        self.write_literal_class_byte(range.start())?;
+                    } else {
+                        self.write_literal_class_byte(range.start())?;
+                        self.wtr.write_str("-")?;
+                        self.write_literal_class_byte(range.end())?;
+                    }
+                }
+                self.wtr.write_str("])")?;
+            }
+            HirKind::Anchor(hir::Anchor::StartLine) => {
+                self.wtr.write_str("(?m:^)")?;
+            }
+            HirKind::Anchor(hir::Anchor::EndLine) => {
+                self.wtr.write_str("(?m:$)")?;
+            }
+            HirKind::Anchor(hir::Anchor::StartText) => {
+                self.wtr.write_str(r"\A")?;
+            }
+            HirKind::Anchor(hir::Anchor::EndText) => {
+                self.wtr.write_str(r"\z")?;
+            }
+            HirKind::WordBoundary(hir::WordBoundary::Unicode) => {
+                self.wtr.write_str(r"\b")?;
+            }
+            HirKind::WordBoundary(hir::WordBoundary::UnicodeNegate) => {
+                self.wtr.write_str(r"\B")?;
+            }
+            HirKind::WordBoundary(hir::WordBoundary::Ascii) => {
+                self.wtr.write_str(r"(?-u:\b)")?;
+            }
+            HirKind::WordBoundary(hir::WordBoundary::AsciiNegate) => {
+                self.wtr.write_str(r"(?-u:\B)")?;
+            }
+            HirKind::Group(ref x) => {
+                match x.kind {
+                    hir::GroupKind::CaptureIndex(_) => {
+                        self.wtr.write_str("(")?;
+                    }
+                    hir::GroupKind::CaptureName { ref name, .. } => {
+                        write!(self.wtr, "(?P<{}>", name)?;
+                    }
+                    hir::GroupKind::NonCapturing => {
+                        self.wtr.write_str("(?:")?;
+                    }
+                }
+            }
+        }
+        Ok(())
+    }
+
+    fn visit_post(&mut self, hir: &Hir) -> fmt::Result {
+        match *hir.kind() {
+            // Handled during visit_pre
+            HirKind::Empty
+            | HirKind::Literal(_)
+            | HirKind::Class(_)
+            | HirKind::Anchor(_)
+            | HirKind::WordBoundary(_)
+            | HirKind::Concat(_)
+            | HirKind::Alternation(_) => {}
+            HirKind::Repetition(ref x) => {
+                match x.kind {
+                    hir::RepetitionKind::ZeroOrOne => {
+                        self.wtr.write_str("?")?;
+                    }
+                    hir::RepetitionKind::ZeroOrMore => {
+                        self.wtr.write_str("*")?;
+                    }
+                    hir::RepetitionKind::OneOrMore => {
+                        self.wtr.write_str("+")?;
+                    }
+                    hir::RepetitionKind::Range(ref x) => {
+                        match *x {
+                            hir::RepetitionRange::Exactly(m) => {
+                                write!(self.wtr, "{{{}}}", m)?;
+                            }
+                            hir::RepetitionRange::AtLeast(m) => {
+                                write!(self.wtr, "{{{},}}", m)?;
+                            }
+                            hir::RepetitionRange::Bounded(m, n) => {
+                                write!(self.wtr, "{{{},{}}}", m, n)?;
+                            }
+                        }
+                    }
+                }
+                if !x.greedy {
+                    self.wtr.write_str("?")?;
+                }
+            }
+            HirKind::Group(_) => {
+                self.wtr.write_str(")")?;
+            }
+        }
+        Ok(())
+    }
+
+    fn visit_alternation_in(&mut self) -> fmt::Result {
+        self.wtr.write_str("|")
+    }
+}
+
+impl<'p, W: fmt::Write> Writer<'p, W> {
+    fn write_literal_char(&mut self, c: char) -> fmt::Result {
+        if is_meta_character(c) {
+            self.wtr.write_str("\\")?;
+        }
+        self.wtr.write_char(c)
+    }
+
+    fn write_literal_byte(&mut self, b: u8) -> fmt::Result {
+        let c = b as char;
+        if c <= 0x7F as char && !c.is_control() && !c.is_whitespace() {
+            self.write_literal_char(c)
+        } else {
+            write!(self.wtr, "(?-u:\\x{:02X})", b)
+        }
+    }
+
+    fn write_literal_class_byte(&mut self, b: u8) -> fmt::Result {
+        let c = b as char;
+        if c <= 0x7F as char && !c.is_control() && !c.is_whitespace() {
+            self.write_literal_char(c)
+        } else {
+            write!(self.wtr, "\\x{:02X}", b)
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use ParserBuilder;
+    use super::Printer;
+
+    fn roundtrip(given: &str, expected: &str) {
+        roundtrip_with(|b| b, given, expected);
+    }
+
+    fn roundtrip_bytes(given: &str, expected: &str) {
+        roundtrip_with(|b| b.allow_invalid_utf8(true), given, expected);
+    }
+
+    fn roundtrip_with<F>(mut f: F, given: &str, expected: &str)
+    where F: FnMut(&mut ParserBuilder) -> &mut ParserBuilder
+    {
+        let mut builder = ParserBuilder::new();
+        f(&mut builder);
+        let hir = builder.build().parse(given).unwrap();
+
+        let mut printer = Printer::new();
+        let mut dst = String::new();
+        printer.print(&hir, &mut dst).unwrap();
+
+        // Check that the result is actually valid.
+        builder.build().parse(&dst).unwrap();
+
+        assert_eq!(expected, dst);
+    }
+
+    #[test]
+    fn print_literal() {
+        roundtrip("a", "a");
+        roundtrip(r"\xff", "\u{FF}");
+        roundtrip_bytes(r"\xff", "\u{FF}");
+        roundtrip_bytes(r"(?-u)\xff", r"(?-u:\xFF)");
+        roundtrip("☃", "☃");
+    }
+
+    #[test]
+    fn print_class() {
+        roundtrip(r"[a]", r"[a]");
+        roundtrip(r"[a-z]", r"[a-z]");
+        roundtrip(r"[a-z--b-c--x-y]", r"[ad-wz]");
+        roundtrip(r"[^\x01-\u{10FFFF}]", "[\u{0}]");
+        roundtrip(r"[-]", r"[\-]");
+        roundtrip(r"[☃-⛄]", r"[☃-⛄]");
+
+        roundtrip(r"(?-u)[a]", r"(?-u:[a])");
+        roundtrip(r"(?-u)[a-z]", r"(?-u:[a-z])");
+        roundtrip_bytes(r"(?-u)[a-\xFF]", r"(?-u:[a-\xFF])");
+
+        // The following test that the printer escapes meta characters
+        // in character classes.
+        roundtrip(r"[\[]", r"[\[]");
+        roundtrip(r"[Z-_]", r"[Z-_]");
+        roundtrip(r"[Z-_--Z]", r"[\[-_]");
+
+        // The following test that the printer escapes meta characters
+        // in byte oriented character classes.
+        roundtrip_bytes(r"(?-u)[\[]", r"(?-u:[\[])");
+        roundtrip_bytes(r"(?-u)[Z-_]", r"(?-u:[Z-_])");
+        roundtrip_bytes(r"(?-u)[Z-_--Z]", r"(?-u:[\[-_])");
+    }
+
+    #[test]
+    fn print_anchor() {
+        roundtrip(r"^", r"\A");
+        roundtrip(r"$", r"\z");
+        roundtrip(r"(?m)^", r"(?m:^)");
+        roundtrip(r"(?m)$", r"(?m:$)");
+    }
+
+    #[test]
+    fn print_word_boundary() {
+        roundtrip(r"\b", r"\b");
+        roundtrip(r"\B", r"\B");
+        roundtrip(r"(?-u)\b", r"(?-u:\b)");
+        roundtrip_bytes(r"(?-u)\B", r"(?-u:\B)");
+    }
+
+    #[test]
+    fn print_repetition() {
+        roundtrip("a?", "a?");
+        roundtrip("a??", "a??");
+        roundtrip("(?U)a?", "a??");
+
+        roundtrip("a*", "a*");
+        roundtrip("a*?", "a*?");
+        roundtrip("(?U)a*", "a*?");
+
+        roundtrip("a+", "a+");
+        roundtrip("a+?", "a+?");
+        roundtrip("(?U)a+", "a+?");
+
+        roundtrip("a{1}", "a{1}");
+        roundtrip("a{1,}", "a{1,}");
+        roundtrip("a{1,5}", "a{1,5}");
+        roundtrip("a{1}?", "a{1}?");
+        roundtrip("a{1,}?", "a{1,}?");
+        roundtrip("a{1,5}?", "a{1,5}?");
+        roundtrip("(?U)a{1}", "a{1}?");
+        roundtrip("(?U)a{1,}", "a{1,}?");
+        roundtrip("(?U)a{1,5}", "a{1,5}?");
+    }
+
+    #[test]
+    fn print_group() {
+        roundtrip("()", "()");
+        roundtrip("(?P<foo>)", "(?P<foo>)");
+        roundtrip("(?:)", "(?:)");
+
+        roundtrip("(a)", "(a)");
+        roundtrip("(?P<foo>a)", "(?P<foo>a)");
+        roundtrip("(?:a)", "(?:a)");
+
+        roundtrip("((((a))))", "((((a))))");
+    }
+
+    #[test]
+    fn print_alternation() {
+        roundtrip("|", "|");
+        roundtrip("||", "||");
+
+        roundtrip("a|b", "a|b");
+        roundtrip("a|b|c", "a|b|c");
+        roundtrip("foo|bar|quux", "foo|bar|quux");
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/hir/translate.rs.html b/target/doc/src/regex_syntax/hir/translate.rs.html new file mode 100644 index 0000000..a0916aa --- /dev/null +++ b/target/doc/src/regex_syntax/hir/translate.rs.html @@ -0,0 +1,5295 @@ +translate.rs.html -- source
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+2035
+2036
+2037
+2038
+2039
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2047
+2048
+2049
+2050
+2051
+2052
+2053
+2054
+2055
+2056
+2057
+2058
+2059
+2060
+2061
+2062
+2063
+2064
+2065
+2066
+2067
+2068
+2069
+2070
+2071
+2072
+2073
+2074
+2075
+2076
+2077
+2078
+2079
+2080
+2081
+2082
+2083
+2084
+2085
+2086
+2087
+2088
+2089
+2090
+2091
+2092
+2093
+2094
+2095
+2096
+2097
+2098
+2099
+2100
+2101
+2102
+2103
+2104
+2105
+2106
+2107
+2108
+2109
+2110
+2111
+2112
+2113
+2114
+2115
+2116
+2117
+2118
+2119
+2120
+2121
+2122
+2123
+2124
+2125
+2126
+2127
+2128
+2129
+2130
+2131
+2132
+2133
+2134
+2135
+2136
+2137
+2138
+2139
+2140
+2141
+2142
+2143
+2144
+2145
+2146
+2147
+2148
+2149
+2150
+2151
+2152
+2153
+2154
+2155
+2156
+2157
+2158
+2159
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
+2178
+2179
+2180
+2181
+2182
+2183
+2184
+2185
+2186
+2187
+2188
+2189
+2190
+2191
+2192
+2193
+2194
+2195
+2196
+2197
+2198
+2199
+2200
+2201
+2202
+2203
+2204
+2205
+2206
+2207
+2208
+2209
+2210
+2211
+2212
+2213
+2214
+2215
+2216
+2217
+2218
+2219
+2220
+2221
+2222
+2223
+2224
+2225
+2226
+2227
+2228
+2229
+2230
+2231
+2232
+2233
+2234
+2235
+2236
+2237
+2238
+2239
+2240
+2241
+2242
+2243
+2244
+2245
+2246
+2247
+2248
+2249
+2250
+2251
+2252
+2253
+2254
+2255
+2256
+2257
+2258
+2259
+2260
+2261
+2262
+2263
+2264
+2265
+2266
+2267
+2268
+2269
+2270
+2271
+2272
+2273
+2274
+2275
+2276
+2277
+2278
+2279
+2280
+2281
+2282
+2283
+2284
+2285
+2286
+2287
+2288
+2289
+2290
+2291
+2292
+2293
+2294
+2295
+2296
+2297
+2298
+2299
+2300
+2301
+2302
+2303
+2304
+2305
+2306
+2307
+2308
+2309
+2310
+2311
+2312
+2313
+2314
+2315
+2316
+2317
+2318
+2319
+2320
+2321
+2322
+2323
+2324
+2325
+2326
+2327
+2328
+2329
+2330
+2331
+2332
+2333
+2334
+2335
+2336
+2337
+2338
+2339
+2340
+2341
+2342
+2343
+2344
+2345
+2346
+2347
+2348
+2349
+2350
+2351
+2352
+2353
+2354
+2355
+2356
+2357
+2358
+2359
+2360
+2361
+2362
+2363
+2364
+2365
+2366
+2367
+2368
+2369
+2370
+2371
+2372
+2373
+2374
+2375
+2376
+2377
+2378
+2379
+2380
+2381
+2382
+2383
+2384
+2385
+2386
+2387
+2388
+2389
+2390
+2391
+2392
+2393
+2394
+2395
+2396
+2397
+2398
+2399
+2400
+2401
+2402
+2403
+2404
+2405
+2406
+2407
+2408
+2409
+2410
+2411
+2412
+2413
+2414
+2415
+2416
+2417
+2418
+2419
+2420
+2421
+2422
+2423
+2424
+2425
+2426
+2427
+2428
+2429
+2430
+2431
+2432
+2433
+2434
+2435
+2436
+2437
+2438
+2439
+2440
+2441
+2442
+2443
+2444
+2445
+2446
+2447
+2448
+2449
+2450
+2451
+2452
+2453
+2454
+2455
+2456
+2457
+2458
+2459
+2460
+2461
+2462
+2463
+2464
+2465
+2466
+2467
+2468
+2469
+2470
+2471
+2472
+2473
+2474
+2475
+2476
+2477
+2478
+2479
+2480
+2481
+2482
+2483
+2484
+2485
+2486
+2487
+2488
+2489
+2490
+2491
+2492
+2493
+2494
+2495
+2496
+2497
+2498
+2499
+2500
+2501
+2502
+2503
+2504
+2505
+2506
+2507
+2508
+2509
+2510
+2511
+2512
+2513
+2514
+2515
+2516
+2517
+2518
+2519
+2520
+2521
+2522
+2523
+2524
+2525
+2526
+2527
+2528
+2529
+2530
+2531
+2532
+2533
+2534
+2535
+2536
+2537
+2538
+2539
+2540
+2541
+2542
+2543
+2544
+2545
+2546
+2547
+2548
+2549
+2550
+2551
+2552
+2553
+2554
+2555
+2556
+2557
+2558
+2559
+2560
+2561
+2562
+2563
+2564
+2565
+2566
+2567
+2568
+2569
+2570
+2571
+2572
+2573
+2574
+2575
+2576
+2577
+2578
+2579
+2580
+2581
+2582
+2583
+2584
+2585
+2586
+2587
+2588
+2589
+2590
+2591
+2592
+2593
+2594
+2595
+2596
+2597
+2598
+2599
+2600
+2601
+2602
+2603
+2604
+2605
+2606
+2607
+2608
+2609
+2610
+2611
+2612
+2613
+2614
+2615
+2616
+2617
+2618
+2619
+2620
+2621
+2622
+2623
+2624
+2625
+2626
+2627
+2628
+2629
+2630
+2631
+2632
+2633
+2634
+2635
+2636
+2637
+2638
+2639
+2640
+2641
+2642
+2643
+2644
+2645
+2646
+
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+Defines a translator that converts an `Ast` to an `Hir`.
+*/
+
+use std::cell::{Cell, RefCell};
+use std::result;
+
+use ast::{self, Ast, Span, Visitor};
+use hir::{self, Error, ErrorKind, Hir};
+use unicode::{self, ClassQuery};
+
+type Result<T> = result::Result<T, Error>;
+
+/// A builder for constructing an AST->HIR translator.
+#[derive(Clone, Debug)]
+pub struct TranslatorBuilder {
+    allow_invalid_utf8: bool,
+    flags: Flags,
+}
+
+impl Default for TranslatorBuilder {
+    fn default() -> TranslatorBuilder {
+        TranslatorBuilder::new()
+    }
+}
+
+impl TranslatorBuilder {
+    /// Create a new translator builder with a default c onfiguration.
+    pub fn new() -> TranslatorBuilder {
+        TranslatorBuilder {
+            allow_invalid_utf8: false,
+            flags: Flags::default(),
+        }
+    }
+
+    /// Build a translator using the current configuration.
+    pub fn build(&self) -> Translator {
+        Translator {
+            stack: RefCell::new(vec![]),
+            flags: Cell::new(self.flags),
+            allow_invalid_utf8: self.allow_invalid_utf8,
+        }
+    }
+
+    /// When enabled, translation will permit the construction of a regular
+    /// expression that may match invalid UTF-8.
+    ///
+    /// When disabled (the default), the translator is guaranteed to produce
+    /// an expression that will only ever match valid UTF-8 (otherwise, the
+    /// translator will return an error).
+    ///
+    /// Perhaps surprisingly, when invalid UTF-8 isn't allowed, a negated ASCII
+    /// word boundary (uttered as `(?-u:\B)` in the concrete syntax) will cause
+    /// the parser to return an error. Namely, a negated ASCII word boundary
+    /// can result in matching positions that aren't valid UTF-8 boundaries.
+    pub fn allow_invalid_utf8(
+        &mut self,
+        yes: bool,
+    ) -> &mut TranslatorBuilder {
+        self.allow_invalid_utf8 = yes;
+        self
+    }
+
+    /// Enable or disable the case insensitive flag (`i`) by default.
+    pub fn case_insensitive(&mut self, yes: bool) -> &mut TranslatorBuilder {
+        self.flags.case_insensitive = if yes { Some(true) } else { None };
+        self
+    }
+
+    /// Enable or disable the multi-line matching flag (`m`) by default.
+    pub fn multi_line(&mut self, yes: bool) -> &mut TranslatorBuilder {
+        self.flags.multi_line = if yes { Some(true) } else { None };
+        self
+    }
+
+    /// Enable or disable the "dot matches any character" flag (`s`) by
+    /// default.
+    pub fn dot_matches_new_line(
+        &mut self,
+        yes: bool,
+    ) -> &mut TranslatorBuilder {
+        self.flags.dot_matches_new_line = if yes { Some(true) } else { None };
+        self
+    }
+
+    /// Enable or disable the "swap greed" flag (`U`) by default.
+    pub fn swap_greed(&mut self, yes: bool) -> &mut TranslatorBuilder {
+        self.flags.swap_greed = if yes { Some(true) } else { None };
+        self
+    }
+
+    /// Enable or disable the Unicode flag (`u`) by default.
+    pub fn unicode(&mut self, yes: bool) -> &mut TranslatorBuilder {
+        self.flags.unicode = if yes { None } else { Some(false) };
+        self
+    }
+}
+
+/// A translator maps abstract syntax to a high level intermediate
+/// representation.
+///
+/// A translator may be benefit from reuse. That is, a translator can translate
+/// many abstract syntax trees.
+///
+/// A `Translator` can be configured in more detail via a
+/// [`TranslatorBuilder`](struct.TranslatorBuilder.html).
+#[derive(Clone, Debug)]
+pub struct Translator {
+    /// Our call stack, but on the heap.
+    stack: RefCell<Vec<HirFrame>>,
+    /// The current flag settings.
+    flags: Cell<Flags>,
+    /// Whether we're allowed to produce HIR that can match arbitrary bytes.
+    allow_invalid_utf8: bool,
+}
+
+impl Translator {
+    /// Create a new translator using the default configuration.
+    pub fn new() -> Translator {
+        TranslatorBuilder::new().build()
+    }
+
+    /// Translate the given abstract syntax tree (AST) into a high level
+    /// intermediate representation (HIR).
+    ///
+    /// If there was a problem doing the translation, then an HIR-specific
+    /// error is returned.
+    ///
+    /// The original pattern string used to produce the `Ast` *must* also be
+    /// provided. The translator does not use the pattern string during any
+    /// correct translation, but is used for error reporting.
+    pub fn translate(&mut self, pattern: &str, ast: &Ast) -> Result<Hir> {
+        ast::visit(ast, TranslatorI::new(self, pattern))
+    }
+}
+
+/// An HirFrame is a single stack frame, represented explicitly, which is
+/// created for each item in the Ast that we traverse.
+///
+/// Note that technically, this type doesn't represent our entire stack
+/// frame. In particular, the Ast visitor represents any state associated with
+/// traversing the Ast itself.
+#[derive(Clone, Debug)]
+enum HirFrame {
+    /// An arbitrary HIR expression. These get pushed whenever we hit a base
+    /// case in the Ast. They get popped after an inductive (i.e., recursive)
+    /// step is complete.
+    Expr(Hir),
+    /// A Unicode character class. This frame is mutated as we descend into
+    /// the Ast of a character class (which is itself its own mini recursive
+    /// structure).
+    ClassUnicode(hir::ClassUnicode),
+    /// A byte-oriented character class. This frame is mutated as we descend
+    /// into the Ast of a character class (which is itself its own mini
+    /// recursive structure).
+    ///
+    /// Byte character classes are created when Unicode mode (`u`) is disabled.
+    /// If `allow_invalid_utf8` is disabled (the default), then a byte
+    /// character is only permitted to match ASCII text.
+    ClassBytes(hir::ClassBytes),
+    /// This is pushed on to the stack upon first seeing any kind of group,
+    /// indicated by parentheses (including non-capturing groups). It is popped
+    /// upon leaving a group.
+    Group {
+        /// The old active flags, if any, when this group was opened.
+        ///
+        /// If this group sets flags, then the new active flags are set to the
+        /// result of merging the old flags with the flags introduced by this
+        /// group.
+        ///
+        /// When this group is popped, the active flags should be restored to
+        /// the flags set here.
+        ///
+        /// The "active" flags correspond to whatever flags are set in the
+        /// Translator.
+        old_flags: Option<Flags>,
+    },
+    /// This is pushed whenever a concatenation is observed. After visiting
+    /// every sub-expression in the concatenation, the translator's stack is
+    /// popped until it sees a Concat frame.
+    Concat,
+    /// This is pushed whenever an alternation is observed. After visiting
+    /// every sub-expression in the alternation, the translator's stack is
+    /// popped until it sees an Alternation frame.
+    Alternation,
+}
+
+impl HirFrame {
+    /// Assert that the current stack frame is an Hir expression and return it.
+    fn unwrap_expr(self) -> Hir {
+        match self {
+            HirFrame::Expr(expr) => expr,
+            _ => panic!("tried to unwrap expr from HirFrame, got: {:?}", self)
+        }
+    }
+
+    /// Assert that the current stack frame is a Unicode class expression and
+    /// return it.
+    fn unwrap_class_unicode(self) -> hir::ClassUnicode {
+        match self {
+            HirFrame::ClassUnicode(cls) => cls,
+            _ => panic!("tried to unwrap Unicode class \
+                         from HirFrame, got: {:?}", self)
+        }
+    }
+
+    /// Assert that the current stack frame is a byte class expression and
+    /// return it.
+    fn unwrap_class_bytes(self) -> hir::ClassBytes {
+        match self {
+            HirFrame::ClassBytes(cls) => cls,
+            _ => panic!("tried to unwrap byte class \
+                         from HirFrame, got: {:?}", self)
+        }
+    }
+
+    /// Assert that the current stack frame is a group indicator and return
+    /// its corresponding flags (the flags that were active at the time the
+    /// group was entered) if they exist.
+    fn unwrap_group(self) -> Option<Flags> {
+        match self {
+            HirFrame::Group { old_flags } => old_flags,
+            _ => panic!("tried to unwrap group from HirFrame, got: {:?}", self)
+        }
+    }
+}
+
+impl<'t, 'p> Visitor for TranslatorI<'t, 'p> {
+    type Output = Hir;
+    type Err = Error;
+
+    fn finish(self) -> Result<Hir> {
+        // ... otherwise, we should have exactly one HIR on the stack.
+        assert_eq!(self.trans().stack.borrow().len(), 1);
+        Ok(self.pop().unwrap().unwrap_expr())
+    }
+
+    fn visit_pre(&mut self, ast: &Ast) -> Result<()> {
+        match *ast {
+            Ast::Class(ast::Class::Bracketed(_)) => {
+                if self.flags().unicode() {
+                    let cls = hir::ClassUnicode::empty();
+                    self.push(HirFrame::ClassUnicode(cls));
+                } else {
+                    let cls = hir::ClassBytes::empty();
+                    self.push(HirFrame::ClassBytes(cls));
+                }
+            }
+            Ast::Group(ref x) => {
+                let old_flags = x.flags().map(|ast| self.set_flags(ast));
+                self.push(HirFrame::Group {
+                    old_flags: old_flags,
+                });
+            }
+            Ast::Concat(ref x) if x.asts.is_empty() => {}
+            Ast::Concat(_) => {
+                self.push(HirFrame::Concat);
+            }
+            Ast::Alternation(ref x) if x.asts.is_empty() => {}
+            Ast::Alternation(_) => {
+                self.push(HirFrame::Alternation);
+            }
+            _ => {}
+        }
+        Ok(())
+    }
+
+    fn visit_post(&mut self, ast: &Ast) -> Result<()> {
+        match *ast {
+            Ast::Empty(_) => {
+                self.push(HirFrame::Expr(Hir::empty()));
+            }
+            Ast::Flags(ref x) => {
+                self.set_flags(&x.flags);
+                // Flags in the AST are generally considered directives and
+                // not actual sub-expressions. However, they can be used in
+                // the concrete syntax like `((?i))`, and we need some kind of
+                // indication of an expression there, and Empty is the correct
+                // choice.
+                //
+                // There can also be things like `(?i)+`, but we rule those out
+                // in the parser. In the future, we might allow them for
+                // consistency sake.
+                self.push(HirFrame::Expr(Hir::empty()));
+            }
+            Ast::Literal(ref x) => {
+                self.push(HirFrame::Expr(self.hir_literal(x)?));
+            }
+            Ast::Dot(span) => {
+                self.push(HirFrame::Expr(self.hir_dot(span)?));
+            }
+            Ast::Assertion(ref x) => {
+                self.push(HirFrame::Expr(self.hir_assertion(x)?));
+            }
+            Ast::Class(ast::Class::Perl(ref x)) => {
+                if self.flags().unicode() {
+                    let cls = self.hir_perl_unicode_class(x);
+                    let hcls = hir::Class::Unicode(cls);
+                    self.push(HirFrame::Expr(Hir::class(hcls)));
+                } else {
+                    let cls = self.hir_perl_byte_class(x);
+                    let hcls = hir::Class::Bytes(cls);
+                    self.push(HirFrame::Expr(Hir::class(hcls)));
+                }
+            }
+            Ast::Class(ast::Class::Unicode(ref x)) => {
+                let cls = hir::Class::Unicode(self.hir_unicode_class(x)?);
+                self.push(HirFrame::Expr(Hir::class(cls)));
+            }
+            Ast::Class(ast::Class::Bracketed(ref ast)) => {
+                if self.flags().unicode() {
+                    let mut cls = self.pop().unwrap().unwrap_class_unicode();
+                    self.unicode_fold_and_negate(ast.negated, &mut cls);
+                    if cls.iter().next().is_none() {
+                        return Err(self.error(
+                            ast.span, ErrorKind::EmptyClassNotAllowed));
+                    }
+                    let expr = Hir::class(hir::Class::Unicode(cls));
+                    self.push(HirFrame::Expr(expr));
+                } else {
+                    let mut cls = self.pop().unwrap().unwrap_class_bytes();
+                    self.bytes_fold_and_negate(
+                        &ast.span, ast.negated, &mut cls)?;
+                    if cls.iter().next().is_none() {
+                        return Err(self.error(
+                            ast.span, ErrorKind::EmptyClassNotAllowed));
+                    }
+
+                    let expr = Hir::class(hir::Class::Bytes(cls));
+                    self.push(HirFrame::Expr(expr));
+                }
+            }
+            Ast::Repetition(ref x) => {
+                let expr = self.pop().unwrap().unwrap_expr();
+                self.push(HirFrame::Expr(self.hir_repetition(x, expr)));
+            }
+            Ast::Group(ref x) => {
+                let expr = self.pop().unwrap().unwrap_expr();
+                if let Some(flags) = self.pop().unwrap().unwrap_group() {
+                    self.trans().flags.set(flags);
+                }
+                self.push(HirFrame::Expr(self.hir_group(x, expr)));
+            }
+            Ast::Concat(_) => {
+                let mut exprs = vec![];
+                while let Some(HirFrame::Expr(expr)) = self.pop() {
+                    if !expr.kind().is_empty() {
+                        exprs.push(expr);
+                    }
+                }
+                exprs.reverse();
+                self.push(HirFrame::Expr(Hir::concat(exprs)));
+            }
+            Ast::Alternation(_) => {
+                let mut exprs = vec![];
+                while let Some(HirFrame::Expr(expr)) = self.pop() {
+                    exprs.push(expr);
+                }
+                exprs.reverse();
+                self.push(HirFrame::Expr(Hir::alternation(exprs)));
+            }
+        }
+        Ok(())
+    }
+
+    fn visit_class_set_item_pre(
+        &mut self,
+        ast: &ast::ClassSetItem,
+    ) -> Result<()> {
+        match *ast {
+            ast::ClassSetItem::Bracketed(_) => {
+                if self.flags().unicode() {
+                    let cls = hir::ClassUnicode::empty();
+                    self.push(HirFrame::ClassUnicode(cls));
+                } else {
+                    let cls = hir::ClassBytes::empty();
+                    self.push(HirFrame::ClassBytes(cls));
+                }
+            }
+            // We needn't handle the Union case here since the visitor will
+            // do it for us.
+            _ => {}
+        }
+        Ok(())
+    }
+
+    fn visit_class_set_item_post(
+        &mut self,
+        ast: &ast::ClassSetItem,
+    ) -> Result<()> {
+        match *ast {
+            ast::ClassSetItem::Empty(_) => {}
+            ast::ClassSetItem::Literal(ref x) => {
+                if self.flags().unicode() {
+                    let mut cls = self.pop().unwrap().unwrap_class_unicode();
+                    cls.push(hir::ClassUnicodeRange::new(x.c, x.c));
+                    self.push(HirFrame::ClassUnicode(cls));
+                } else {
+                    let mut cls = self.pop().unwrap().unwrap_class_bytes();
+                    let byte = self.class_literal_byte(x)?;
+                    cls.push(hir::ClassBytesRange::new(byte, byte));
+                    self.push(HirFrame::ClassBytes(cls));
+                }
+            }
+            ast::ClassSetItem::Range(ref x) => {
+                if self.flags().unicode() {
+                    let mut cls = self.pop().unwrap().unwrap_class_unicode();
+                    cls.push(hir::ClassUnicodeRange::new(x.start.c, x.end.c));
+                    self.push(HirFrame::ClassUnicode(cls));
+                } else {
+                    let mut cls = self.pop().unwrap().unwrap_class_bytes();
+                    let start = self.class_literal_byte(&x.start)?;
+                    let end = self.class_literal_byte(&x.end)?;
+                    cls.push(hir::ClassBytesRange::new(start, end));
+                    self.push(HirFrame::ClassBytes(cls));
+                }
+            }
+            ast::ClassSetItem::Ascii(ref x) => {
+                if self.flags().unicode() {
+                    let mut cls = self.pop().unwrap().unwrap_class_unicode();
+                    for &(s, e) in ascii_class(&x.kind) {
+                        cls.push(hir::ClassUnicodeRange::new(s, e));
+                    }
+                    self.unicode_fold_and_negate(x.negated, &mut cls);
+                    self.push(HirFrame::ClassUnicode(cls));
+                } else {
+                    let mut cls = self.pop().unwrap().unwrap_class_bytes();
+                    for &(s, e) in ascii_class(&x.kind) {
+                        cls.push(hir::ClassBytesRange::new(s as u8, e as u8));
+                    }
+                    self.bytes_fold_and_negate(
+                        &x.span, x.negated, &mut cls)?;
+                    self.push(HirFrame::ClassBytes(cls));
+                }
+            }
+            ast::ClassSetItem::Unicode(ref x) => {
+                let xcls = self.hir_unicode_class(x)?;
+                let mut cls = self.pop().unwrap().unwrap_class_unicode();
+                cls.union(&xcls);
+                self.push(HirFrame::ClassUnicode(cls));
+            }
+            ast::ClassSetItem::Perl(ref x) => {
+                if self.flags().unicode() {
+                    let xcls = self.hir_perl_unicode_class(x);
+                    let mut cls = self.pop().unwrap().unwrap_class_unicode();
+                    cls.union(&xcls);
+                    self.push(HirFrame::ClassUnicode(cls));
+                } else {
+                    let xcls = self.hir_perl_byte_class(x);
+                    let mut cls = self.pop().unwrap().unwrap_class_bytes();
+                    cls.union(&xcls);
+                    self.push(HirFrame::ClassBytes(cls));
+                }
+            }
+            ast::ClassSetItem::Bracketed(ref ast) => {
+                if self.flags().unicode() {
+                    let mut cls1 = self.pop().unwrap().unwrap_class_unicode();
+                    self.unicode_fold_and_negate(ast.negated, &mut cls1);
+
+                    let mut cls2 = self.pop().unwrap().unwrap_class_unicode();
+                    cls2.union(&cls1);
+                    self.push(HirFrame::ClassUnicode(cls2));
+                } else {
+                    let mut cls1 = self.pop().unwrap().unwrap_class_bytes();
+                    self.bytes_fold_and_negate(
+                        &ast.span, ast.negated, &mut cls1)?;
+
+                    let mut cls2 = self.pop().unwrap().unwrap_class_bytes();
+                    cls2.union(&cls1);
+                    self.push(HirFrame::ClassBytes(cls2));
+                }
+            }
+            // This is handled automatically by the visitor.
+            ast::ClassSetItem::Union(_) => {}
+        }
+        Ok(())
+    }
+
+    fn visit_class_set_binary_op_pre(
+        &mut self,
+        _op: &ast::ClassSetBinaryOp,
+    ) -> Result<()> {
+        if self.flags().unicode() {
+            let cls = hir::ClassUnicode::empty();
+            self.push(HirFrame::ClassUnicode(cls));
+        } else {
+            let cls = hir::ClassBytes::empty();
+            self.push(HirFrame::ClassBytes(cls));
+        }
+        Ok(())
+    }
+
+    fn visit_class_set_binary_op_in(
+        &mut self,
+        _op: &ast::ClassSetBinaryOp,
+    ) -> Result<()> {
+        if self.flags().unicode() {
+            let cls = hir::ClassUnicode::empty();
+            self.push(HirFrame::ClassUnicode(cls));
+        } else {
+            let cls = hir::ClassBytes::empty();
+            self.push(HirFrame::ClassBytes(cls));
+        }
+        Ok(())
+    }
+
+    fn visit_class_set_binary_op_post(
+        &mut self,
+        op: &ast::ClassSetBinaryOp,
+    ) -> Result<()> {
+        use ast::ClassSetBinaryOpKind::*;
+
+        if self.flags().unicode() {
+            let mut rhs = self.pop().unwrap().unwrap_class_unicode();
+            let mut lhs = self.pop().unwrap().unwrap_class_unicode();
+            let mut cls = self.pop().unwrap().unwrap_class_unicode();
+            if self.flags().case_insensitive() {
+                rhs.case_fold_simple();
+                lhs.case_fold_simple();
+            }
+            match op.kind {
+                Intersection => lhs.intersect(&rhs),
+                Difference => lhs.difference(&rhs),
+                SymmetricDifference => lhs.symmetric_difference(&rhs),
+            }
+            cls.union(&lhs);
+            self.push(HirFrame::ClassUnicode(cls));
+        } else {
+            let mut rhs = self.pop().unwrap().unwrap_class_bytes();
+            let mut lhs = self.pop().unwrap().unwrap_class_bytes();
+            let mut cls = self.pop().unwrap().unwrap_class_bytes();
+            if self.flags().case_insensitive() {
+                rhs.case_fold_simple();
+                lhs.case_fold_simple();
+            }
+            match op.kind {
+                Intersection => lhs.intersect(&rhs),
+                Difference => lhs.difference(&rhs),
+                SymmetricDifference => lhs.symmetric_difference(&rhs),
+            }
+            cls.union(&lhs);
+            self.push(HirFrame::ClassBytes(cls));
+        }
+        Ok(())
+    }
+}
+
+/// The internal implementation of a translator.
+///
+/// This type is responsible for carrying around the original pattern string,
+/// which is not tied to the internal state of a translator.
+///
+/// A TranslatorI exists for the time it takes to translate a single Ast.
+#[derive(Clone, Debug)]
+struct TranslatorI<'t, 'p> {
+    trans: &'t Translator,
+    pattern: &'p str,
+}
+
+impl<'t, 'p> TranslatorI<'t, 'p> {
+    /// Build a new internal translator.
+    fn new(trans: &'t Translator, pattern: &'p str) -> TranslatorI<'t, 'p> {
+        TranslatorI { trans: trans, pattern: pattern }
+    }
+
+    /// Return a reference to the underlying translator.
+    fn trans(&self) -> &Translator {
+        &self.trans
+    }
+
+    /// Push the given frame on to the call stack.
+    fn push(&self, frame: HirFrame) {
+        self.trans().stack.borrow_mut().push(frame);
+    }
+
+    /// Pop the top of the call stack. If the call stack is empty, return None.
+    fn pop(&self) -> Option<HirFrame> {
+        self.trans().stack.borrow_mut().pop()
+    }
+
+    /// Create a new error with the given span and error type.
+    fn error(&self, span: Span, kind: ErrorKind) -> Error {
+        Error { kind: kind, pattern: self.pattern.to_string(), span: span }
+    }
+
+    /// Return a copy of the active flags.
+    fn flags(&self) -> Flags {
+        self.trans().flags.get()
+    }
+
+    /// Set the flags of this translator from the flags set in the given AST.
+    /// Then, return the old flags.
+    fn set_flags(&self, ast_flags: &ast::Flags) -> Flags {
+        let old_flags = self.flags();
+        let mut new_flags = Flags::from_ast(ast_flags);
+        new_flags.merge(&old_flags);
+        self.trans().flags.set(new_flags);
+        old_flags
+    }
+
+    fn hir_literal(&self, lit: &ast::Literal) -> Result<Hir> {
+        let ch = match self.literal_to_char(lit)? {
+            byte @ hir::Literal::Byte(_) => return Ok(Hir::literal(byte)),
+            hir::Literal::Unicode(ch) => ch,
+        };
+        if self.flags().case_insensitive() {
+            self.hir_from_char_case_insensitive(lit.span, ch)
+        } else {
+            self.hir_from_char(lit.span, ch)
+        }
+    }
+
+    /// Convert an Ast literal to its scalar representation.
+    ///
+    /// When Unicode mode is enabled, then this always succeeds and returns a
+    /// `char` (Unicode scalar value).
+    ///
+    /// When Unicode mode is disabled, then a raw byte is returned. If that
+    /// byte is not ASCII and invalid UTF-8 is not allowed, then this returns
+    /// an error.
+    fn literal_to_char(&self, lit: &ast::Literal) -> Result<hir::Literal> {
+        if self.flags().unicode() {
+            return Ok(hir::Literal::Unicode(lit.c));
+        }
+        let byte = match lit.byte() {
+            None => return Ok(hir::Literal::Unicode(lit.c)),
+            Some(byte) => byte,
+        };
+        if byte <= 0x7F {
+            return Ok(hir::Literal::Unicode(byte as char));
+        }
+        if !self.trans().allow_invalid_utf8 {
+            return Err(self.error(lit.span, ErrorKind::InvalidUtf8));
+        }
+        Ok(hir::Literal::Byte(byte))
+    }
+
+    fn hir_from_char(&self, span: Span, c: char) -> Result<Hir> {
+        if !self.flags().unicode() && c.len_utf8() > 1 {
+            return Err(self.error(span, ErrorKind::UnicodeNotAllowed));
+        }
+        Ok(Hir::literal(hir::Literal::Unicode(c)))
+    }
+
+    fn hir_from_char_case_insensitive(
+        &self,
+        span: Span,
+        c: char,
+    ) -> Result<Hir> {
+        // If case folding won't do anything, then don't bother trying.
+        if !unicode::contains_simple_case_mapping(c, c) {
+            return self.hir_from_char(span, c);
+        }
+        if self.flags().unicode() {
+            let mut cls = hir::ClassUnicode::new(vec![
+                hir::ClassUnicodeRange::new(c, c),
+            ]);
+            cls.case_fold_simple();
+            Ok(Hir::class(hir::Class::Unicode(cls)))
+        } else {
+            if c.len_utf8() > 1 {
+                return Err(self.error(span, ErrorKind::UnicodeNotAllowed));
+            }
+            let mut cls = hir::ClassBytes::new(vec![
+                hir::ClassBytesRange::new(c as u8, c as u8),
+            ]);
+            cls.case_fold_simple();
+            Ok(Hir::class(hir::Class::Bytes(cls)))
+        }
+    }
+
+    fn hir_dot(&self, span: Span) -> Result<Hir> {
+        let unicode = self.flags().unicode();
+        if !unicode && !self.trans().allow_invalid_utf8 {
+            return Err(self.error(span, ErrorKind::InvalidUtf8));
+        }
+        Ok(if self.flags().dot_matches_new_line() {
+            Hir::any(!unicode)
+        } else {
+            Hir::dot(!unicode)
+        })
+    }
+
+    fn hir_assertion(&self, asst: &ast::Assertion) -> Result<Hir> {
+        let unicode = self.flags().unicode();
+        let multi_line = self.flags().multi_line();
+        Ok(match asst.kind {
+            ast::AssertionKind::StartLine => {
+                Hir::anchor(if multi_line {
+                    hir::Anchor::StartLine
+                } else {
+                    hir::Anchor::StartText
+                })
+            }
+            ast::AssertionKind::EndLine => {
+                Hir::anchor(if multi_line {
+                    hir::Anchor::EndLine
+                } else {
+                    hir::Anchor::EndText
+                })
+            }
+            ast::AssertionKind::StartText => {
+                Hir::anchor(hir::Anchor::StartText)
+            }
+            ast::AssertionKind::EndText => {
+                Hir::anchor(hir::Anchor::EndText)
+            }
+            ast::AssertionKind::WordBoundary => {
+                Hir::word_boundary(if unicode {
+                    hir::WordBoundary::Unicode
+                } else {
+                    hir::WordBoundary::Ascii
+                })
+            }
+            ast::AssertionKind::NotWordBoundary => {
+                Hir::word_boundary(if unicode {
+                    hir::WordBoundary::UnicodeNegate
+                } else {
+                    // It is possible for negated ASCII word boundaries to
+                    // match at invalid UTF-8 boundaries, even when searching
+                    // valid UTF-8.
+                    if !self.trans().allow_invalid_utf8 {
+                        return Err(self.error(
+                            asst.span, ErrorKind::InvalidUtf8));
+                    }
+                    hir::WordBoundary::AsciiNegate
+                })
+            }
+        })
+    }
+
+    fn hir_group(&self, group: &ast::Group, expr: Hir) -> Hir {
+        let kind = match group.kind {
+            ast::GroupKind::CaptureIndex(idx) => {
+                hir::GroupKind::CaptureIndex(idx)
+            }
+            ast::GroupKind::CaptureName(ref capname) => {
+                hir::GroupKind::CaptureName {
+                    name: capname.name.clone(),
+                    index: capname.index,
+                }
+            }
+            ast::GroupKind::NonCapturing(_) => hir::GroupKind::NonCapturing,
+        };
+        Hir::group(hir::Group {
+            kind: kind,
+            hir: Box::new(expr),
+        })
+    }
+
+    fn hir_repetition(&self, rep: &ast::Repetition, expr: Hir) -> Hir {
+        let kind = match rep.op.kind {
+            ast::RepetitionKind::ZeroOrOne => hir::RepetitionKind::ZeroOrOne,
+            ast::RepetitionKind::ZeroOrMore => hir::RepetitionKind::ZeroOrMore,
+            ast::RepetitionKind::OneOrMore => hir::RepetitionKind::OneOrMore,
+            ast::RepetitionKind::Range(ast::RepetitionRange::Exactly(m)) => {
+                hir::RepetitionKind::Range(hir::RepetitionRange::Exactly(m))
+            }
+            ast::RepetitionKind::Range(ast::RepetitionRange::AtLeast(m)) => {
+                hir::RepetitionKind::Range(hir::RepetitionRange::AtLeast(m))
+            }
+            ast::RepetitionKind::Range(ast::RepetitionRange::Bounded(m,n)) => {
+                hir::RepetitionKind::Range(hir::RepetitionRange::Bounded(m, n))
+            }
+        };
+        let greedy =
+            if self.flags().swap_greed() {
+                !rep.greedy
+            } else {
+                rep.greedy
+            };
+        Hir::repetition(hir::Repetition {
+            kind: kind,
+            greedy: greedy,
+            hir: Box::new(expr),
+        })
+    }
+
+    fn hir_unicode_class(
+        &self,
+        ast_class: &ast::ClassUnicode,
+    ) -> Result<hir::ClassUnicode> {
+        use ast::ClassUnicodeKind::*;
+
+        if !self.flags().unicode() {
+            return Err(self.error(
+                ast_class.span,
+                ErrorKind::UnicodeNotAllowed,
+            ));
+        }
+        let query = match ast_class.kind {
+            OneLetter(name) => ClassQuery::OneLetter(name),
+            Named(ref name) => ClassQuery::Binary(name),
+            NamedValue { ref name, ref value, .. } => {
+                ClassQuery::ByValue {
+                    property_name: name,
+                    property_value: value,
+                }
+            }
+        };
+        match unicode::class(query) {
+            Ok(mut class) => {
+                self.unicode_fold_and_negate(ast_class.negated, &mut class);
+                Ok(class)
+            }
+            Err(unicode::Error::PropertyNotFound) => {
+                Err(self.error(
+                    ast_class.span,
+                    ErrorKind::UnicodePropertyNotFound,
+                ))
+            }
+            Err(unicode::Error::PropertyValueNotFound) => {
+                Err(self.error(
+                    ast_class.span,
+                    ErrorKind::UnicodePropertyValueNotFound,
+                ))
+            }
+        }
+    }
+
+    fn hir_perl_unicode_class(
+        &self,
+        ast_class: &ast::ClassPerl,
+    ) -> hir::ClassUnicode {
+        use ast::ClassPerlKind::*;
+        use unicode_tables::perl_word::PERL_WORD;
+
+        assert!(self.flags().unicode());
+        let mut class = match ast_class.kind {
+            Digit => {
+                let query = ClassQuery::Binary("Decimal_Number");
+                unicode::class(query).unwrap()
+            }
+            Space => {
+                let query = ClassQuery::Binary("Whitespace");
+                unicode::class(query).unwrap()
+            }
+            Word => unicode::hir_class(PERL_WORD),
+        };
+        // We needn't apply case folding here because the Perl Unicode classes
+        // are already closed under Unicode simple case folding.
+        if ast_class.negated {
+            class.negate();
+        }
+        class
+    }
+
+    fn hir_perl_byte_class(
+        &self,
+        ast_class: &ast::ClassPerl,
+    ) -> hir::ClassBytes {
+        use ast::ClassPerlKind::*;
+
+        assert!(!self.flags().unicode());
+        let mut class = match ast_class.kind {
+            Digit => hir_ascii_class_bytes(&ast::ClassAsciiKind::Digit),
+            Space => hir_ascii_class_bytes(&ast::ClassAsciiKind::Space),
+            Word => hir_ascii_class_bytes(&ast::ClassAsciiKind::Word),
+        };
+        // We needn't apply case folding here because the Perl ASCII classes
+        // are already closed (under ASCII case folding).
+        if ast_class.negated {
+            class.negate();
+        }
+        class
+    }
+
+    fn unicode_fold_and_negate(
+        &self,
+        negated: bool,
+        class: &mut hir::ClassUnicode,
+    ) {
+        // Note that we must apply case folding before negation!
+        // Consider `(?i)[^x]`. If we applied negation field, then
+        // the result would be the character class that matched any
+        // Unicode scalar value.
+        if self.flags().case_insensitive() {
+            class.case_fold_simple();
+        }
+        if negated {
+            class.negate();
+        }
+    }
+
+    fn bytes_fold_and_negate(
+        &self,
+        span: &Span,
+        negated: bool,
+        class: &mut hir::ClassBytes,
+    ) -> Result<()> {
+        // Note that we must apply case folding before negation!
+        // Consider `(?i)[^x]`. If we applied negation field, then
+        // the result would be the character class that matched any
+        // Unicode scalar value.
+        if self.flags().case_insensitive() {
+            class.case_fold_simple();
+        }
+        if negated {
+            class.negate();
+        }
+        if !self.trans().allow_invalid_utf8 && !class.is_all_ascii() {
+            return Err(self.error(span.clone(), ErrorKind::InvalidUtf8));
+        }
+        Ok(())
+    }
+
+    /// Return a scalar byte value suitable for use as a literal in a byte
+    /// character class.
+    fn class_literal_byte(&self, ast: &ast::Literal) -> Result<u8> {
+        match self.literal_to_char(ast)? {
+            hir::Literal::Byte(byte) => Ok(byte),
+            hir::Literal::Unicode(ch) => {
+                if ch <= 0x7F as char {
+                    Ok(ch as u8)
+                } else {
+                    // We can't feasibly support Unicode in
+                    // byte oriented classes. Byte classes don't
+                    // do Unicode case folding.
+                    Err(self.error(ast.span, ErrorKind::UnicodeNotAllowed))
+                }
+            }
+        }
+    }
+}
+
+/// A translator's representation of a regular expression's flags at any given
+/// moment in time.
+///
+/// Each flag can be in one of three states: absent, present but disabled or
+/// present but enabled.
+#[derive(Clone, Copy, Debug, Default)]
+struct Flags {
+    case_insensitive: Option<bool>,
+    multi_line: Option<bool>,
+    dot_matches_new_line: Option<bool>,
+    swap_greed: Option<bool>,
+    unicode: Option<bool>,
+    // Note that `ignore_whitespace` is omitted here because it is handled
+    // entirely in the parser.
+}
+
+impl Flags {
+    fn from_ast(ast: &ast::Flags) -> Flags {
+        let mut flags = Flags::default();
+        let mut enable = true;
+        for item in &ast.items {
+            match item.kind {
+                ast::FlagsItemKind::Negation => {
+                    enable = false;
+                }
+                ast::FlagsItemKind::Flag(ast::Flag::CaseInsensitive) => {
+                    flags.case_insensitive = Some(enable);
+                }
+                ast::FlagsItemKind::Flag(ast::Flag::MultiLine) => {
+                    flags.multi_line = Some(enable);
+                }
+                ast::FlagsItemKind::Flag(ast::Flag::DotMatchesNewLine) => {
+                    flags.dot_matches_new_line = Some(enable);
+                }
+                ast::FlagsItemKind::Flag(ast::Flag::SwapGreed) => {
+                    flags.swap_greed = Some(enable);
+                }
+                ast::FlagsItemKind::Flag(ast::Flag::Unicode) => {
+                    flags.unicode = Some(enable);
+                }
+                ast::FlagsItemKind::Flag(ast::Flag::IgnoreWhitespace) => {}
+            }
+        }
+        flags
+    }
+
+    fn merge(&mut self, previous: &Flags) {
+        if self.case_insensitive.is_none() {
+            self.case_insensitive = previous.case_insensitive;
+        }
+        if self.multi_line.is_none() {
+            self.multi_line = previous.multi_line;
+        }
+        if self.dot_matches_new_line.is_none() {
+            self.dot_matches_new_line = previous.dot_matches_new_line;
+        }
+        if self.swap_greed.is_none() {
+            self.swap_greed = previous.swap_greed;
+        }
+        if self.unicode.is_none() {
+            self.unicode = previous.unicode;
+        }
+    }
+
+    fn case_insensitive(&self) -> bool {
+        self.case_insensitive.unwrap_or(false)
+    }
+
+    fn multi_line(&self) -> bool {
+        self.multi_line.unwrap_or(false)
+    }
+
+    fn dot_matches_new_line(&self) -> bool {
+        self.dot_matches_new_line.unwrap_or(false)
+    }
+
+    fn swap_greed(&self) -> bool {
+        self.swap_greed.unwrap_or(false)
+    }
+
+    fn unicode(&self) -> bool {
+        self.unicode.unwrap_or(true)
+    }
+}
+
+fn hir_ascii_class_bytes(kind: &ast::ClassAsciiKind) -> hir::ClassBytes {
+    let ranges: Vec<_> = ascii_class(kind).iter().cloned().map(|(s, e)| {
+        hir::ClassBytesRange::new(s as u8, e as u8)
+    }).collect();
+    hir::ClassBytes::new(ranges)
+}
+
+fn ascii_class(kind: &ast::ClassAsciiKind) -> &'static [(char, char)] {
+    use ast::ClassAsciiKind::*;
+
+    // The contortions below with `const` appear necessary for older versions
+    // of Rust.
+    type T = &'static [(char, char)];
+    match *kind {
+        Alnum => {
+            const X: T = &[('0', '9'), ('A', 'Z'), ('a', 'z')];
+            X
+        }
+        Alpha => {
+            const X: T = &[('A', 'Z'), ('a', 'z')];
+            X
+        }
+        Ascii => {
+            const X: T = &[('\x00', '\x7F')];
+            X
+        }
+        Blank => {
+            const X: T = &[('\t', '\t'), (' ', ' ')];
+            X
+        }
+        Cntrl => {
+            const X: T = &[('\x00', '\x1F'), ('\x7F', '\x7F')];
+            X
+        }
+        Digit => {
+            const X: T = &[('0', '9')];
+            X
+        }
+        Graph => {
+            const X: T = &[('!', '~')];
+            X
+        }
+        Lower => {
+            const X: T = &[('a', 'z')];
+            X
+        }
+        Print => {
+            const X: T = &[(' ', '~')];
+            X
+        }
+        Punct => {
+            const X: T = &[('!', '/'), (':', '@'), ('[', '`'), ('{', '~')];
+            X
+        }
+        Space => {
+            const X: T = &[
+                ('\t', '\t'), ('\n', '\n'), ('\x0B', '\x0B'), ('\x0C', '\x0C'),
+                ('\r', '\r'), (' ', ' '),
+            ];
+            X
+        }
+        Upper => {
+            const X: T = &[('A', 'Z')];
+            X
+        }
+        Word => {
+            const X: T = &[('0', '9'), ('A', 'Z'), ('_', '_'), ('a', 'z')];
+            X
+        }
+        Xdigit => {
+            const X: T = &[('0', '9'), ('A', 'F'), ('a', 'f')];
+            X
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use ast::{self, Ast, Position, Span};
+    use ast::parse::ParserBuilder;
+    use hir::{self, Hir, HirKind};
+    use unicode::{self, ClassQuery};
+
+    use super::{TranslatorBuilder, ascii_class};
+
+    // We create these errors to compare with real hir::Errors in the tests.
+    // We define equality between TestError and hir::Error to disregard the
+    // pattern string in hir::Error, which is annoying to provide in tests.
+    #[derive(Clone, Debug)]
+    struct TestError {
+        span: Span,
+        kind: hir::ErrorKind,
+    }
+
+    impl PartialEq<hir::Error> for TestError {
+        fn eq(&self, other: &hir::Error) -> bool {
+            self.span == other.span && self.kind == other.kind
+        }
+    }
+
+    impl PartialEq<TestError> for hir::Error {
+        fn eq(&self, other: &TestError) -> bool {
+            self.span == other.span && self.kind == other.kind
+        }
+    }
+
+    fn parse(pattern: &str) -> Ast {
+        ParserBuilder::new().octal(true).build().parse(pattern).unwrap()
+    }
+
+    fn t(pattern: &str) -> Hir {
+        TranslatorBuilder::new()
+            .allow_invalid_utf8(false)
+            .build()
+            .translate(pattern, &parse(pattern))
+            .unwrap()
+    }
+
+    fn t_err(pattern: &str) -> hir::Error {
+        TranslatorBuilder::new()
+            .allow_invalid_utf8(false)
+            .build()
+            .translate(pattern, &parse(pattern))
+            .unwrap_err()
+    }
+
+    fn t_bytes(pattern: &str) -> Hir {
+        TranslatorBuilder::new()
+            .allow_invalid_utf8(true)
+            .build()
+            .translate(pattern, &parse(pattern))
+            .unwrap()
+    }
+
+    fn hir_lit(s: &str) -> Hir {
+        match s.len() {
+            0 => Hir::empty(),
+            _ => {
+                let lits = s
+                    .chars()
+                    .map(hir::Literal::Unicode)
+                    .map(Hir::literal)
+                    .collect();
+                Hir::concat(lits)
+            }
+        }
+    }
+
+    fn hir_blit(s: &[u8]) -> Hir {
+        match s.len() {
+            0 => Hir::empty(),
+            1 => Hir::literal(hir::Literal::Byte(s[0])),
+            _ => {
+                let lits = s
+                    .iter()
+                    .cloned()
+                    .map(hir::Literal::Byte)
+                    .map(Hir::literal)
+                    .collect();
+                Hir::concat(lits)
+            }
+        }
+    }
+
+    fn hir_group(i: u32, expr: Hir)  -> Hir {
+        Hir::group(hir::Group {
+            kind: hir::GroupKind::CaptureIndex(i),
+            hir: Box::new(expr),
+        })
+    }
+
+    fn hir_group_name(i: u32, name: &str, expr: Hir)  -> Hir {
+        Hir::group(hir::Group {
+            kind: hir::GroupKind::CaptureName {
+                name: name.to_string(),
+                index: i,
+            },
+            hir: Box::new(expr),
+        })
+    }
+
+    fn hir_group_nocap(expr: Hir)  -> Hir {
+        Hir::group(hir::Group {
+            kind: hir::GroupKind::NonCapturing,
+            hir: Box::new(expr),
+        })
+    }
+
+    fn hir_quest(greedy: bool, expr: Hir) -> Hir {
+        Hir::repetition(hir::Repetition {
+            kind: hir::RepetitionKind::ZeroOrOne,
+            greedy: greedy,
+            hir: Box::new(expr),
+        })
+    }
+
+    fn hir_star(greedy: bool, expr: Hir) -> Hir {
+        Hir::repetition(hir::Repetition {
+            kind: hir::RepetitionKind::ZeroOrMore,
+            greedy: greedy,
+            hir: Box::new(expr),
+        })
+    }
+
+    fn hir_plus(greedy: bool, expr: Hir) -> Hir {
+        Hir::repetition(hir::Repetition {
+            kind: hir::RepetitionKind::OneOrMore,
+            greedy: greedy,
+            hir: Box::new(expr),
+        })
+    }
+
+    fn hir_range(greedy: bool, range: hir::RepetitionRange, expr: Hir) -> Hir {
+        Hir::repetition(hir::Repetition {
+            kind: hir::RepetitionKind::Range(range),
+            greedy: greedy,
+            hir: Box::new(expr),
+        })
+    }
+
+    fn hir_alt(alts: Vec<Hir>) -> Hir {
+        Hir::alternation(alts)
+    }
+
+    fn hir_cat(exprs: Vec<Hir>) -> Hir {
+        Hir::concat(exprs)
+    }
+
+    fn hir_uclass_query(query: ClassQuery) -> Hir {
+        Hir::class(hir::Class::Unicode(unicode::class(query).unwrap()))
+    }
+
+    fn hir_uclass_perl_word() -> Hir {
+        use unicode_tables::perl_word::PERL_WORD;
+        Hir::class(hir::Class::Unicode(unicode::hir_class(PERL_WORD)))
+    }
+
+    fn hir_uclass(ranges: &[(char, char)]) -> Hir {
+        let ranges: Vec<hir::ClassUnicodeRange> = ranges
+            .iter()
+            .map(|&(s, e)| hir::ClassUnicodeRange::new(s, e))
+            .collect();
+        Hir::class(hir::Class::Unicode(hir::ClassUnicode::new(ranges)))
+    }
+
+    fn hir_bclass(ranges: &[(u8, u8)]) -> Hir {
+        let ranges: Vec<hir::ClassBytesRange> = ranges
+            .iter()
+            .map(|&(s, e)| hir::ClassBytesRange::new(s, e))
+            .collect();
+        Hir::class(hir::Class::Bytes(hir::ClassBytes::new(ranges)))
+    }
+
+    fn hir_bclass_from_char(ranges: &[(char, char)]) -> Hir {
+        let ranges: Vec<hir::ClassBytesRange> = ranges
+            .iter()
+            .map(|&(s, e)| {
+                assert!(s as u32 <= 0x7F);
+                assert!(e as u32 <= 0x7F);
+                hir::ClassBytesRange::new(s as u8, e as u8)
+            })
+            .collect();
+        Hir::class(hir::Class::Bytes(hir::ClassBytes::new(ranges)))
+    }
+
+    fn hir_case_fold(expr: Hir) -> Hir {
+        match expr.into_kind() {
+            HirKind::Class(mut cls) => {
+                cls.case_fold_simple();
+                Hir::class(cls)
+            }
+            _ => panic!("cannot case fold non-class Hir expr"),
+        }
+    }
+
+    fn hir_negate(expr: Hir) -> Hir {
+        match expr.into_kind() {
+            HirKind::Class(mut cls) => {
+                cls.negate();
+                Hir::class(cls)
+            }
+            _ => panic!("cannot negate non-class Hir expr"),
+        }
+    }
+
+    fn hir_union(expr1: Hir, expr2: Hir) -> Hir {
+        use hir::Class::{Bytes, Unicode};
+
+        match (expr1.into_kind(), expr2.into_kind()) {
+            (
+                HirKind::Class(Unicode(mut c1)),
+                HirKind::Class(Unicode(c2)),
+            ) => {
+                c1.union(&c2);
+                Hir::class(hir::Class::Unicode(c1))
+            }
+            (
+                HirKind::Class(Bytes(mut c1)),
+                HirKind::Class(Bytes(c2)),
+            ) => {
+                c1.union(&c2);
+                Hir::class(hir::Class::Bytes(c1))
+            }
+            _ => panic!("cannot union non-class Hir exprs"),
+        }
+    }
+
+    fn hir_difference(expr1: Hir, expr2: Hir) -> Hir {
+        use hir::Class::{Bytes, Unicode};
+
+        match (expr1.into_kind(), expr2.into_kind()) {
+            (
+                HirKind::Class(Unicode(mut c1)),
+                HirKind::Class(Unicode(c2)),
+            ) => {
+                c1.difference(&c2);
+                Hir::class(hir::Class::Unicode(c1))
+            }
+            (
+                HirKind::Class(Bytes(mut c1)),
+                HirKind::Class(Bytes(c2)),
+            ) => {
+                c1.difference(&c2);
+                Hir::class(hir::Class::Bytes(c1))
+            }
+            _ => panic!("cannot difference non-class Hir exprs"),
+        }
+    }
+
+    fn hir_anchor(anchor: hir::Anchor) -> Hir {
+        Hir::anchor(anchor)
+    }
+
+    fn hir_word(wb: hir::WordBoundary) -> Hir {
+        Hir::word_boundary(wb)
+    }
+
+    #[test]
+    fn empty() {
+        assert_eq!(t(""), Hir::empty());
+        assert_eq!(t("(?i)"), Hir::empty());
+        assert_eq!(t("()"), hir_group(1, Hir::empty()));
+        assert_eq!(t("(?:)"), hir_group_nocap(Hir::empty()));
+        assert_eq!(t("(?P<wat>)"), hir_group_name(1, "wat", Hir::empty()));
+        assert_eq!(t("|"), hir_alt(vec![Hir::empty(), Hir::empty()]));
+        assert_eq!(t("()|()"), hir_alt(vec![
+            hir_group(1, Hir::empty()),
+            hir_group(2, Hir::empty()),
+        ]));
+        assert_eq!(t("(|b)"), hir_group(1, hir_alt(vec![
+            Hir::empty(),
+            hir_lit("b"),
+        ])));
+        assert_eq!(t("(a|)"), hir_group(1, hir_alt(vec![
+            hir_lit("a"),
+            Hir::empty(),
+        ])));
+        assert_eq!(t("(a||c)"), hir_group(1, hir_alt(vec![
+            hir_lit("a"),
+            Hir::empty(),
+            hir_lit("c"),
+        ])));
+        assert_eq!(t("(||)"), hir_group(1, hir_alt(vec![
+            Hir::empty(),
+            Hir::empty(),
+            Hir::empty(),
+        ])));
+    }
+
+    #[test]
+    fn literal() {
+        assert_eq!(t("a"), hir_lit("a"));
+        assert_eq!(t("(?-u)a"), hir_lit("a"));
+        assert_eq!(t("☃"), hir_lit("☃"));
+        assert_eq!(t("abcd"), hir_lit("abcd"));
+
+        assert_eq!(t_bytes("(?-u)a"), hir_lit("a"));
+        assert_eq!(t_bytes("(?-u)\x61"), hir_lit("a"));
+        assert_eq!(t_bytes(r"(?-u)\x61"), hir_lit("a"));
+        assert_eq!(t_bytes(r"(?-u)\xFF"), hir_blit(b"\xFF"));
+
+        assert_eq!(t_err("(?-u)☃"), TestError {
+            kind: hir::ErrorKind::UnicodeNotAllowed,
+            span: Span::new(Position::new(5, 1, 6), Position::new(8, 1, 7)),
+        });
+        assert_eq!(t_err(r"(?-u)\xFF"), TestError {
+            kind: hir::ErrorKind::InvalidUtf8,
+            span: Span::new(Position::new(5, 1, 6), Position::new(9, 1, 10)),
+        });
+    }
+
+    #[test]
+    fn literal_case_insensitive() {
+        assert_eq!(t("(?i)a"), hir_uclass(&[
+            ('A', 'A'), ('a', 'a'),
+        ]));
+        assert_eq!(t("(?i:a)"), hir_group_nocap(hir_uclass(&[
+            ('A', 'A'), ('a', 'a')],
+        )));
+        assert_eq!(t("a(?i)a(?-i)a"), hir_cat(vec![
+            hir_lit("a"),
+            hir_uclass(&[('A', 'A'), ('a', 'a')]),
+            hir_lit("a"),
+        ]));
+        assert_eq!(t("(?i)ab@c"), hir_cat(vec![
+            hir_uclass(&[('A', 'A'), ('a', 'a')]),
+            hir_uclass(&[('B', 'B'), ('b', 'b')]),
+            hir_lit("@"),
+            hir_uclass(&[('C', 'C'), ('c', 'c')]),
+        ]));
+        assert_eq!(t("(?i)β"), hir_uclass(&[
+            ('Β', 'Β'), ('β', 'β'), ('ϐ', 'ϐ'),
+        ]));
+
+        assert_eq!(t("(?i-u)a"), hir_bclass(&[
+            (b'A', b'A'), (b'a', b'a'),
+        ]));
+        assert_eq!(t("(?-u)a(?i)a(?-i)a"), hir_cat(vec![
+            hir_lit("a"),
+            hir_bclass(&[(b'A', b'A'), (b'a', b'a')]),
+            hir_lit("a"),
+        ]));
+        assert_eq!(t("(?i-u)ab@c"), hir_cat(vec![
+            hir_bclass(&[(b'A', b'A'), (b'a', b'a')]),
+            hir_bclass(&[(b'B', b'B'), (b'b', b'b')]),
+            hir_lit("@"),
+            hir_bclass(&[(b'C', b'C'), (b'c', b'c')]),
+        ]));
+
+        assert_eq!(t_bytes("(?i-u)a"), hir_bclass(&[
+            (b'A', b'A'), (b'a', b'a'),
+        ]));
+        assert_eq!(t_bytes("(?i-u)\x61"), hir_bclass(&[
+            (b'A', b'A'), (b'a', b'a'),
+        ]));
+        assert_eq!(t_bytes(r"(?i-u)\x61"), hir_bclass(&[
+            (b'A', b'A'), (b'a', b'a'),
+        ]));
+        assert_eq!(t_bytes(r"(?i-u)\xFF"), hir_blit(b"\xFF"));
+
+        assert_eq!(t_err("(?i-u)β"), TestError {
+            kind: hir::ErrorKind::UnicodeNotAllowed,
+            span: Span::new(
+                Position::new(6, 1, 7),
+                Position::new(8, 1, 8),
+            ),
+        });
+    }
+
+    #[test]
+    fn dot() {
+        assert_eq!(t("."), hir_uclass(&[
+            ('\0', '\t'),
+            ('\x0B', '\u{10FFFF}'),
+        ]));
+        assert_eq!(t("(?s)."), hir_uclass(&[
+            ('\0', '\u{10FFFF}'),
+        ]));
+        assert_eq!(t_bytes("(?-u)."), hir_bclass(&[
+            (b'\0', b'\t'),
+            (b'\x0B', b'\xFF'),
+        ]));
+        assert_eq!(t_bytes("(?s-u)."), hir_bclass(&[
+            (b'\0', b'\xFF'),
+        ]));
+
+        // If invalid UTF-8 isn't allowed, then non-Unicode `.` isn't allowed.
+        assert_eq!(t_err("(?-u)."), TestError {
+            kind: hir::ErrorKind::InvalidUtf8,
+            span: Span::new(Position::new(5, 1, 6), Position::new(6, 1, 7)),
+        });
+        assert_eq!(t_err("(?s-u)."), TestError {
+            kind: hir::ErrorKind::InvalidUtf8,
+            span: Span::new(Position::new(6, 1, 7), Position::new(7, 1, 8)),
+        });
+    }
+
+    #[test]
+    fn assertions() {
+        assert_eq!(t("^"), hir_anchor(hir::Anchor::StartText));
+        assert_eq!(t("$"), hir_anchor(hir::Anchor::EndText));
+        assert_eq!(t(r"\A"), hir_anchor(hir::Anchor::StartText));
+        assert_eq!(t(r"\z"), hir_anchor(hir::Anchor::EndText));
+        assert_eq!(t("(?m)^"), hir_anchor(hir::Anchor::StartLine));
+        assert_eq!(t("(?m)$"), hir_anchor(hir::Anchor::EndLine));
+        assert_eq!(t(r"(?m)\A"), hir_anchor(hir::Anchor::StartText));
+        assert_eq!(t(r"(?m)\z"), hir_anchor(hir::Anchor::EndText));
+
+        assert_eq!(t(r"\b"), hir_word(hir::WordBoundary::Unicode));
+        assert_eq!(t(r"\B"), hir_word(hir::WordBoundary::UnicodeNegate));
+        assert_eq!(t(r"(?-u)\b"), hir_word(hir::WordBoundary::Ascii));
+        assert_eq!(
+            t_bytes(r"(?-u)\B"),
+            hir_word(hir::WordBoundary::AsciiNegate));
+
+        assert_eq!(t_err(r"(?-u)\B"), TestError {
+            kind: hir::ErrorKind::InvalidUtf8,
+            span: Span::new(Position::new(5, 1, 6), Position::new(7, 1, 8)),
+        });
+    }
+
+    #[test]
+    fn group() {
+        assert_eq!(t("(a)"), hir_group(1, hir_lit("a")));
+        assert_eq!(t("(a)(b)"), hir_cat(vec![
+            hir_group(1, hir_lit("a")),
+            hir_group(2, hir_lit("b")),
+        ]));
+        assert_eq!(t("(a)|(b)"), hir_alt(vec![
+            hir_group(1, hir_lit("a")),
+            hir_group(2, hir_lit("b")),
+        ]));
+        assert_eq!(t("(?P<foo>)"), hir_group_name(1, "foo", Hir::empty()));
+        assert_eq!(t("(?P<foo>a)"), hir_group_name(1, "foo", hir_lit("a")));
+        assert_eq!(t("(?P<foo>a)(?P<bar>b)"), hir_cat(vec![
+            hir_group_name(1, "foo", hir_lit("a")),
+            hir_group_name(2, "bar", hir_lit("b")),
+        ]));
+        assert_eq!(t("(?:)"), hir_group_nocap(Hir::empty()));
+        assert_eq!(t("(?:a)"), hir_group_nocap(hir_lit("a")));
+        assert_eq!(t("(?:a)(b)"), hir_cat(vec![
+            hir_group_nocap(hir_lit("a")),
+            hir_group(1, hir_lit("b")),
+        ]));
+        assert_eq!(t("(a)(?:b)(c)"), hir_cat(vec![
+            hir_group(1, hir_lit("a")),
+            hir_group_nocap(hir_lit("b")),
+            hir_group(2, hir_lit("c")),
+        ]));
+        assert_eq!(t("(a)(?P<foo>b)(c)"), hir_cat(vec![
+            hir_group(1, hir_lit("a")),
+            hir_group_name(2, "foo", hir_lit("b")),
+            hir_group(3, hir_lit("c")),
+        ]));
+        assert_eq!(t("()"), hir_group(1, Hir::empty()));
+        assert_eq!(t("((?i))"), hir_group(1, Hir::empty()));
+        assert_eq!(t("((?x))"), hir_group(1, Hir::empty()));
+        assert_eq!(t("(((?x)))"), hir_group(1, hir_group(2, Hir::empty())));
+    }
+
+    #[test]
+    fn flags() {
+        assert_eq!(t("(?i:a)a"), hir_cat(vec![
+            hir_group_nocap(hir_uclass(&[('A', 'A'), ('a', 'a')])),
+            hir_lit("a"),
+        ]));
+        assert_eq!(t("(?i-u:a)β"), hir_cat(vec![
+            hir_group_nocap(hir_bclass(&[(b'A', b'A'), (b'a', b'a')])),
+            hir_lit("β"),
+        ]));
+        assert_eq!(t("(?i)(?-i:a)a"), hir_cat(vec![
+            hir_group_nocap(hir_lit("a")),
+            hir_uclass(&[('A', 'A'), ('a', 'a')]),
+        ]));
+        assert_eq!(t("(?im)a^"), hir_cat(vec![
+            hir_uclass(&[('A', 'A'), ('a', 'a')]),
+            hir_anchor(hir::Anchor::StartLine),
+        ]));
+        assert_eq!(t("(?im)a^(?i-m)a^"), hir_cat(vec![
+            hir_uclass(&[('A', 'A'), ('a', 'a')]),
+            hir_anchor(hir::Anchor::StartLine),
+            hir_uclass(&[('A', 'A'), ('a', 'a')]),
+            hir_anchor(hir::Anchor::StartText),
+        ]));
+        assert_eq!(t("(?U)a*a*?(?-U)a*a*?"), hir_cat(vec![
+            hir_star(false, hir_lit("a")),
+            hir_star(true, hir_lit("a")),
+            hir_star(true, hir_lit("a")),
+            hir_star(false, hir_lit("a")),
+        ]));
+        assert_eq!(t("(?:a(?i)a)a"), hir_cat(vec![
+            hir_group_nocap(hir_cat(vec![
+                hir_lit("a"),
+                hir_uclass(&[('A', 'A'), ('a', 'a')]),
+            ])),
+            hir_lit("a"),
+        ]));
+        assert_eq!(t("(?i)(?:a(?-i)a)a"), hir_cat(vec![
+            hir_group_nocap(hir_cat(vec![
+                hir_uclass(&[('A', 'A'), ('a', 'a')]),
+                hir_lit("a"),
+            ])),
+            hir_uclass(&[('A', 'A'), ('a', 'a')]),
+        ]));
+    }
+
+    #[test]
+    fn escape() {
+        assert_eq!(
+            t(r"\\\.\+\*\?\(\)\|\[\]\{\}\^\$\#"),
+            hir_lit(r"\.+*?()|[]{}^$#"));
+    }
+
+    #[test]
+    fn repetition() {
+        assert_eq!(t("a?"), hir_quest(true, hir_lit("a")));
+        assert_eq!(t("a*"), hir_star(true, hir_lit("a")));
+        assert_eq!(t("a+"), hir_plus(true, hir_lit("a")));
+        assert_eq!(t("a??"), hir_quest(false, hir_lit("a")));
+        assert_eq!(t("a*?"), hir_star(false, hir_lit("a")));
+        assert_eq!(t("a+?"), hir_plus(false, hir_lit("a")));
+
+        assert_eq!(
+            t("a{1}"),
+            hir_range(
+                true,
+                hir::RepetitionRange::Exactly(1),
+                hir_lit("a"),
+            ));
+        assert_eq!(
+            t("a{1,}"),
+            hir_range(
+                true,
+                hir::RepetitionRange::AtLeast(1),
+                hir_lit("a"),
+            ));
+        assert_eq!(
+            t("a{1,2}"),
+            hir_range(
+                true,
+                hir::RepetitionRange::Bounded(1, 2),
+                hir_lit("a"),
+            ));
+        assert_eq!(
+            t("a{1}?"),
+            hir_range(
+                false,
+                hir::RepetitionRange::Exactly(1),
+                hir_lit("a"),
+            ));
+        assert_eq!(
+            t("a{1,}?"),
+            hir_range(
+                false,
+                hir::RepetitionRange::AtLeast(1),
+                hir_lit("a"),
+            ));
+        assert_eq!(
+            t("a{1,2}?"),
+            hir_range(
+                false,
+                hir::RepetitionRange::Bounded(1, 2),
+                hir_lit("a"),
+            ));
+
+        assert_eq!(t("ab?"), hir_cat(vec![
+            hir_lit("a"),
+            hir_quest(true, hir_lit("b")),
+        ]));
+        assert_eq!(t("(ab)?"), hir_quest(true, hir_group(1, hir_cat(vec![
+            hir_lit("a"),
+            hir_lit("b"),
+        ]))));
+        assert_eq!(t("a|b?"), hir_alt(vec![
+            hir_lit("a"),
+            hir_quest(true, hir_lit("b")),
+        ]));
+    }
+
+    #[test]
+    fn cat_alt() {
+        assert_eq!(t("(ab)"), hir_group(1, hir_cat(vec![
+            hir_lit("a"),
+            hir_lit("b"),
+        ])));
+        assert_eq!(t("a|b"), hir_alt(vec![
+            hir_lit("a"),
+            hir_lit("b"),
+        ]));
+        assert_eq!(t("a|b|c"), hir_alt(vec![
+            hir_lit("a"),
+            hir_lit("b"),
+            hir_lit("c"),
+        ]));
+        assert_eq!(t("ab|bc|cd"), hir_alt(vec![
+            hir_lit("ab"),
+            hir_lit("bc"),
+            hir_lit("cd"),
+        ]));
+        assert_eq!(t("(a|b)"), hir_group(1, hir_alt(vec![
+            hir_lit("a"),
+            hir_lit("b"),
+        ])));
+        assert_eq!(t("(a|b|c)"), hir_group(1, hir_alt(vec![
+            hir_lit("a"),
+            hir_lit("b"),
+            hir_lit("c"),
+        ])));
+        assert_eq!(t("(ab|bc|cd)"), hir_group(1, hir_alt(vec![
+            hir_lit("ab"),
+            hir_lit("bc"),
+            hir_lit("cd"),
+        ])));
+        assert_eq!(t("(ab|(bc|(cd)))"), hir_group(1, hir_alt(vec![
+            hir_lit("ab"),
+            hir_group(2, hir_alt(vec![
+                hir_lit("bc"),
+                hir_group(3, hir_lit("cd")),
+            ])),
+        ])));
+    }
+
+    #[test]
+    fn class_ascii() {
+        assert_eq!(
+            t("[[:alnum:]]"),
+            hir_uclass(ascii_class(&ast::ClassAsciiKind::Alnum)));
+        assert_eq!(
+            t("[[:alpha:]]"),
+            hir_uclass(ascii_class(&ast::ClassAsciiKind::Alpha)));
+        assert_eq!(
+            t("[[:ascii:]]"),
+            hir_uclass(ascii_class(&ast::ClassAsciiKind::Ascii)));
+        assert_eq!(
+            t("[[:blank:]]"),
+            hir_uclass(ascii_class(&ast::ClassAsciiKind::Blank)));
+        assert_eq!(
+            t("[[:cntrl:]]"),
+            hir_uclass(ascii_class(&ast::ClassAsciiKind::Cntrl)));
+        assert_eq!(
+            t("[[:digit:]]"),
+            hir_uclass(ascii_class(&ast::ClassAsciiKind::Digit)));
+        assert_eq!(
+            t("[[:graph:]]"),
+            hir_uclass(ascii_class(&ast::ClassAsciiKind::Graph)));
+        assert_eq!(
+            t("[[:lower:]]"),
+            hir_uclass(ascii_class(&ast::ClassAsciiKind::Lower)));
+        assert_eq!(
+            t("[[:print:]]"),
+            hir_uclass(ascii_class(&ast::ClassAsciiKind::Print)));
+        assert_eq!(
+            t("[[:punct:]]"),
+            hir_uclass(ascii_class(&ast::ClassAsciiKind::Punct)));
+        assert_eq!(
+            t("[[:space:]]"),
+            hir_uclass(ascii_class(&ast::ClassAsciiKind::Space)));
+        assert_eq!(
+            t("[[:upper:]]"),
+            hir_uclass(ascii_class(&ast::ClassAsciiKind::Upper)));
+        assert_eq!(
+            t("[[:word:]]"),
+            hir_uclass(ascii_class(&ast::ClassAsciiKind::Word)));
+        assert_eq!(
+            t("[[:xdigit:]]"),
+            hir_uclass(ascii_class(&ast::ClassAsciiKind::Xdigit)));
+
+        assert_eq!(
+            t("[[:^lower:]]"),
+            hir_negate(hir_uclass(ascii_class(&ast::ClassAsciiKind::Lower))));
+        assert_eq!(
+            t("(?i)[[:lower:]]"),
+            hir_uclass(&[
+                ('A', 'Z'), ('a', 'z'),
+                ('\u{17F}', '\u{17F}'),
+                ('\u{212A}', '\u{212A}'),
+            ]));
+
+        assert_eq!(
+            t("(?-u)[[:lower:]]"),
+            hir_bclass_from_char(ascii_class(&ast::ClassAsciiKind::Lower)));
+        assert_eq!(
+            t("(?i-u)[[:lower:]]"),
+            hir_case_fold(hir_bclass_from_char(ascii_class(
+                &ast::ClassAsciiKind::Lower))));
+
+        assert_eq!(t_err("(?-u)[[:^lower:]]"), TestError {
+            kind: hir::ErrorKind::InvalidUtf8,
+            span: Span::new(Position::new(6, 1, 7), Position::new(16, 1, 17)),
+        });
+        assert_eq!(t_err("(?i-u)[[:^lower:]]"), TestError {
+            kind: hir::ErrorKind::InvalidUtf8,
+            span: Span::new(Position::new(7, 1, 8), Position::new(17, 1, 18)),
+        });
+    }
+
+    #[test]
+    fn class_perl() {
+        // Unicode
+        assert_eq!(
+            t(r"\d"),
+            hir_uclass_query(ClassQuery::Binary("digit")));
+        assert_eq!(
+            t(r"\s"),
+            hir_uclass_query(ClassQuery::Binary("space")));
+        assert_eq!(
+            t(r"\w"),
+            hir_uclass_perl_word());
+        assert_eq!(
+            t(r"(?i)\d"),
+            hir_uclass_query(ClassQuery::Binary("digit")));
+        assert_eq!(
+            t(r"(?i)\s"),
+            hir_uclass_query(ClassQuery::Binary("space")));
+        assert_eq!(
+            t(r"(?i)\w"),
+            hir_uclass_perl_word());
+
+        // Unicode, negated
+        assert_eq!(
+            t(r"\D"),
+            hir_negate(hir_uclass_query(ClassQuery::Binary("digit"))));
+        assert_eq!(
+            t(r"\S"),
+            hir_negate(hir_uclass_query(ClassQuery::Binary("space"))));
+        assert_eq!(
+            t(r"\W"),
+            hir_negate(hir_uclass_perl_word()));
+        assert_eq!(
+            t(r"(?i)\D"),
+            hir_negate(hir_uclass_query(ClassQuery::Binary("digit"))));
+        assert_eq!(
+            t(r"(?i)\S"),
+            hir_negate(hir_uclass_query(ClassQuery::Binary("space"))));
+        assert_eq!(
+            t(r"(?i)\W"),
+            hir_negate(hir_uclass_perl_word()));
+
+        // ASCII only
+        assert_eq!(
+            t(r"(?-u)\d"),
+            hir_bclass_from_char(ascii_class(&ast::ClassAsciiKind::Digit)));
+        assert_eq!(
+            t(r"(?-u)\s"),
+            hir_bclass_from_char(ascii_class(&ast::ClassAsciiKind::Space)));
+        assert_eq!(
+            t(r"(?-u)\w"),
+            hir_bclass_from_char(ascii_class(&ast::ClassAsciiKind::Word)));
+        assert_eq!(
+            t(r"(?i-u)\d"),
+            hir_bclass_from_char(ascii_class(&ast::ClassAsciiKind::Digit)));
+        assert_eq!(
+            t(r"(?i-u)\s"),
+            hir_bclass_from_char(ascii_class(&ast::ClassAsciiKind::Space)));
+        assert_eq!(
+            t(r"(?i-u)\w"),
+            hir_bclass_from_char(ascii_class(&ast::ClassAsciiKind::Word)));
+
+        // ASCII only, negated
+        assert_eq!(
+            t(r"(?-u)\D"),
+            hir_negate(hir_bclass_from_char(ascii_class(
+                &ast::ClassAsciiKind::Digit))));
+        assert_eq!(
+            t(r"(?-u)\S"),
+            hir_negate(hir_bclass_from_char(ascii_class(
+                &ast::ClassAsciiKind::Space))));
+        assert_eq!(
+            t(r"(?-u)\W"),
+            hir_negate(hir_bclass_from_char(ascii_class(
+                &ast::ClassAsciiKind::Word))));
+        assert_eq!(
+            t(r"(?i-u)\D"),
+            hir_negate(hir_bclass_from_char(ascii_class(
+                &ast::ClassAsciiKind::Digit))));
+        assert_eq!(
+            t(r"(?i-u)\S"),
+            hir_negate(hir_bclass_from_char(ascii_class(
+                &ast::ClassAsciiKind::Space))));
+        assert_eq!(
+            t(r"(?i-u)\W"),
+            hir_negate(hir_bclass_from_char(ascii_class(
+                &ast::ClassAsciiKind::Word))));
+    }
+
+    #[test]
+    fn class_unicode() {
+        assert_eq!(
+            t(r"\pZ"),
+            hir_uclass_query(ClassQuery::Binary("Z")));
+        assert_eq!(
+            t(r"\pz"),
+            hir_uclass_query(ClassQuery::Binary("Z")));
+        assert_eq!(
+            t(r"\p{Separator}"),
+            hir_uclass_query(ClassQuery::Binary("Z")));
+        assert_eq!(
+            t(r"\p{se      PaRa ToR}"),
+            hir_uclass_query(ClassQuery::Binary("Z")));
+        assert_eq!(
+            t(r"\p{gc:Separator}"),
+            hir_uclass_query(ClassQuery::Binary("Z")));
+        assert_eq!(
+            t(r"\p{gc=Separator}"),
+            hir_uclass_query(ClassQuery::Binary("Z")));
+        assert_eq!(
+            t(r"\p{Other}"),
+            hir_uclass_query(ClassQuery::Binary("Other")));
+        assert_eq!(
+            t(r"\pC"),
+            hir_uclass_query(ClassQuery::Binary("Other")));
+
+        assert_eq!(
+            t(r"\PZ"),
+            hir_negate(hir_uclass_query(ClassQuery::Binary("Z"))));
+        assert_eq!(
+            t(r"\P{separator}"),
+            hir_negate(hir_uclass_query(ClassQuery::Binary("Z"))));
+        assert_eq!(
+            t(r"\P{gc!=separator}"),
+            hir_negate(hir_uclass_query(ClassQuery::Binary("Z"))));
+
+        assert_eq!(
+            t(r"\p{Greek}"),
+            hir_uclass_query(ClassQuery::Binary("Greek")));
+        assert_eq!(
+            t(r"(?i)\p{Greek}"),
+            hir_case_fold(hir_uclass_query(ClassQuery::Binary("Greek"))));
+        assert_eq!(
+            t(r"(?i)\P{Greek}"),
+            hir_negate(hir_case_fold(hir_uclass_query(
+                ClassQuery::Binary("Greek")))));
+
+        assert_eq!(
+            t(r"\p{any}"),
+            hir_uclass_query(ClassQuery::Binary("Any")));
+        assert_eq!(
+            t(r"\p{assigned}"),
+            hir_uclass_query(ClassQuery::Binary("Assigned")));
+        assert_eq!(
+            t(r"\p{ascii}"),
+            hir_uclass_query(ClassQuery::Binary("ASCII")));
+        assert_eq!(
+            t(r"\p{gc:any}"),
+            hir_uclass_query(ClassQuery::Binary("Any")));
+        assert_eq!(
+            t(r"\p{gc:assigned}"),
+            hir_uclass_query(ClassQuery::Binary("Assigned")));
+        assert_eq!(
+            t(r"\p{gc:ascii}"),
+            hir_uclass_query(ClassQuery::Binary("ASCII")));
+
+        assert_eq!(t_err(r"(?-u)\pZ"), TestError {
+            kind: hir::ErrorKind::UnicodeNotAllowed,
+            span: Span::new(Position::new(5, 1, 6), Position::new(8, 1, 9)),
+        });
+        assert_eq!(t_err(r"(?-u)\p{Separator}"), TestError {
+            kind: hir::ErrorKind::UnicodeNotAllowed,
+            span: Span::new(Position::new(5, 1, 6), Position::new(18, 1, 19)),
+        });
+        assert_eq!(t_err(r"\pE"), TestError {
+            kind: hir::ErrorKind::UnicodePropertyNotFound,
+            span: Span::new(Position::new(0, 1, 1), Position::new(3, 1, 4)),
+        });
+        assert_eq!(t_err(r"\p{Foo}"), TestError {
+            kind: hir::ErrorKind::UnicodePropertyNotFound,
+            span: Span::new(Position::new(0, 1, 1), Position::new(7, 1, 8)),
+        });
+        assert_eq!(t_err(r"\p{gc:Foo}"), TestError {
+            kind: hir::ErrorKind::UnicodePropertyValueNotFound,
+            span: Span::new(Position::new(0, 1, 1), Position::new(10, 1, 11)),
+        });
+        assert_eq!(t_err(r"\p{sc:Foo}"), TestError {
+            kind: hir::ErrorKind::UnicodePropertyValueNotFound,
+            span: Span::new(Position::new(0, 1, 1), Position::new(10, 1, 11)),
+        });
+        assert_eq!(t_err(r"\p{scx:Foo}"), TestError {
+            kind: hir::ErrorKind::UnicodePropertyValueNotFound,
+            span: Span::new(Position::new(0, 1, 1), Position::new(11, 1, 12)),
+        });
+        assert_eq!(t_err(r"\p{age:Foo}"), TestError {
+            kind: hir::ErrorKind::UnicodePropertyValueNotFound,
+            span: Span::new(Position::new(0, 1, 1), Position::new(11, 1, 12)),
+        });
+    }
+
+    #[test]
+    fn class_bracketed() {
+        assert_eq!(t("[a]"), hir_uclass(&[('a', 'a')]));
+        assert_eq!(t("[^[a]]"), hir_negate(hir_uclass(&[('a', 'a')])));
+        assert_eq!(t("[a-z]"), hir_uclass(&[('a', 'z')]));
+        assert_eq!(t("[a-fd-h]"), hir_uclass(&[('a', 'h')]));
+        assert_eq!(t("[a-fg-m]"), hir_uclass(&[('a', 'm')]));
+        assert_eq!(t(r"[\x00]"), hir_uclass(&[('\0', '\0')]));
+        assert_eq!(t(r"[\n]"), hir_uclass(&[('\n', '\n')]));
+        assert_eq!(t("[\n]"), hir_uclass(&[('\n', '\n')]));
+        assert_eq!(
+            t(r"[\d]"),
+            hir_uclass_query(ClassQuery::Binary("digit")));
+        assert_eq!(
+            t(r"[\pZ]"),
+            hir_uclass_query(ClassQuery::Binary("separator")));
+        assert_eq!(
+            t(r"[\p{separator}]"),
+            hir_uclass_query(ClassQuery::Binary("separator")));
+        assert_eq!(
+            t(r"[^\D]"),
+            hir_uclass_query(ClassQuery::Binary("digit")));
+        assert_eq!(
+            t(r"[^\PZ]"),
+            hir_uclass_query(ClassQuery::Binary("separator")));
+        assert_eq!(
+            t(r"[^\P{separator}]"),
+            hir_uclass_query(ClassQuery::Binary("separator")));
+        assert_eq!(
+            t(r"(?i)[^\D]"),
+            hir_uclass_query(ClassQuery::Binary("digit")));
+        assert_eq!(
+            t(r"(?i)[^\P{greek}]"),
+            hir_case_fold(hir_uclass_query(ClassQuery::Binary("greek"))));
+
+        assert_eq!(t("(?-u)[a]"), hir_bclass(&[(b'a', b'a')]));
+        assert_eq!(t(r"(?-u)[\x00]"), hir_bclass(&[(b'\0', b'\0')]));
+        assert_eq!(t_bytes(r"(?-u)[\xFF]"), hir_bclass(&[(b'\xFF', b'\xFF')]));
+
+        assert_eq!(t("(?i)[a]"), hir_uclass(&[('A', 'A'), ('a', 'a')]));
+        assert_eq!(t("(?i)[k]"), hir_uclass(&[
+            ('K', 'K'), ('k', 'k'), ('\u{212A}', '\u{212A}'),
+        ]));
+        assert_eq!(t("(?i)[β]"), hir_uclass(&[
+            ('Β', 'Β'), ('β', 'β'), ('ϐ', 'ϐ'),
+        ]));
+        assert_eq!(t("(?i-u)[k]"), hir_bclass(&[
+            (b'K', b'K'), (b'k', b'k'),
+        ]));
+
+        assert_eq!(t("[^a]"), hir_negate(hir_uclass(&[('a', 'a')])));
+        assert_eq!(t(r"[^\x00]"), hir_negate(hir_uclass(&[('\0', '\0')])));
+        assert_eq!(
+            t_bytes("(?-u)[^a]"),
+            hir_negate(hir_bclass(&[(b'a', b'a')])));
+        assert_eq!(
+            t(r"[^\d]"),
+            hir_negate(hir_uclass_query(ClassQuery::Binary("digit"))));
+        assert_eq!(
+            t(r"[^\pZ]"),
+            hir_negate(hir_uclass_query(ClassQuery::Binary("separator"))));
+        assert_eq!(
+            t(r"[^\p{separator}]"),
+            hir_negate(hir_uclass_query(ClassQuery::Binary("separator"))));
+        assert_eq!(
+            t(r"(?i)[^\p{greek}]"),
+            hir_negate(hir_case_fold(hir_uclass_query(
+                ClassQuery::Binary("greek")))));
+        assert_eq!(
+            t(r"(?i)[\P{greek}]"),
+            hir_negate(hir_case_fold(hir_uclass_query(
+                ClassQuery::Binary("greek")))));
+
+        // Test some weird cases.
+        assert_eq!(t(r"[\[]"), hir_uclass(&[('[', '[')]));
+
+        assert_eq!(t(r"[&]"), hir_uclass(&[('&', '&')]));
+        assert_eq!(t(r"[\&]"), hir_uclass(&[('&', '&')]));
+        assert_eq!(t(r"[\&\&]"), hir_uclass(&[('&', '&')]));
+        assert_eq!(t(r"[\x00-&]"), hir_uclass(&[('\0', '&')]));
+        assert_eq!(t(r"[&-\xFF]"), hir_uclass(&[('&', '\u{FF}')]));
+
+        assert_eq!(t(r"[~]"), hir_uclass(&[('~', '~')]));
+        assert_eq!(t(r"[\~]"), hir_uclass(&[('~', '~')]));
+        assert_eq!(t(r"[\~\~]"), hir_uclass(&[('~', '~')]));
+        assert_eq!(t(r"[\x00-~]"), hir_uclass(&[('\0', '~')]));
+        assert_eq!(t(r"[~-\xFF]"), hir_uclass(&[('~', '\u{FF}')]));
+
+        assert_eq!(t(r"[-]"), hir_uclass(&[('-', '-')]));
+        assert_eq!(t(r"[\-]"), hir_uclass(&[('-', '-')]));
+        assert_eq!(t(r"[\-\-]"), hir_uclass(&[('-', '-')]));
+        assert_eq!(t(r"[\x00-\-]"), hir_uclass(&[('\0', '-')]));
+        assert_eq!(t(r"[\--\xFF]"), hir_uclass(&[('-', '\u{FF}')]));
+
+        assert_eq!(t_err("(?-u)[^a]"), TestError {
+            kind: hir::ErrorKind::InvalidUtf8,
+            span: Span::new(Position::new(5, 1, 6), Position::new(9, 1, 10)),
+        });
+        assert_eq!(t_err(r"[^\s\S]"), TestError {
+            kind: hir::ErrorKind::EmptyClassNotAllowed,
+            span: Span::new(Position::new(0, 1, 1), Position::new(7, 1, 8)),
+        });
+        assert_eq!(t_err(r"(?-u)[^\s\S]"), TestError {
+            kind: hir::ErrorKind::EmptyClassNotAllowed,
+            span: Span::new(Position::new(5, 1, 6), Position::new(12, 1, 13)),
+        });
+    }
+
+    #[test]
+    fn class_bracketed_union() {
+        assert_eq!(
+            t("[a-zA-Z]"),
+            hir_uclass(&[('A', 'Z'), ('a', 'z')]));
+        assert_eq!(
+            t(r"[a\pZb]"),
+            hir_union(
+                hir_uclass(&[('a', 'b')]),
+                hir_uclass_query(ClassQuery::Binary("separator"))));
+        assert_eq!(
+            t(r"[\pZ\p{Greek}]"),
+            hir_union(
+                hir_uclass_query(ClassQuery::Binary("greek")),
+                hir_uclass_query(ClassQuery::Binary("separator"))));
+        assert_eq!(
+            t(r"[\p{age:3.0}\pZ\p{Greek}]"),
+            hir_union(
+                hir_uclass_query(ClassQuery::ByValue {
+                    property_name: "age",
+                    property_value: "3.0",
+                }),
+                hir_union(
+                    hir_uclass_query(ClassQuery::Binary("greek")),
+                    hir_uclass_query(ClassQuery::Binary("separator")))));
+        assert_eq!(
+            t(r"[[[\p{age:3.0}\pZ]\p{Greek}][\p{Cyrillic}]]"),
+            hir_union(
+                hir_uclass_query(ClassQuery::ByValue {
+                    property_name: "age",
+                    property_value: "3.0",
+                }),
+                hir_union(
+                    hir_uclass_query(ClassQuery::Binary("cyrillic")),
+                    hir_union(
+                        hir_uclass_query(ClassQuery::Binary("greek")),
+                        hir_uclass_query(ClassQuery::Binary("separator"))))));
+
+        assert_eq!(
+            t(r"(?i)[\p{age:3.0}\pZ\p{Greek}]"),
+            hir_case_fold(hir_union(
+                hir_uclass_query(ClassQuery::ByValue {
+                    property_name: "age",
+                    property_value: "3.0",
+                }),
+                hir_union(
+                    hir_uclass_query(ClassQuery::Binary("greek")),
+                    hir_uclass_query(ClassQuery::Binary("separator"))))));
+        assert_eq!(
+            t(r"[^\p{age:3.0}\pZ\p{Greek}]"),
+            hir_negate(hir_union(
+                hir_uclass_query(ClassQuery::ByValue {
+                    property_name: "age",
+                    property_value: "3.0",
+                }),
+                hir_union(
+                    hir_uclass_query(ClassQuery::Binary("greek")),
+                    hir_uclass_query(ClassQuery::Binary("separator"))))));
+        assert_eq!(
+            t(r"(?i)[^\p{age:3.0}\pZ\p{Greek}]"),
+            hir_negate(hir_case_fold(hir_union(
+                hir_uclass_query(ClassQuery::ByValue {
+                    property_name: "age",
+                    property_value: "3.0",
+                }),
+                hir_union(
+                    hir_uclass_query(ClassQuery::Binary("greek")),
+                    hir_uclass_query(ClassQuery::Binary("separator")))))));
+    }
+
+    #[test]
+    fn class_bracketed_nested() {
+        assert_eq!(
+            t(r"[a[^c]]"),
+            hir_negate(hir_uclass(&[('c', 'c')])));
+        assert_eq!(
+            t(r"[a-b[^c]]"),
+            hir_negate(hir_uclass(&[('c', 'c')])));
+        assert_eq!(
+            t(r"[a-c[^c]]"),
+            hir_negate(hir_uclass(&[])));
+
+        assert_eq!(
+            t(r"[^a[^c]]"),
+            hir_uclass(&[('c', 'c')]));
+        assert_eq!(
+            t(r"[^a-b[^c]]"),
+            hir_uclass(&[('c', 'c')]));
+
+        assert_eq!(
+            t(r"(?i)[a[^c]]"),
+            hir_negate(hir_case_fold(hir_uclass(&[('c', 'c')]))));
+        assert_eq!(
+            t(r"(?i)[a-b[^c]]"),
+            hir_negate(hir_case_fold(hir_uclass(&[('c', 'c')]))));
+
+        assert_eq!(
+            t(r"(?i)[^a[^c]]"),
+            hir_uclass(&[('C', 'C'), ('c', 'c')]));
+        assert_eq!(
+            t(r"(?i)[^a-b[^c]]"),
+            hir_uclass(&[('C', 'C'), ('c', 'c')]));
+
+        assert_eq!(t_err(r"[^a-c[^c]]"), TestError {
+            kind: hir::ErrorKind::EmptyClassNotAllowed,
+            span: Span::new(Position::new(0, 1, 1), Position::new(10, 1, 11)),
+        });
+        assert_eq!(t_err(r"(?i)[^a-c[^c]]"), TestError {
+            kind: hir::ErrorKind::EmptyClassNotAllowed,
+            span: Span::new(Position::new(4, 1, 5), Position::new(14, 1, 15)),
+        });
+    }
+
+    #[test]
+    fn class_bracketed_intersect() {
+        assert_eq!(t("[abc&&b-c]"), hir_uclass(&[('b', 'c')]));
+        assert_eq!(t("[abc&&[b-c]]"), hir_uclass(&[('b', 'c')]));
+        assert_eq!(t("[[abc]&&[b-c]]"), hir_uclass(&[('b', 'c')]));
+        assert_eq!(t("[a-z&&b-y&&c-x]"), hir_uclass(&[('c', 'x')]));
+        assert_eq!(t("[c-da-b&&a-d]"), hir_uclass(&[('a', 'd')]));
+        assert_eq!(t("[a-d&&c-da-b]"), hir_uclass(&[('a', 'd')]));
+        assert_eq!(t(r"[a-z&&a-c]"), hir_uclass(&[('a', 'c')]));
+        assert_eq!(t(r"[[a-z&&a-c]]"), hir_uclass(&[('a', 'c')]));
+        assert_eq!(t(r"[^[a-z&&a-c]]"), hir_negate(hir_uclass(&[('a', 'c')])));
+
+        assert_eq!(t("(?-u)[abc&&b-c]"), hir_bclass(&[(b'b', b'c')]));
+        assert_eq!(t("(?-u)[abc&&[b-c]]"), hir_bclass(&[(b'b', b'c')]));
+        assert_eq!(t("(?-u)[[abc]&&[b-c]]"), hir_bclass(&[(b'b', b'c')]));
+        assert_eq!(t("(?-u)[a-z&&b-y&&c-x]"), hir_bclass(&[(b'c', b'x')]));
+        assert_eq!(t("(?-u)[c-da-b&&a-d]"), hir_bclass(&[(b'a', b'd')]));
+        assert_eq!(t("(?-u)[a-d&&c-da-b]"), hir_bclass(&[(b'a', b'd')]));
+
+        assert_eq!(
+            t("(?i)[abc&&b-c]"),
+            hir_case_fold(hir_uclass(&[('b', 'c')])));
+        assert_eq!(
+            t("(?i)[abc&&[b-c]]"),
+            hir_case_fold(hir_uclass(&[('b', 'c')])));
+        assert_eq!(
+            t("(?i)[[abc]&&[b-c]]"),
+            hir_case_fold(hir_uclass(&[('b', 'c')])));
+        assert_eq!(
+            t("(?i)[a-z&&b-y&&c-x]"),
+            hir_case_fold(hir_uclass(&[('c', 'x')])));
+        assert_eq!(
+            t("(?i)[c-da-b&&a-d]"),
+            hir_case_fold(hir_uclass(&[('a', 'd')])));
+        assert_eq!(
+            t("(?i)[a-d&&c-da-b]"),
+            hir_case_fold(hir_uclass(&[('a', 'd')])));
+
+        assert_eq!(
+            t("(?i-u)[abc&&b-c]"),
+            hir_case_fold(hir_bclass(&[(b'b', b'c')])));
+        assert_eq!(
+            t("(?i-u)[abc&&[b-c]]"),
+            hir_case_fold(hir_bclass(&[(b'b', b'c')])));
+        assert_eq!(
+            t("(?i-u)[[abc]&&[b-c]]"),
+            hir_case_fold(hir_bclass(&[(b'b', b'c')])));
+        assert_eq!(
+            t("(?i-u)[a-z&&b-y&&c-x]"),
+            hir_case_fold(hir_bclass(&[(b'c', b'x')])));
+        assert_eq!(
+            t("(?i-u)[c-da-b&&a-d]"),
+            hir_case_fold(hir_bclass(&[(b'a', b'd')])));
+        assert_eq!(
+            t("(?i-u)[a-d&&c-da-b]"),
+            hir_case_fold(hir_bclass(&[(b'a', b'd')])));
+
+        // In `[a^]`, `^` does not need to be escaped, so it makes sense that
+        // `^` is also allowed to be unescaped after `&&`.
+        assert_eq!(t(r"[\^&&^]"), hir_uclass(&[('^', '^')]));
+        // `]` needs to be escaped after `&&` since it's not at start of class.
+        assert_eq!(t(r"[]&&\]]"), hir_uclass(&[(']', ']')]));
+        assert_eq!(t(r"[-&&-]"), hir_uclass(&[('-', '-')]));
+        assert_eq!(t(r"[\&&&&]"), hir_uclass(&[('&', '&')]));
+        assert_eq!(t(r"[\&&&\&]"), hir_uclass(&[('&', '&')]));
+        // Test precedence.
+        assert_eq!(
+            t(r"[a-w&&[^c-g]z]"),
+            hir_uclass(&[('a', 'b'), ('h', 'w')]));
+    }
+
+    #[test]
+    fn class_bracketed_intersect_negate() {
+        assert_eq!(
+            t(r"[^\w&&\d]"),
+            hir_negate(hir_uclass_query(ClassQuery::Binary("digit"))));
+        assert_eq!(
+            t(r"[^[a-z&&a-c]]"),
+            hir_negate(hir_uclass(&[('a', 'c')])));
+        assert_eq!(
+            t(r"[^[\w&&\d]]"),
+            hir_negate(hir_uclass_query(ClassQuery::Binary("digit"))));
+        assert_eq!(
+            t(r"[^[^\w&&\d]]"),
+            hir_uclass_query(ClassQuery::Binary("digit")));
+        assert_eq!(
+            t(r"[[[^\w]&&[^\d]]]"),
+            hir_negate(hir_uclass_perl_word()));
+
+        assert_eq!(
+            t_bytes(r"(?-u)[^\w&&\d]"),
+            hir_negate(hir_bclass_from_char(ascii_class(
+                &ast::ClassAsciiKind::Digit))));
+        assert_eq!(
+            t_bytes(r"(?-u)[^[a-z&&a-c]]"),
+            hir_negate(hir_bclass(&[(b'a', b'c')])));
+        assert_eq!(
+            t_bytes(r"(?-u)[^[\w&&\d]]"),
+            hir_negate(hir_bclass_from_char(ascii_class(
+                &ast::ClassAsciiKind::Digit))));
+        assert_eq!(
+            t_bytes(r"(?-u)[^[^\w&&\d]]"),
+            hir_bclass_from_char(ascii_class(
+                &ast::ClassAsciiKind::Digit)));
+        assert_eq!(
+            t_bytes(r"(?-u)[[[^\w]&&[^\d]]]"),
+            hir_negate(hir_bclass_from_char(ascii_class(
+                &ast::ClassAsciiKind::Word))));
+    }
+
+    #[test]
+    fn class_bracketed_difference() {
+        assert_eq!(
+            t(r"[\pL--[:ascii:]]"),
+            hir_difference(
+                hir_uclass_query(ClassQuery::Binary("letter")),
+                hir_uclass(&[('\0', '\x7F')])));
+
+        assert_eq!(
+            t(r"(?-u)[[:alpha:]--[:lower:]]"),
+            hir_bclass(&[(b'A', b'Z')]));
+    }
+
+    #[test]
+    fn class_bracketed_symmetric_difference() {
+        assert_eq!(
+            t(r"[\p{sc:Greek}~~\p{scx:Greek}]"),
+            hir_uclass(&[
+                ('\u{0342}', '\u{0342}'),
+                ('\u{0345}', '\u{0345}'),
+                ('\u{1DC0}', '\u{1DC1}'),
+            ]));
+        assert_eq!(
+            t(r"[a-g~~c-j]"),
+            hir_uclass(&[('a', 'b'), ('h', 'j')]));
+
+        assert_eq!(
+            t(r"(?-u)[a-g~~c-j]"),
+            hir_bclass(&[(b'a', b'b'), (b'h', b'j')]));
+    }
+
+    #[test]
+    fn ignore_whitespace() {
+        assert_eq!(t(r"(?x)\12 3"), hir_lit("\n3"));
+        assert_eq!(t(r"(?x)\x { 53 }"), hir_lit("S"));
+        assert_eq!(t(r"(?x)\x # comment
+{ # comment
+    53 # comment
+} #comment"), hir_lit("S"));
+
+        assert_eq!(t(r"(?x)\x 53"), hir_lit("S"));
+        assert_eq!(t(r"(?x)\x # comment
+        53 # comment"), hir_lit("S"));
+        assert_eq!(t(r"(?x)\x5 3"), hir_lit("S"));
+
+        assert_eq!(t(r"(?x)\p # comment
+{ # comment
+    Separator # comment
+} # comment"), hir_uclass_query(ClassQuery::Binary("separator")));
+
+        assert_eq!(t(r"(?x)a # comment
+{ # comment
+    5 # comment
+    , # comment
+    10 # comment
+} # comment"),
+            hir_range(
+                true, hir::RepetitionRange::Bounded(5, 10), hir_lit("a")));
+
+        assert_eq!(t(r"(?x)a\  # hi there"), hir_lit("a "));
+    }
+
+    #[test]
+    fn analysis_is_always_utf8() {
+        // Positive examples.
+        assert!(t_bytes(r"a").is_always_utf8());
+        assert!(t_bytes(r"ab").is_always_utf8());
+        assert!(t_bytes(r"(?-u)a").is_always_utf8());
+        assert!(t_bytes(r"(?-u)ab").is_always_utf8());
+        assert!(t_bytes(r"\xFF").is_always_utf8());
+        assert!(t_bytes(r"\xFF\xFF").is_always_utf8());
+        assert!(t_bytes(r"[^a]").is_always_utf8());
+        assert!(t_bytes(r"[^a][^a]").is_always_utf8());
+        assert!(t_bytes(r"\b").is_always_utf8());
+        assert!(t_bytes(r"\B").is_always_utf8());
+        assert!(t_bytes(r"(?-u)\b").is_always_utf8());
+
+        // Negative examples.
+        assert!(!t_bytes(r"(?-u)\xFF").is_always_utf8());
+        assert!(!t_bytes(r"(?-u)\xFF\xFF").is_always_utf8());
+        assert!(!t_bytes(r"(?-u)[^a]").is_always_utf8());
+        assert!(!t_bytes(r"(?-u)[^a][^a]").is_always_utf8());
+        assert!(!t_bytes(r"(?-u)\B").is_always_utf8());
+    }
+
+    #[test]
+    fn analysis_is_all_assertions() {
+        // Positive examples.
+        assert!(t(r"\b").is_all_assertions());
+        assert!(t(r"\B").is_all_assertions());
+        assert!(t(r"^").is_all_assertions());
+        assert!(t(r"$").is_all_assertions());
+        assert!(t(r"\A").is_all_assertions());
+        assert!(t(r"\z").is_all_assertions());
+        assert!(t(r"$^\z\A\b\B").is_all_assertions());
+        assert!(t(r"$|^|\z|\A|\b|\B").is_all_assertions());
+        assert!(t(r"^$|$^").is_all_assertions());
+        assert!(t(r"((\b)+())*^").is_all_assertions());
+
+        // Negative examples.
+        assert!(!t(r"^a").is_all_assertions());
+    }
+
+    #[test]
+    fn analysis_is_anchored() {
+        // Positive examples.
+        assert!(t(r"^").is_anchored_start());
+        assert!(t(r"$").is_anchored_end());
+        assert!(t(r"^").is_line_anchored_start());
+        assert!(t(r"$").is_line_anchored_end());
+
+        assert!(t(r"^^").is_anchored_start());
+        assert!(t(r"$$").is_anchored_end());
+        assert!(t(r"^^").is_line_anchored_start());
+        assert!(t(r"$$").is_line_anchored_end());
+
+        assert!(t(r"^$").is_anchored_start());
+        assert!(t(r"^$").is_anchored_end());
+        assert!(t(r"^$").is_line_anchored_start());
+        assert!(t(r"^$").is_line_anchored_end());
+
+        assert!(t(r"^foo").is_anchored_start());
+        assert!(t(r"foo$").is_anchored_end());
+        assert!(t(r"^foo").is_line_anchored_start());
+        assert!(t(r"foo$").is_line_anchored_end());
+
+        assert!(t(r"^foo|^bar").is_anchored_start());
+        assert!(t(r"foo$|bar$").is_anchored_end());
+        assert!(t(r"^foo|^bar").is_line_anchored_start());
+        assert!(t(r"foo$|bar$").is_line_anchored_end());
+
+        assert!(t(r"^(foo|bar)").is_anchored_start());
+        assert!(t(r"(foo|bar)$").is_anchored_end());
+        assert!(t(r"^(foo|bar)").is_line_anchored_start());
+        assert!(t(r"(foo|bar)$").is_line_anchored_end());
+
+        assert!(t(r"^+").is_anchored_start());
+        assert!(t(r"$+").is_anchored_end());
+        assert!(t(r"^+").is_line_anchored_start());
+        assert!(t(r"$+").is_line_anchored_end());
+        assert!(t(r"^++").is_anchored_start());
+        assert!(t(r"$++").is_anchored_end());
+        assert!(t(r"^++").is_line_anchored_start());
+        assert!(t(r"$++").is_line_anchored_end());
+        assert!(t(r"(^)+").is_anchored_start());
+        assert!(t(r"($)+").is_anchored_end());
+        assert!(t(r"(^)+").is_line_anchored_start());
+        assert!(t(r"($)+").is_line_anchored_end());
+
+        assert!(t(r"$^").is_anchored_start());
+        assert!(t(r"$^").is_anchored_start());
+        assert!(t(r"$^").is_line_anchored_end());
+        assert!(t(r"$^").is_line_anchored_end());
+        assert!(t(r"$^|^$").is_anchored_start());
+        assert!(t(r"$^|^$").is_anchored_end());
+        assert!(t(r"$^|^$").is_line_anchored_start());
+        assert!(t(r"$^|^$").is_line_anchored_end());
+
+        assert!(t(r"\b^").is_anchored_start());
+        assert!(t(r"$\b").is_anchored_end());
+        assert!(t(r"\b^").is_line_anchored_start());
+        assert!(t(r"$\b").is_line_anchored_end());
+        assert!(t(r"^(?m:^)").is_anchored_start());
+        assert!(t(r"(?m:$)$").is_anchored_end());
+        assert!(t(r"^(?m:^)").is_line_anchored_start());
+        assert!(t(r"(?m:$)$").is_line_anchored_end());
+        assert!(t(r"(?m:^)^").is_anchored_start());
+        assert!(t(r"$(?m:$)").is_anchored_end());
+        assert!(t(r"(?m:^)^").is_line_anchored_start());
+        assert!(t(r"$(?m:$)").is_line_anchored_end());
+
+        // Negative examples.
+        assert!(!t(r"(?m)^").is_anchored_start());
+        assert!(!t(r"(?m)$").is_anchored_end());
+        assert!(!t(r"(?m:^$)|$^").is_anchored_start());
+        assert!(!t(r"(?m:^$)|$^").is_anchored_end());
+        assert!(!t(r"$^|(?m:^$)").is_anchored_start());
+        assert!(!t(r"$^|(?m:^$)").is_anchored_end());
+
+        assert!(!t(r"a^").is_anchored_start());
+        assert!(!t(r"$a").is_anchored_start());
+        assert!(!t(r"a^").is_line_anchored_start());
+        assert!(!t(r"$a").is_line_anchored_start());
+
+        assert!(!t(r"a^").is_anchored_end());
+        assert!(!t(r"$a").is_anchored_end());
+        assert!(!t(r"a^").is_line_anchored_end());
+        assert!(!t(r"$a").is_line_anchored_end());
+
+        assert!(!t(r"^foo|bar").is_anchored_start());
+        assert!(!t(r"foo|bar$").is_anchored_end());
+        assert!(!t(r"^foo|bar").is_line_anchored_start());
+        assert!(!t(r"foo|bar$").is_line_anchored_end());
+
+        assert!(!t(r"^*").is_anchored_start());
+        assert!(!t(r"$*").is_anchored_end());
+        assert!(!t(r"^*").is_line_anchored_start());
+        assert!(!t(r"$*").is_line_anchored_end());
+        assert!(!t(r"^*+").is_anchored_start());
+        assert!(!t(r"$*+").is_anchored_end());
+        assert!(!t(r"^*+").is_line_anchored_start());
+        assert!(!t(r"$*+").is_line_anchored_end());
+        assert!(!t(r"^+*").is_anchored_start());
+        assert!(!t(r"$+*").is_anchored_end());
+        assert!(!t(r"^+*").is_line_anchored_start());
+        assert!(!t(r"$+*").is_line_anchored_end());
+        assert!(!t(r"(^)*").is_anchored_start());
+        assert!(!t(r"($)*").is_anchored_end());
+        assert!(!t(r"(^)*").is_line_anchored_start());
+        assert!(!t(r"($)*").is_line_anchored_end());
+    }
+
+    #[test]
+    fn analysis_is_line_anchored() {
+        assert!(t(r"(?m)^(foo|bar)").is_line_anchored_start());
+        assert!(t(r"(?m)(foo|bar)$").is_line_anchored_end());
+
+        assert!(t(r"(?m)^foo|^bar").is_line_anchored_start());
+        assert!(t(r"(?m)foo$|bar$").is_line_anchored_end());
+
+        assert!(t(r"(?m)^").is_line_anchored_start());
+        assert!(t(r"(?m)$").is_line_anchored_end());
+
+        assert!(t(r"(?m:^$)|$^").is_line_anchored_start());
+        assert!(t(r"(?m:^$)|$^").is_line_anchored_end());
+
+        assert!(t(r"$^|(?m:^$)").is_line_anchored_start());
+        assert!(t(r"$^|(?m:^$)").is_line_anchored_end());
+    }
+
+    #[test]
+    fn analysis_is_any_anchored() {
+        // Positive examples.
+        assert!(t(r"^").is_any_anchored_start());
+        assert!(t(r"$").is_any_anchored_end());
+        assert!(t(r"\A").is_any_anchored_start());
+        assert!(t(r"\z").is_any_anchored_end());
+
+        // Negative examples.
+        assert!(!t(r"(?m)^").is_any_anchored_start());
+        assert!(!t(r"(?m)$").is_any_anchored_end());
+        assert!(!t(r"$").is_any_anchored_start());
+        assert!(!t(r"^").is_any_anchored_end());
+    }
+
+    #[test]
+    fn analysis_is_match_empty() {
+        // Positive examples.
+        assert!(t(r"").is_match_empty());
+        assert!(t(r"()").is_match_empty());
+        assert!(t(r"()*").is_match_empty());
+        assert!(t(r"()+").is_match_empty());
+        assert!(t(r"()?").is_match_empty());
+        assert!(t(r"a*").is_match_empty());
+        assert!(t(r"a?").is_match_empty());
+        assert!(t(r"a{0}").is_match_empty());
+        assert!(t(r"a{0,}").is_match_empty());
+        assert!(t(r"a{0,1}").is_match_empty());
+        assert!(t(r"a{0,10}").is_match_empty());
+        assert!(t(r"\pL*").is_match_empty());
+        assert!(t(r"a*|b").is_match_empty());
+        assert!(t(r"b|a*").is_match_empty());
+        assert!(t(r"a*a?(abcd)*").is_match_empty());
+        assert!(t(r"^").is_match_empty());
+        assert!(t(r"$").is_match_empty());
+        assert!(t(r"(?m)^").is_match_empty());
+        assert!(t(r"(?m)$").is_match_empty());
+        assert!(t(r"\A").is_match_empty());
+        assert!(t(r"\z").is_match_empty());
+        assert!(t(r"\B").is_match_empty());
+        assert!(t_bytes(r"(?-u)\B").is_match_empty());
+
+        // Negative examples.
+        assert!(!t(r"a+").is_match_empty());
+        assert!(!t(r"a{1}").is_match_empty());
+        assert!(!t(r"a{1,}").is_match_empty());
+        assert!(!t(r"a{1,2}").is_match_empty());
+        assert!(!t(r"a{1,10}").is_match_empty());
+        assert!(!t(r"b|a").is_match_empty());
+        assert!(!t(r"a*a+(abcd)*").is_match_empty());
+        assert!(!t(r"\b").is_match_empty());
+        assert!(!t(r"(?-u)\b").is_match_empty());
+    }
+
+    #[test]
+    fn analysis_is_literal() {
+        // Positive examples.
+        assert!(t(r"").is_literal());
+        assert!(t(r"a").is_literal());
+        assert!(t(r"ab").is_literal());
+        assert!(t(r"abc").is_literal());
+        assert!(t(r"(?m)abc").is_literal());
+
+        // Negative examples.
+        assert!(!t(r"^").is_literal());
+        assert!(!t(r"a|b").is_literal());
+        assert!(!t(r"(a)").is_literal());
+        assert!(!t(r"a+").is_literal());
+        assert!(!t(r"foo(a)").is_literal());
+        assert!(!t(r"(a)foo").is_literal());
+        assert!(!t(r"[a]").is_literal());
+    }
+
+    #[test]
+    fn analysis_is_alternation_literal() {
+        // Positive examples.
+        assert!(t(r"").is_alternation_literal());
+        assert!(t(r"a").is_alternation_literal());
+        assert!(t(r"ab").is_alternation_literal());
+        assert!(t(r"abc").is_alternation_literal());
+        assert!(t(r"(?m)abc").is_alternation_literal());
+        assert!(t(r"a|b").is_alternation_literal());
+        assert!(t(r"a|b|c").is_alternation_literal());
+        assert!(t(r"foo|bar").is_alternation_literal());
+        assert!(t(r"foo|bar|baz").is_alternation_literal());
+
+        // Negative examples.
+        assert!(!t(r"^").is_alternation_literal());
+        assert!(!t(r"(a)").is_alternation_literal());
+        assert!(!t(r"a+").is_alternation_literal());
+        assert!(!t(r"foo(a)").is_alternation_literal());
+        assert!(!t(r"(a)foo").is_alternation_literal());
+        assert!(!t(r"[a]").is_alternation_literal());
+        assert!(!t(r"[a]|b").is_alternation_literal());
+        assert!(!t(r"a|[b]").is_alternation_literal());
+        assert!(!t(r"(a)|b").is_alternation_literal());
+        assert!(!t(r"a|(b)").is_alternation_literal());
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/hir/visitor.rs.html b/target/doc/src/regex_syntax/hir/visitor.rs.html new file mode 100644 index 0000000..16102d9 --- /dev/null +++ b/target/doc/src/regex_syntax/hir/visitor.rs.html @@ -0,0 +1,447 @@ +visitor.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use hir::{self, Hir, HirKind};
+
+/// A trait for visiting the high-level IR (HIR) in depth first order.
+///
+/// The principle aim of this trait is to enable callers to perform case
+/// analysis on a high-level intermediate representation of a regular
+/// expression without necessarily using recursion. In particular, this permits
+/// callers to do case analysis with constant stack usage, which can be
+/// important since the size of an HIR may be proportional to end user input.
+///
+/// Typical usage of this trait involves providing an implementation and then
+/// running it using the [`visit`](fn.visit.html) function.
+pub trait Visitor {
+    /// The result of visiting an HIR.
+    type Output;
+    /// An error that visiting an HIR might return.
+    type Err;
+
+    /// All implementors of `Visitor` must provide a `finish` method, which
+    /// yields the result of visiting the HIR or an error.
+    fn finish(self) -> Result<Self::Output, Self::Err>;
+
+    /// This method is called before beginning traversal of the HIR.
+    fn start(&mut self) {}
+
+    /// This method is called on an `Hir` before descending into child `Hir`
+    /// nodes.
+    fn visit_pre(&mut self, _hir: &Hir) -> Result<(), Self::Err> {
+        Ok(())
+    }
+
+    /// This method is called on an `Hir` after descending all of its child
+    /// `Hir` nodes.
+    fn visit_post(&mut self, _hir: &Hir) -> Result<(), Self::Err> {
+        Ok(())
+    }
+
+    /// This method is called between child nodes of an alternation.
+    fn visit_alternation_in(&mut self) -> Result<(), Self::Err> {
+        Ok(())
+    }
+}
+
+/// Executes an implementation of `Visitor` in constant stack space.
+///
+/// This function will visit every node in the given `Hir` while calling
+/// appropriate methods provided by the
+/// [`Visitor`](trait.Visitor.html) trait.
+///
+/// The primary use case for this method is when one wants to perform case
+/// analysis over an `Hir` without using a stack size proportional to the depth
+/// of the `Hir`. Namely, this method will instead use constant stack space,
+/// but will use heap space proportional to the size of the `Hir`. This may be
+/// desirable in cases where the size of `Hir` is proportional to end user
+/// input.
+///
+/// If the visitor returns an error at any point, then visiting is stopped and
+/// the error is returned.
+pub fn visit<V: Visitor>(hir: &Hir, visitor: V) -> Result<V::Output, V::Err> {
+    HeapVisitor::new().visit(hir, visitor)
+}
+
+/// HeapVisitor visits every item in an `Hir` recursively using constant stack
+/// size and a heap size proportional to the size of the `Hir`.
+struct HeapVisitor<'a> {
+    /// A stack of `Hir` nodes. This is roughly analogous to the call stack
+    /// used in a typical recursive visitor.
+    stack: Vec<(&'a Hir, Frame<'a>)>,
+}
+
+/// Represents a single stack frame while performing structural induction over
+/// an `Hir`.
+enum Frame<'a> {
+    /// A stack frame allocated just before descending into a repetition
+    /// operator's child node.
+    Repetition(&'a hir::Repetition),
+    /// A stack frame allocated just before descending into a group's child
+    /// node.
+    Group(&'a hir::Group),
+    /// The stack frame used while visiting every child node of a concatenation
+    /// of expressions.
+    Concat {
+        /// The child node we are currently visiting.
+        head: &'a Hir,
+        /// The remaining child nodes to visit (which may be empty).
+        tail: &'a [Hir],
+    },
+    /// The stack frame used while visiting every child node of an alternation
+    /// of expressions.
+    Alternation {
+        /// The child node we are currently visiting.
+        head: &'a Hir,
+        /// The remaining child nodes to visit (which may be empty).
+        tail: &'a [Hir],
+    },
+}
+
+impl<'a> HeapVisitor<'a> {
+    fn new() -> HeapVisitor<'a> {
+        HeapVisitor { stack: vec![] }
+    }
+
+    fn visit<V: Visitor>(
+        &mut self,
+        mut hir: &'a Hir,
+        mut visitor: V,
+    ) -> Result<V::Output, V::Err> {
+        self.stack.clear();
+
+        visitor.start();
+        loop {
+            visitor.visit_pre(hir)?;
+            if let Some(x) = self.induct(hir) {
+                let child = x.child();
+                self.stack.push((hir, x));
+                hir = child;
+                continue;
+            }
+            // No induction means we have a base case, so we can post visit
+            // it now.
+            visitor.visit_post(hir)?;
+
+            // At this point, we now try to pop our call stack until it is
+            // either empty or we hit another inductive case.
+            loop {
+                let (post_hir, frame) = match self.stack.pop() {
+                    None => return visitor.finish(),
+                    Some((post_hir, frame)) => (post_hir, frame),
+                };
+                // If this is a concat/alternate, then we might have additional
+                // inductive steps to process.
+                if let Some(x) = self.pop(frame) {
+                    if let Frame::Alternation {..} = x {
+                        visitor.visit_alternation_in()?;
+                    }
+                    hir = x.child();
+                    self.stack.push((post_hir, x));
+                    break;
+                }
+                // Otherwise, we've finished visiting all the child nodes for
+                // this HIR, so we can post visit it now.
+                visitor.visit_post(post_hir)?;
+            }
+        }
+    }
+
+    /// Build a stack frame for the given HIR if one is needed (which occurs if
+    /// and only if there are child nodes in the HIR). Otherwise, return None.
+    fn induct(&mut self, hir: &'a Hir) -> Option<Frame<'a>> {
+        match *hir.kind() {
+            HirKind::Repetition(ref x) => Some(Frame::Repetition(x)),
+            HirKind::Group(ref x) => Some(Frame::Group(x)),
+            HirKind::Concat(ref x) if x.is_empty() => None,
+            HirKind::Concat(ref x) => {
+                Some(Frame::Concat {
+                    head: &x[0],
+                    tail: &x[1..],
+                })
+            }
+            HirKind::Alternation(ref x) if x.is_empty() => None,
+            HirKind::Alternation(ref x) => {
+                Some(Frame::Alternation {
+                    head: &x[0],
+                    tail: &x[1..],
+                })
+            }
+            _ => None,
+        }
+    }
+
+    /// Pops the given frame. If the frame has an additional inductive step,
+    /// then return it, otherwise return `None`.
+    fn pop(&self, induct: Frame<'a>) -> Option<Frame<'a>> {
+        match induct {
+            Frame::Repetition(_) => None,
+            Frame::Group(_) => None,
+            Frame::Concat { tail, .. } => {
+                if tail.is_empty() {
+                    None
+                } else {
+                    Some(Frame::Concat {
+                        head: &tail[0],
+                        tail: &tail[1..],
+                    })
+                }
+            }
+            Frame::Alternation { tail, .. } => {
+                if tail.is_empty() {
+                    None
+                } else {
+                    Some(Frame::Alternation {
+                        head: &tail[0],
+                        tail: &tail[1..],
+                    })
+                }
+            }
+        }
+    }
+}
+
+impl<'a> Frame<'a> {
+    /// Perform the next inductive step on this frame and return the next
+    /// child HIR node to visit.
+    fn child(&self) -> &'a Hir {
+        match *self {
+            Frame::Repetition(rep) => &rep.hir,
+            Frame::Group(group) => &group.hir,
+            Frame::Concat { head, .. } => head,
+            Frame::Alternation { head, .. } => head,
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/lib.rs.html b/target/doc/src/regex_syntax/lib.rs.html new file mode 100644 index 0000000..f71c287 --- /dev/null +++ b/target/doc/src/regex_syntax/lib.rs.html @@ -0,0 +1,459 @@ +lib.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+This crate provides a robust regular expression parser.
+
+This crate defines two primary types:
+
+* [`Ast`](ast/enum.Ast.html) is the abstract syntax of a regular expression.
+  An abstract syntax corresponds to a *structured representation* of the
+  concrete syntax of a regular expression, where the concrete syntax is the
+  pattern string itself (e.g., `foo(bar)+`). Given some abstract syntax, it
+  can be converted back to the original concrete syntax (modulo some details,
+  like whitespace). To a first approximation, the abstract syntax is complex
+  and difficult to analyze.
+* [`Hir`](hir/struct.Hir.html) is the high-level intermediate representation
+  ("HIR" or "high-level IR" for short) of regular expression. It corresponds to
+  an intermediate state of a regular expression that sits between the abstract
+  syntax and the low level compiled opcodes that are eventually responsible for
+  executing a regular expression search. Given some high-level IR, it is not
+  possible to produce the original concrete syntax (although it is possible to
+  produce an equivalent concrete syntax, but it will likely scarcely resemble
+  the original pattern). To a first approximation, the high-level IR is simple
+  and easy to analyze.
+
+These two types come with conversion routines:
+
+* An [`ast::parse::Parser`](ast/parse/struct.Parser.html) converts concrete
+  syntax (a `&str`) to an [`Ast`](ast/enum.Ast.html).
+* A [`hir::translate::Translator`](hir/translate/struct.Translator.html)
+  converts an [`Ast`](ast/enum.Ast.html) to a [`Hir`](hir/struct.Hir.html).
+
+As a convenience, the above two conversion routines are combined into one via
+the top-level [`Parser`](struct.Parser.html) type. This `Parser` will first
+convert your pattern to an `Ast` and then convert the `Ast` to an `Hir`.
+
+
+# Example
+
+This example shows how to parse a pattern string into its HIR:
+
+```
+use regex_syntax::Parser;
+use regex_syntax::hir::{self, Hir};
+
+let hir = Parser::new().parse("a|b").unwrap();
+assert_eq!(hir, Hir::alternation(vec![
+    Hir::literal(hir::Literal::Unicode('a')),
+    Hir::literal(hir::Literal::Unicode('b')),
+]));
+```
+
+
+# Concrete syntax supported
+
+The concrete syntax is documented as part of the public API of the
+[`regex` crate](https://docs.rs/regex/%2A/regex/#syntax).
+
+
+# Input safety
+
+A key feature of this library is that it is safe to use with end user facing
+input. This plays a significant role in the internal implementation. In
+particular:
+
+1. Parsers provide a `nest_limit` option that permits callers to control how
+   deeply nested a regular expression is allowed to be. This makes it possible
+   to do case analysis over an `Ast` or an `Hir` using recursion without
+   worrying about stack overflow.
+2. Since relying on a particular stack size is brittle, this crate goes to
+   great lengths to ensure that all interactions with both the `Ast` and the
+   `Hir` do not use recursion. Namely, they use constant stack space and heap
+   space proportional to the size of the original pattern string (in bytes).
+   This includes the type's corresponding destructors. (One exception to this
+   is literal extraction, but this will eventually get fixed.)
+
+
+# Error reporting
+
+The `Display` implementations on all `Error` types exposed in this library
+provide nice human readable errors that are suitable for showing to end users
+in a monospace font.
+
+
+# Literal extraction
+
+This crate provides limited support for
+[literal extraction from `Hir` values](hir/literal/struct.Literals.html).
+Be warned that literal extraction currently uses recursion, and therefore,
+stack size proportional to the size of the `Hir`.
+
+The purpose of literal extraction is to speed up searches. That is, if you
+know a regular expression must match a prefix or suffix literal, then it is
+often quicker to search for instances of that literal, and then confirm or deny
+the match using the full regular expression engine. These optimizations are
+done automatically in the `regex` crate.
+*/
+
+#![deny(missing_docs)]
+
+extern crate ucd_util;
+
+pub use error::{Error, Result};
+pub use parser::{Parser, ParserBuilder};
+
+pub mod ast;
+mod either;
+mod error;
+pub mod hir;
+mod parser;
+mod unicode;
+mod unicode_tables;
+
+/// Escapes all regular expression meta characters in `text`.
+///
+/// The string returned may be safely used as a literal in a regular
+/// expression.
+pub fn escape(text: &str) -> String {
+    let mut quoted = String::with_capacity(text.len());
+    escape_into(text, &mut quoted);
+    quoted
+}
+
+/// Escapes all meta characters in `text` and writes the result into `buf`.
+///
+/// This will append escape characters into the given buffer. The characters
+/// that are appended are safe to use as a literal in a regular expression.
+pub fn escape_into(text: &str, buf: &mut String) {
+    for c in text.chars() {
+        if is_meta_character(c) {
+            buf.push('\\');
+        }
+        buf.push(c);
+    }
+}
+
+/// Returns true if the give character has significance in a regex.
+///
+/// These are the only characters that are allowed to be escaped, with one
+/// exception: an ASCII space character may be escaped when extended mode (with
+/// the `x` flag) is enabld. In particular, `is_meta_character(' ')` returns
+/// `false`.
+///
+/// Note that the set of characters for which this function returns `true` or
+/// `false` is fixed and won't change in a semver compatible release.
+pub fn is_meta_character(c: char) -> bool {
+    match c {
+        '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' |
+        '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~' => true,
+        _ => false,
+    }
+}
+
+/// Returns true if and only if the given character is a Unicode word
+/// character.
+///
+/// A Unicode word character is defined by
+/// [UTS#18 Annex C](http://unicode.org/reports/tr18/#Compatibility_Properties).
+/// In particular, a character
+/// is considered a word character if it is in either of the `Alphabetic` or
+/// `Join_Control` properties, or is in one of the `Decimal_Number`, `Mark`
+/// or `Connector_Punctuation` general categories.
+pub fn is_word_character(c: char) -> bool {
+    use std::cmp::Ordering;
+    use unicode_tables::perl_word::PERL_WORD;
+
+    if c <= 0x7F as char && is_word_byte(c as u8) {
+        return true;
+    }
+    PERL_WORD
+        .binary_search_by(|&(start, end)| {
+            if start <= c && c <= end {
+                Ordering::Equal
+            } else if start > c {
+                Ordering::Greater
+            } else {
+                Ordering::Less
+            }
+        }).is_ok()
+}
+
+/// Returns true if and only if the given character is an ASCII word character.
+///
+/// An ASCII word character is defined by the following character class:
+/// `[_0-9a-zA-Z]'.
+pub fn is_word_byte(c: u8) -> bool {
+    match c {
+        b'_' | b'0' ..= b'9' | b'a' ..= b'z' | b'A' ..= b'Z'  => true,
+        _ => false,
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn escape_meta() {
+        assert_eq!(
+            escape(r"\.+*?()|[]{}^$#&-~"),
+            r"\\\.\+\*\?\(\)\|\[\]\{\}\^\$\#\&\-\~".to_string());
+    }
+
+    #[test]
+    fn word() {
+        assert!(is_word_byte(b'a'));
+        assert!(!is_word_byte(b'-'));
+
+        assert!(is_word_character('a'), "ASCII");
+        assert!(is_word_character('à'), "Latin-1");
+        assert!(is_word_character('β'), "Greek");
+        assert!(is_word_character('\u{11011}'), "Brahmi (Unicode 6.0)");
+        assert!(is_word_character('\u{11611}'), "Modi (Unicode 7.0)");
+        assert!(is_word_character('\u{11711}'), "Ahom (Unicode 8.0)");
+        assert!(is_word_character('\u{17828}'), "Tangut (Unicode 9.0)");
+        assert!(is_word_character('\u{1B1B1}'), "Nushu (Unicode 10.0)");
+        assert!(is_word_character('\u{16E40}'), "Medefaidrin (Unicode 11.0)");
+        assert!(!is_word_character('-'));
+        assert!(!is_word_character('☃'));
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/parser.rs.html b/target/doc/src/regex_syntax/parser.rs.html new file mode 100644 index 0000000..46712b8 --- /dev/null +++ b/target/doc/src/regex_syntax/parser.rs.html @@ -0,0 +1,415 @@ +parser.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+
+use ast;
+use hir;
+
+use Result;
+
+/// A builder for a regular expression parser.
+///
+/// This builder permits modifying configuration options for the parser.
+///
+/// This type combines the builder options for both the
+/// [AST `ParserBuilder`](ast/parse/struct.ParserBuilder.html)
+/// and the
+/// [HIR `TranslatorBuilder`](hir/translate/struct.TranslatorBuilder.html).
+#[derive(Clone, Debug, Default)]
+pub struct ParserBuilder {
+    ast: ast::parse::ParserBuilder,
+    hir: hir::translate::TranslatorBuilder,
+}
+
+impl ParserBuilder {
+    /// Create a new parser builder with a default configuration.
+    pub fn new() -> ParserBuilder {
+        ParserBuilder::default()
+    }
+
+    /// Build a parser from this configuration with the given pattern.
+    pub fn build(&self) -> Parser {
+        Parser {
+            ast: self.ast.build(),
+            hir: self.hir.build(),
+        }
+    }
+
+    /// Set the nesting limit for this parser.
+    ///
+    /// The nesting limit controls how deep the abstract syntax tree is allowed
+    /// to be. If the AST exceeds the given limit (e.g., with too many nested
+    /// groups), then an error is returned by the parser.
+    ///
+    /// The purpose of this limit is to act as a heuristic to prevent stack
+    /// overflow for consumers that do structural induction on an `Ast` using
+    /// explicit recursion. While this crate never does this (instead using
+    /// constant stack space and moving the call stack to the heap), other
+    /// crates may.
+    ///
+    /// This limit is not checked until the entire Ast is parsed. Therefore,
+    /// if callers want to put a limit on the amount of heap space used, then
+    /// they should impose a limit on the length, in bytes, of the concrete
+    /// pattern string. In particular, this is viable since this parser
+    /// implementation will limit itself to heap space proportional to the
+    /// lenth of the pattern string.
+    ///
+    /// Note that a nest limit of `0` will return a nest limit error for most
+    /// patterns but not all. For example, a nest limit of `0` permits `a` but
+    /// not `ab`, since `ab` requires a concatenation, which results in a nest
+    /// depth of `1`. In general, a nest limit is not something that manifests
+    /// in an obvious way in the concrete syntax, therefore, it should not be
+    /// used in a granular way.
+    pub fn nest_limit(&mut self, limit: u32) -> &mut ParserBuilder {
+        self.ast.nest_limit(limit);
+        self
+    }
+
+    /// Whether to support octal syntax or not.
+    ///
+    /// Octal syntax is a little-known way of uttering Unicode codepoints in
+    /// a regular expression. For example, `a`, `\x61`, `\u0061` and
+    /// `\141` are all equivalent regular expressions, where the last example
+    /// shows octal syntax.
+    ///
+    /// While supporting octal syntax isn't in and of itself a problem, it does
+    /// make good error messages harder. That is, in PCRE based regex engines,
+    /// syntax like `\0` invokes a backreference, which is explicitly
+    /// unsupported in Rust's regex engine. However, many users expect it to
+    /// be supported. Therefore, when octal support is disabled, the error
+    /// message will explicitly mention that backreferences aren't supported.
+    ///
+    /// Octal syntax is disabled by default.
+    pub fn octal(&mut self, yes: bool) -> &mut ParserBuilder {
+        self.ast.octal(yes);
+        self
+    }
+
+    /// When enabled, the parser will permit the construction of a regular
+    /// expression that may match invalid UTF-8.
+    ///
+    /// When disabled (the default), the parser is guaranteed to produce
+    /// an expression that will only ever match valid UTF-8 (otherwise, the
+    /// parser will return an error).
+    ///
+    /// Perhaps surprisingly, when invalid UTF-8 isn't allowed, a negated ASCII
+    /// word boundary (uttered as `(?-u:\B)` in the concrete syntax) will cause
+    /// the parser to return an error. Namely, a negated ASCII word boundary
+    /// can result in matching positions that aren't valid UTF-8 boundaries.
+    pub fn allow_invalid_utf8(&mut self, yes: bool) -> &mut ParserBuilder {
+        self.hir.allow_invalid_utf8(yes);
+        self
+    }
+
+    /// Enable verbose mode in the regular expression.
+    ///
+    /// When enabled, verbose mode permits insigificant whitespace in many
+    /// places in the regular expression, as well as comments. Comments are
+    /// started using `#` and continue until the end of the line.
+    ///
+    /// By default, this is disabled. It may be selectively enabled in the
+    /// regular expression by using the `x` flag regardless of this setting.
+    pub fn ignore_whitespace(&mut self, yes: bool) -> &mut ParserBuilder {
+        self.ast.ignore_whitespace(yes);
+        self
+    }
+
+    /// Enable or disable the case insensitive flag by default.
+    ///
+    /// By default this is disabled. It may alternatively be selectively
+    /// enabled in the regular expression itself via the `i` flag.
+    pub fn case_insensitive(&mut self, yes: bool) -> &mut ParserBuilder {
+        self.hir.case_insensitive(yes);
+        self
+    }
+
+    /// Enable or disable the multi-line matching flag by default.
+    ///
+    /// By default this is disabled. It may alternatively be selectively
+    /// enabled in the regular expression itself via the `m` flag.
+    pub fn multi_line(&mut self, yes: bool) -> &mut ParserBuilder {
+        self.hir.multi_line(yes);
+        self
+    }
+
+    /// Enable or disable the "dot matches any character" flag by default.
+    ///
+    /// By default this is disabled. It may alternatively be selectively
+    /// enabled in the regular expression itself via the `s` flag.
+    pub fn dot_matches_new_line(
+        &mut self,
+        yes: bool,
+    ) -> &mut ParserBuilder {
+        self.hir.dot_matches_new_line(yes);
+        self
+    }
+
+    /// Enable or disable the "swap greed" flag by default.
+    ///
+    /// By default this is disabled. It may alternatively be selectively
+    /// enabled in the regular expression itself via the `U` flag.
+    pub fn swap_greed(&mut self, yes: bool) -> &mut ParserBuilder {
+        self.hir.swap_greed(yes);
+        self
+    }
+
+    /// Enable or disable the Unicode flag (`u`) by default.
+    ///
+    /// By default this is **enabled**. It may alternatively be selectively
+    /// disabled in the regular expression itself via the `u` flag.
+    ///
+    /// Note that unless `allow_invalid_utf8` is enabled (it's disabled by
+    /// default), a regular expression will fail to parse if Unicode mode is
+    /// disabled and a sub-expression could possibly match invalid UTF-8.
+    pub fn unicode(&mut self, yes: bool) -> &mut ParserBuilder {
+        self.hir.unicode(yes);
+        self
+    }
+}
+
+/// A convenience parser for regular expressions.
+///
+/// This parser takes as input a regular expression pattern string (the
+/// "concrete syntax") and returns a high-level intermediate representation
+/// (the HIR) suitable for most types of analysis. In particular, this parser
+/// hides the intermediate state of producing an AST (the "abstract syntax").
+/// The AST is itself far more complex than the HIR, so this parser serves as a
+/// convenience for never having to deal with it at all.
+///
+/// If callers have more fine grained use cases that need an AST, then please
+/// see the [`ast::parse`](ast/parse/index.html) module.
+///
+/// A `Parser` can be configured in more detail via a
+/// [`ParserBuilder`](struct.ParserBuilder.html).
+#[derive(Clone, Debug)]
+pub struct Parser {
+    ast: ast::parse::Parser,
+    hir: hir::translate::Translator,
+}
+
+impl Parser {
+    /// Create a new parser with a default configuration.
+    ///
+    /// The parser can be run with `parse` method. The parse method returns
+    /// a high level intermediate representation of the given regular
+    /// expression.
+    ///
+    /// To set configuration options on the parser, use
+    /// [`ParserBuilder`](struct.ParserBuilder.html).
+    pub fn new() -> Parser {
+        ParserBuilder::new().build()
+    }
+
+    /// Parse the regular expression into a high level intermediate
+    /// representation.
+    pub fn parse(&mut self, pattern: &str) -> Result<hir::Hir> {
+        let ast = self.ast.parse(pattern)?;
+        let hir = self.hir.translate(pattern, &ast)?;
+        Ok(hir)
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/unicode.rs.html b/target/doc/src/regex_syntax/unicode.rs.html new file mode 100644 index 0000000..60c7782 --- /dev/null +++ b/target/doc/src/regex_syntax/unicode.rs.html @@ -0,0 +1,917 @@ +unicode.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+
+use std::cmp::Ordering;
+use std::result;
+
+use ucd_util::{self, PropertyValues};
+
+use hir;
+use unicode_tables::age;
+use unicode_tables::case_folding_simple::CASE_FOLDING_SIMPLE;
+use unicode_tables::general_category;
+use unicode_tables::grapheme_cluster_break;
+use unicode_tables::property_bool;
+use unicode_tables::property_names::PROPERTY_NAMES;
+use unicode_tables::property_values::PROPERTY_VALUES;
+use unicode_tables::script;
+use unicode_tables::script_extension;
+use unicode_tables::sentence_break;
+use unicode_tables::word_break;
+
+type Result<T> = result::Result<T, Error>;
+
+/// An error that occurs when dealing with Unicode.
+///
+/// We don't impl the Error trait here because these always get converted
+/// into other public errors. (This error type isn't exported.)
+#[derive(Debug)]
+pub enum Error {
+    PropertyNotFound,
+    PropertyValueNotFound,
+}
+
+/// An iterator over a codepoint's simple case equivalence class.
+#[derive(Debug)]
+pub struct SimpleFoldIter(::std::slice::Iter<'static, char>);
+
+impl Iterator for SimpleFoldIter {
+    type Item = char;
+
+    fn next(&mut self) -> Option<char> {
+        self.0.next().map(|c| *c)
+    }
+}
+
+/// Return an iterator over the equivalence class of simple case mappings
+/// for the given codepoint. The equivalence class does not include the
+/// given codepoint.
+///
+/// If the equivalence class is empty, then this returns the next scalar
+/// value that has a non-empty equivalence class, if it exists. If no such
+/// scalar value exists, then `None` is returned. The point of this behavior
+/// is to permit callers to avoid calling `simple_fold` more than they need
+/// to, since there is some cost to fetching the equivalence class.
+pub fn simple_fold(c: char) -> result::Result<SimpleFoldIter, Option<char>> {
+    CASE_FOLDING_SIMPLE
+        .binary_search_by_key(&c, |&(c1, _)| c1)
+        .map(|i| SimpleFoldIter(CASE_FOLDING_SIMPLE[i].1.iter()))
+        .map_err(|i| {
+            if i >= CASE_FOLDING_SIMPLE.len() {
+                None
+            } else {
+                Some(CASE_FOLDING_SIMPLE[i].0)
+            }
+        })
+}
+
+/// Returns true if and only if the given (inclusive) range contains at least
+/// one Unicode scalar value that has a non-empty non-trivial simple case
+/// mapping.
+///
+/// This function panics if `end < start`.
+pub fn contains_simple_case_mapping(start: char, end: char) -> bool {
+    assert!(start <= end);
+    CASE_FOLDING_SIMPLE
+        .binary_search_by(|&(c, _)| {
+            if start <= c && c <= end {
+                Ordering::Equal
+            } else if c > end {
+                Ordering::Greater
+            } else {
+                Ordering::Less
+            }
+        }).is_ok()
+}
+
+/// A query for finding a character class defined by Unicode. This supports
+/// either use of a property name directly, or lookup by property value. The
+/// former generally refers to Binary properties (see UTS#44, Table 8), but
+/// as a special exception (see UTS#18, Section 1.2) both general categories
+/// (an enumeration) and scripts (a catalog) are supported as if each of their
+/// possible values were a binary property.
+///
+/// In all circumstances, property names and values are normalized and
+/// canonicalized. That is, `GC == gc == GeneralCategory == general_category`.
+///
+/// The lifetime `'a` refers to the shorter of the lifetimes of property name
+/// and property value.
+#[derive(Debug)]
+pub enum ClassQuery<'a> {
+    /// Return a class corresponding to a Unicode binary property, named by
+    /// a single letter.
+    OneLetter(char),
+    /// Return a class corresponding to a Unicode binary property.
+    ///
+    /// Note that, by special exception (see UTS#18, Section 1.2), both
+    /// general category values and script values are permitted here as if
+    /// they were a binary property.
+    Binary(&'a str),
+    /// Return a class corresponding to all codepoints whose property
+    /// (identified by `property_name`) corresponds to the given value
+    /// (identified by `property_value`).
+    ByValue {
+        /// A property name.
+        property_name: &'a str,
+        /// A property value.
+        property_value: &'a str,
+    },
+}
+
+impl<'a> ClassQuery<'a> {
+    fn canonicalize(&self) -> Result<CanonicalClassQuery> {
+        match *self {
+            ClassQuery::OneLetter(c) => self.canonical_binary(&c.to_string()),
+            ClassQuery::Binary(name) => self.canonical_binary(name),
+            ClassQuery::ByValue { property_name, property_value } => {
+                let property_name = normalize(property_name);
+                let property_value = normalize(property_value);
+
+                let canon_name = match canonical_prop(&property_name) {
+                    None => return Err(Error::PropertyNotFound),
+                    Some(canon_name) => canon_name,
+                };
+                Ok(match canon_name {
+                    "General_Category" => {
+                        let canon = match canonical_gencat(&property_value) {
+                            None => return Err(Error::PropertyValueNotFound),
+                            Some(canon) => canon,
+                        };
+                        CanonicalClassQuery::GeneralCategory(canon)
+                    }
+                    "Script" => {
+                        let canon = match canonical_script(&property_value) {
+                            None => return Err(Error::PropertyValueNotFound),
+                            Some(canon) => canon,
+                        };
+                        CanonicalClassQuery::Script(canon)
+                    }
+                    _ => {
+                        let vals = match property_values(canon_name) {
+                            None => return Err(Error::PropertyValueNotFound),
+                            Some(vals) => vals,
+                        };
+                        let canon_val = match canonical_value(
+                            vals,
+                            &property_value,
+                        ) {
+                            None => return Err(Error::PropertyValueNotFound),
+                            Some(canon_val) => canon_val,
+                        };
+                        CanonicalClassQuery::ByValue {
+                            property_name: canon_name,
+                            property_value: canon_val,
+                        }
+                    }
+                })
+            }
+        }
+    }
+
+    fn canonical_binary(&self, name: &str) -> Result<CanonicalClassQuery> {
+        let norm = normalize(name);
+
+        if let Some(canon) = canonical_prop(&norm) {
+            return Ok(CanonicalClassQuery::Binary(canon));
+        }
+        if let Some(canon) = canonical_gencat(&norm) {
+            return Ok(CanonicalClassQuery::GeneralCategory(canon));
+        }
+        if let Some(canon) = canonical_script(&norm) {
+            return Ok(CanonicalClassQuery::Script(canon));
+        }
+        Err(Error::PropertyNotFound)
+    }
+}
+
+/// Like ClassQuery, but its parameters have been canonicalized. This also
+/// differentiates binary properties from flattened general categories and
+/// scripts.
+#[derive(Debug, Eq, PartialEq)]
+enum CanonicalClassQuery {
+    /// The canonical binary property name.
+    Binary(&'static str),
+    /// The canonical general category name.
+    GeneralCategory(&'static str),
+    /// The canonical script name.
+    Script(&'static str),
+    /// An arbitrary association between property and value, both of which
+    /// have been canonicalized.
+    ///
+    /// Note that by construction, the property name of ByValue will never
+    /// be General_Category or Script. Those two cases are subsumed by the
+    /// eponymous variants.
+    ByValue {
+        /// The canonical property name.
+        property_name: &'static str,
+        /// The canonical property value.
+        property_value: &'static str,
+    },
+}
+
+/// Looks up a Unicode class given a query. If one doesn't exist, then
+/// `None` is returned.
+pub fn class<'a>(query: ClassQuery<'a>) -> Result<hir::ClassUnicode> {
+    use self::CanonicalClassQuery::*;
+
+    match query.canonicalize()? {
+        Binary(name) => {
+            property_set(property_bool::BY_NAME, name)
+                .map(hir_class)
+                .ok_or(Error::PropertyNotFound)
+        }
+        GeneralCategory("Any") => {
+            Ok(hir_class(&[('\0', '\u{10FFFF}')]))
+        }
+        GeneralCategory("Assigned") => {
+            let mut cls =
+                property_set(general_category::BY_NAME, "Unassigned")
+                    .map(hir_class)
+                    .ok_or(Error::PropertyNotFound)?;
+            cls.negate();
+            Ok(cls)
+        }
+        GeneralCategory("ASCII") => {
+            Ok(hir_class(&[('\0', '\x7F')]))
+        }
+        GeneralCategory(name) => {
+            property_set(general_category::BY_NAME, name)
+                .map(hir_class)
+                .ok_or(Error::PropertyValueNotFound)
+        }
+        Script(name) => {
+            property_set(script::BY_NAME, name)
+                .map(hir_class)
+                .ok_or(Error::PropertyValueNotFound)
+        }
+        ByValue { property_name: "Age", property_value } => {
+            let mut class = hir::ClassUnicode::empty();
+            for set in ages(property_value)? {
+                class.union(&hir_class(set));
+            }
+            Ok(class)
+        }
+        ByValue { property_name: "Script_Extensions", property_value } => {
+            property_set(script_extension::BY_NAME, property_value)
+                .map(hir_class)
+                .ok_or(Error::PropertyValueNotFound)
+        }
+        ByValue { property_name: "Grapheme_Cluster_Break", property_value } => {
+            property_set(grapheme_cluster_break::BY_NAME, property_value)
+                .map(hir_class)
+                .ok_or(Error::PropertyValueNotFound)
+        }
+        ByValue { property_name: "Sentence_Break", property_value } => {
+            property_set(sentence_break::BY_NAME, property_value)
+                .map(hir_class)
+                .ok_or(Error::PropertyValueNotFound)
+        }
+        ByValue { property_name: "Word_Break", property_value } => {
+            property_set(word_break::BY_NAME, property_value)
+                .map(hir_class)
+                .ok_or(Error::PropertyValueNotFound)
+        }
+        _ => {
+            // What else should we support?
+            Err(Error::PropertyNotFound)
+        }
+    }
+}
+
+/// Build a Unicode HIR class from a sequence of Unicode scalar value ranges.
+pub fn hir_class(ranges: &[(char, char)]) -> hir::ClassUnicode {
+    let hir_ranges: Vec<hir::ClassUnicodeRange> = ranges
+        .iter()
+        .map(|&(s, e)| hir::ClassUnicodeRange::new(s, e))
+        .collect();
+    hir::ClassUnicode::new(hir_ranges)
+}
+
+fn canonical_prop(normalized_name: &str) -> Option<&'static str> {
+    ucd_util::canonical_property_name(PROPERTY_NAMES, normalized_name)
+}
+
+fn canonical_gencat(normalized_value: &str) -> Option<&'static str> {
+    match normalized_value {
+        "any" => Some("Any"),
+        "assigned" => Some("Assigned"),
+        "ascii" => Some("ASCII"),
+        _ => {
+            let gencats = property_values("General_Category").unwrap();
+            canonical_value(gencats, normalized_value)
+        }
+    }
+}
+
+fn canonical_script(normalized_value: &str) -> Option<&'static str> {
+    let scripts = property_values("Script").unwrap();
+    canonical_value(scripts, normalized_value)
+}
+
+fn canonical_value(
+    vals: PropertyValues,
+    normalized_value: &str,
+) -> Option<&'static str> {
+    ucd_util::canonical_property_value(vals, normalized_value)
+}
+
+fn normalize(x: &str) -> String {
+    let mut x = x.to_string();
+    ucd_util::symbolic_name_normalize(&mut x);
+    x
+}
+
+fn property_values(
+    canonical_property_name: &'static str,
+) -> Option<PropertyValues>
+{
+    ucd_util::property_values(PROPERTY_VALUES, canonical_property_name)
+}
+
+fn property_set(
+    name_map: &'static [(&'static str, &'static [(char, char)])],
+    canonical: &'static str,
+) -> Option<&'static [(char, char)]> {
+    name_map
+        .binary_search_by_key(&canonical, |x| x.0)
+        .ok()
+        .map(|i| name_map[i].1)
+}
+
+/// An iterator over Unicode Age sets. Each item corresponds to a set of
+/// codepoints that were added in a particular revision of Unicode. The
+/// iterator yields items in chronological order.
+#[derive(Debug)]
+struct AgeIter {
+    ages: &'static [(&'static str, &'static [(char, char)])],
+}
+
+fn ages(canonical_age: &str) -> Result<AgeIter> {
+    const AGES: &'static [(&'static str, &'static [(char, char)])] = &[
+        ("V1_1", age::V1_1),
+        ("V2_0", age::V2_0),
+        ("V2_1", age::V2_1),
+        ("V3_0", age::V3_0),
+        ("V3_1", age::V3_1),
+        ("V3_2", age::V3_2),
+        ("V4_0", age::V4_0),
+        ("V4_1", age::V4_1),
+        ("V5_0", age::V5_0),
+        ("V5_1", age::V5_1),
+        ("V5_2", age::V5_2),
+        ("V6_0", age::V6_0),
+        ("V6_1", age::V6_1),
+        ("V6_2", age::V6_2),
+        ("V6_3", age::V6_3),
+        ("V7_0", age::V7_0),
+        ("V8_0", age::V8_0),
+        ("V9_0", age::V9_0),
+        ("V10_0", age::V10_0),
+        ("V11_0", age::V11_0),
+        ("V12_0", age::V12_0),
+        ("V12_1", age::V12_1),
+    ];
+    assert_eq!(AGES.len(), age::BY_NAME.len(), "ages are out of sync");
+
+    let pos = AGES.iter().position(|&(age, _)| canonical_age == age);
+    match pos {
+        None => Err(Error::PropertyValueNotFound),
+        Some(i) => Ok(AgeIter { ages: &AGES[..i+1] }),
+    }
+}
+
+impl Iterator for AgeIter {
+    type Item = &'static [(char, char)];
+
+    fn next(&mut self) -> Option<&'static [(char, char)]> {
+        if self.ages.is_empty() {
+            None
+        } else {
+            let set = self.ages[0];
+            self.ages = &self.ages[1..];
+            Some(set.1)
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::{contains_simple_case_mapping, simple_fold};
+
+    #[test]
+    fn simple_fold_k() {
+        let xs: Vec<char> = simple_fold('k').unwrap().collect();
+        assert_eq!(xs, vec!['K', 'K']);
+
+        let xs: Vec<char> = simple_fold('K').unwrap().collect();
+        assert_eq!(xs, vec!['k', 'K']);
+
+        let xs: Vec<char> = simple_fold('K').unwrap().collect();
+        assert_eq!(xs, vec!['K', 'k']);
+    }
+
+    #[test]
+    fn simple_fold_a() {
+        let xs: Vec<char> = simple_fold('a').unwrap().collect();
+        assert_eq!(xs, vec!['A']);
+
+        let xs: Vec<char> = simple_fold('A').unwrap().collect();
+        assert_eq!(xs, vec!['a']);
+    }
+
+    #[test]
+    fn simple_fold_empty() {
+        assert_eq!(Some('A'), simple_fold('?').unwrap_err());
+        assert_eq!(Some('A'), simple_fold('@').unwrap_err());
+        assert_eq!(Some('a'), simple_fold('[').unwrap_err());
+        assert_eq!(Some('Ⰰ'), simple_fold('☃').unwrap_err());
+    }
+
+    #[test]
+    fn simple_fold_max() {
+        assert_eq!(None, simple_fold('\u{10FFFE}').unwrap_err());
+        assert_eq!(None, simple_fold('\u{10FFFF}').unwrap_err());
+    }
+
+    #[test]
+    fn range_contains() {
+        assert!(contains_simple_case_mapping('A', 'A'));
+        assert!(contains_simple_case_mapping('Z', 'Z'));
+        assert!(contains_simple_case_mapping('A', 'Z'));
+        assert!(contains_simple_case_mapping('@', 'A'));
+        assert!(contains_simple_case_mapping('Z', '['));
+        assert!(contains_simple_case_mapping('☃', 'Ⰰ'));
+
+        assert!(!contains_simple_case_mapping('[', '['));
+        assert!(!contains_simple_case_mapping('[', '`'));
+
+        assert!(!contains_simple_case_mapping('☃', '☃'));
+    }
+
+    #[test]
+    fn regression_466() {
+        use super::{CanonicalClassQuery, ClassQuery};
+
+        let q = ClassQuery::OneLetter('C');
+        assert_eq!(
+            q.canonicalize().unwrap(),
+            CanonicalClassQuery::GeneralCategory("Other"));
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/unicode_tables/age.rs.html b/target/doc/src/regex_syntax/unicode_tables/age.rs.html new file mode 100644 index 0000000..c9f1b43 --- /dev/null +++ b/target/doc/src/regex_syntax/unicode_tables/age.rs.html @@ -0,0 +1,1001 @@ +age.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+
+// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
+//
+//  ucd-generate age /tmp/ucd-12.1.0/ --chars
+//
+// ucd-generate is available on crates.io.
+
+pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
+  ("V10_0", V10_0), ("V11_0", V11_0), ("V12_0", V12_0), ("V12_1", V12_1),
+  ("V1_1", V1_1), ("V2_0", V2_0), ("V2_1", V2_1), ("V3_0", V3_0),
+  ("V3_1", V3_1), ("V3_2", V3_2), ("V4_0", V4_0), ("V4_1", V4_1),
+  ("V5_0", V5_0), ("V5_1", V5_1), ("V5_2", V5_2), ("V6_0", V6_0),
+  ("V6_1", V6_1), ("V6_2", V6_2), ("V6_3", V6_3), ("V7_0", V7_0),
+  ("V8_0", V8_0), ("V9_0", V9_0),
+];
+
+pub const V10_0: &'static [(char, char)] = &[
+  ('ࡠ', 'ࡪ'), ('ৼ', '৽'), ('\u{afa}', '\u{aff}'),
+  ('\u{d00}', '\u{d00}'), ('\u{d3b}', '\u{d3c}'), ('᳷', '᳷'),
+  ('\u{1df6}', '\u{1df9}'), ('₿', '₿'), ('⏿', '⏿'), ('⯒', '⯒'),
+  ('⹅', '⹉'), ('ㄮ', 'ㄮ'), ('鿖', '鿪'), ('𐌭', '𐌯'),
+  ('𑨀', '\u{11a47}'), ('𑩐', '𑪃'), ('𑪆', '𑪜'), ('𑪞', '𑪢'),
+  ('𑴀', '𑴆'), ('𑴈', '𑴉'), ('𑴋', '\u{11d36}'),
+  ('\u{11d3a}', '\u{11d3a}'), ('\u{11d3c}', '\u{11d3d}'),
+  ('\u{11d3f}', '\u{11d47}'), ('𑵐', '𑵙'), ('𖿡', '𖿡'),
+  ('𛀂', '𛄞'), ('𛅰', '𛋻'), ('🉠', '🉥'), ('🛓', '🛔'),
+  ('🛷', '🛸'), ('🤀', '🤋'), ('🤟', '🤟'), ('🤨', '🤯'),
+  ('🤱', '🤲'), ('🥌', '🥌'), ('🥟', '🥫'), ('🦒', '🦗'),
+  ('🧐', '🧦'), ('𬺰', '𮯠'),
+];
+
+pub const V11_0: &'static [(char, char)] = &[
+  ('ՠ', 'ՠ'), ('ֈ', 'ֈ'), ('ׯ', 'ׯ'), ('\u{7fd}', '߿'),
+  ('\u{8d3}', '\u{8d3}'), ('\u{9fe}', '\u{9fe}'), ('੶', '੶'),
+  ('\u{c04}', '\u{c04}'), ('಄', '಄'), ('ᡸ', 'ᡸ'), ('Ა', 'Ჺ'),
+  ('Ჽ', 'Ჿ'), ('⮺', '⮼'), ('⯓', '⯫'), ('⯰', '⯾'),
+  ('⹊', '⹎'), ('ㄯ', 'ㄯ'), ('鿫', '鿯'), ('ꞯ', 'ꞯ'),
+  ('Ꞹ', 'ꞹ'), ('ꣾ', '\u{a8ff}'), ('𐨴', '𐨵'), ('𐩈', '𐩈'),
+  ('𐴀', '\u{10d27}'), ('𐴰', '𐴹'), ('𐼀', '𐼧'), ('𐼰', '𐽙'),
+  ('\u{110cd}', '\u{110cd}'), ('𑅄', '𑅆'), ('\u{1133b}', '\u{1133b}'),
+  ('\u{1145e}', '\u{1145e}'), ('𑜚', '𑜚'), ('𑠀', '𑠻'),
+  ('𑪝', '𑪝'), ('𑵠', '𑵥'), ('𑵧', '𑵨'), ('𑵪', '𑶎'),
+  ('\u{11d90}', '\u{11d91}'), ('𑶓', '𑶘'), ('𑶠', '𑶩'),
+  ('𑻠', '𑻸'), ('𖹀', '𖺚'), ('𘟭', '𘟱'), ('𝋠', '𝋳'),
+  ('𝍲', '𝍸'), ('𞱱', '𞲴'), ('🄯', '🄯'), ('🛹', '🛹'),
+  ('🟕', '🟘'), ('🥍', '🥏'), ('🥬', '🥰'), ('🥳', '🥶'),
+  ('🥺', '🥺'), ('🥼', '🥿'), ('🦘', '🦢'), ('🦰', '🦹'),
+  ('🧁', '🧂'), ('🧧', '🧿'), ('🩠', '🩭'),
+];
+
+pub const V12_0: &'static [(char, char)] = &[
+  ('\u{c77}', '\u{c77}'), ('\u{e86}', '\u{e86}'), ('\u{e89}', '\u{e89}'),
+  ('\u{e8c}', '\u{e8c}'), ('\u{e8e}', '\u{e93}'), ('\u{e98}', '\u{e98}'),
+  ('\u{ea0}', '\u{ea0}'), ('\u{ea8}', '\u{ea9}'), ('\u{eac}', '\u{eac}'),
+  ('\u{eba}', '\u{eba}'), ('\u{1cfa}', '\u{1cfa}'), ('\u{2bc9}', '\u{2bc9}'),
+  ('\u{2bff}', '\u{2bff}'), ('\u{2e4f}', '\u{2e4f}'),
+  ('\u{a7ba}', '\u{a7bf}'), ('\u{a7c2}', '\u{a7c6}'),
+  ('\u{ab66}', '\u{ab67}'), ('\u{10fe0}', '\u{10ff6}'),
+  ('\u{1145f}', '\u{1145f}'), ('\u{116b8}', '\u{116b8}'),
+  ('\u{119a0}', '\u{119a7}'), ('\u{119aa}', '\u{119d7}'),
+  ('\u{119da}', '\u{119e4}'), ('\u{11a84}', '\u{11a85}'),
+  ('\u{11fc0}', '\u{11ff1}'), ('\u{11fff}', '\u{11fff}'),
+  ('\u{13430}', '\u{13438}'), ('\u{16f45}', '\u{16f4a}'),
+  ('\u{16f4f}', '\u{16f4f}'), ('\u{16f7f}', '\u{16f87}'),
+  ('\u{16fe2}', '\u{16fe3}'), ('\u{187f2}', '\u{187f7}'),
+  ('\u{1b150}', '\u{1b152}'), ('\u{1b164}', '\u{1b167}'),
+  ('\u{1e100}', '\u{1e12c}'), ('\u{1e130}', '\u{1e13d}'),
+  ('\u{1e140}', '\u{1e149}'), ('\u{1e14e}', '\u{1e14f}'),
+  ('\u{1e2c0}', '\u{1e2f9}'), ('\u{1e2ff}', '\u{1e2ff}'),
+  ('\u{1e94b}', '\u{1e94b}'), ('\u{1ed01}', '\u{1ed3d}'),
+  ('\u{1f16c}', '\u{1f16c}'), ('\u{1f6d5}', '\u{1f6d5}'),
+  ('\u{1f6fa}', '\u{1f6fa}'), ('\u{1f7e0}', '\u{1f7eb}'),
+  ('\u{1f90d}', '\u{1f90f}'), ('\u{1f93f}', '\u{1f93f}'),
+  ('\u{1f971}', '\u{1f971}'), ('\u{1f97b}', '\u{1f97b}'),
+  ('\u{1f9a5}', '\u{1f9aa}'), ('\u{1f9ae}', '\u{1f9af}'),
+  ('\u{1f9ba}', '\u{1f9bf}'), ('\u{1f9c3}', '\u{1f9ca}'),
+  ('\u{1f9cd}', '\u{1f9cf}'), ('\u{1fa00}', '\u{1fa53}'),
+  ('\u{1fa70}', '\u{1fa73}'), ('\u{1fa78}', '\u{1fa7a}'),
+  ('\u{1fa80}', '\u{1fa82}'), ('\u{1fa90}', '\u{1fa95}'),
+];
+
+pub const V12_1: &'static [(char, char)] = &[
+  ('\u{32ff}', '\u{32ff}'),
+];
+
+pub const V1_1: &'static [(char, char)] = &[
+  ('\u{0}', 'ǵ'), ('Ǻ', 'ȗ'), ('ɐ', 'ʨ'), ('ʰ', '˞'), ('ˠ', '˩'),
+  ('\u{300}', '\u{345}'), ('\u{360}', '\u{361}'), ('ʹ', '͵'), ('ͺ', 'ͺ'),
+  (';', ';'), ('΄', 'Ί'), ('Ό', 'Ό'), ('Ύ', 'Ρ'), ('Σ', 'ώ'),
+  ('ϐ', 'ϖ'), ('Ϛ', 'Ϛ'), ('Ϝ', 'Ϝ'), ('Ϟ', 'Ϟ'), ('Ϡ', 'Ϡ'),
+  ('Ϣ', 'ϳ'), ('Ё', 'Ќ'), ('Ў', 'я'), ('ё', 'ќ'), ('ў', '\u{486}'),
+  ('Ґ', 'ӄ'), ('Ӈ', 'ӈ'), ('Ӌ', 'ӌ'), ('Ӑ', 'ӫ'), ('Ӯ', 'ӵ'),
+  ('Ӹ', 'ӹ'), ('Ա', 'Ֆ'), ('ՙ', '՟'), ('ա', 'և'), ('։', '։'),
+  ('\u{5b0}', '\u{5b9}'), ('\u{5bb}', '׃'), ('א', 'ת'), ('װ', '״'),
+  ('،', '،'), ('؛', '؛'), ('؟', '؟'), ('ء', 'غ'), ('ـ', '\u{652}'),
+  ('٠', '٭'), ('\u{670}', 'ڷ'), ('ں', 'ھ'), ('ۀ', 'ێ'),
+  ('ې', '\u{6ed}'), ('۰', '۹'), ('\u{901}', 'ः'), ('अ', 'ह'),
+  ('\u{93c}', '\u{94d}'), ('ॐ', '\u{954}'), ('क़', '॰'),
+  ('\u{981}', 'ঃ'), ('অ', 'ঌ'), ('এ', 'ঐ'), ('ও', 'ন'),
+  ('প', 'র'), ('ল', 'ল'), ('শ', 'হ'), ('\u{9bc}', '\u{9bc}'),
+  ('\u{9be}', '\u{9c4}'), ('ে', 'ৈ'), ('ো', '\u{9cd}'),
+  ('\u{9d7}', '\u{9d7}'), ('ড়', 'ঢ়'), ('য়', '\u{9e3}'), ('০', '৺'),
+  ('\u{a02}', '\u{a02}'), ('ਅ', 'ਊ'), ('ਏ', 'ਐ'), ('ਓ', 'ਨ'),
+  ('ਪ', 'ਰ'), ('ਲ', 'ਲ਼'), ('ਵ', 'ਸ਼'), ('ਸ', 'ਹ'),
+  ('\u{a3c}', '\u{a3c}'), ('ਾ', '\u{a42}'), ('\u{a47}', '\u{a48}'),
+  ('\u{a4b}', '\u{a4d}'), ('ਖ਼', 'ੜ'), ('ਫ਼', 'ਫ਼'), ('੦', 'ੴ'),
+  ('\u{a81}', 'ઃ'), ('અ', 'ઋ'), ('ઍ', 'ઍ'), ('એ', 'ઑ'),
+  ('ઓ', 'ન'), ('પ', 'ર'), ('લ', 'ળ'), ('વ', 'હ'),
+  ('\u{abc}', '\u{ac5}'), ('\u{ac7}', 'ૉ'), ('ો', '\u{acd}'),
+  ('ૐ', 'ૐ'), ('ૠ', 'ૠ'), ('૦', '૯'), ('\u{b01}', 'ଃ'),
+  ('ଅ', 'ଌ'), ('ଏ', 'ଐ'), ('ଓ', 'ନ'), ('ପ', 'ର'),
+  ('ଲ', 'ଳ'), ('ଶ', 'ହ'), ('\u{b3c}', '\u{b43}'), ('େ', 'ୈ'),
+  ('ୋ', '\u{b4d}'), ('\u{b56}', '\u{b57}'), ('ଡ଼', 'ଢ଼'), ('ୟ', 'ୡ'),
+  ('୦', '୰'), ('\u{b82}', 'ஃ'), ('அ', 'ஊ'), ('எ', 'ஐ'),
+  ('ஒ', 'க'), ('ங', 'ச'), ('ஜ', 'ஜ'), ('ஞ', 'ட'),
+  ('ண', 'த'), ('ந', 'ப'), ('ம', 'வ'), ('ஷ', 'ஹ'),
+  ('\u{bbe}', 'ூ'), ('ெ', 'ை'), ('ொ', '\u{bcd}'),
+  ('\u{bd7}', '\u{bd7}'), ('௧', '௲'), ('ఁ', 'ః'), ('అ', 'ఌ'),
+  ('ఎ', 'ఐ'), ('ఒ', 'న'), ('ప', 'ళ'), ('వ', 'హ'),
+  ('\u{c3e}', 'ౄ'), ('\u{c46}', '\u{c48}'), ('\u{c4a}', '\u{c4d}'),
+  ('\u{c55}', '\u{c56}'), ('ౠ', 'ౡ'), ('౦', '౯'), ('ಂ', 'ಃ'),
+  ('ಅ', 'ಌ'), ('ಎ', 'ಐ'), ('ಒ', 'ನ'), ('ಪ', 'ಳ'),
+  ('ವ', 'ಹ'), ('ಾ', 'ೄ'), ('\u{cc6}', 'ೈ'), ('ೊ', '\u{ccd}'),
+  ('\u{cd5}', '\u{cd6}'), ('ೞ', 'ೞ'), ('ೠ', 'ೡ'), ('೦', '೯'),
+  ('ം', 'ഃ'), ('അ', 'ഌ'), ('എ', 'ഐ'), ('ഒ', 'ന'),
+  ('പ', 'ഹ'), ('\u{d3e}', '\u{d43}'), ('െ', 'ൈ'), ('ൊ', '\u{d4d}'),
+  ('\u{d57}', '\u{d57}'), ('ൠ', 'ൡ'), ('൦', '൯'), ('ก', '\u{e3a}'),
+  ('฿', '๛'), ('ກ', 'ຂ'), ('ຄ', 'ຄ'), ('ງ', 'ຈ'),
+  ('ຊ', 'ຊ'), ('ຍ', 'ຍ'), ('ດ', 'ທ'), ('ນ', 'ຟ'),
+  ('ມ', 'ຣ'), ('ລ', 'ລ'), ('ວ', 'ວ'), ('ສ', 'ຫ'),
+  ('ອ', '\u{eb9}'), ('\u{ebb}', 'ຽ'), ('ເ', 'ໄ'), ('ໆ', 'ໆ'),
+  ('\u{ec8}', '\u{ecd}'), ('໐', '໙'), ('ໜ', 'ໝ'), ('Ⴀ', 'Ⴥ'),
+  ('ა', 'ჶ'), ('჻', '჻'), ('ᄀ', 'ᅙ'), ('ᅟ', 'ᆢ'),
+  ('ᆨ', 'ᇹ'), ('Ḁ', 'ẚ'), ('Ạ', 'ỹ'), ('ἀ', 'ἕ'),
+  ('Ἐ', 'Ἕ'), ('ἠ', 'ὅ'), ('Ὀ', 'Ὅ'), ('ὐ', 'ὗ'),
+  ('Ὑ', 'Ὑ'), ('Ὓ', 'Ὓ'), ('Ὕ', 'Ὕ'), ('Ὗ', 'ώ'),
+  ('ᾀ', 'ᾴ'), ('ᾶ', 'ῄ'), ('ῆ', 'ΐ'), ('ῖ', 'Ί'),
+  ('῝', '`'), ('ῲ', 'ῴ'), ('ῶ', '῾'), ('\u{2000}', '\u{202e}'),
+  ('‰', '⁆'), ('\u{206a}', '⁰'), ('⁴', '₎'), ('₠', '₪'),
+  ('\u{20d0}', '\u{20e1}'), ('℀', 'ℸ'), ('⅓', 'ↂ'), ('←', '⇪'),
+  ('∀', '⋱'), ('⌀', '⌀'), ('⌂', '⍺'), ('␀', '␤'),
+  ('⑀', '⑊'), ('①', '⓪'), ('─', '▕'), ('■', '◯'),
+  ('☀', '☓'), ('☚', '♯'), ('✁', '✄'), ('✆', '✉'),
+  ('✌', '✧'), ('✩', '❋'), ('❍', '❍'), ('❏', '❒'),
+  ('❖', '❖'), ('❘', '❞'), ('❡', '❧'), ('❶', '➔'),
+  ('➘', '➯'), ('➱', '➾'), ('\u{3000}', '〷'), ('〿', '〿'),
+  ('ぁ', 'ゔ'), ('\u{3099}', 'ゞ'), ('ァ', 'ヾ'), ('ㄅ', 'ㄬ'),
+  ('ㄱ', 'ㆎ'), ('㆐', '㆟'), ('㈀', '㈜'), ('㈠', '㉃'),
+  ('㉠', '㉻'), ('㉿', '㊰'), ('㋀', '㋋'), ('㋐', '㋾'),
+  ('㌀', '㍶'), ('㍻', '㏝'), ('㏠', '㏾'), ('一', '龥'),
+  ('\u{e000}', '鶴'), ('ff', 'st'), ('ﬓ', 'ﬗ'), ('\u{fb1e}', 'זּ'),
+  ('טּ', 'לּ'), ('מּ', 'מּ'), ('נּ', 'סּ'), ('ףּ', 'פּ'),
+  ('צּ', 'ﮱ'), ('ﯓ', '﴿'), ('ﵐ', 'ﶏ'), ('ﶒ', 'ﷇ'),
+  ('ﷰ', 'ﷻ'), ('\u{fe20}', '\u{fe23}'), ('︰', '﹄'), ('﹉', '﹒'),
+  ('﹔', '﹦'), ('﹨', '﹫'), ('ﹰ', 'ﹲ'), ('ﹴ', 'ﹴ'),
+  ('ﹶ', 'ﻼ'), ('\u{feff}', '\u{feff}'), ('!', '~'), ('。', 'ᄒ'),
+  ('ᅡ', 'ᅦ'), ('ᅧ', 'ᅬ'), ('ᅭ', 'ᅲ'), ('ᅳ', 'ᅵ'),
+  ('¢', '₩'), ('│', '○'), ('�', '\u{ffff}'),
+];
+
+pub const V2_0: &'static [(char, char)] = &[
+  ('\u{591}', '\u{5a1}'), ('\u{5a3}', '\u{5af}'), ('\u{5c4}', '\u{5c4}'),
+  ('ༀ', 'ཇ'), ('ཉ', 'ཀྵ'), ('\u{f71}', 'ྋ'), ('\u{f90}', '\u{f95}'),
+  ('\u{f97}', '\u{f97}'), ('\u{f99}', '\u{fad}'), ('\u{fb1}', '\u{fb7}'),
+  ('\u{fb9}', '\u{fb9}'), ('ẛ', 'ẛ'), ('₫', '₫'), ('가', '힣'),
+  ('\u{1fffe}', '\u{1ffff}'), ('\u{2fffe}', '\u{2ffff}'),
+  ('\u{3fffe}', '\u{3ffff}'), ('\u{4fffe}', '\u{4ffff}'),
+  ('\u{5fffe}', '\u{5ffff}'), ('\u{6fffe}', '\u{6ffff}'),
+  ('\u{7fffe}', '\u{7ffff}'), ('\u{8fffe}', '\u{8ffff}'),
+  ('\u{9fffe}', '\u{9ffff}'), ('\u{afffe}', '\u{affff}'),
+  ('\u{bfffe}', '\u{bffff}'), ('\u{cfffe}', '\u{cffff}'),
+  ('\u{dfffe}', '\u{dffff}'), ('\u{efffe}', '\u{10ffff}'),
+];
+
+pub const V2_1: &'static [(char, char)] = &[
+  ('€', '€'), ('', ''),
+];
+
+pub const V3_0: &'static [(char, char)] = &[
+  ('Ƕ', 'ǹ'), ('Ș', 'ȟ'), ('Ȣ', 'ȳ'), ('ʩ', 'ʭ'), ('˟', '˟'),
+  ('˪', 'ˮ'), ('\u{346}', '\u{34e}'), ('\u{362}', '\u{362}'), ('ϗ', 'ϗ'),
+  ('ϛ', 'ϛ'), ('ϝ', 'ϝ'), ('ϟ', 'ϟ'), ('ϡ', 'ϡ'), ('Ѐ', 'Ѐ'),
+  ('Ѝ', 'Ѝ'), ('ѐ', 'ѐ'), ('ѝ', 'ѝ'), ('\u{488}', '\u{489}'),
+  ('Ҍ', 'ҏ'), ('Ӭ', 'ӭ'), ('֊', '֊'), ('\u{653}', '\u{655}'),
+  ('ڸ', 'ڹ'), ('ڿ', 'ڿ'), ('ۏ', 'ۏ'), ('ۺ', '۾'), ('܀', '܍'),
+  ('\u{70f}', 'ܬ'), ('\u{730}', '\u{74a}'), ('ހ', '\u{7b0}'),
+  ('ං', 'ඃ'), ('අ', 'ඖ'), ('ක', 'න'), ('ඳ', 'ර'),
+  ('ල', 'ල'), ('ව', 'ෆ'), ('\u{dca}', '\u{dca}'),
+  ('\u{dcf}', '\u{dd4}'), ('\u{dd6}', '\u{dd6}'), ('ෘ', '\u{ddf}'),
+  ('ෲ', '෴'), ('ཪ', 'ཪ'), ('\u{f96}', '\u{f96}'),
+  ('\u{fae}', '\u{fb0}'), ('\u{fb8}', '\u{fb8}'), ('\u{fba}', '\u{fbc}'),
+  ('྾', '࿌'), ('࿏', '࿏'), ('က', 'အ'), ('ဣ', 'ဧ'),
+  ('ဩ', 'ဪ'), ('ာ', '\u{1032}'), ('\u{1036}', '\u{1039}'),
+  ('၀', '\u{1059}'), ('ሀ', 'ሆ'), ('ለ', 'ቆ'), ('ቈ', 'ቈ'),
+  ('ቊ', 'ቍ'), ('ቐ', 'ቖ'), ('ቘ', 'ቘ'), ('ቚ', 'ቝ'),
+  ('በ', 'ኆ'), ('ኈ', 'ኈ'), ('ኊ', 'ኍ'), ('ነ', 'ኮ'),
+  ('ኰ', 'ኰ'), ('ኲ', 'ኵ'), ('ኸ', 'ኾ'), ('ዀ', 'ዀ'),
+  ('ዂ', 'ዅ'), ('ወ', 'ዎ'), ('ዐ', 'ዖ'), ('ዘ', 'ዮ'),
+  ('ደ', 'ጎ'), ('ጐ', 'ጐ'), ('ጒ', 'ጕ'), ('ጘ', 'ጞ'),
+  ('ጠ', 'ፆ'), ('ፈ', 'ፚ'), ('፡', '፼'), ('Ꭰ', 'Ᏼ'),
+  ('ᐁ', 'ᙶ'), ('\u{1680}', '᚜'), ('ᚠ', 'ᛰ'), ('ក', 'ៜ'),
+  ('០', '៩'), ('᠀', '\u{180e}'), ('᠐', '᠙'), ('ᠠ', 'ᡷ'),
+  ('ᢀ', '\u{18a9}'), ('\u{202f}', '\u{202f}'), ('⁈', '⁍'),
+  ('₭', '₯'), ('\u{20e2}', '\u{20e3}'), ('ℹ', '℺'), ('Ↄ', 'Ↄ'),
+  ('⇫', '⇳'), ('⌁', '⌁'), ('⍻', '⍻'), ('⍽', '⎚'),
+  ('␥', '␦'), ('◰', '◷'), ('☙', '☙'), ('♰', '♱'),
+  ('⠀', '⣿'), ('⺀', '⺙'), ('⺛', '⻳'), ('⼀', '⿕'),
+  ('⿰', '⿻'), ('〸', '〺'), ('〾', '〾'), ('ㆠ', 'ㆷ'),
+  ('㐀', '䶵'), ('ꀀ', 'ꒌ'), ('꒐', '꒡'), ('꒤', '꒳'),
+  ('꒵', '꓀'), ('꓂', '꓄'), ('꓆', '꓆'), ('יִ', 'יִ'),
+  ('\u{fff9}', '\u{fffb}'),
+];
+
+pub const V3_1: &'static [(char, char)] = &[
+  ('ϴ', 'ϵ'), ('\u{fdd0}', '\u{fdef}'), ('𐌀', '𐌞'), ('𐌠', '𐌣'),
+  ('𐌰', '𐍊'), ('𐐀', '𐐥'), ('𐐨', '𐑍'), ('𝀀', '𝃵'),
+  ('𝄀', '𝄦'), ('𝄪', '𝇝'), ('𝐀', '𝑔'), ('𝑖', '𝒜'),
+  ('𝒞', '𝒟'), ('𝒢', '𝒢'), ('𝒥', '𝒦'), ('𝒩', '𝒬'),
+  ('𝒮', '𝒹'), ('𝒻', '𝒻'), ('𝒽', '𝓀'), ('𝓂', '𝓃'),
+  ('𝓅', '𝔅'), ('𝔇', '𝔊'), ('𝔍', '𝔔'), ('𝔖', '𝔜'),
+  ('𝔞', '𝔹'), ('𝔻', '𝔾'), ('𝕀', '𝕄'), ('𝕆', '𝕆'),
+  ('𝕊', '𝕐'), ('𝕒', '𝚣'), ('𝚨', '𝟉'), ('𝟎', '𝟿'),
+  ('𠀀', '𪛖'), ('丽', '𪘀'), ('\u{e0001}', '\u{e0001}'),
+  ('\u{e0020}', '\u{e007f}'),
+];
+
+pub const V3_2: &'static [(char, char)] = &[
+  ('Ƞ', 'Ƞ'), ('\u{34f}', '\u{34f}'), ('\u{363}', '\u{36f}'), ('Ϙ', 'ϙ'),
+  ('϶', '϶'), ('Ҋ', 'ҋ'), ('Ӆ', 'ӆ'), ('Ӊ', 'ӊ'), ('Ӎ', 'ӎ'),
+  ('Ԁ', 'ԏ'), ('ٮ', 'ٯ'), ('ޱ', 'ޱ'), ('ჷ', 'ჸ'), ('ᜀ', 'ᜌ'),
+  ('ᜎ', '\u{1714}'), ('ᜠ', '᜶'), ('ᝀ', '\u{1753}'), ('ᝠ', 'ᝬ'),
+  ('ᝮ', 'ᝰ'), ('\u{1772}', '\u{1773}'), ('⁇', '⁇'), ('⁎', '⁒'),
+  ('⁗', '⁗'), ('\u{205f}', '\u{2063}'), ('ⁱ', 'ⁱ'), ('₰', '₱'),
+  ('\u{20e4}', '\u{20ea}'), ('ℽ', '⅋'), ('⇴', '⇿'), ('⋲', '⋿'),
+  ('⍼', '⍼'), ('⎛', '⏎'), ('⓫', '⓾'), ('▖', '▟'),
+  ('◸', '◿'), ('☖', '☗'), ('♲', '♽'), ('⚀', '⚉'),
+  ('❨', '❵'), ('⟐', '⟫'), ('⟰', '⟿'), ('⤀', '⫿'),
+  ('〻', '〽'), ('ゕ', 'ゖ'), ('ゟ', '゠'), ('ヿ', 'ヿ'),
+  ('ㇰ', 'ㇿ'), ('㉑', '㉟'), ('㊱', '㊿'), ('꒢', '꒣'),
+  ('꒴', '꒴'), ('꓁', '꓁'), ('꓅', '꓅'), ('侮', '頻'),
+  ('﷼', '﷼'), ('\u{fe00}', '\u{fe0f}'), ('﹅', '﹆'), ('ﹳ', 'ﹳ'),
+  ('⦅', '⦆'),
+];
+
+pub const V4_0: &'static [(char, char)] = &[
+  ('ȡ', 'ȡ'), ('ȴ', 'ȶ'), ('ʮ', 'ʯ'), ('˯', '˿'),
+  ('\u{350}', '\u{357}'), ('\u{35d}', '\u{35f}'), ('Ϸ', 'ϻ'),
+  ('\u{600}', '\u{603}'), ('؍', '\u{615}'), ('\u{656}', '\u{658}'),
+  ('ۮ', 'ۯ'), ('ۿ', 'ۿ'), ('ܭ', 'ܯ'), ('ݍ', 'ݏ'), ('ऄ', 'ऄ'),
+  ('ঽ', 'ঽ'), ('\u{a01}', '\u{a01}'), ('ਃ', 'ਃ'), ('ઌ', 'ઌ'),
+  ('ૡ', '\u{ae3}'), ('૱', '૱'), ('ଵ', 'ଵ'), ('ୱ', 'ୱ'),
+  ('௳', '௺'), ('\u{cbc}', 'ಽ'), ('\u{17dd}', '\u{17dd}'),
+  ('៰', '៹'), ('ᤀ', 'ᤜ'), ('\u{1920}', 'ᤫ'), ('ᤰ', '\u{193b}'),
+  ('᥀', '᥀'), ('᥄', 'ᥭ'), ('ᥰ', 'ᥴ'), ('᧠', '᧿'),
+  ('ᴀ', 'ᵫ'), ('⁓', '⁔'), ('℻', '℻'), ('⏏', '⏐'),
+  ('⓿', '⓿'), ('☔', '☕'), ('⚊', '⚑'), ('⚠', '⚡'),
+  ('⬀', '⬍'), ('㈝', '㈞'), ('㉐', '㉐'), ('㉼', '㉽'),
+  ('㋌', '㋏'), ('㍷', '㍺'), ('㏞', '㏟'), ('㏿', '㏿'),
+  ('䷀', '䷿'), ('﷽', '﷽'), ('﹇', '﹈'), ('𐀀', '𐀋'),
+  ('𐀍', '𐀦'), ('𐀨', '𐀺'), ('𐀼', '𐀽'), ('𐀿', '𐁍'),
+  ('𐁐', '𐁝'), ('𐂀', '𐃺'), ('𐄀', '𐄂'), ('𐄇', '𐄳'),
+  ('𐄷', '𐄿'), ('𐎀', '𐎝'), ('𐎟', '𐎟'), ('𐐦', '𐐧'),
+  ('𐑎', '𐒝'), ('𐒠', '𐒩'), ('𐠀', '𐠅'), ('𐠈', '𐠈'),
+  ('𐠊', '𐠵'), ('𐠷', '𐠸'), ('𐠼', '𐠼'), ('𐠿', '𐠿'),
+  ('𝌀', '𝍖'), ('𝓁', '𝓁'), ('\u{e0100}', '\u{e01ef}'),
+];
+
+pub const V4_1: &'static [(char, char)] = &[
+  ('ȷ', 'Ɂ'), ('\u{358}', '\u{35c}'), ('ϼ', 'Ͽ'), ('Ӷ', 'ӷ'),
+  ('\u{5a2}', '\u{5a2}'), ('\u{5c5}', '\u{5c7}'), ('؋', '؋'), ('؞', '؞'),
+  ('\u{659}', '\u{65e}'), ('ݐ', 'ݭ'), ('ॽ', 'ॽ'), ('ৎ', 'ৎ'),
+  ('ஶ', 'ஶ'), ('௦', '௦'), ('࿐', '࿑'), ('ჹ', 'ჺ'),
+  ('ჼ', 'ჼ'), ('ሇ', 'ሇ'), ('ቇ', 'ቇ'), ('ኇ', 'ኇ'),
+  ('ኯ', 'ኯ'), ('ዏ', 'ዏ'), ('ዯ', 'ዯ'), ('ጏ', 'ጏ'),
+  ('ጟ', 'ጟ'), ('ፇ', 'ፇ'), ('\u{135f}', '፠'), ('ᎀ', '᎙'),
+  ('ᦀ', 'ᦩ'), ('ᦰ', 'ᧉ'), ('᧐', '᧙'), ('᧞', '᧟'),
+  ('ᨀ', '\u{1a1b}'), ('᨞', '᨟'), ('ᵬ', '\u{1dc3}'), ('⁕', '⁖'),
+  ('⁘', '⁞'), ('ₐ', 'ₔ'), ('₲', '₵'), ('\u{20eb}', '\u{20eb}'),
+  ('ℼ', 'ℼ'), ('⅌', '⅌'), ('⏑', '⏛'), ('☘', '☘'),
+  ('♾', '♿'), ('⚒', '⚜'), ('⚢', '⚱'), ('⟀', '⟆'),
+  ('⬎', '⬓'), ('Ⰰ', 'Ⱞ'), ('ⰰ', 'ⱞ'), ('Ⲁ', '⳪'),
+  ('⳹', 'ⴥ'), ('ⴰ', 'ⵥ'), ('ⵯ', 'ⵯ'), ('ⶀ', 'ⶖ'),
+  ('ⶠ', 'ⶦ'), ('ⶨ', 'ⶮ'), ('ⶰ', 'ⶶ'), ('ⶸ', 'ⶾ'),
+  ('ⷀ', 'ⷆ'), ('ⷈ', 'ⷎ'), ('ⷐ', 'ⷖ'), ('ⷘ', 'ⷞ'),
+  ('⸀', '⸗'), ('⸜', '⸝'), ('㇀', '㇏'), ('㉾', '㉾'),
+  ('龦', '龻'), ('꜀', '꜖'), ('ꠀ', '꠫'), ('並', '龎'),
+  ('︐', '︙'), ('𐅀', '𐆊'), ('𐎠', '𐏃'), ('𐏈', '𐏕'),
+  ('𐨀', '\u{10a03}'), ('\u{10a05}', '\u{10a06}'), ('\u{10a0c}', '𐨓'),
+  ('𐨕', '𐨗'), ('𐨙', '𐨳'), ('\u{10a38}', '\u{10a3a}'),
+  ('\u{10a3f}', '𐩇'), ('𐩐', '𐩘'), ('𝈀', '𝉅'), ('𝚤', '𝚥'),
+];
+
+pub const V5_0: &'static [(char, char)] = &[
+  ('ɂ', 'ɏ'), ('ͻ', 'ͽ'), ('ӏ', 'ӏ'), ('Ӻ', 'ӿ'), ('Ԑ', 'ԓ'),
+  ('\u{5ba}', '\u{5ba}'), ('߀', 'ߺ'), ('ॻ', 'ॼ'), ('ॾ', 'ॿ'),
+  ('\u{ce2}', '\u{ce3}'), ('ೱ', 'ೲ'), ('\u{1b00}', 'ᭋ'), ('᭐', '᭼'),
+  ('\u{1dc4}', '\u{1dca}'), ('\u{1dfe}', '\u{1dff}'),
+  ('\u{20ec}', '\u{20ef}'), ('⅍', 'ⅎ'), ('ↄ', 'ↄ'), ('⏜', '⏧'),
+  ('⚲', '⚲'), ('⟇', '⟊'), ('⬔', '⬚'), ('⬠', '⬣'),
+  ('Ⱡ', 'ⱬ'), ('ⱴ', 'ⱷ'), ('ꜗ', 'ꜚ'), ('꜠', '꜡'),
+  ('ꡀ', '꡷'), ('𐤀', '𐤙'), ('𐤟', '𐤟'), ('𒀀', '𒍮'),
+  ('𒐀', '𒑢'), ('𒑰', '𒑳'), ('𝍠', '𝍱'), ('𝟊', '𝟋'),
+];
+
+pub const V5_1: &'static [(char, char)] = &[
+  ('Ͱ', 'ͳ'), ('Ͷ', 'ͷ'), ('Ϗ', 'Ϗ'), ('\u{487}', '\u{487}'),
+  ('Ԕ', 'ԣ'), ('؆', '؊'), ('\u{616}', '\u{61a}'), ('ػ', 'ؿ'),
+  ('ݮ', 'ݿ'), ('ॱ', 'ॲ'), ('\u{a51}', '\u{a51}'),
+  ('\u{a75}', '\u{a75}'), ('\u{b44}', '\u{b44}'), ('\u{b62}', '\u{b63}'),
+  ('ௐ', 'ௐ'), ('ఽ', 'ఽ'), ('ౘ', 'ౙ'), ('\u{c62}', '\u{c63}'),
+  ('౸', '౿'), ('ഽ', 'ഽ'), ('\u{d44}', '\u{d44}'),
+  ('\u{d62}', '\u{d63}'), ('൰', '൵'), ('൹', 'ൿ'), ('ཫ', 'ཬ'),
+  ('࿎', '࿎'), ('࿒', '࿔'), ('ဢ', 'ဢ'), ('ဨ', 'ဨ'),
+  ('ါ', 'ါ'), ('\u{1033}', '\u{1035}'), ('\u{103a}', 'ဿ'),
+  ('ၚ', '႙'), ('႞', '႟'), ('ᢪ', 'ᢪ'), ('\u{1b80}', '᮪'),
+  ('ᮮ', '᮹'), ('ᰀ', '\u{1c37}'), ('᰻', '᱉'), ('ᱍ', '᱿'),
+  ('\u{1dcb}', '\u{1de6}'), ('ẜ', 'ẟ'), ('Ỻ', 'ỿ'),
+  ('\u{2064}', '\u{2064}'), ('\u{20f0}', '\u{20f0}'), ('⅏', '⅏'),
+  ('ↅ', 'ↈ'), ('⚝', '⚝'), ('⚳', '⚼'), ('⛀', '⛃'),
+  ('⟌', '⟌'), ('⟬', '⟯'), ('⬛', '⬟'), ('⬤', '⭌'),
+  ('⭐', '⭔'), ('Ɑ', 'Ɐ'), ('ⱱ', 'ⱳ'), ('ⱸ', 'ⱽ'),
+  ('\u{2de0}', '\u{2dff}'), ('⸘', '⸛'), ('⸞', '⸰'), ('ㄭ', 'ㄭ'),
+  ('㇐', '㇣'), ('龼', '鿃'), ('ꔀ', 'ꘫ'), ('Ꙁ', 'ꙟ'),
+  ('Ꙣ', '꙳'), ('\u{a67c}', 'ꚗ'), ('ꜛ', 'ꜟ'), ('Ꜣ', 'ꞌ'),
+  ('ꟻ', 'ꟿ'), ('ꢀ', '\u{a8c4}'), ('꣎', '꣙'), ('꤀', '꥓'),
+  ('꥟', '꥟'), ('ꨀ', '\u{aa36}'), ('ꩀ', 'ꩍ'), ('꩐', '꩙'),
+  ('꩜', '꩟'), ('\u{fe24}', '\u{fe26}'), ('𐆐', '𐆛'),
+  ('𐇐', '\u{101fd}'), ('𐊀', '𐊜'), ('𐊠', '𐋐'), ('𐤠', '𐤹'),
+  ('𐤿', '𐤿'), ('𝄩', '𝄩'), ('🀀', '🀫'), ('🀰', '🂓'),
+];
+
+pub const V5_2: &'static [(char, char)] = &[
+  ('Ԥ', 'ԥ'), ('ࠀ', '\u{82d}'), ('࠰', '࠾'), ('\u{900}', '\u{900}'),
+  ('ॎ', 'ॎ'), ('\u{955}', '\u{955}'), ('ॹ', 'ॺ'), ('৻', '৻'),
+  ('࿕', '࿘'), ('ႚ', '\u{109d}'), ('ᅚ', 'ᅞ'), ('ᆣ', 'ᆧ'),
+  ('ᇺ', 'ᇿ'), ('᐀', '᐀'), ('ᙷ', 'ᙿ'), ('ᢰ', 'ᣵ'),
+  ('ᦪ', 'ᦫ'), ('᧚', '᧚'), ('ᨠ', '\u{1a5e}'),
+  ('\u{1a60}', '\u{1a7c}'), ('\u{1a7f}', '᪉'), ('᪐', '᪙'),
+  ('᪠', '᪭'), ('\u{1cd0}', 'ᳲ'), ('\u{1dfd}', '\u{1dfd}'),
+  ('₶', '₸'), ('⅐', '⅒'), ('↉', '↉'), ('⏨', '⏨'),
+  ('⚞', '⚟'), ('⚽', '⚿'), ('⛄', '⛍'), ('⛏', '⛡'),
+  ('⛣', '⛣'), ('⛨', '⛿'), ('❗', '❗'), ('⭕', '⭙'),
+  ('Ɒ', 'Ɒ'), ('Ȿ', 'Ɀ'), ('Ⳬ', '\u{2cf1}'), ('⸱', '⸱'),
+  ('㉄', '㉏'), ('鿄', '鿋'), ('ꓐ', '꓿'), ('ꚠ', '꛷'),
+  ('꠰', '꠹'), ('\u{a8e0}', 'ꣻ'), ('ꥠ', 'ꥼ'), ('\u{a980}', '꧍'),
+  ('ꧏ', '꧙'), ('꧞', '꧟'), ('ꩠ', 'ꩻ'), ('ꪀ', 'ꫂ'),
+  ('ꫛ', '꫟'), ('ꯀ', '\u{abed}'), ('꯰', '꯹'), ('ힰ', 'ퟆ'),
+  ('ퟋ', 'ퟻ'), ('恵', '舘'), ('𐡀', '𐡕'), ('𐡗', '𐡟'),
+  ('𐤚', '𐤛'), ('𐩠', '𐩿'), ('𐬀', '𐬵'), ('𐬹', '𐭕'),
+  ('𐭘', '𐭲'), ('𐭸', '𐭿'), ('𐰀', '𐱈'), ('𐹠', '𐹾'),
+  ('\u{11080}', '𑃁'), ('𓀀', '𓐮'), ('🄀', '🄊'), ('🄐', '🄮'),
+  ('🄱', '🄱'), ('🄽', '🄽'), ('🄿', '🄿'), ('🅂', '🅂'),
+  ('🅆', '🅆'), ('🅊', '🅎'), ('🅗', '🅗'), ('🅟', '🅟'),
+  ('🅹', '🅹'), ('🅻', '🅼'), ('🅿', '🅿'), ('🆊', '🆍'),
+  ('🆐', '🆐'), ('🈀', '🈀'), ('🈐', '🈱'), ('🉀', '🉈'),
+  ('𪜀', '𫜴'),
+];
+
+pub const V6_0: &'static [(char, char)] = &[
+  ('Ԧ', 'ԧ'), ('ؠ', 'ؠ'), ('\u{65f}', '\u{65f}'), ('ࡀ', '\u{85b}'),
+  ('࡞', '࡞'), ('\u{93a}', 'ऻ'), ('ॏ', 'ॏ'), ('\u{956}', '\u{957}'),
+  ('ॳ', 'ॷ'), ('୲', '୷'), ('ഩ', 'ഩ'), ('ഺ', 'ഺ'),
+  ('ൎ', 'ൎ'), ('ྌ', '\u{f8f}'), ('࿙', '࿚'),
+  ('\u{135d}', '\u{135e}'), ('ᯀ', '᯳'), ('᯼', '᯿'),
+  ('\u{1dfc}', '\u{1dfc}'), ('ₕ', 'ₜ'), ('₹', '₹'), ('⏩', '⏳'),
+  ('⛎', '⛎'), ('⛢', '⛢'), ('⛤', '⛧'), ('✅', '✅'),
+  ('✊', '✋'), ('✨', '✨'), ('❌', '❌'), ('❎', '❎'),
+  ('❓', '❕'), ('❟', '❠'), ('➕', '➗'), ('➰', '➰'),
+  ('➿', '➿'), ('⟎', '⟏'), ('⵰', '⵰'), ('\u{2d7f}', '\u{2d7f}'),
+  ('ㆸ', 'ㆺ'), ('Ꙡ', 'ꙡ'), ('Ɥ', 'ꞎ'), ('Ꞑ', 'ꞑ'),
+  ('Ꞡ', 'ꞩ'), ('ꟺ', 'ꟺ'), ('ꬁ', 'ꬆ'), ('ꬉ', 'ꬎ'),
+  ('ꬑ', 'ꬖ'), ('ꬠ', 'ꬦ'), ('ꬨ', 'ꬮ'), ('﮲', '﯁'),
+  ('𑀀', '𑁍'), ('𑁒', '𑁯'), ('𖠀', '𖨸'), ('𛀀', '𛀁'),
+  ('🂠', '🂮'), ('🂱', '🂾'), ('🃁', '🃏'), ('🃑', '🃟'),
+  ('🄰', '🄰'), ('🄲', '🄼'), ('🄾', '🄾'), ('🅀', '🅁'),
+  ('🅃', '🅅'), ('🅇', '🅉'), ('🅏', '🅖'), ('🅘', '🅞'),
+  ('🅠', '🅩'), ('🅰', '🅸'), ('🅺', '🅺'), ('🅽', '🅾'),
+  ('🆀', '🆉'), ('🆎', '🆏'), ('🆑', '🆚'), ('🇦', '🇿'),
+  ('🈁', '🈂'), ('🈲', '🈺'), ('🉐', '🉑'), ('🌀', '🌠'),
+  ('🌰', '🌵'), ('🌷', '🍼'), ('🎀', '🎓'), ('🎠', '🏄'),
+  ('🏆', '🏊'), ('🏠', '🏰'), ('🐀', '🐾'), ('👀', '👀'),
+  ('👂', '📷'), ('📹', '📼'), ('🔀', '🔽'), ('🕐', '🕧'),
+  ('🗻', '🗿'), ('😁', '😐'), ('😒', '😔'), ('😖', '😖'),
+  ('😘', '😘'), ('😚', '😚'), ('😜', '😞'), ('😠', '😥'),
+  ('😨', '😫'), ('😭', '😭'), ('😰', '😳'), ('😵', '🙀'),
+  ('🙅', '🙏'), ('🚀', '🛅'), ('🜀', '🝳'), ('𫝀', '𫠝'),
+];
+
+pub const V6_1: &'static [(char, char)] = &[
+  ('֏', '֏'), ('\u{604}', '\u{604}'), ('ࢠ', 'ࢠ'), ('ࢢ', 'ࢬ'),
+  ('\u{8e4}', '\u{8fe}'), ('૰', '૰'), ('ໞ', 'ໟ'), ('Ⴧ', 'Ⴧ'),
+  ('Ⴭ', 'Ⴭ'), ('ჽ', 'ჿ'), ('\u{1bab}', '\u{1bad}'), ('ᮺ', 'ᮿ'),
+  ('᳀', '᳇'), ('ᳳ', 'ᳶ'), ('⟋', '⟋'), ('⟍', '⟍'),
+  ('Ⳳ', 'ⳳ'), ('ⴧ', 'ⴧ'), ('ⴭ', 'ⴭ'), ('ⵦ', 'ⵧ'),
+  ('⸲', '⸻'), ('鿌', '鿌'), ('\u{a674}', '\u{a67b}'),
+  ('\u{a69f}', '\u{a69f}'), ('Ꞓ', 'ꞓ'), ('Ɦ', 'Ɦ'), ('ꟸ', 'ꟹ'),
+  ('ꫠ', '\u{aaf6}'), ('郞', '隷'), ('𐦀', '𐦷'), ('𐦾', '𐦿'),
+  ('𑃐', '𑃨'), ('𑃰', '𑃹'), ('\u{11100}', '\u{11134}'),
+  ('𑄶', '𑅃'), ('\u{11180}', '𑇈'), ('𑇐', '𑇙'),
+  ('𑚀', '\u{116b7}'), ('𑛀', '𑛉'), ('𖼀', '𖽄'), ('𖽐', '𖽾'),
+  ('\u{16f8f}', '𖾟'), ('𞸀', '𞸃'), ('𞸅', '𞸟'), ('𞸡', '𞸢'),
+  ('𞸤', '𞸤'), ('𞸧', '𞸧'), ('𞸩', '𞸲'), ('𞸴', '𞸷'),
+  ('𞸹', '𞸹'), ('𞸻', '𞸻'), ('𞹂', '𞹂'), ('𞹇', '𞹇'),
+  ('𞹉', '𞹉'), ('𞹋', '𞹋'), ('𞹍', '𞹏'), ('𞹑', '𞹒'),
+  ('𞹔', '𞹔'), ('𞹗', '𞹗'), ('𞹙', '𞹙'), ('𞹛', '𞹛'),
+  ('𞹝', '𞹝'), ('𞹟', '𞹟'), ('𞹡', '𞹢'), ('𞹤', '𞹤'),
+  ('𞹧', '𞹪'), ('𞹬', '𞹲'), ('𞹴', '𞹷'), ('𞹹', '𞹼'),
+  ('𞹾', '𞹾'), ('𞺀', '𞺉'), ('𞺋', '𞺛'), ('𞺡', '𞺣'),
+  ('𞺥', '𞺩'), ('𞺫', '𞺻'), ('𞻰', '𞻱'), ('🅪', '🅫'),
+  ('🕀', '🕃'), ('😀', '😀'), ('😑', '😑'), ('😕', '😕'),
+  ('😗', '😗'), ('😙', '😙'), ('😛', '😛'), ('😟', '😟'),
+  ('😦', '😧'), ('😬', '😬'), ('😮', '😯'), ('😴', '😴'),
+];
+
+pub const V6_2: &'static [(char, char)] = &[
+  ('₺', '₺'),
+];
+
+pub const V6_3: &'static [(char, char)] = &[
+  ('\u{61c}', '\u{61c}'), ('\u{2066}', '\u{2069}'),
+];
+
+pub const V7_0: &'static [(char, char)] = &[
+  ('Ϳ', 'Ϳ'), ('Ԩ', 'ԯ'), ('֍', '֎'), ('\u{605}', '\u{605}'),
+  ('ࢡ', 'ࢡ'), ('ࢭ', 'ࢲ'), ('\u{8ff}', '\u{8ff}'), ('ॸ', 'ॸ'),
+  ('ঀ', 'ঀ'), ('\u{c00}', '\u{c00}'), ('ఴ', 'ఴ'),
+  ('\u{c81}', '\u{c81}'), ('\u{d01}', '\u{d01}'), ('෦', '෯'),
+  ('ᛱ', 'ᛸ'), ('ᤝ', 'ᤞ'), ('\u{1ab0}', '\u{1abe}'),
+  ('\u{1cf8}', '\u{1cf9}'), ('\u{1de7}', '\u{1df5}'), ('₻', '₽'),
+  ('⏴', '⏺'), ('✀', '✀'), ('⭍', '⭏'), ('⭚', '⭳'),
+  ('⭶', '⮕'), ('⮘', '⮹'), ('⮽', '⯈'), ('⯊', '⯑'),
+  ('⸼', '⹂'), ('Ꚙ', 'ꚝ'), ('ꞔ', 'ꞟ'), ('Ɜ', 'Ɬ'),
+  ('Ʞ', 'Ʇ'), ('ꟷ', 'ꟷ'), ('ꧠ', 'ꧾ'), ('\u{aa7c}', 'ꩿ'),
+  ('ꬰ', 'ꭟ'), ('ꭤ', 'ꭥ'), ('\u{fe27}', '\u{fe2d}'), ('𐆋', '𐆌'),
+  ('𐆠', '𐆠'), ('\u{102e0}', '𐋻'), ('𐌟', '𐌟'),
+  ('𐍐', '\u{1037a}'), ('𐔀', '𐔧'), ('𐔰', '𐕣'), ('𐕯', '𐕯'),
+  ('𐘀', '𐜶'), ('𐝀', '𐝕'), ('𐝠', '𐝧'), ('𐡠', '𐢞'),
+  ('𐢧', '𐢯'), ('𐪀', '𐪟'), ('𐫀', '\u{10ae6}'), ('𐫫', '𐫶'),
+  ('𐮀', '𐮑'), ('𐮙', '𐮜'), ('𐮩', '𐮯'),
+  ('\u{1107f}', '\u{1107f}'), ('𑅐', '𑅶'), ('𑇍', '𑇍'),
+  ('𑇚', '𑇚'), ('𑇡', '𑇴'), ('𑈀', '𑈑'), ('𑈓', '𑈽'),
+  ('𑊰', '\u{112ea}'), ('𑋰', '𑋹'), ('\u{11301}', '𑌃'),
+  ('𑌅', '𑌌'), ('𑌏', '𑌐'), ('𑌓', '𑌨'), ('𑌪', '𑌰'),
+  ('𑌲', '𑌳'), ('𑌵', '𑌹'), ('\u{1133c}', '𑍄'), ('𑍇', '𑍈'),
+  ('𑍋', '𑍍'), ('\u{11357}', '\u{11357}'), ('𑍝', '𑍣'),
+  ('\u{11366}', '\u{1136c}'), ('\u{11370}', '\u{11374}'), ('𑒀', '𑓇'),
+  ('𑓐', '𑓙'), ('𑖀', '\u{115b5}'), ('𑖸', '𑗉'), ('𑘀', '𑙄'),
+  ('𑙐', '𑙙'), ('𑢠', '𑣲'), ('𑣿', '𑣿'), ('𑫀', '𑫸'),
+  ('𒍯', '𒎘'), ('𒑣', '𒑮'), ('𒑴', '𒑴'), ('𖩀', '𖩞'),
+  ('𖩠', '𖩩'), ('𖩮', '𖩯'), ('𖫐', '𖫭'), ('\u{16af0}', '𖫵'),
+  ('𖬀', '𖭅'), ('𖭐', '𖭙'), ('𖭛', '𖭡'), ('𖭣', '𖭷'),
+  ('𖭽', '𖮏'), ('𛰀', '𛱪'), ('𛱰', '𛱼'), ('𛲀', '𛲈'),
+  ('𛲐', '𛲙'), ('𛲜', '\u{1bca3}'), ('𞠀', '𞣄'),
+  ('𞣇', '\u{1e8d6}'), ('🂿', '🂿'), ('🃠', '🃵'), ('🄋', '🄌'),
+  ('🌡', '🌬'), ('🌶', '🌶'), ('🍽', '🍽'), ('🎔', '🎟'),
+  ('🏅', '🏅'), ('🏋', '🏎'), ('🏔', '🏟'), ('🏱', '🏷'),
+  ('🐿', '🐿'), ('👁', '👁'), ('📸', '📸'), ('📽', '📾'),
+  ('🔾', '🔿'), ('🕄', '🕊'), ('🕨', '🕹'), ('🕻', '🖣'),
+  ('🖥', '🗺'), ('🙁', '🙂'), ('🙐', '🙿'), ('🛆', '🛏'),
+  ('🛠', '🛬'), ('🛰', '🛳'), ('🞀', '🟔'), ('🠀', '🠋'),
+  ('🠐', '🡇'), ('🡐', '🡙'), ('🡠', '🢇'), ('🢐', '🢭'),
+];
+
+pub const V8_0: &'static [(char, char)] = &[
+  ('ࢳ', 'ࢴ'), ('\u{8e3}', '\u{8e3}'), ('ૹ', 'ૹ'), ('ౚ', 'ౚ'),
+  ('ൟ', 'ൟ'), ('Ᏽ', 'Ᏽ'), ('ᏸ', 'ᏽ'), ('₾', '₾'),
+  ('↊', '↋'), ('⯬', '⯯'), ('鿍', '鿕'), ('\u{a69e}', '\u{a69e}'),
+  ('ꞏ', 'ꞏ'), ('Ʝ', 'ꞷ'), ('꣼', 'ꣽ'), ('ꭠ', 'ꭣ'),
+  ('ꭰ', 'ꮿ'), ('\u{fe2e}', '\u{fe2f}'), ('𐣠', '𐣲'),
+  ('𐣴', '𐣵'), ('𐣻', '𐣿'), ('𐦼', '𐦽'), ('𐧀', '𐧏'),
+  ('𐧒', '𐧿'), ('𐲀', '𐲲'), ('𐳀', '𐳲'), ('𐳺', '𐳿'),
+  ('\u{111c9}', '\u{111cc}'), ('𑇛', '𑇟'), ('𑊀', '𑊆'),
+  ('𑊈', '𑊈'), ('𑊊', '𑊍'), ('𑊏', '𑊝'), ('𑊟', '𑊩'),
+  ('\u{11300}', '\u{11300}'), ('𑍐', '𑍐'), ('𑗊', '\u{115dd}'),
+  ('𑜀', '𑜙'), ('\u{1171d}', '\u{1172b}'), ('𑜰', '𑜿'),
+  ('𒎙', '𒎙'), ('𒒀', '𒕃'), ('𔐀', '𔙆'), ('𝇞', '𝇨'),
+  ('𝠀', '𝪋'), ('\u{1da9b}', '\u{1da9f}'), ('\u{1daa1}', '\u{1daaf}'),
+  ('🌭', '🌯'), ('🍾', '🍿'), ('🏏', '🏓'), ('🏸', '🏿'),
+  ('📿', '📿'), ('🕋', '🕏'), ('🙃', '🙄'), ('🛐', '🛐'),
+  ('🤐', '🤘'), ('🦀', '🦄'), ('🧀', '🧀'), ('𫠠', '𬺡'),
+];
+
+pub const V9_0: &'static [(char, char)] = &[
+  ('ࢶ', 'ࢽ'), ('\u{8d4}', '\u{8e2}'), ('ಀ', 'ಀ'), ('൏', '൏'),
+  ('ൔ', 'ൖ'), ('൘', '൞'), ('൶', '൸'), ('ᲀ', 'ᲈ'),
+  ('\u{1dfb}', '\u{1dfb}'), ('⏻', '⏾'), ('⹃', '⹄'), ('Ɪ', 'Ɪ'),
+  ('\u{a8c5}', '\u{a8c5}'), ('𐆍', '𐆎'), ('𐒰', '𐓓'),
+  ('𐓘', '𐓻'), ('\u{1123e}', '\u{1123e}'), ('𑐀', '𑑙'),
+  ('𑑛', '𑑛'), ('𑑝', '𑑝'), ('𑙠', '𑙬'), ('𑰀', '𑰈'),
+  ('𑰊', '\u{11c36}'), ('\u{11c38}', '𑱅'), ('𑱐', '𑱬'),
+  ('𑱰', '𑲏'), ('\u{11c92}', '\u{11ca7}'), ('𑲩', '\u{11cb6}'),
+  ('𖿠', '𖿠'), ('𗀀', '𘟬'), ('𘠀', '𘫲'),
+  ('\u{1e000}', '\u{1e006}'), ('\u{1e008}', '\u{1e018}'),
+  ('\u{1e01b}', '\u{1e021}'), ('\u{1e023}', '\u{1e024}'),
+  ('\u{1e026}', '\u{1e02a}'), ('𞤀', '\u{1e94a}'), ('𞥐', '𞥙'),
+  ('𞥞', '𞥟'), ('🆛', '🆬'), ('🈻', '🈻'), ('🕺', '🕺'),
+  ('🖤', '🖤'), ('🛑', '🛒'), ('🛴', '🛶'), ('🤙', '🤞'),
+  ('🤠', '🤧'), ('🤰', '🤰'), ('🤳', '🤾'), ('🥀', '🥋'),
+  ('🥐', '🥞'), ('🦅', '🦑'),
+];
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/unicode_tables/case_folding_simple.rs.html b/target/doc/src/regex_syntax/unicode_tables/case_folding_simple.rs.html new file mode 100644 index 0000000..ab373f2 --- /dev/null +++ b/target/doc/src/regex_syntax/unicode_tables/case_folding_simple.rs.html @@ -0,0 +1,1421 @@ +case_folding_simple.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+
+// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
+//
+//  ucd-generate case-folding-simple /tmp/ucd-12.1.0/ --chars --all-pairs
+//
+// ucd-generate is available on crates.io.
+
+pub const CASE_FOLDING_SIMPLE: &'static [(char, &'static [char])] = &[
+  ('A', &['a']), ('B', &['b']), ('C', &['c']), ('D', &['d']), ('E', &['e']),
+  ('F', &['f']), ('G', &['g']), ('H', &['h']), ('I', &['i']), ('J', &['j']),
+  ('K', &['k', 'K', ]), ('L', &['l']), ('M', &['m']), ('N', &['n']), ('O', &[
+  'o']), ('P', &['p']), ('Q', &['q']), ('R', &['r']), ('S', &['s', 'ſ', ]),
+  ('T', &['t']), ('U', &['u']), ('V', &['v']), ('W', &['w']), ('X', &['x']),
+  ('Y', &['y']), ('Z', &['z']), ('a', &['A']), ('b', &['B']), ('c', &['C']),
+  ('d', &['D']), ('e', &['E']), ('f', &['F']), ('g', &['G']), ('h', &['H']),
+  ('i', &['I']), ('j', &['J']), ('k', &['K', 'K', ]), ('l', &['L']), ('m', &[
+  'M']), ('n', &['N']), ('o', &['O']), ('p', &['P']), ('q', &['Q']), ('r', &[
+  'R']), ('s', &['S', 'ſ', ]), ('t', &['T']), ('u', &['U']), ('v', &['V']),
+  ('w', &['W']), ('x', &['X']), ('y', &['Y']), ('z', &['Z']), ('µ', &['Μ',
+  'μ', ]), ('À', &['à']), ('Á', &['á']), ('Â', &['â']), ('Ã', &['ã'
+  ]), ('Ä', &['ä']), ('Å', &['å', 'Å', ]), ('Æ', &['æ']), ('Ç', &['ç'
+  ]), ('È', &['è']), ('É', &['é']), ('Ê', &['ê']), ('Ë', &['ë']),
+  ('Ì', &['ì']), ('Í', &['í']), ('Î', &['î']), ('Ï', &['ï']), ('Ð', &[
+  'ð']), ('Ñ', &['ñ']), ('Ò', &['ò']), ('Ó', &['ó']), ('Ô', &['ô']),
+  ('Õ', &['õ']), ('Ö', &['ö']), ('Ø', &['ø']), ('Ù', &['ù']), ('Ú', &[
+  'ú']), ('Û', &['û']), ('Ü', &['ü']), ('Ý', &['ý']), ('Þ', &['þ']),
+  ('ß', &['ẞ']), ('à', &['À']), ('á', &['Á']), ('â', &['Â']),
+  ('ã', &['Ã']), ('ä', &['Ä']), ('å', &['Å', 'Å', ]), ('æ', &['Æ']),
+  ('ç', &['Ç']), ('è', &['È']), ('é', &['É']), ('ê', &['Ê']), ('ë', &[
+  'Ë']), ('ì', &['Ì']), ('í', &['Í']), ('î', &['Î']), ('ï', &['Ï']),
+  ('ð', &['Ð']), ('ñ', &['Ñ']), ('ò', &['Ò']), ('ó', &['Ó']), ('ô', &[
+  'Ô']), ('õ', &['Õ']), ('ö', &['Ö']), ('ø', &['Ø']), ('ù', &['Ù']),
+  ('ú', &['Ú']), ('û', &['Û']), ('ü', &['Ü']), ('ý', &['Ý']), ('þ', &[
+  'Þ']), ('ÿ', &['Ÿ']), ('Ā', &['ā']), ('ā', &['Ā']), ('Ă', &['ă']),
+  ('ă', &['Ă']), ('Ą', &['ą']), ('ą', &['Ą']), ('Ć', &['ć']), ('ć', &[
+  'Ć']), ('Ĉ', &['ĉ']), ('ĉ', &['Ĉ']), ('Ċ', &['ċ']), ('ċ', &['Ċ']),
+  ('Č', &['č']), ('č', &['Č']), ('Ď', &['ď']), ('ď', &['Ď']), ('Đ', &[
+  'đ']), ('đ', &['Đ']), ('Ē', &['ē']), ('ē', &['Ē']), ('Ĕ', &['ĕ']),
+  ('ĕ', &['Ĕ']), ('Ė', &['ė']), ('ė', &['Ė']), ('Ę', &['ę']), ('ę', &[
+  'Ę']), ('Ě', &['ě']), ('ě', &['Ě']), ('Ĝ', &['ĝ']), ('ĝ', &['Ĝ']),
+  ('Ğ', &['ğ']), ('ğ', &['Ğ']), ('Ġ', &['ġ']), ('ġ', &['Ġ']), ('Ģ', &[
+  'ģ']), ('ģ', &['Ģ']), ('Ĥ', &['ĥ']), ('ĥ', &['Ĥ']), ('Ħ', &['ħ']),
+  ('ħ', &['Ħ']), ('Ĩ', &['ĩ']), ('ĩ', &['Ĩ']), ('Ī', &['ī']), ('ī', &[
+  'Ī']), ('Ĭ', &['ĭ']), ('ĭ', &['Ĭ']), ('Į', &['į']), ('į', &['Į']),
+  ('IJ', &['ij']), ('ij', &['IJ']), ('Ĵ', &['ĵ']), ('ĵ', &['Ĵ']), ('Ķ', &[
+  'ķ']), ('ķ', &['Ķ']), ('Ĺ', &['ĺ']), ('ĺ', &['Ĺ']), ('Ļ', &['ļ']),
+  ('ļ', &['Ļ']), ('Ľ', &['ľ']), ('ľ', &['Ľ']), ('Ŀ', &['ŀ']), ('ŀ', &[
+  'Ŀ']), ('Ł', &['ł']), ('ł', &['Ł']), ('Ń', &['ń']), ('ń', &['Ń']),
+  ('Ņ', &['ņ']), ('ņ', &['Ņ']), ('Ň', &['ň']), ('ň', &['Ň']), ('Ŋ', &[
+  'ŋ']), ('ŋ', &['Ŋ']), ('Ō', &['ō']), ('ō', &['Ō']), ('Ŏ', &['ŏ']),
+  ('ŏ', &['Ŏ']), ('Ő', &['ő']), ('ő', &['Ő']), ('Œ', &['œ']), ('œ', &[
+  'Œ']), ('Ŕ', &['ŕ']), ('ŕ', &['Ŕ']), ('Ŗ', &['ŗ']), ('ŗ', &['Ŗ']),
+  ('Ř', &['ř']), ('ř', &['Ř']), ('Ś', &['ś']), ('ś', &['Ś']), ('Ŝ', &[
+  'ŝ']), ('ŝ', &['Ŝ']), ('Ş', &['ş']), ('ş', &['Ş']), ('Š', &['š']),
+  ('š', &['Š']), ('Ţ', &['ţ']), ('ţ', &['Ţ']), ('Ť', &['ť']), ('ť', &[
+  'Ť']), ('Ŧ', &['ŧ']), ('ŧ', &['Ŧ']), ('Ũ', &['ũ']), ('ũ', &['Ũ']),
+  ('Ū', &['ū']), ('ū', &['Ū']), ('Ŭ', &['ŭ']), ('ŭ', &['Ŭ']), ('Ů', &[
+  'ů']), ('ů', &['Ů']), ('Ű', &['ű']), ('ű', &['Ű']), ('Ų', &['ų']),
+  ('ų', &['Ų']), ('Ŵ', &['ŵ']), ('ŵ', &['Ŵ']), ('Ŷ', &['ŷ']), ('ŷ', &[
+  'Ŷ']), ('Ÿ', &['ÿ']), ('Ź', &['ź']), ('ź', &['Ź']), ('Ż', &['ż']),
+  ('ż', &['Ż']), ('Ž', &['ž']), ('ž', &['Ž']), ('ſ', &['S', 's', ]),
+  ('ƀ', &['Ƀ']), ('Ɓ', &['ɓ']), ('Ƃ', &['ƃ']), ('ƃ', &['Ƃ']), ('Ƅ', &[
+  'ƅ']), ('ƅ', &['Ƅ']), ('Ɔ', &['ɔ']), ('Ƈ', &['ƈ']), ('ƈ', &['Ƈ']),
+  ('Ɖ', &['ɖ']), ('Ɗ', &['ɗ']), ('Ƌ', &['ƌ']), ('ƌ', &['Ƌ']), ('Ǝ', &[
+  'ǝ']), ('Ə', &['ə']), ('Ɛ', &['ɛ']), ('Ƒ', &['ƒ']), ('ƒ', &['Ƒ']),
+  ('Ɠ', &['ɠ']), ('Ɣ', &['ɣ']), ('ƕ', &['Ƕ']), ('Ɩ', &['ɩ']), ('Ɨ', &[
+  'ɨ']), ('Ƙ', &['ƙ']), ('ƙ', &['Ƙ']), ('ƚ', &['Ƚ']), ('Ɯ', &['ɯ']),
+  ('Ɲ', &['ɲ']), ('ƞ', &['Ƞ']), ('Ɵ', &['ɵ']), ('Ơ', &['ơ']), ('ơ', &[
+  'Ơ']), ('Ƣ', &['ƣ']), ('ƣ', &['Ƣ']), ('Ƥ', &['ƥ']), ('ƥ', &['Ƥ']),
+  ('Ʀ', &['ʀ']), ('Ƨ', &['ƨ']), ('ƨ', &['Ƨ']), ('Ʃ', &['ʃ']), ('Ƭ', &[
+  'ƭ']), ('ƭ', &['Ƭ']), ('Ʈ', &['ʈ']), ('Ư', &['ư']), ('ư', &['Ư']),
+  ('Ʊ', &['ʊ']), ('Ʋ', &['ʋ']), ('Ƴ', &['ƴ']), ('ƴ', &['Ƴ']), ('Ƶ', &[
+  'ƶ']), ('ƶ', &['Ƶ']), ('Ʒ', &['ʒ']), ('Ƹ', &['ƹ']), ('ƹ', &['Ƹ']),
+  ('Ƽ', &['ƽ']), ('ƽ', &['Ƽ']), ('ƿ', &['Ƿ']), ('DŽ', &['Dž', 'dž', ]),
+  ('Dž', &['DŽ', 'dž', ]), ('dž', &['DŽ', 'Dž', ]), ('LJ', &['Lj', 'lj', ]),
+  ('Lj', &['LJ', 'lj', ]), ('lj', &['LJ', 'Lj', ]), ('NJ', &['Nj', 'nj', ]),
+  ('Nj', &['NJ', 'nj', ]), ('nj', &['NJ', 'Nj', ]), ('Ǎ', &['ǎ']), ('ǎ', &[
+  'Ǎ']), ('Ǐ', &['ǐ']), ('ǐ', &['Ǐ']), ('Ǒ', &['ǒ']), ('ǒ', &['Ǒ']),
+  ('Ǔ', &['ǔ']), ('ǔ', &['Ǔ']), ('Ǖ', &['ǖ']), ('ǖ', &['Ǖ']), ('Ǘ', &[
+  'ǘ']), ('ǘ', &['Ǘ']), ('Ǚ', &['ǚ']), ('ǚ', &['Ǚ']), ('Ǜ', &['ǜ']),
+  ('ǜ', &['Ǜ']), ('ǝ', &['Ǝ']), ('Ǟ', &['ǟ']), ('ǟ', &['Ǟ']), ('Ǡ', &[
+  'ǡ']), ('ǡ', &['Ǡ']), ('Ǣ', &['ǣ']), ('ǣ', &['Ǣ']), ('Ǥ', &['ǥ']),
+  ('ǥ', &['Ǥ']), ('Ǧ', &['ǧ']), ('ǧ', &['Ǧ']), ('Ǩ', &['ǩ']), ('ǩ', &[
+  'Ǩ']), ('Ǫ', &['ǫ']), ('ǫ', &['Ǫ']), ('Ǭ', &['ǭ']), ('ǭ', &['Ǭ']),
+  ('Ǯ', &['ǯ']), ('ǯ', &['Ǯ']), ('DZ', &['Dz', 'dz', ]), ('Dz', &['DZ',
+  'dz', ]), ('dz', &['DZ', 'Dz', ]), ('Ǵ', &['ǵ']), ('ǵ', &['Ǵ']),
+  ('Ƕ', &['ƕ']), ('Ƿ', &['ƿ']), ('Ǹ', &['ǹ']), ('ǹ', &['Ǹ']), ('Ǻ', &[
+  'ǻ']), ('ǻ', &['Ǻ']), ('Ǽ', &['ǽ']), ('ǽ', &['Ǽ']), ('Ǿ', &['ǿ']),
+  ('ǿ', &['Ǿ']), ('Ȁ', &['ȁ']), ('ȁ', &['Ȁ']), ('Ȃ', &['ȃ']), ('ȃ', &[
+  'Ȃ']), ('Ȅ', &['ȅ']), ('ȅ', &['Ȅ']), ('Ȇ', &['ȇ']), ('ȇ', &['Ȇ']),
+  ('Ȉ', &['ȉ']), ('ȉ', &['Ȉ']), ('Ȋ', &['ȋ']), ('ȋ', &['Ȋ']), ('Ȍ', &[
+  'ȍ']), ('ȍ', &['Ȍ']), ('Ȏ', &['ȏ']), ('ȏ', &['Ȏ']), ('Ȑ', &['ȑ']),
+  ('ȑ', &['Ȑ']), ('Ȓ', &['ȓ']), ('ȓ', &['Ȓ']), ('Ȕ', &['ȕ']), ('ȕ', &[
+  'Ȕ']), ('Ȗ', &['ȗ']), ('ȗ', &['Ȗ']), ('Ș', &['ș']), ('ș', &['Ș']),
+  ('Ț', &['ț']), ('ț', &['Ț']), ('Ȝ', &['ȝ']), ('ȝ', &['Ȝ']), ('Ȟ', &[
+  'ȟ']), ('ȟ', &['Ȟ']), ('Ƞ', &['ƞ']), ('Ȣ', &['ȣ']), ('ȣ', &['Ȣ']),
+  ('Ȥ', &['ȥ']), ('ȥ', &['Ȥ']), ('Ȧ', &['ȧ']), ('ȧ', &['Ȧ']), ('Ȩ', &[
+  'ȩ']), ('ȩ', &['Ȩ']), ('Ȫ', &['ȫ']), ('ȫ', &['Ȫ']), ('Ȭ', &['ȭ']),
+  ('ȭ', &['Ȭ']), ('Ȯ', &['ȯ']), ('ȯ', &['Ȯ']), ('Ȱ', &['ȱ']), ('ȱ', &[
+  'Ȱ']), ('Ȳ', &['ȳ']), ('ȳ', &['Ȳ']), ('Ⱥ', &['ⱥ']), ('Ȼ', &['ȼ']),
+  ('ȼ', &['Ȼ']), ('Ƚ', &['ƚ']), ('Ⱦ', &['ⱦ']), ('ȿ', &['Ȿ']),
+  ('ɀ', &['Ɀ']), ('Ɂ', &['ɂ']), ('ɂ', &['Ɂ']), ('Ƀ', &['ƀ']),
+  ('Ʉ', &['ʉ']), ('Ʌ', &['ʌ']), ('Ɇ', &['ɇ']), ('ɇ', &['Ɇ']), ('Ɉ', &[
+  'ɉ']), ('ɉ', &['Ɉ']), ('Ɋ', &['ɋ']), ('ɋ', &['Ɋ']), ('Ɍ', &['ɍ']),
+  ('ɍ', &['Ɍ']), ('Ɏ', &['ɏ']), ('ɏ', &['Ɏ']), ('ɐ', &['Ɐ']),
+  ('ɑ', &['Ɑ']), ('ɒ', &['Ɒ']), ('ɓ', &['Ɓ']), ('ɔ', &['Ɔ']),
+  ('ɖ', &['Ɖ']), ('ɗ', &['Ɗ']), ('ə', &['Ə']), ('ɛ', &['Ɛ']), ('ɜ', &[
+  'Ɜ']), ('ɠ', &['Ɠ']), ('ɡ', &['Ɡ']), ('ɣ', &['Ɣ']), ('ɥ', &['Ɥ'
+  ]), ('ɦ', &['Ɦ']), ('ɨ', &['Ɨ']), ('ɩ', &['Ɩ']), ('ɪ', &['Ɪ']),
+  ('ɫ', &['Ɫ']), ('ɬ', &['Ɬ']), ('ɯ', &['Ɯ']), ('ɱ', &['Ɱ']),
+  ('ɲ', &['Ɲ']), ('ɵ', &['Ɵ']), ('ɽ', &['Ɽ']), ('ʀ', &['Ʀ']),
+  ('ʂ', &['\u{a7c5}']), ('ʃ', &['Ʃ']), ('ʇ', &['Ʇ']), ('ʈ', &['Ʈ']),
+  ('ʉ', &['Ʉ']), ('ʊ', &['Ʊ']), ('ʋ', &['Ʋ']), ('ʌ', &['Ʌ']), ('ʒ', &[
+  'Ʒ']), ('ʝ', &['Ʝ']), ('ʞ', &['Ʞ']), ('\u{345}', &['Ι', 'ι', 'ι',
+  ]), ('Ͱ', &['ͱ']), ('ͱ', &['Ͱ']), ('Ͳ', &['ͳ']), ('ͳ', &['Ͳ']),
+  ('Ͷ', &['ͷ']), ('ͷ', &['Ͷ']), ('ͻ', &['Ͻ']), ('ͼ', &['Ͼ']), ('ͽ', &[
+  'Ͽ']), ('Ϳ', &['ϳ']), ('Ά', &['ά']), ('Έ', &['έ']), ('Ή', &['ή']),
+  ('Ί', &['ί']), ('Ό', &['ό']), ('Ύ', &['ύ']), ('Ώ', &['ώ']), ('Α', &[
+  'α']), ('Β', &['β', 'ϐ', ]), ('Γ', &['γ']), ('Δ', &['δ']), ('Ε', &[
+  'ε', 'ϵ', ]), ('Ζ', &['ζ']), ('Η', &['η']), ('Θ', &['θ', 'ϑ', 'ϴ',
+  ]), ('Ι', &['\u{345}', 'ι', 'ι', ]), ('Κ', &['κ', 'ϰ', ]), ('Λ', &[
+  'λ']), ('Μ', &['µ', 'μ', ]), ('Ν', &['ν']), ('Ξ', &['ξ']), ('Ο', &[
+  'ο']), ('Π', &['π', 'ϖ', ]), ('Ρ', &['ρ', 'ϱ', ]), ('Σ', &['ς',
+  'σ', ]), ('Τ', &['τ']), ('Υ', &['υ']), ('Φ', &['φ', 'ϕ', ]),
+  ('Χ', &['χ']), ('Ψ', &['ψ']), ('Ω', &['ω', 'Ω', ]), ('Ϊ', &['ϊ']),
+  ('Ϋ', &['ϋ']), ('ά', &['Ά']), ('έ', &['Έ']), ('ή', &['Ή']), ('ί', &[
+  'Ί']), ('α', &['Α']), ('β', &['Β', 'ϐ', ]), ('γ', &['Γ']), ('δ', &[
+  'Δ']), ('ε', &['Ε', 'ϵ', ]), ('ζ', &['Ζ']), ('η', &['Η']), ('θ', &[
+  'Θ', 'ϑ', 'ϴ', ]), ('ι', &['\u{345}', 'Ι', 'ι', ]), ('κ', &['Κ',
+  'ϰ', ]), ('λ', &['Λ']), ('μ', &['µ', 'Μ', ]), ('ν', &['Ν']),
+  ('ξ', &['Ξ']), ('ο', &['Ο']), ('π', &['Π', 'ϖ', ]), ('ρ', &['Ρ',
+  'ϱ', ]), ('ς', &['Σ', 'σ', ]), ('σ', &['Σ', 'ς', ]), ('τ', &['Τ']),
+  ('υ', &['Υ']), ('φ', &['Φ', 'ϕ', ]), ('χ', &['Χ']), ('ψ', &['Ψ']),
+  ('ω', &['Ω', 'Ω', ]), ('ϊ', &['Ϊ']), ('ϋ', &['Ϋ']), ('ό', &['Ό']),
+  ('ύ', &['Ύ']), ('ώ', &['Ώ']), ('Ϗ', &['ϗ']), ('ϐ', &['Β', 'β', ]),
+  ('ϑ', &['Θ', 'θ', 'ϴ', ]), ('ϕ', &['Φ', 'φ', ]), ('ϖ', &['Π', 'π',
+  ]), ('ϗ', &['Ϗ']), ('Ϙ', &['ϙ']), ('ϙ', &['Ϙ']), ('Ϛ', &['ϛ']),
+  ('ϛ', &['Ϛ']), ('Ϝ', &['ϝ']), ('ϝ', &['Ϝ']), ('Ϟ', &['ϟ']), ('ϟ', &[
+  'Ϟ']), ('Ϡ', &['ϡ']), ('ϡ', &['Ϡ']), ('Ϣ', &['ϣ']), ('ϣ', &['Ϣ']),
+  ('Ϥ', &['ϥ']), ('ϥ', &['Ϥ']), ('Ϧ', &['ϧ']), ('ϧ', &['Ϧ']), ('Ϩ', &[
+  'ϩ']), ('ϩ', &['Ϩ']), ('Ϫ', &['ϫ']), ('ϫ', &['Ϫ']), ('Ϭ', &['ϭ']),
+  ('ϭ', &['Ϭ']), ('Ϯ', &['ϯ']), ('ϯ', &['Ϯ']), ('ϰ', &['Κ', 'κ', ]),
+  ('ϱ', &['Ρ', 'ρ', ]), ('ϲ', &['Ϲ']), ('ϳ', &['Ϳ']), ('ϴ', &['Θ',
+  'θ', 'ϑ', ]), ('ϵ', &['Ε', 'ε', ]), ('Ϸ', &['ϸ']), ('ϸ', &['Ϸ']),
+  ('Ϲ', &['ϲ']), ('Ϻ', &['ϻ']), ('ϻ', &['Ϻ']), ('Ͻ', &['ͻ']), ('Ͼ', &[
+  'ͼ']), ('Ͽ', &['ͽ']), ('Ѐ', &['ѐ']), ('Ё', &['ё']), ('Ђ', &['ђ']),
+  ('Ѓ', &['ѓ']), ('Є', &['є']), ('Ѕ', &['ѕ']), ('І', &['і']), ('Ї', &[
+  'ї']), ('Ј', &['ј']), ('Љ', &['љ']), ('Њ', &['њ']), ('Ћ', &['ћ']),
+  ('Ќ', &['ќ']), ('Ѝ', &['ѝ']), ('Ў', &['ў']), ('Џ', &['џ']), ('А', &[
+  'а']), ('Б', &['б']), ('В', &['в', 'ᲀ', ]), ('Г', &['г']), ('Д', &[
+  'д', 'ᲁ', ]), ('Е', &['е']), ('Ж', &['ж']), ('З', &['з']), ('И', &[
+  'и']), ('Й', &['й']), ('К', &['к']), ('Л', &['л']), ('М', &['м']),
+  ('Н', &['н']), ('О', &['о', 'ᲂ', ]), ('П', &['п']), ('Р', &['р']),
+  ('С', &['с', 'ᲃ', ]), ('Т', &['т', 'ᲄ', 'ᲅ', ]), ('У', &['у']),
+  ('Ф', &['ф']), ('Х', &['х']), ('Ц', &['ц']), ('Ч', &['ч']), ('Ш', &[
+  'ш']), ('Щ', &['щ']), ('Ъ', &['ъ', 'ᲆ', ]), ('Ы', &['ы']), ('Ь', &[
+  'ь']), ('Э', &['э']), ('Ю', &['ю']), ('Я', &['я']), ('а', &['А']),
+  ('б', &['Б']), ('в', &['В', 'ᲀ', ]), ('г', &['Г']), ('д', &['Д',
+  'ᲁ', ]), ('е', &['Е']), ('ж', &['Ж']), ('з', &['З']), ('и', &['И'
+  ]), ('й', &['Й']), ('к', &['К']), ('л', &['Л']), ('м', &['М']),
+  ('н', &['Н']), ('о', &['О', 'ᲂ', ]), ('п', &['П']), ('р', &['Р']),
+  ('с', &['С', 'ᲃ', ]), ('т', &['Т', 'ᲄ', 'ᲅ', ]), ('у', &['У']),
+  ('ф', &['Ф']), ('х', &['Х']), ('ц', &['Ц']), ('ч', &['Ч']), ('ш', &[
+  'Ш']), ('щ', &['Щ']), ('ъ', &['Ъ', 'ᲆ', ]), ('ы', &['Ы']), ('ь', &[
+  'Ь']), ('э', &['Э']), ('ю', &['Ю']), ('я', &['Я']), ('ѐ', &['Ѐ']),
+  ('ё', &['Ё']), ('ђ', &['Ђ']), ('ѓ', &['Ѓ']), ('є', &['Є']), ('ѕ', &[
+  'Ѕ']), ('і', &['І']), ('ї', &['Ї']), ('ј', &['Ј']), ('љ', &['Љ']),
+  ('њ', &['Њ']), ('ћ', &['Ћ']), ('ќ', &['Ќ']), ('ѝ', &['Ѝ']), ('ў', &[
+  'Ў']), ('џ', &['Џ']), ('Ѡ', &['ѡ']), ('ѡ', &['Ѡ']), ('Ѣ', &['ѣ',
+  'ᲇ', ]), ('ѣ', &['Ѣ', 'ᲇ', ]), ('Ѥ', &['ѥ']), ('ѥ', &['Ѥ']),
+  ('Ѧ', &['ѧ']), ('ѧ', &['Ѧ']), ('Ѩ', &['ѩ']), ('ѩ', &['Ѩ']), ('Ѫ', &[
+  'ѫ']), ('ѫ', &['Ѫ']), ('Ѭ', &['ѭ']), ('ѭ', &['Ѭ']), ('Ѯ', &['ѯ']),
+  ('ѯ', &['Ѯ']), ('Ѱ', &['ѱ']), ('ѱ', &['Ѱ']), ('Ѳ', &['ѳ']), ('ѳ', &[
+  'Ѳ']), ('Ѵ', &['ѵ']), ('ѵ', &['Ѵ']), ('Ѷ', &['ѷ']), ('ѷ', &['Ѷ']),
+  ('Ѹ', &['ѹ']), ('ѹ', &['Ѹ']), ('Ѻ', &['ѻ']), ('ѻ', &['Ѻ']), ('Ѽ', &[
+  'ѽ']), ('ѽ', &['Ѽ']), ('Ѿ', &['ѿ']), ('ѿ', &['Ѿ']), ('Ҁ', &['ҁ']),
+  ('ҁ', &['Ҁ']), ('Ҋ', &['ҋ']), ('ҋ', &['Ҋ']), ('Ҍ', &['ҍ']), ('ҍ', &[
+  'Ҍ']), ('Ҏ', &['ҏ']), ('ҏ', &['Ҏ']), ('Ґ', &['ґ']), ('ґ', &['Ґ']),
+  ('Ғ', &['ғ']), ('ғ', &['Ғ']), ('Ҕ', &['ҕ']), ('ҕ', &['Ҕ']), ('Җ', &[
+  'җ']), ('җ', &['Җ']), ('Ҙ', &['ҙ']), ('ҙ', &['Ҙ']), ('Қ', &['қ']),
+  ('қ', &['Қ']), ('Ҝ', &['ҝ']), ('ҝ', &['Ҝ']), ('Ҟ', &['ҟ']), ('ҟ', &[
+  'Ҟ']), ('Ҡ', &['ҡ']), ('ҡ', &['Ҡ']), ('Ң', &['ң']), ('ң', &['Ң']),
+  ('Ҥ', &['ҥ']), ('ҥ', &['Ҥ']), ('Ҧ', &['ҧ']), ('ҧ', &['Ҧ']), ('Ҩ', &[
+  'ҩ']), ('ҩ', &['Ҩ']), ('Ҫ', &['ҫ']), ('ҫ', &['Ҫ']), ('Ҭ', &['ҭ']),
+  ('ҭ', &['Ҭ']), ('Ү', &['ү']), ('ү', &['Ү']), ('Ұ', &['ұ']), ('ұ', &[
+  'Ұ']), ('Ҳ', &['ҳ']), ('ҳ', &['Ҳ']), ('Ҵ', &['ҵ']), ('ҵ', &['Ҵ']),
+  ('Ҷ', &['ҷ']), ('ҷ', &['Ҷ']), ('Ҹ', &['ҹ']), ('ҹ', &['Ҹ']), ('Һ', &[
+  'һ']), ('һ', &['Һ']), ('Ҽ', &['ҽ']), ('ҽ', &['Ҽ']), ('Ҿ', &['ҿ']),
+  ('ҿ', &['Ҿ']), ('Ӏ', &['ӏ']), ('Ӂ', &['ӂ']), ('ӂ', &['Ӂ']), ('Ӄ', &[
+  'ӄ']), ('ӄ', &['Ӄ']), ('Ӆ', &['ӆ']), ('ӆ', &['Ӆ']), ('Ӈ', &['ӈ']),
+  ('ӈ', &['Ӈ']), ('Ӊ', &['ӊ']), ('ӊ', &['Ӊ']), ('Ӌ', &['ӌ']), ('ӌ', &[
+  'Ӌ']), ('Ӎ', &['ӎ']), ('ӎ', &['Ӎ']), ('ӏ', &['Ӏ']), ('Ӑ', &['ӑ']),
+  ('ӑ', &['Ӑ']), ('Ӓ', &['ӓ']), ('ӓ', &['Ӓ']), ('Ӕ', &['ӕ']), ('ӕ', &[
+  'Ӕ']), ('Ӗ', &['ӗ']), ('ӗ', &['Ӗ']), ('Ә', &['ә']), ('ә', &['Ә']),
+  ('Ӛ', &['ӛ']), ('ӛ', &['Ӛ']), ('Ӝ', &['ӝ']), ('ӝ', &['Ӝ']), ('Ӟ', &[
+  'ӟ']), ('ӟ', &['Ӟ']), ('Ӡ', &['ӡ']), ('ӡ', &['Ӡ']), ('Ӣ', &['ӣ']),
+  ('ӣ', &['Ӣ']), ('Ӥ', &['ӥ']), ('ӥ', &['Ӥ']), ('Ӧ', &['ӧ']), ('ӧ', &[
+  'Ӧ']), ('Ө', &['ө']), ('ө', &['Ө']), ('Ӫ', &['ӫ']), ('ӫ', &['Ӫ']),
+  ('Ӭ', &['ӭ']), ('ӭ', &['Ӭ']), ('Ӯ', &['ӯ']), ('ӯ', &['Ӯ']), ('Ӱ', &[
+  'ӱ']), ('ӱ', &['Ӱ']), ('Ӳ', &['ӳ']), ('ӳ', &['Ӳ']), ('Ӵ', &['ӵ']),
+  ('ӵ', &['Ӵ']), ('Ӷ', &['ӷ']), ('ӷ', &['Ӷ']), ('Ӹ', &['ӹ']), ('ӹ', &[
+  'Ӹ']), ('Ӻ', &['ӻ']), ('ӻ', &['Ӻ']), ('Ӽ', &['ӽ']), ('ӽ', &['Ӽ']),
+  ('Ӿ', &['ӿ']), ('ӿ', &['Ӿ']), ('Ԁ', &['ԁ']), ('ԁ', &['Ԁ']), ('Ԃ', &[
+  'ԃ']), ('ԃ', &['Ԃ']), ('Ԅ', &['ԅ']), ('ԅ', &['Ԅ']), ('Ԇ', &['ԇ']),
+  ('ԇ', &['Ԇ']), ('Ԉ', &['ԉ']), ('ԉ', &['Ԉ']), ('Ԋ', &['ԋ']), ('ԋ', &[
+  'Ԋ']), ('Ԍ', &['ԍ']), ('ԍ', &['Ԍ']), ('Ԏ', &['ԏ']), ('ԏ', &['Ԏ']),
+  ('Ԑ', &['ԑ']), ('ԑ', &['Ԑ']), ('Ԓ', &['ԓ']), ('ԓ', &['Ԓ']), ('Ԕ', &[
+  'ԕ']), ('ԕ', &['Ԕ']), ('Ԗ', &['ԗ']), ('ԗ', &['Ԗ']), ('Ԙ', &['ԙ']),
+  ('ԙ', &['Ԙ']), ('Ԛ', &['ԛ']), ('ԛ', &['Ԛ']), ('Ԝ', &['ԝ']), ('ԝ', &[
+  'Ԝ']), ('Ԟ', &['ԟ']), ('ԟ', &['Ԟ']), ('Ԡ', &['ԡ']), ('ԡ', &['Ԡ']),
+  ('Ԣ', &['ԣ']), ('ԣ', &['Ԣ']), ('Ԥ', &['ԥ']), ('ԥ', &['Ԥ']), ('Ԧ', &[
+  'ԧ']), ('ԧ', &['Ԧ']), ('Ԩ', &['ԩ']), ('ԩ', &['Ԩ']), ('Ԫ', &['ԫ']),
+  ('ԫ', &['Ԫ']), ('Ԭ', &['ԭ']), ('ԭ', &['Ԭ']), ('Ԯ', &['ԯ']), ('ԯ', &[
+  'Ԯ']), ('Ա', &['ա']), ('Բ', &['բ']), ('Գ', &['գ']), ('Դ', &['դ']),
+  ('Ե', &['ե']), ('Զ', &['զ']), ('Է', &['է']), ('Ը', &['ը']), ('Թ', &[
+  'թ']), ('Ժ', &['ժ']), ('Ի', &['ի']), ('Լ', &['լ']), ('Խ', &['խ']),
+  ('Ծ', &['ծ']), ('Կ', &['կ']), ('Հ', &['հ']), ('Ձ', &['ձ']), ('Ղ', &[
+  'ղ']), ('Ճ', &['ճ']), ('Մ', &['մ']), ('Յ', &['յ']), ('Ն', &['ն']),
+  ('Շ', &['շ']), ('Ո', &['ո']), ('Չ', &['չ']), ('Պ', &['պ']), ('Ջ', &[
+  'ջ']), ('Ռ', &['ռ']), ('Ս', &['ս']), ('Վ', &['վ']), ('Տ', &['տ']),
+  ('Ր', &['ր']), ('Ց', &['ց']), ('Ւ', &['ւ']), ('Փ', &['փ']), ('Ք', &[
+  'ք']), ('Օ', &['օ']), ('Ֆ', &['ֆ']), ('ա', &['Ա']), ('բ', &['Բ']),
+  ('գ', &['Գ']), ('դ', &['Դ']), ('ե', &['Ե']), ('զ', &['Զ']), ('է', &[
+  'Է']), ('ը', &['Ը']), ('թ', &['Թ']), ('ժ', &['Ժ']), ('ի', &['Ի']),
+  ('լ', &['Լ']), ('խ', &['Խ']), ('ծ', &['Ծ']), ('կ', &['Կ']), ('հ', &[
+  'Հ']), ('ձ', &['Ձ']), ('ղ', &['Ղ']), ('ճ', &['Ճ']), ('մ', &['Մ']),
+  ('յ', &['Յ']), ('ն', &['Ն']), ('շ', &['Շ']), ('ո', &['Ո']), ('չ', &[
+  'Չ']), ('պ', &['Պ']), ('ջ', &['Ջ']), ('ռ', &['Ռ']), ('ս', &['Ս']),
+  ('վ', &['Վ']), ('տ', &['Տ']), ('ր', &['Ր']), ('ց', &['Ց']), ('ւ', &[
+  'Ւ']), ('փ', &['Փ']), ('ք', &['Ք']), ('օ', &['Օ']), ('ֆ', &['Ֆ']),
+  ('Ⴀ', &['ⴀ']), ('Ⴁ', &['ⴁ']), ('Ⴂ', &['ⴂ']), ('Ⴃ', &['ⴃ']),
+  ('Ⴄ', &['ⴄ']), ('Ⴅ', &['ⴅ']), ('Ⴆ', &['ⴆ']), ('Ⴇ', &['ⴇ']),
+  ('Ⴈ', &['ⴈ']), ('Ⴉ', &['ⴉ']), ('Ⴊ', &['ⴊ']), ('Ⴋ', &['ⴋ']),
+  ('Ⴌ', &['ⴌ']), ('Ⴍ', &['ⴍ']), ('Ⴎ', &['ⴎ']), ('Ⴏ', &['ⴏ']),
+  ('Ⴐ', &['ⴐ']), ('Ⴑ', &['ⴑ']), ('Ⴒ', &['ⴒ']), ('Ⴓ', &['ⴓ']),
+  ('Ⴔ', &['ⴔ']), ('Ⴕ', &['ⴕ']), ('Ⴖ', &['ⴖ']), ('Ⴗ', &['ⴗ']),
+  ('Ⴘ', &['ⴘ']), ('Ⴙ', &['ⴙ']), ('Ⴚ', &['ⴚ']), ('Ⴛ', &['ⴛ']),
+  ('Ⴜ', &['ⴜ']), ('Ⴝ', &['ⴝ']), ('Ⴞ', &['ⴞ']), ('Ⴟ', &['ⴟ']),
+  ('Ⴠ', &['ⴠ']), ('Ⴡ', &['ⴡ']), ('Ⴢ', &['ⴢ']), ('Ⴣ', &['ⴣ']),
+  ('Ⴤ', &['ⴤ']), ('Ⴥ', &['ⴥ']), ('Ⴧ', &['ⴧ']), ('Ⴭ', &['ⴭ']),
+  ('ა', &['Ა']), ('ბ', &['Ბ']), ('გ', &['Გ']), ('დ', &['Დ']),
+  ('ე', &['Ე']), ('ვ', &['Ვ']), ('ზ', &['Ზ']), ('თ', &['Თ']),
+  ('ი', &['Ი']), ('კ', &['Კ']), ('ლ', &['Ლ']), ('მ', &['Მ']),
+  ('ნ', &['Ნ']), ('ო', &['Ო']), ('პ', &['Პ']), ('ჟ', &['Ჟ']),
+  ('რ', &['Რ']), ('ს', &['Ს']), ('ტ', &['Ტ']), ('უ', &['Უ']),
+  ('ფ', &['Ფ']), ('ქ', &['Ქ']), ('ღ', &['Ღ']), ('ყ', &['Ყ']),
+  ('შ', &['Შ']), ('ჩ', &['Ჩ']), ('ც', &['Ც']), ('ძ', &['Ძ']),
+  ('წ', &['Წ']), ('ჭ', &['Ჭ']), ('ხ', &['Ხ']), ('ჯ', &['Ჯ']),
+  ('ჰ', &['Ჰ']), ('ჱ', &['Ჱ']), ('ჲ', &['Ჲ']), ('ჳ', &['Ჳ']),
+  ('ჴ', &['Ჴ']), ('ჵ', &['Ჵ']), ('ჶ', &['Ჶ']), ('ჷ', &['Ჷ']),
+  ('ჸ', &['Ჸ']), ('ჹ', &['Ჹ']), ('ჺ', &['Ჺ']), ('ჽ', &['Ჽ']),
+  ('ჾ', &['Ჾ']), ('ჿ', &['Ჿ']), ('Ꭰ', &['ꭰ']), ('Ꭱ', &['ꭱ']),
+  ('Ꭲ', &['ꭲ']), ('Ꭳ', &['ꭳ']), ('Ꭴ', &['ꭴ']), ('Ꭵ', &['ꭵ']),
+  ('Ꭶ', &['ꭶ']), ('Ꭷ', &['ꭷ']), ('Ꭸ', &['ꭸ']), ('Ꭹ', &['ꭹ']),
+  ('Ꭺ', &['ꭺ']), ('Ꭻ', &['ꭻ']), ('Ꭼ', &['ꭼ']), ('Ꭽ', &['ꭽ']),
+  ('Ꭾ', &['ꭾ']), ('Ꭿ', &['ꭿ']), ('Ꮀ', &['ꮀ']), ('Ꮁ', &['ꮁ']),
+  ('Ꮂ', &['ꮂ']), ('Ꮃ', &['ꮃ']), ('Ꮄ', &['ꮄ']), ('Ꮅ', &['ꮅ']),
+  ('Ꮆ', &['ꮆ']), ('Ꮇ', &['ꮇ']), ('Ꮈ', &['ꮈ']), ('Ꮉ', &['ꮉ']),
+  ('Ꮊ', &['ꮊ']), ('Ꮋ', &['ꮋ']), ('Ꮌ', &['ꮌ']), ('Ꮍ', &['ꮍ']),
+  ('Ꮎ', &['ꮎ']), ('Ꮏ', &['ꮏ']), ('Ꮐ', &['ꮐ']), ('Ꮑ', &['ꮑ']),
+  ('Ꮒ', &['ꮒ']), ('Ꮓ', &['ꮓ']), ('Ꮔ', &['ꮔ']), ('Ꮕ', &['ꮕ']),
+  ('Ꮖ', &['ꮖ']), ('Ꮗ', &['ꮗ']), ('Ꮘ', &['ꮘ']), ('Ꮙ', &['ꮙ']),
+  ('Ꮚ', &['ꮚ']), ('Ꮛ', &['ꮛ']), ('Ꮜ', &['ꮜ']), ('Ꮝ', &['ꮝ']),
+  ('Ꮞ', &['ꮞ']), ('Ꮟ', &['ꮟ']), ('Ꮠ', &['ꮠ']), ('Ꮡ', &['ꮡ']),
+  ('Ꮢ', &['ꮢ']), ('Ꮣ', &['ꮣ']), ('Ꮤ', &['ꮤ']), ('Ꮥ', &['ꮥ']),
+  ('Ꮦ', &['ꮦ']), ('Ꮧ', &['ꮧ']), ('Ꮨ', &['ꮨ']), ('Ꮩ', &['ꮩ']),
+  ('Ꮪ', &['ꮪ']), ('Ꮫ', &['ꮫ']), ('Ꮬ', &['ꮬ']), ('Ꮭ', &['ꮭ']),
+  ('Ꮮ', &['ꮮ']), ('Ꮯ', &['ꮯ']), ('Ꮰ', &['ꮰ']), ('Ꮱ', &['ꮱ']),
+  ('Ꮲ', &['ꮲ']), ('Ꮳ', &['ꮳ']), ('Ꮴ', &['ꮴ']), ('Ꮵ', &['ꮵ']),
+  ('Ꮶ', &['ꮶ']), ('Ꮷ', &['ꮷ']), ('Ꮸ', &['ꮸ']), ('Ꮹ', &['ꮹ']),
+  ('Ꮺ', &['ꮺ']), ('Ꮻ', &['ꮻ']), ('Ꮼ', &['ꮼ']), ('Ꮽ', &['ꮽ']),
+  ('Ꮾ', &['ꮾ']), ('Ꮿ', &['ꮿ']), ('Ᏸ', &['ᏸ']), ('Ᏹ', &['ᏹ']),
+  ('Ᏺ', &['ᏺ']), ('Ᏻ', &['ᏻ']), ('Ᏼ', &['ᏼ']), ('Ᏽ', &['ᏽ']),
+  ('ᏸ', &['Ᏸ']), ('ᏹ', &['Ᏹ']), ('ᏺ', &['Ᏺ']), ('ᏻ', &['Ᏻ']),
+  ('ᏼ', &['Ᏼ']), ('ᏽ', &['Ᏽ']), ('ᲀ', &['В', 'в', ]), ('ᲁ', &[
+  'Д', 'д', ]), ('ᲂ', &['О', 'о', ]), ('ᲃ', &['С', 'с', ]),
+  ('ᲄ', &['Т', 'т', 'ᲅ', ]), ('ᲅ', &['Т', 'т', 'ᲄ', ]), ('ᲆ', &[
+  'Ъ', 'ъ', ]), ('ᲇ', &['Ѣ', 'ѣ', ]), ('ᲈ', &['Ꙋ', 'ꙋ', ]),
+  ('Ა', &['ა']), ('Ბ', &['ბ']), ('Გ', &['გ']), ('Დ', &['დ']),
+  ('Ე', &['ე']), ('Ვ', &['ვ']), ('Ზ', &['ზ']), ('Თ', &['თ']),
+  ('Ი', &['ი']), ('Კ', &['კ']), ('Ლ', &['ლ']), ('Მ', &['მ']),
+  ('Ნ', &['ნ']), ('Ო', &['ო']), ('Პ', &['პ']), ('Ჟ', &['ჟ']),
+  ('Რ', &['რ']), ('Ს', &['ს']), ('Ტ', &['ტ']), ('Უ', &['უ']),
+  ('Ფ', &['ფ']), ('Ქ', &['ქ']), ('Ღ', &['ღ']), ('Ყ', &['ყ']),
+  ('Შ', &['შ']), ('Ჩ', &['ჩ']), ('Ც', &['ც']), ('Ძ', &['ძ']),
+  ('Წ', &['წ']), ('Ჭ', &['ჭ']), ('Ხ', &['ხ']), ('Ჯ', &['ჯ']),
+  ('Ჰ', &['ჰ']), ('Ჱ', &['ჱ']), ('Ჲ', &['ჲ']), ('Ჳ', &['ჳ']),
+  ('Ჴ', &['ჴ']), ('Ჵ', &['ჵ']), ('Ჶ', &['ჶ']), ('Ჷ', &['ჷ']),
+  ('Ჸ', &['ჸ']), ('Ჹ', &['ჹ']), ('Ჺ', &['ჺ']), ('Ჽ', &['ჽ']),
+  ('Ჾ', &['ჾ']), ('Ჿ', &['ჿ']), ('ᵹ', &['Ᵹ']), ('ᵽ', &['Ᵽ']),
+  ('ᶎ', &['\u{a7c6}']), ('Ḁ', &['ḁ']), ('ḁ', &['Ḁ']), ('Ḃ', &['ḃ'
+  ]), ('ḃ', &['Ḃ']), ('Ḅ', &['ḅ']), ('ḅ', &['Ḅ']), ('Ḇ', &['ḇ'
+  ]), ('ḇ', &['Ḇ']), ('Ḉ', &['ḉ']), ('ḉ', &['Ḉ']), ('Ḋ', &['ḋ'
+  ]), ('ḋ', &['Ḋ']), ('Ḍ', &['ḍ']), ('ḍ', &['Ḍ']), ('Ḏ', &['ḏ'
+  ]), ('ḏ', &['Ḏ']), ('Ḑ', &['ḑ']), ('ḑ', &['Ḑ']), ('Ḓ', &['ḓ'
+  ]), ('ḓ', &['Ḓ']), ('Ḕ', &['ḕ']), ('ḕ', &['Ḕ']), ('Ḗ', &['ḗ'
+  ]), ('ḗ', &['Ḗ']), ('Ḙ', &['ḙ']), ('ḙ', &['Ḙ']), ('Ḛ', &['ḛ'
+  ]), ('ḛ', &['Ḛ']), ('Ḝ', &['ḝ']), ('ḝ', &['Ḝ']), ('Ḟ', &['ḟ'
+  ]), ('ḟ', &['Ḟ']), ('Ḡ', &['ḡ']), ('ḡ', &['Ḡ']), ('Ḣ', &['ḣ'
+  ]), ('ḣ', &['Ḣ']), ('Ḥ', &['ḥ']), ('ḥ', &['Ḥ']), ('Ḧ', &['ḧ'
+  ]), ('ḧ', &['Ḧ']), ('Ḩ', &['ḩ']), ('ḩ', &['Ḩ']), ('Ḫ', &['ḫ'
+  ]), ('ḫ', &['Ḫ']), ('Ḭ', &['ḭ']), ('ḭ', &['Ḭ']), ('Ḯ', &['ḯ'
+  ]), ('ḯ', &['Ḯ']), ('Ḱ', &['ḱ']), ('ḱ', &['Ḱ']), ('Ḳ', &['ḳ'
+  ]), ('ḳ', &['Ḳ']), ('Ḵ', &['ḵ']), ('ḵ', &['Ḵ']), ('Ḷ', &['ḷ'
+  ]), ('ḷ', &['Ḷ']), ('Ḹ', &['ḹ']), ('ḹ', &['Ḹ']), ('Ḻ', &['ḻ'
+  ]), ('ḻ', &['Ḻ']), ('Ḽ', &['ḽ']), ('ḽ', &['Ḽ']), ('Ḿ', &['ḿ'
+  ]), ('ḿ', &['Ḿ']), ('Ṁ', &['ṁ']), ('ṁ', &['Ṁ']), ('Ṃ', &['ṃ'
+  ]), ('ṃ', &['Ṃ']), ('Ṅ', &['ṅ']), ('ṅ', &['Ṅ']), ('Ṇ', &['ṇ'
+  ]), ('ṇ', &['Ṇ']), ('Ṉ', &['ṉ']), ('ṉ', &['Ṉ']), ('Ṋ', &['ṋ'
+  ]), ('ṋ', &['Ṋ']), ('Ṍ', &['ṍ']), ('ṍ', &['Ṍ']), ('Ṏ', &['ṏ'
+  ]), ('ṏ', &['Ṏ']), ('Ṑ', &['ṑ']), ('ṑ', &['Ṑ']), ('Ṓ', &['ṓ'
+  ]), ('ṓ', &['Ṓ']), ('Ṕ', &['ṕ']), ('ṕ', &['Ṕ']), ('Ṗ', &['ṗ'
+  ]), ('ṗ', &['Ṗ']), ('Ṙ', &['ṙ']), ('ṙ', &['Ṙ']), ('Ṛ', &['ṛ'
+  ]), ('ṛ', &['Ṛ']), ('Ṝ', &['ṝ']), ('ṝ', &['Ṝ']), ('Ṟ', &['ṟ'
+  ]), ('ṟ', &['Ṟ']), ('Ṡ', &['ṡ', 'ẛ', ]), ('ṡ', &['Ṡ', 'ẛ',
+  ]), ('Ṣ', &['ṣ']), ('ṣ', &['Ṣ']), ('Ṥ', &['ṥ']), ('ṥ', &['Ṥ'
+  ]), ('Ṧ', &['ṧ']), ('ṧ', &['Ṧ']), ('Ṩ', &['ṩ']), ('ṩ', &['Ṩ'
+  ]), ('Ṫ', &['ṫ']), ('ṫ', &['Ṫ']), ('Ṭ', &['ṭ']), ('ṭ', &['Ṭ'
+  ]), ('Ṯ', &['ṯ']), ('ṯ', &['Ṯ']), ('Ṱ', &['ṱ']), ('ṱ', &['Ṱ'
+  ]), ('Ṳ', &['ṳ']), ('ṳ', &['Ṳ']), ('Ṵ', &['ṵ']), ('ṵ', &['Ṵ'
+  ]), ('Ṷ', &['ṷ']), ('ṷ', &['Ṷ']), ('Ṹ', &['ṹ']), ('ṹ', &['Ṹ'
+  ]), ('Ṻ', &['ṻ']), ('ṻ', &['Ṻ']), ('Ṽ', &['ṽ']), ('ṽ', &['Ṽ'
+  ]), ('Ṿ', &['ṿ']), ('ṿ', &['Ṿ']), ('Ẁ', &['ẁ']), ('ẁ', &['Ẁ'
+  ]), ('Ẃ', &['ẃ']), ('ẃ', &['Ẃ']), ('Ẅ', &['ẅ']), ('ẅ', &['Ẅ'
+  ]), ('Ẇ', &['ẇ']), ('ẇ', &['Ẇ']), ('Ẉ', &['ẉ']), ('ẉ', &['Ẉ'
+  ]), ('Ẋ', &['ẋ']), ('ẋ', &['Ẋ']), ('Ẍ', &['ẍ']), ('ẍ', &['Ẍ'
+  ]), ('Ẏ', &['ẏ']), ('ẏ', &['Ẏ']), ('Ẑ', &['ẑ']), ('ẑ', &['Ẑ'
+  ]), ('Ẓ', &['ẓ']), ('ẓ', &['Ẓ']), ('Ẕ', &['ẕ']), ('ẕ', &['Ẕ'
+  ]), ('ẛ', &['Ṡ', 'ṡ', ]), ('ẞ', &['ß']), ('Ạ', &['ạ']),
+  ('ạ', &['Ạ']), ('Ả', &['ả']), ('ả', &['Ả']), ('Ấ', &['ấ']),
+  ('ấ', &['Ấ']), ('Ầ', &['ầ']), ('ầ', &['Ầ']), ('Ẩ', &['ẩ']),
+  ('ẩ', &['Ẩ']), ('Ẫ', &['ẫ']), ('ẫ', &['Ẫ']), ('Ậ', &['ậ']),
+  ('ậ', &['Ậ']), ('Ắ', &['ắ']), ('ắ', &['Ắ']), ('Ằ', &['ằ']),
+  ('ằ', &['Ằ']), ('Ẳ', &['ẳ']), ('ẳ', &['Ẳ']), ('Ẵ', &['ẵ']),
+  ('ẵ', &['Ẵ']), ('Ặ', &['ặ']), ('ặ', &['Ặ']), ('Ẹ', &['ẹ']),
+  ('ẹ', &['Ẹ']), ('Ẻ', &['ẻ']), ('ẻ', &['Ẻ']), ('Ẽ', &['ẽ']),
+  ('ẽ', &['Ẽ']), ('Ế', &['ế']), ('ế', &['Ế']), ('Ề', &['ề']),
+  ('ề', &['Ề']), ('Ể', &['ể']), ('ể', &['Ể']), ('Ễ', &['ễ']),
+  ('ễ', &['Ễ']), ('Ệ', &['ệ']), ('ệ', &['Ệ']), ('Ỉ', &['ỉ']),
+  ('ỉ', &['Ỉ']), ('Ị', &['ị']), ('ị', &['Ị']), ('Ọ', &['ọ']),
+  ('ọ', &['Ọ']), ('Ỏ', &['ỏ']), ('ỏ', &['Ỏ']), ('Ố', &['ố']),
+  ('ố', &['Ố']), ('Ồ', &['ồ']), ('ồ', &['Ồ']), ('Ổ', &['ổ']),
+  ('ổ', &['Ổ']), ('Ỗ', &['ỗ']), ('ỗ', &['Ỗ']), ('Ộ', &['ộ']),
+  ('ộ', &['Ộ']), ('Ớ', &['ớ']), ('ớ', &['Ớ']), ('Ờ', &['ờ']),
+  ('ờ', &['Ờ']), ('Ở', &['ở']), ('ở', &['Ở']), ('Ỡ', &['ỡ']),
+  ('ỡ', &['Ỡ']), ('Ợ', &['ợ']), ('ợ', &['Ợ']), ('Ụ', &['ụ']),
+  ('ụ', &['Ụ']), ('Ủ', &['ủ']), ('ủ', &['Ủ']), ('Ứ', &['ứ']),
+  ('ứ', &['Ứ']), ('Ừ', &['ừ']), ('ừ', &['Ừ']), ('Ử', &['ử']),
+  ('ử', &['Ử']), ('Ữ', &['ữ']), ('ữ', &['Ữ']), ('Ự', &['ự']),
+  ('ự', &['Ự']), ('Ỳ', &['ỳ']), ('ỳ', &['Ỳ']), ('Ỵ', &['ỵ']),
+  ('ỵ', &['Ỵ']), ('Ỷ', &['ỷ']), ('ỷ', &['Ỷ']), ('Ỹ', &['ỹ']),
+  ('ỹ', &['Ỹ']), ('Ỻ', &['ỻ']), ('ỻ', &['Ỻ']), ('Ỽ', &['ỽ']),
+  ('ỽ', &['Ỽ']), ('Ỿ', &['ỿ']), ('ỿ', &['Ỿ']), ('ἀ', &['Ἀ']),
+  ('ἁ', &['Ἁ']), ('ἂ', &['Ἂ']), ('ἃ', &['Ἃ']), ('ἄ', &['Ἄ']),
+  ('ἅ', &['Ἅ']), ('ἆ', &['Ἆ']), ('ἇ', &['Ἇ']), ('Ἀ', &['ἀ']),
+  ('Ἁ', &['ἁ']), ('Ἂ', &['ἂ']), ('Ἃ', &['ἃ']), ('Ἄ', &['ἄ']),
+  ('Ἅ', &['ἅ']), ('Ἆ', &['ἆ']), ('Ἇ', &['ἇ']), ('ἐ', &['Ἐ']),
+  ('ἑ', &['Ἑ']), ('ἒ', &['Ἒ']), ('ἓ', &['Ἓ']), ('ἔ', &['Ἔ']),
+  ('ἕ', &['Ἕ']), ('Ἐ', &['ἐ']), ('Ἑ', &['ἑ']), ('Ἒ', &['ἒ']),
+  ('Ἓ', &['ἓ']), ('Ἔ', &['ἔ']), ('Ἕ', &['ἕ']), ('ἠ', &['Ἠ']),
+  ('ἡ', &['Ἡ']), ('ἢ', &['Ἢ']), ('ἣ', &['Ἣ']), ('ἤ', &['Ἤ']),
+  ('ἥ', &['Ἥ']), ('ἦ', &['Ἦ']), ('ἧ', &['Ἧ']), ('Ἠ', &['ἠ']),
+  ('Ἡ', &['ἡ']), ('Ἢ', &['ἢ']), ('Ἣ', &['ἣ']), ('Ἤ', &['ἤ']),
+  ('Ἥ', &['ἥ']), ('Ἦ', &['ἦ']), ('Ἧ', &['ἧ']), ('ἰ', &['Ἰ']),
+  ('ἱ', &['Ἱ']), ('ἲ', &['Ἲ']), ('ἳ', &['Ἳ']), ('ἴ', &['Ἴ']),
+  ('ἵ', &['Ἵ']), ('ἶ', &['Ἶ']), ('ἷ', &['Ἷ']), ('Ἰ', &['ἰ']),
+  ('Ἱ', &['ἱ']), ('Ἲ', &['ἲ']), ('Ἳ', &['ἳ']), ('Ἴ', &['ἴ']),
+  ('Ἵ', &['ἵ']), ('Ἶ', &['ἶ']), ('Ἷ', &['ἷ']), ('ὀ', &['Ὀ']),
+  ('ὁ', &['Ὁ']), ('ὂ', &['Ὂ']), ('ὃ', &['Ὃ']), ('ὄ', &['Ὄ']),
+  ('ὅ', &['Ὅ']), ('Ὀ', &['ὀ']), ('Ὁ', &['ὁ']), ('Ὂ', &['ὂ']),
+  ('Ὃ', &['ὃ']), ('Ὄ', &['ὄ']), ('Ὅ', &['ὅ']), ('ὑ', &['Ὑ']),
+  ('ὓ', &['Ὓ']), ('ὕ', &['Ὕ']), ('ὗ', &['Ὗ']), ('Ὑ', &['ὑ']),
+  ('Ὓ', &['ὓ']), ('Ὕ', &['ὕ']), ('Ὗ', &['ὗ']), ('ὠ', &['Ὠ']),
+  ('ὡ', &['Ὡ']), ('ὢ', &['Ὢ']), ('ὣ', &['Ὣ']), ('ὤ', &['Ὤ']),
+  ('ὥ', &['Ὥ']), ('ὦ', &['Ὦ']), ('ὧ', &['Ὧ']), ('Ὠ', &['ὠ']),
+  ('Ὡ', &['ὡ']), ('Ὢ', &['ὢ']), ('Ὣ', &['ὣ']), ('Ὤ', &['ὤ']),
+  ('Ὥ', &['ὥ']), ('Ὦ', &['ὦ']), ('Ὧ', &['ὧ']), ('ὰ', &['Ὰ']),
+  ('ά', &['Ά']), ('ὲ', &['Ὲ']), ('έ', &['Έ']), ('ὴ', &['Ὴ']),
+  ('ή', &['Ή']), ('ὶ', &['Ὶ']), ('ί', &['Ί']), ('ὸ', &['Ὸ']),
+  ('ό', &['Ό']), ('ὺ', &['Ὺ']), ('ύ', &['Ύ']), ('ὼ', &['Ὼ']),
+  ('ώ', &['Ώ']), ('ᾀ', &['ᾈ']), ('ᾁ', &['ᾉ']), ('ᾂ', &['ᾊ']),
+  ('ᾃ', &['ᾋ']), ('ᾄ', &['ᾌ']), ('ᾅ', &['ᾍ']), ('ᾆ', &['ᾎ']),
+  ('ᾇ', &['ᾏ']), ('ᾈ', &['ᾀ']), ('ᾉ', &['ᾁ']), ('ᾊ', &['ᾂ']),
+  ('ᾋ', &['ᾃ']), ('ᾌ', &['ᾄ']), ('ᾍ', &['ᾅ']), ('ᾎ', &['ᾆ']),
+  ('ᾏ', &['ᾇ']), ('ᾐ', &['ᾘ']), ('ᾑ', &['ᾙ']), ('ᾒ', &['ᾚ']),
+  ('ᾓ', &['ᾛ']), ('ᾔ', &['ᾜ']), ('ᾕ', &['ᾝ']), ('ᾖ', &['ᾞ']),
+  ('ᾗ', &['ᾟ']), ('ᾘ', &['ᾐ']), ('ᾙ', &['ᾑ']), ('ᾚ', &['ᾒ']),
+  ('ᾛ', &['ᾓ']), ('ᾜ', &['ᾔ']), ('ᾝ', &['ᾕ']), ('ᾞ', &['ᾖ']),
+  ('ᾟ', &['ᾗ']), ('ᾠ', &['ᾨ']), ('ᾡ', &['ᾩ']), ('ᾢ', &['ᾪ']),
+  ('ᾣ', &['ᾫ']), ('ᾤ', &['ᾬ']), ('ᾥ', &['ᾭ']), ('ᾦ', &['ᾮ']),
+  ('ᾧ', &['ᾯ']), ('ᾨ', &['ᾠ']), ('ᾩ', &['ᾡ']), ('ᾪ', &['ᾢ']),
+  ('ᾫ', &['ᾣ']), ('ᾬ', &['ᾤ']), ('ᾭ', &['ᾥ']), ('ᾮ', &['ᾦ']),
+  ('ᾯ', &['ᾧ']), ('ᾰ', &['Ᾰ']), ('ᾱ', &['Ᾱ']), ('ᾳ', &['ᾼ']),
+  ('Ᾰ', &['ᾰ']), ('Ᾱ', &['ᾱ']), ('Ὰ', &['ὰ']), ('Ά', &['ά']),
+  ('ᾼ', &['ᾳ']), ('ι', &['\u{345}', 'Ι', 'ι', ]), ('ῃ', &['ῌ']),
+  ('Ὲ', &['ὲ']), ('Έ', &['έ']), ('Ὴ', &['ὴ']), ('Ή', &['ή']),
+  ('ῌ', &['ῃ']), ('ῐ', &['Ῐ']), ('ῑ', &['Ῑ']), ('Ῐ', &['ῐ']),
+  ('Ῑ', &['ῑ']), ('Ὶ', &['ὶ']), ('Ί', &['ί']), ('ῠ', &['Ῠ']),
+  ('ῡ', &['Ῡ']), ('ῥ', &['Ῥ']), ('Ῠ', &['ῠ']), ('Ῡ', &['ῡ']),
+  ('Ὺ', &['ὺ']), ('Ύ', &['ύ']), ('Ῥ', &['ῥ']), ('ῳ', &['ῼ']),
+  ('Ὸ', &['ὸ']), ('Ό', &['ό']), ('Ὼ', &['ὼ']), ('Ώ', &['ώ']),
+  ('ῼ', &['ῳ']), ('Ω', &['Ω', 'ω', ]), ('K', &['K', 'k', ]),
+  ('Å', &['Å', 'å', ]), ('Ⅎ', &['ⅎ']), ('ⅎ', &['Ⅎ']), ('Ⅰ', &[
+  'ⅰ']), ('Ⅱ', &['ⅱ']), ('Ⅲ', &['ⅲ']), ('Ⅳ', &['ⅳ']), ('Ⅴ', &[
+  'ⅴ']), ('Ⅵ', &['ⅵ']), ('Ⅶ', &['ⅶ']), ('Ⅷ', &['ⅷ']), ('Ⅸ', &[
+  'ⅸ']), ('Ⅹ', &['ⅹ']), ('Ⅺ', &['ⅺ']), ('Ⅻ', &['ⅻ']), ('Ⅼ', &[
+  'ⅼ']), ('Ⅽ', &['ⅽ']), ('Ⅾ', &['ⅾ']), ('Ⅿ', &['ⅿ']), ('ⅰ', &[
+  'Ⅰ']), ('ⅱ', &['Ⅱ']), ('ⅲ', &['Ⅲ']), ('ⅳ', &['Ⅳ']), ('ⅴ', &[
+  'Ⅴ']), ('ⅵ', &['Ⅵ']), ('ⅶ', &['Ⅶ']), ('ⅷ', &['Ⅷ']), ('ⅸ', &[
+  'Ⅸ']), ('ⅹ', &['Ⅹ']), ('ⅺ', &['Ⅺ']), ('ⅻ', &['Ⅻ']), ('ⅼ', &[
+  'Ⅼ']), ('ⅽ', &['Ⅽ']), ('ⅾ', &['Ⅾ']), ('ⅿ', &['Ⅿ']), ('Ↄ', &[
+  'ↄ']), ('ↄ', &['Ↄ']), ('Ⓐ', &['ⓐ']), ('Ⓑ', &['ⓑ']), ('Ⓒ', &[
+  'ⓒ']), ('Ⓓ', &['ⓓ']), ('Ⓔ', &['ⓔ']), ('Ⓕ', &['ⓕ']), ('Ⓖ', &[
+  'ⓖ']), ('Ⓗ', &['ⓗ']), ('Ⓘ', &['ⓘ']), ('Ⓙ', &['ⓙ']), ('Ⓚ', &[
+  'ⓚ']), ('Ⓛ', &['ⓛ']), ('Ⓜ', &['ⓜ']), ('Ⓝ', &['ⓝ']), ('Ⓞ', &[
+  'ⓞ']), ('Ⓟ', &['ⓟ']), ('Ⓠ', &['ⓠ']), ('Ⓡ', &['ⓡ']), ('Ⓢ', &[
+  'ⓢ']), ('Ⓣ', &['ⓣ']), ('Ⓤ', &['ⓤ']), ('Ⓥ', &['ⓥ']), ('Ⓦ', &[
+  'ⓦ']), ('Ⓧ', &['ⓧ']), ('Ⓨ', &['ⓨ']), ('Ⓩ', &['ⓩ']), ('ⓐ', &[
+  'Ⓐ']), ('ⓑ', &['Ⓑ']), ('ⓒ', &['Ⓒ']), ('ⓓ', &['Ⓓ']), ('ⓔ', &[
+  'Ⓔ']), ('ⓕ', &['Ⓕ']), ('ⓖ', &['Ⓖ']), ('ⓗ', &['Ⓗ']), ('ⓘ', &[
+  'Ⓘ']), ('ⓙ', &['Ⓙ']), ('ⓚ', &['Ⓚ']), ('ⓛ', &['Ⓛ']), ('ⓜ', &[
+  'Ⓜ']), ('ⓝ', &['Ⓝ']), ('ⓞ', &['Ⓞ']), ('ⓟ', &['Ⓟ']), ('ⓠ', &[
+  'Ⓠ']), ('ⓡ', &['Ⓡ']), ('ⓢ', &['Ⓢ']), ('ⓣ', &['Ⓣ']), ('ⓤ', &[
+  'Ⓤ']), ('ⓥ', &['Ⓥ']), ('ⓦ', &['Ⓦ']), ('ⓧ', &['Ⓧ']), ('ⓨ', &[
+  'Ⓨ']), ('ⓩ', &['Ⓩ']), ('Ⰰ', &['ⰰ']), ('Ⰱ', &['ⰱ']), ('Ⰲ', &[
+  'ⰲ']), ('Ⰳ', &['ⰳ']), ('Ⰴ', &['ⰴ']), ('Ⰵ', &['ⰵ']), ('Ⰶ', &[
+  'ⰶ']), ('Ⰷ', &['ⰷ']), ('Ⰸ', &['ⰸ']), ('Ⰹ', &['ⰹ']), ('Ⰺ', &[
+  'ⰺ']), ('Ⰻ', &['ⰻ']), ('Ⰼ', &['ⰼ']), ('Ⰽ', &['ⰽ']), ('Ⰾ', &[
+  'ⰾ']), ('Ⰿ', &['ⰿ']), ('Ⱀ', &['ⱀ']), ('Ⱁ', &['ⱁ']), ('Ⱂ', &[
+  'ⱂ']), ('Ⱃ', &['ⱃ']), ('Ⱄ', &['ⱄ']), ('Ⱅ', &['ⱅ']), ('Ⱆ', &[
+  'ⱆ']), ('Ⱇ', &['ⱇ']), ('Ⱈ', &['ⱈ']), ('Ⱉ', &['ⱉ']), ('Ⱊ', &[
+  'ⱊ']), ('Ⱋ', &['ⱋ']), ('Ⱌ', &['ⱌ']), ('Ⱍ', &['ⱍ']), ('Ⱎ', &[
+  'ⱎ']), ('Ⱏ', &['ⱏ']), ('Ⱐ', &['ⱐ']), ('Ⱑ', &['ⱑ']), ('Ⱒ', &[
+  'ⱒ']), ('Ⱓ', &['ⱓ']), ('Ⱔ', &['ⱔ']), ('Ⱕ', &['ⱕ']), ('Ⱖ', &[
+  'ⱖ']), ('Ⱗ', &['ⱗ']), ('Ⱘ', &['ⱘ']), ('Ⱙ', &['ⱙ']), ('Ⱚ', &[
+  'ⱚ']), ('Ⱛ', &['ⱛ']), ('Ⱜ', &['ⱜ']), ('Ⱝ', &['ⱝ']), ('Ⱞ', &[
+  'ⱞ']), ('ⰰ', &['Ⰰ']), ('ⰱ', &['Ⰱ']), ('ⰲ', &['Ⰲ']), ('ⰳ', &[
+  'Ⰳ']), ('ⰴ', &['Ⰴ']), ('ⰵ', &['Ⰵ']), ('ⰶ', &['Ⰶ']), ('ⰷ', &[
+  'Ⰷ']), ('ⰸ', &['Ⰸ']), ('ⰹ', &['Ⰹ']), ('ⰺ', &['Ⰺ']), ('ⰻ', &[
+  'Ⰻ']), ('ⰼ', &['Ⰼ']), ('ⰽ', &['Ⰽ']), ('ⰾ', &['Ⰾ']), ('ⰿ', &[
+  'Ⰿ']), ('ⱀ', &['Ⱀ']), ('ⱁ', &['Ⱁ']), ('ⱂ', &['Ⱂ']), ('ⱃ', &[
+  'Ⱃ']), ('ⱄ', &['Ⱄ']), ('ⱅ', &['Ⱅ']), ('ⱆ', &['Ⱆ']), ('ⱇ', &[
+  'Ⱇ']), ('ⱈ', &['Ⱈ']), ('ⱉ', &['Ⱉ']), ('ⱊ', &['Ⱊ']), ('ⱋ', &[
+  'Ⱋ']), ('ⱌ', &['Ⱌ']), ('ⱍ', &['Ⱍ']), ('ⱎ', &['Ⱎ']), ('ⱏ', &[
+  'Ⱏ']), ('ⱐ', &['Ⱐ']), ('ⱑ', &['Ⱑ']), ('ⱒ', &['Ⱒ']), ('ⱓ', &[
+  'Ⱓ']), ('ⱔ', &['Ⱔ']), ('ⱕ', &['Ⱕ']), ('ⱖ', &['Ⱖ']), ('ⱗ', &[
+  'Ⱗ']), ('ⱘ', &['Ⱘ']), ('ⱙ', &['Ⱙ']), ('ⱚ', &['Ⱚ']), ('ⱛ', &[
+  'Ⱛ']), ('ⱜ', &['Ⱜ']), ('ⱝ', &['Ⱝ']), ('ⱞ', &['Ⱞ']), ('Ⱡ', &[
+  'ⱡ']), ('ⱡ', &['Ⱡ']), ('Ɫ', &['ɫ']), ('Ᵽ', &['ᵽ']), ('Ɽ', &[
+  'ɽ']), ('ⱥ', &['Ⱥ']), ('ⱦ', &['Ⱦ']), ('Ⱨ', &['ⱨ']), ('ⱨ', &[
+  'Ⱨ']), ('Ⱪ', &['ⱪ']), ('ⱪ', &['Ⱪ']), ('Ⱬ', &['ⱬ']), ('ⱬ', &[
+  'Ⱬ']), ('Ɑ', &['ɑ']), ('Ɱ', &['ɱ']), ('Ɐ', &['ɐ']), ('Ɒ', &['ɒ'
+  ]), ('Ⱳ', &['ⱳ']), ('ⱳ', &['Ⱳ']), ('Ⱶ', &['ⱶ']), ('ⱶ', &['Ⱶ'
+  ]), ('Ȿ', &['ȿ']), ('Ɀ', &['ɀ']), ('Ⲁ', &['ⲁ']), ('ⲁ', &['Ⲁ'
+  ]), ('Ⲃ', &['ⲃ']), ('ⲃ', &['Ⲃ']), ('Ⲅ', &['ⲅ']), ('ⲅ', &['Ⲅ'
+  ]), ('Ⲇ', &['ⲇ']), ('ⲇ', &['Ⲇ']), ('Ⲉ', &['ⲉ']), ('ⲉ', &['Ⲉ'
+  ]), ('Ⲋ', &['ⲋ']), ('ⲋ', &['Ⲋ']), ('Ⲍ', &['ⲍ']), ('ⲍ', &['Ⲍ'
+  ]), ('Ⲏ', &['ⲏ']), ('ⲏ', &['Ⲏ']), ('Ⲑ', &['ⲑ']), ('ⲑ', &['Ⲑ'
+  ]), ('Ⲓ', &['ⲓ']), ('ⲓ', &['Ⲓ']), ('Ⲕ', &['ⲕ']), ('ⲕ', &['Ⲕ'
+  ]), ('Ⲗ', &['ⲗ']), ('ⲗ', &['Ⲗ']), ('Ⲙ', &['ⲙ']), ('ⲙ', &['Ⲙ'
+  ]), ('Ⲛ', &['ⲛ']), ('ⲛ', &['Ⲛ']), ('Ⲝ', &['ⲝ']), ('ⲝ', &['Ⲝ'
+  ]), ('Ⲟ', &['ⲟ']), ('ⲟ', &['Ⲟ']), ('Ⲡ', &['ⲡ']), ('ⲡ', &['Ⲡ'
+  ]), ('Ⲣ', &['ⲣ']), ('ⲣ', &['Ⲣ']), ('Ⲥ', &['ⲥ']), ('ⲥ', &['Ⲥ'
+  ]), ('Ⲧ', &['ⲧ']), ('ⲧ', &['Ⲧ']), ('Ⲩ', &['ⲩ']), ('ⲩ', &['Ⲩ'
+  ]), ('Ⲫ', &['ⲫ']), ('ⲫ', &['Ⲫ']), ('Ⲭ', &['ⲭ']), ('ⲭ', &['Ⲭ'
+  ]), ('Ⲯ', &['ⲯ']), ('ⲯ', &['Ⲯ']), ('Ⲱ', &['ⲱ']), ('ⲱ', &['Ⲱ'
+  ]), ('Ⲳ', &['ⲳ']), ('ⲳ', &['Ⲳ']), ('Ⲵ', &['ⲵ']), ('ⲵ', &['Ⲵ'
+  ]), ('Ⲷ', &['ⲷ']), ('ⲷ', &['Ⲷ']), ('Ⲹ', &['ⲹ']), ('ⲹ', &['Ⲹ'
+  ]), ('Ⲻ', &['ⲻ']), ('ⲻ', &['Ⲻ']), ('Ⲽ', &['ⲽ']), ('ⲽ', &['Ⲽ'
+  ]), ('Ⲿ', &['ⲿ']), ('ⲿ', &['Ⲿ']), ('Ⳁ', &['ⳁ']), ('ⳁ', &['Ⳁ'
+  ]), ('Ⳃ', &['ⳃ']), ('ⳃ', &['Ⳃ']), ('Ⳅ', &['ⳅ']), ('ⳅ', &['Ⳅ'
+  ]), ('Ⳇ', &['ⳇ']), ('ⳇ', &['Ⳇ']), ('Ⳉ', &['ⳉ']), ('ⳉ', &['Ⳉ'
+  ]), ('Ⳋ', &['ⳋ']), ('ⳋ', &['Ⳋ']), ('Ⳍ', &['ⳍ']), ('ⳍ', &['Ⳍ'
+  ]), ('Ⳏ', &['ⳏ']), ('ⳏ', &['Ⳏ']), ('Ⳑ', &['ⳑ']), ('ⳑ', &['Ⳑ'
+  ]), ('Ⳓ', &['ⳓ']), ('ⳓ', &['Ⳓ']), ('Ⳕ', &['ⳕ']), ('ⳕ', &['Ⳕ'
+  ]), ('Ⳗ', &['ⳗ']), ('ⳗ', &['Ⳗ']), ('Ⳙ', &['ⳙ']), ('ⳙ', &['Ⳙ'
+  ]), ('Ⳛ', &['ⳛ']), ('ⳛ', &['Ⳛ']), ('Ⳝ', &['ⳝ']), ('ⳝ', &['Ⳝ'
+  ]), ('Ⳟ', &['ⳟ']), ('ⳟ', &['Ⳟ']), ('Ⳡ', &['ⳡ']), ('ⳡ', &['Ⳡ'
+  ]), ('Ⳣ', &['ⳣ']), ('ⳣ', &['Ⳣ']), ('Ⳬ', &['ⳬ']), ('ⳬ', &['Ⳬ'
+  ]), ('Ⳮ', &['ⳮ']), ('ⳮ', &['Ⳮ']), ('Ⳳ', &['ⳳ']), ('ⳳ', &['Ⳳ'
+  ]), ('ⴀ', &['Ⴀ']), ('ⴁ', &['Ⴁ']), ('ⴂ', &['Ⴂ']), ('ⴃ', &['Ⴃ'
+  ]), ('ⴄ', &['Ⴄ']), ('ⴅ', &['Ⴅ']), ('ⴆ', &['Ⴆ']), ('ⴇ', &['Ⴇ'
+  ]), ('ⴈ', &['Ⴈ']), ('ⴉ', &['Ⴉ']), ('ⴊ', &['Ⴊ']), ('ⴋ', &['Ⴋ'
+  ]), ('ⴌ', &['Ⴌ']), ('ⴍ', &['Ⴍ']), ('ⴎ', &['Ⴎ']), ('ⴏ', &['Ⴏ'
+  ]), ('ⴐ', &['Ⴐ']), ('ⴑ', &['Ⴑ']), ('ⴒ', &['Ⴒ']), ('ⴓ', &['Ⴓ'
+  ]), ('ⴔ', &['Ⴔ']), ('ⴕ', &['Ⴕ']), ('ⴖ', &['Ⴖ']), ('ⴗ', &['Ⴗ'
+  ]), ('ⴘ', &['Ⴘ']), ('ⴙ', &['Ⴙ']), ('ⴚ', &['Ⴚ']), ('ⴛ', &['Ⴛ'
+  ]), ('ⴜ', &['Ⴜ']), ('ⴝ', &['Ⴝ']), ('ⴞ', &['Ⴞ']), ('ⴟ', &['Ⴟ'
+  ]), ('ⴠ', &['Ⴠ']), ('ⴡ', &['Ⴡ']), ('ⴢ', &['Ⴢ']), ('ⴣ', &['Ⴣ'
+  ]), ('ⴤ', &['Ⴤ']), ('ⴥ', &['Ⴥ']), ('ⴧ', &['Ⴧ']), ('ⴭ', &['Ⴭ'
+  ]), ('Ꙁ', &['ꙁ']), ('ꙁ', &['Ꙁ']), ('Ꙃ', &['ꙃ']), ('ꙃ', &['Ꙃ'
+  ]), ('Ꙅ', &['ꙅ']), ('ꙅ', &['Ꙅ']), ('Ꙇ', &['ꙇ']), ('ꙇ', &['Ꙇ'
+  ]), ('Ꙉ', &['ꙉ']), ('ꙉ', &['Ꙉ']), ('Ꙋ', &['ᲈ', 'ꙋ', ]),
+  ('ꙋ', &['ᲈ', 'Ꙋ', ]), ('Ꙍ', &['ꙍ']), ('ꙍ', &['Ꙍ']), ('Ꙏ', &[
+  'ꙏ']), ('ꙏ', &['Ꙏ']), ('Ꙑ', &['ꙑ']), ('ꙑ', &['Ꙑ']), ('Ꙓ', &[
+  'ꙓ']), ('ꙓ', &['Ꙓ']), ('Ꙕ', &['ꙕ']), ('ꙕ', &['Ꙕ']), ('Ꙗ', &[
+  'ꙗ']), ('ꙗ', &['Ꙗ']), ('Ꙙ', &['ꙙ']), ('ꙙ', &['Ꙙ']), ('Ꙛ', &[
+  'ꙛ']), ('ꙛ', &['Ꙛ']), ('Ꙝ', &['ꙝ']), ('ꙝ', &['Ꙝ']), ('Ꙟ', &[
+  'ꙟ']), ('ꙟ', &['Ꙟ']), ('Ꙡ', &['ꙡ']), ('ꙡ', &['Ꙡ']), ('Ꙣ', &[
+  'ꙣ']), ('ꙣ', &['Ꙣ']), ('Ꙥ', &['ꙥ']), ('ꙥ', &['Ꙥ']), ('Ꙧ', &[
+  'ꙧ']), ('ꙧ', &['Ꙧ']), ('Ꙩ', &['ꙩ']), ('ꙩ', &['Ꙩ']), ('Ꙫ', &[
+  'ꙫ']), ('ꙫ', &['Ꙫ']), ('Ꙭ', &['ꙭ']), ('ꙭ', &['Ꙭ']), ('Ꚁ', &[
+  'ꚁ']), ('ꚁ', &['Ꚁ']), ('Ꚃ', &['ꚃ']), ('ꚃ', &['Ꚃ']), ('Ꚅ', &[
+  'ꚅ']), ('ꚅ', &['Ꚅ']), ('Ꚇ', &['ꚇ']), ('ꚇ', &['Ꚇ']), ('Ꚉ', &[
+  'ꚉ']), ('ꚉ', &['Ꚉ']), ('Ꚋ', &['ꚋ']), ('ꚋ', &['Ꚋ']), ('Ꚍ', &[
+  'ꚍ']), ('ꚍ', &['Ꚍ']), ('Ꚏ', &['ꚏ']), ('ꚏ', &['Ꚏ']), ('Ꚑ', &[
+  'ꚑ']), ('ꚑ', &['Ꚑ']), ('Ꚓ', &['ꚓ']), ('ꚓ', &['Ꚓ']), ('Ꚕ', &[
+  'ꚕ']), ('ꚕ', &['Ꚕ']), ('Ꚗ', &['ꚗ']), ('ꚗ', &['Ꚗ']), ('Ꚙ', &[
+  'ꚙ']), ('ꚙ', &['Ꚙ']), ('Ꚛ', &['ꚛ']), ('ꚛ', &['Ꚛ']), ('Ꜣ', &[
+  'ꜣ']), ('ꜣ', &['Ꜣ']), ('Ꜥ', &['ꜥ']), ('ꜥ', &['Ꜥ']), ('Ꜧ', &[
+  'ꜧ']), ('ꜧ', &['Ꜧ']), ('Ꜩ', &['ꜩ']), ('ꜩ', &['Ꜩ']), ('Ꜫ', &[
+  'ꜫ']), ('ꜫ', &['Ꜫ']), ('Ꜭ', &['ꜭ']), ('ꜭ', &['Ꜭ']), ('Ꜯ', &[
+  'ꜯ']), ('ꜯ', &['Ꜯ']), ('Ꜳ', &['ꜳ']), ('ꜳ', &['Ꜳ']), ('Ꜵ', &[
+  'ꜵ']), ('ꜵ', &['Ꜵ']), ('Ꜷ', &['ꜷ']), ('ꜷ', &['Ꜷ']), ('Ꜹ', &[
+  'ꜹ']), ('ꜹ', &['Ꜹ']), ('Ꜻ', &['ꜻ']), ('ꜻ', &['Ꜻ']), ('Ꜽ', &[
+  'ꜽ']), ('ꜽ', &['Ꜽ']), ('Ꜿ', &['ꜿ']), ('ꜿ', &['Ꜿ']), ('Ꝁ', &[
+  'ꝁ']), ('ꝁ', &['Ꝁ']), ('Ꝃ', &['ꝃ']), ('ꝃ', &['Ꝃ']), ('Ꝅ', &[
+  'ꝅ']), ('ꝅ', &['Ꝅ']), ('Ꝇ', &['ꝇ']), ('ꝇ', &['Ꝇ']), ('Ꝉ', &[
+  'ꝉ']), ('ꝉ', &['Ꝉ']), ('Ꝋ', &['ꝋ']), ('ꝋ', &['Ꝋ']), ('Ꝍ', &[
+  'ꝍ']), ('ꝍ', &['Ꝍ']), ('Ꝏ', &['ꝏ']), ('ꝏ', &['Ꝏ']), ('Ꝑ', &[
+  'ꝑ']), ('ꝑ', &['Ꝑ']), ('Ꝓ', &['ꝓ']), ('ꝓ', &['Ꝓ']), ('Ꝕ', &[
+  'ꝕ']), ('ꝕ', &['Ꝕ']), ('Ꝗ', &['ꝗ']), ('ꝗ', &['Ꝗ']), ('Ꝙ', &[
+  'ꝙ']), ('ꝙ', &['Ꝙ']), ('Ꝛ', &['ꝛ']), ('ꝛ', &['Ꝛ']), ('Ꝝ', &[
+  'ꝝ']), ('ꝝ', &['Ꝝ']), ('Ꝟ', &['ꝟ']), ('ꝟ', &['Ꝟ']), ('Ꝡ', &[
+  'ꝡ']), ('ꝡ', &['Ꝡ']), ('Ꝣ', &['ꝣ']), ('ꝣ', &['Ꝣ']), ('Ꝥ', &[
+  'ꝥ']), ('ꝥ', &['Ꝥ']), ('Ꝧ', &['ꝧ']), ('ꝧ', &['Ꝧ']), ('Ꝩ', &[
+  'ꝩ']), ('ꝩ', &['Ꝩ']), ('Ꝫ', &['ꝫ']), ('ꝫ', &['Ꝫ']), ('Ꝭ', &[
+  'ꝭ']), ('ꝭ', &['Ꝭ']), ('Ꝯ', &['ꝯ']), ('ꝯ', &['Ꝯ']), ('Ꝺ', &[
+  'ꝺ']), ('ꝺ', &['Ꝺ']), ('Ꝼ', &['ꝼ']), ('ꝼ', &['Ꝼ']), ('Ᵹ', &[
+  'ᵹ']), ('Ꝿ', &['ꝿ']), ('ꝿ', &['Ꝿ']), ('Ꞁ', &['ꞁ']), ('ꞁ', &[
+  'Ꞁ']), ('Ꞃ', &['ꞃ']), ('ꞃ', &['Ꞃ']), ('Ꞅ', &['ꞅ']), ('ꞅ', &[
+  'Ꞅ']), ('Ꞇ', &['ꞇ']), ('ꞇ', &['Ꞇ']), ('Ꞌ', &['ꞌ']), ('ꞌ', &[
+  'Ꞌ']), ('Ɥ', &['ɥ']), ('Ꞑ', &['ꞑ']), ('ꞑ', &['Ꞑ']), ('Ꞓ', &[
+  'ꞓ']), ('ꞓ', &['Ꞓ']), ('ꞔ', &['\u{a7c4}']), ('Ꞗ', &['ꞗ']),
+  ('ꞗ', &['Ꞗ']), ('Ꞙ', &['ꞙ']), ('ꞙ', &['Ꞙ']), ('Ꞛ', &['ꞛ']),
+  ('ꞛ', &['Ꞛ']), ('Ꞝ', &['ꞝ']), ('ꞝ', &['Ꞝ']), ('Ꞟ', &['ꞟ']),
+  ('ꞟ', &['Ꞟ']), ('Ꞡ', &['ꞡ']), ('ꞡ', &['Ꞡ']), ('Ꞣ', &['ꞣ']),
+  ('ꞣ', &['Ꞣ']), ('Ꞥ', &['ꞥ']), ('ꞥ', &['Ꞥ']), ('Ꞧ', &['ꞧ']),
+  ('ꞧ', &['Ꞧ']), ('Ꞩ', &['ꞩ']), ('ꞩ', &['Ꞩ']), ('Ɦ', &['ɦ']),
+  ('Ɜ', &['ɜ']), ('Ɡ', &['ɡ']), ('Ɬ', &['ɬ']), ('Ɪ', &['ɪ']),
+  ('Ʞ', &['ʞ']), ('Ʇ', &['ʇ']), ('Ʝ', &['ʝ']), ('Ꭓ', &['ꭓ']),
+  ('Ꞵ', &['ꞵ']), ('ꞵ', &['Ꞵ']), ('Ꞷ', &['ꞷ']), ('ꞷ', &['Ꞷ']),
+  ('Ꞹ', &['ꞹ']), ('ꞹ', &['Ꞹ']), ('\u{a7ba}', &['\u{a7bb}']),
+  ('\u{a7bb}', &['\u{a7ba}']), ('\u{a7bc}', &['\u{a7bd}']), ('\u{a7bd}', &[
+  '\u{a7bc}']), ('\u{a7be}', &['\u{a7bf}']), ('\u{a7bf}', &['\u{a7be}']),
+  ('\u{a7c2}', &['\u{a7c3}']), ('\u{a7c3}', &['\u{a7c2}']), ('\u{a7c4}', &[
+  'ꞔ']), ('\u{a7c5}', &['ʂ']), ('\u{a7c6}', &['ᶎ']), ('ꭓ', &['Ꭓ']),
+  ('ꭰ', &['Ꭰ']), ('ꭱ', &['Ꭱ']), ('ꭲ', &['Ꭲ']), ('ꭳ', &['Ꭳ']),
+  ('ꭴ', &['Ꭴ']), ('ꭵ', &['Ꭵ']), ('ꭶ', &['Ꭶ']), ('ꭷ', &['Ꭷ']),
+  ('ꭸ', &['Ꭸ']), ('ꭹ', &['Ꭹ']), ('ꭺ', &['Ꭺ']), ('ꭻ', &['Ꭻ']),
+  ('ꭼ', &['Ꭼ']), ('ꭽ', &['Ꭽ']), ('ꭾ', &['Ꭾ']), ('ꭿ', &['Ꭿ']),
+  ('ꮀ', &['Ꮀ']), ('ꮁ', &['Ꮁ']), ('ꮂ', &['Ꮂ']), ('ꮃ', &['Ꮃ']),
+  ('ꮄ', &['Ꮄ']), ('ꮅ', &['Ꮅ']), ('ꮆ', &['Ꮆ']), ('ꮇ', &['Ꮇ']),
+  ('ꮈ', &['Ꮈ']), ('ꮉ', &['Ꮉ']), ('ꮊ', &['Ꮊ']), ('ꮋ', &['Ꮋ']),
+  ('ꮌ', &['Ꮌ']), ('ꮍ', &['Ꮍ']), ('ꮎ', &['Ꮎ']), ('ꮏ', &['Ꮏ']),
+  ('ꮐ', &['Ꮐ']), ('ꮑ', &['Ꮑ']), ('ꮒ', &['Ꮒ']), ('ꮓ', &['Ꮓ']),
+  ('ꮔ', &['Ꮔ']), ('ꮕ', &['Ꮕ']), ('ꮖ', &['Ꮖ']), ('ꮗ', &['Ꮗ']),
+  ('ꮘ', &['Ꮘ']), ('ꮙ', &['Ꮙ']), ('ꮚ', &['Ꮚ']), ('ꮛ', &['Ꮛ']),
+  ('ꮜ', &['Ꮜ']), ('ꮝ', &['Ꮝ']), ('ꮞ', &['Ꮞ']), ('ꮟ', &['Ꮟ']),
+  ('ꮠ', &['Ꮠ']), ('ꮡ', &['Ꮡ']), ('ꮢ', &['Ꮢ']), ('ꮣ', &['Ꮣ']),
+  ('ꮤ', &['Ꮤ']), ('ꮥ', &['Ꮥ']), ('ꮦ', &['Ꮦ']), ('ꮧ', &['Ꮧ']),
+  ('ꮨ', &['Ꮨ']), ('ꮩ', &['Ꮩ']), ('ꮪ', &['Ꮪ']), ('ꮫ', &['Ꮫ']),
+  ('ꮬ', &['Ꮬ']), ('ꮭ', &['Ꮭ']), ('ꮮ', &['Ꮮ']), ('ꮯ', &['Ꮯ']),
+  ('ꮰ', &['Ꮰ']), ('ꮱ', &['Ꮱ']), ('ꮲ', &['Ꮲ']), ('ꮳ', &['Ꮳ']),
+  ('ꮴ', &['Ꮴ']), ('ꮵ', &['Ꮵ']), ('ꮶ', &['Ꮶ']), ('ꮷ', &['Ꮷ']),
+  ('ꮸ', &['Ꮸ']), ('ꮹ', &['Ꮹ']), ('ꮺ', &['Ꮺ']), ('ꮻ', &['Ꮻ']),
+  ('ꮼ', &['Ꮼ']), ('ꮽ', &['Ꮽ']), ('ꮾ', &['Ꮾ']), ('ꮿ', &['Ꮿ']),
+  ('A', &['a']), ('B', &['b']), ('C', &['c']), ('D', &['d']),
+  ('E', &['e']), ('F', &['f']), ('G', &['g']), ('H', &['h']),
+  ('I', &['i']), ('J', &['j']), ('K', &['k']), ('L', &['l']),
+  ('M', &['m']), ('N', &['n']), ('O', &['o']), ('P', &['p']),
+  ('Q', &['q']), ('R', &['r']), ('S', &['s']), ('T', &['t']),
+  ('U', &['u']), ('V', &['v']), ('W', &['w']), ('X', &['x']),
+  ('Y', &['y']), ('Z', &['z']), ('a', &['A']), ('b', &['B']),
+  ('c', &['C']), ('d', &['D']), ('e', &['E']), ('f', &['F']),
+  ('g', &['G']), ('h', &['H']), ('i', &['I']), ('j', &['J']),
+  ('k', &['K']), ('l', &['L']), ('m', &['M']), ('n', &['N']),
+  ('o', &['O']), ('p', &['P']), ('q', &['Q']), ('r', &['R']),
+  ('s', &['S']), ('t', &['T']), ('u', &['U']), ('v', &['V']),
+  ('w', &['W']), ('x', &['X']), ('y', &['Y']), ('z', &['Z']),
+  ('𐐀', &['𐐨']), ('𐐁', &['𐐩']), ('𐐂', &['𐐪']), ('𐐃', &[
+  '𐐫']), ('𐐄', &['𐐬']), ('𐐅', &['𐐭']), ('𐐆', &['𐐮']),
+  ('𐐇', &['𐐯']), ('𐐈', &['𐐰']), ('𐐉', &['𐐱']), ('𐐊', &[
+  '𐐲']), ('𐐋', &['𐐳']), ('𐐌', &['𐐴']), ('𐐍', &['𐐵']),
+  ('𐐎', &['𐐶']), ('𐐏', &['𐐷']), ('𐐐', &['𐐸']), ('𐐑', &[
+  '𐐹']), ('𐐒', &['𐐺']), ('𐐓', &['𐐻']), ('𐐔', &['𐐼']),
+  ('𐐕', &['𐐽']), ('𐐖', &['𐐾']), ('𐐗', &['𐐿']), ('𐐘', &[
+  '𐑀']), ('𐐙', &['𐑁']), ('𐐚', &['𐑂']), ('𐐛', &['𐑃']),
+  ('𐐜', &['𐑄']), ('𐐝', &['𐑅']), ('𐐞', &['𐑆']), ('𐐟', &[
+  '𐑇']), ('𐐠', &['𐑈']), ('𐐡', &['𐑉']), ('𐐢', &['𐑊']),
+  ('𐐣', &['𐑋']), ('𐐤', &['𐑌']), ('𐐥', &['𐑍']), ('𐐦', &[
+  '𐑎']), ('𐐧', &['𐑏']), ('𐐨', &['𐐀']), ('𐐩', &['𐐁']),
+  ('𐐪', &['𐐂']), ('𐐫', &['𐐃']), ('𐐬', &['𐐄']), ('𐐭', &[
+  '𐐅']), ('𐐮', &['𐐆']), ('𐐯', &['𐐇']), ('𐐰', &['𐐈']),
+  ('𐐱', &['𐐉']), ('𐐲', &['𐐊']), ('𐐳', &['𐐋']), ('𐐴', &[
+  '𐐌']), ('𐐵', &['𐐍']), ('𐐶', &['𐐎']), ('𐐷', &['𐐏']),
+  ('𐐸', &['𐐐']), ('𐐹', &['𐐑']), ('𐐺', &['𐐒']), ('𐐻', &[
+  '𐐓']), ('𐐼', &['𐐔']), ('𐐽', &['𐐕']), ('𐐾', &['𐐖']),
+  ('𐐿', &['𐐗']), ('𐑀', &['𐐘']), ('𐑁', &['𐐙']), ('𐑂', &[
+  '𐐚']), ('𐑃', &['𐐛']), ('𐑄', &['𐐜']), ('𐑅', &['𐐝']),
+  ('𐑆', &['𐐞']), ('𐑇', &['𐐟']), ('𐑈', &['𐐠']), ('𐑉', &[
+  '𐐡']), ('𐑊', &['𐐢']), ('𐑋', &['𐐣']), ('𐑌', &['𐐤']),
+  ('𐑍', &['𐐥']), ('𐑎', &['𐐦']), ('𐑏', &['𐐧']), ('𐒰', &[
+  '𐓘']), ('𐒱', &['𐓙']), ('𐒲', &['𐓚']), ('𐒳', &['𐓛']),
+  ('𐒴', &['𐓜']), ('𐒵', &['𐓝']), ('𐒶', &['𐓞']), ('𐒷', &[
+  '𐓟']), ('𐒸', &['𐓠']), ('𐒹', &['𐓡']), ('𐒺', &['𐓢']),
+  ('𐒻', &['𐓣']), ('𐒼', &['𐓤']), ('𐒽', &['𐓥']), ('𐒾', &[
+  '𐓦']), ('𐒿', &['𐓧']), ('𐓀', &['𐓨']), ('𐓁', &['𐓩']),
+  ('𐓂', &['𐓪']), ('𐓃', &['𐓫']), ('𐓄', &['𐓬']), ('𐓅', &[
+  '𐓭']), ('𐓆', &['𐓮']), ('𐓇', &['𐓯']), ('𐓈', &['𐓰']),
+  ('𐓉', &['𐓱']), ('𐓊', &['𐓲']), ('𐓋', &['𐓳']), ('𐓌', &[
+  '𐓴']), ('𐓍', &['𐓵']), ('𐓎', &['𐓶']), ('𐓏', &['𐓷']),
+  ('𐓐', &['𐓸']), ('𐓑', &['𐓹']), ('𐓒', &['𐓺']), ('𐓓', &[
+  '𐓻']), ('𐓘', &['𐒰']), ('𐓙', &['𐒱']), ('𐓚', &['𐒲']),
+  ('𐓛', &['𐒳']), ('𐓜', &['𐒴']), ('𐓝', &['𐒵']), ('𐓞', &[
+  '𐒶']), ('𐓟', &['𐒷']), ('𐓠', &['𐒸']), ('𐓡', &['𐒹']),
+  ('𐓢', &['𐒺']), ('𐓣', &['𐒻']), ('𐓤', &['𐒼']), ('𐓥', &[
+  '𐒽']), ('𐓦', &['𐒾']), ('𐓧', &['𐒿']), ('𐓨', &['𐓀']),
+  ('𐓩', &['𐓁']), ('𐓪', &['𐓂']), ('𐓫', &['𐓃']), ('𐓬', &[
+  '𐓄']), ('𐓭', &['𐓅']), ('𐓮', &['𐓆']), ('𐓯', &['𐓇']),
+  ('𐓰', &['𐓈']), ('𐓱', &['𐓉']), ('𐓲', &['𐓊']), ('𐓳', &[
+  '𐓋']), ('𐓴', &['𐓌']), ('𐓵', &['𐓍']), ('𐓶', &['𐓎']),
+  ('𐓷', &['𐓏']), ('𐓸', &['𐓐']), ('𐓹', &['𐓑']), ('𐓺', &[
+  '𐓒']), ('𐓻', &['𐓓']), ('𐲀', &['𐳀']), ('𐲁', &['𐳁']),
+  ('𐲂', &['𐳂']), ('𐲃', &['𐳃']), ('𐲄', &['𐳄']), ('𐲅', &[
+  '𐳅']), ('𐲆', &['𐳆']), ('𐲇', &['𐳇']), ('𐲈', &['𐳈']),
+  ('𐲉', &['𐳉']), ('𐲊', &['𐳊']), ('𐲋', &['𐳋']), ('𐲌', &[
+  '𐳌']), ('𐲍', &['𐳍']), ('𐲎', &['𐳎']), ('𐲏', &['𐳏']),
+  ('𐲐', &['𐳐']), ('𐲑', &['𐳑']), ('𐲒', &['𐳒']), ('𐲓', &[
+  '𐳓']), ('𐲔', &['𐳔']), ('𐲕', &['𐳕']), ('𐲖', &['𐳖']),
+  ('𐲗', &['𐳗']), ('𐲘', &['𐳘']), ('𐲙', &['𐳙']), ('𐲚', &[
+  '𐳚']), ('𐲛', &['𐳛']), ('𐲜', &['𐳜']), ('𐲝', &['𐳝']),
+  ('𐲞', &['𐳞']), ('𐲟', &['𐳟']), ('𐲠', &['𐳠']), ('𐲡', &[
+  '𐳡']), ('𐲢', &['𐳢']), ('𐲣', &['𐳣']), ('𐲤', &['𐳤']),
+  ('𐲥', &['𐳥']), ('𐲦', &['𐳦']), ('𐲧', &['𐳧']), ('𐲨', &[
+  '𐳨']), ('𐲩', &['𐳩']), ('𐲪', &['𐳪']), ('𐲫', &['𐳫']),
+  ('𐲬', &['𐳬']), ('𐲭', &['𐳭']), ('𐲮', &['𐳮']), ('𐲯', &[
+  '𐳯']), ('𐲰', &['𐳰']), ('𐲱', &['𐳱']), ('𐲲', &['𐳲']),
+  ('𐳀', &['𐲀']), ('𐳁', &['𐲁']), ('𐳂', &['𐲂']), ('𐳃', &[
+  '𐲃']), ('𐳄', &['𐲄']), ('𐳅', &['𐲅']), ('𐳆', &['𐲆']),
+  ('𐳇', &['𐲇']), ('𐳈', &['𐲈']), ('𐳉', &['𐲉']), ('𐳊', &[
+  '𐲊']), ('𐳋', &['𐲋']), ('𐳌', &['𐲌']), ('𐳍', &['𐲍']),
+  ('𐳎', &['𐲎']), ('𐳏', &['𐲏']), ('𐳐', &['𐲐']), ('𐳑', &[
+  '𐲑']), ('𐳒', &['𐲒']), ('𐳓', &['𐲓']), ('𐳔', &['𐲔']),
+  ('𐳕', &['𐲕']), ('𐳖', &['𐲖']), ('𐳗', &['𐲗']), ('𐳘', &[
+  '𐲘']), ('𐳙', &['𐲙']), ('𐳚', &['𐲚']), ('𐳛', &['𐲛']),
+  ('𐳜', &['𐲜']), ('𐳝', &['𐲝']), ('𐳞', &['𐲞']), ('𐳟', &[
+  '𐲟']), ('𐳠', &['𐲠']), ('𐳡', &['𐲡']), ('𐳢', &['𐲢']),
+  ('𐳣', &['𐲣']), ('𐳤', &['𐲤']), ('𐳥', &['𐲥']), ('𐳦', &[
+  '𐲦']), ('𐳧', &['𐲧']), ('𐳨', &['𐲨']), ('𐳩', &['𐲩']),
+  ('𐳪', &['𐲪']), ('𐳫', &['𐲫']), ('𐳬', &['𐲬']), ('𐳭', &[
+  '𐲭']), ('𐳮', &['𐲮']), ('𐳯', &['𐲯']), ('𐳰', &['𐲰']),
+  ('𐳱', &['𐲱']), ('𐳲', &['𐲲']), ('𑢠', &['𑣀']), ('𑢡', &[
+  '𑣁']), ('𑢢', &['𑣂']), ('𑢣', &['𑣃']), ('𑢤', &['𑣄']),
+  ('𑢥', &['𑣅']), ('𑢦', &['𑣆']), ('𑢧', &['𑣇']), ('𑢨', &[
+  '𑣈']), ('𑢩', &['𑣉']), ('𑢪', &['𑣊']), ('𑢫', &['𑣋']),
+  ('𑢬', &['𑣌']), ('𑢭', &['𑣍']), ('𑢮', &['𑣎']), ('𑢯', &[
+  '𑣏']), ('𑢰', &['𑣐']), ('𑢱', &['𑣑']), ('𑢲', &['𑣒']),
+  ('𑢳', &['𑣓']), ('𑢴', &['𑣔']), ('𑢵', &['𑣕']), ('𑢶', &[
+  '𑣖']), ('𑢷', &['𑣗']), ('𑢸', &['𑣘']), ('𑢹', &['𑣙']),
+  ('𑢺', &['𑣚']), ('𑢻', &['𑣛']), ('𑢼', &['𑣜']), ('𑢽', &[
+  '𑣝']), ('𑢾', &['𑣞']), ('𑢿', &['𑣟']), ('𑣀', &['𑢠']),
+  ('𑣁', &['𑢡']), ('𑣂', &['𑢢']), ('𑣃', &['𑢣']), ('𑣄', &[
+  '𑢤']), ('𑣅', &['𑢥']), ('𑣆', &['𑢦']), ('𑣇', &['𑢧']),
+  ('𑣈', &['𑢨']), ('𑣉', &['𑢩']), ('𑣊', &['𑢪']), ('𑣋', &[
+  '𑢫']), ('𑣌', &['𑢬']), ('𑣍', &['𑢭']), ('𑣎', &['𑢮']),
+  ('𑣏', &['𑢯']), ('𑣐', &['𑢰']), ('𑣑', &['𑢱']), ('𑣒', &[
+  '𑢲']), ('𑣓', &['𑢳']), ('𑣔', &['𑢴']), ('𑣕', &['𑢵']),
+  ('𑣖', &['𑢶']), ('𑣗', &['𑢷']), ('𑣘', &['𑢸']), ('𑣙', &[
+  '𑢹']), ('𑣚', &['𑢺']), ('𑣛', &['𑢻']), ('𑣜', &['𑢼']),
+  ('𑣝', &['𑢽']), ('𑣞', &['𑢾']), ('𑣟', &['𑢿']), ('𖹀', &[
+  '𖹠']), ('𖹁', &['𖹡']), ('𖹂', &['𖹢']), ('𖹃', &['𖹣']),
+  ('𖹄', &['𖹤']), ('𖹅', &['𖹥']), ('𖹆', &['𖹦']), ('𖹇', &[
+  '𖹧']), ('𖹈', &['𖹨']), ('𖹉', &['𖹩']), ('𖹊', &['𖹪']),
+  ('𖹋', &['𖹫']), ('𖹌', &['𖹬']), ('𖹍', &['𖹭']), ('𖹎', &[
+  '𖹮']), ('𖹏', &['𖹯']), ('𖹐', &['𖹰']), ('𖹑', &['𖹱']),
+  ('𖹒', &['𖹲']), ('𖹓', &['𖹳']), ('𖹔', &['𖹴']), ('𖹕', &[
+  '𖹵']), ('𖹖', &['𖹶']), ('𖹗', &['𖹷']), ('𖹘', &['𖹸']),
+  ('𖹙', &['𖹹']), ('𖹚', &['𖹺']), ('𖹛', &['𖹻']), ('𖹜', &[
+  '𖹼']), ('𖹝', &['𖹽']), ('𖹞', &['𖹾']), ('𖹟', &['𖹿']),
+  ('𖹠', &['𖹀']), ('𖹡', &['𖹁']), ('𖹢', &['𖹂']), ('𖹣', &[
+  '𖹃']), ('𖹤', &['𖹄']), ('𖹥', &['𖹅']), ('𖹦', &['𖹆']),
+  ('𖹧', &['𖹇']), ('𖹨', &['𖹈']), ('𖹩', &['𖹉']), ('𖹪', &[
+  '𖹊']), ('𖹫', &['𖹋']), ('𖹬', &['𖹌']), ('𖹭', &['𖹍']),
+  ('𖹮', &['𖹎']), ('𖹯', &['𖹏']), ('𖹰', &['𖹐']), ('𖹱', &[
+  '𖹑']), ('𖹲', &['𖹒']), ('𖹳', &['𖹓']), ('𖹴', &['𖹔']),
+  ('𖹵', &['𖹕']), ('𖹶', &['𖹖']), ('𖹷', &['𖹗']), ('𖹸', &[
+  '𖹘']), ('𖹹', &['𖹙']), ('𖹺', &['𖹚']), ('𖹻', &['𖹛']),
+  ('𖹼', &['𖹜']), ('𖹽', &['𖹝']), ('𖹾', &['𖹞']), ('𖹿', &[
+  '𖹟']), ('𞤀', &['𞤢']), ('𞤁', &['𞤣']), ('𞤂', &['𞤤']),
+  ('𞤃', &['𞤥']), ('𞤄', &['𞤦']), ('𞤅', &['𞤧']), ('𞤆', &[
+  '𞤨']), ('𞤇', &['𞤩']), ('𞤈', &['𞤪']), ('𞤉', &['𞤫']),
+  ('𞤊', &['𞤬']), ('𞤋', &['𞤭']), ('𞤌', &['𞤮']), ('𞤍', &[
+  '𞤯']), ('𞤎', &['𞤰']), ('𞤏', &['𞤱']), ('𞤐', &['𞤲']),
+  ('𞤑', &['𞤳']), ('𞤒', &['𞤴']), ('𞤓', &['𞤵']), ('𞤔', &[
+  '𞤶']), ('𞤕', &['𞤷']), ('𞤖', &['𞤸']), ('𞤗', &['𞤹']),
+  ('𞤘', &['𞤺']), ('𞤙', &['𞤻']), ('𞤚', &['𞤼']), ('𞤛', &[
+  '𞤽']), ('𞤜', &['𞤾']), ('𞤝', &['𞤿']), ('𞤞', &['𞥀']),
+  ('𞤟', &['𞥁']), ('𞤠', &['𞥂']), ('𞤡', &['𞥃']), ('𞤢', &[
+  '𞤀']), ('𞤣', &['𞤁']), ('𞤤', &['𞤂']), ('𞤥', &['𞤃']),
+  ('𞤦', &['𞤄']), ('𞤧', &['𞤅']), ('𞤨', &['𞤆']), ('𞤩', &[
+  '𞤇']), ('𞤪', &['𞤈']), ('𞤫', &['𞤉']), ('𞤬', &['𞤊']),
+  ('𞤭', &['𞤋']), ('𞤮', &['𞤌']), ('𞤯', &['𞤍']), ('𞤰', &[
+  '𞤎']), ('𞤱', &['𞤏']), ('𞤲', &['𞤐']), ('𞤳', &['𞤑']),
+  ('𞤴', &['𞤒']), ('𞤵', &['𞤓']), ('𞤶', &['𞤔']), ('𞤷', &[
+  '𞤕']), ('𞤸', &['𞤖']), ('𞤹', &['𞤗']), ('𞤺', &['𞤘']),
+  ('𞤻', &['𞤙']), ('𞤼', &['𞤚']), ('𞤽', &['𞤛']), ('𞤾', &[
+  '𞤜']), ('𞤿', &['𞤝']), ('𞥀', &['𞤞']), ('𞥁', &['𞤟']),
+  ('𞥂', &['𞤠']), ('𞥃', &['𞤡']),
+];
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/unicode_tables/general_category.rs.html b/target/doc/src/regex_syntax/unicode_tables/general_category.rs.html new file mode 100644 index 0000000..5657300 --- /dev/null +++ b/target/doc/src/regex_syntax/unicode_tables/general_category.rs.html @@ -0,0 +1,4071 @@ +general_category.rs.html -- source
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+
+// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
+//
+//  ucd-generate general-category /tmp/ucd-12.1.0/ --chars --exclude surrogate
+//
+// ucd-generate is available on crates.io.
+
+pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
+  ("Cased_Letter", CASED_LETTER), ("Close_Punctuation", CLOSE_PUNCTUATION),
+  ("Connector_Punctuation", CONNECTOR_PUNCTUATION), ("Control", CONTROL),
+  ("Currency_Symbol", CURRENCY_SYMBOL),
+  ("Dash_Punctuation", DASH_PUNCTUATION), ("Decimal_Number", DECIMAL_NUMBER),
+  ("Enclosing_Mark", ENCLOSING_MARK),
+  ("Final_Punctuation", FINAL_PUNCTUATION), ("Format", FORMAT),
+  ("Initial_Punctuation", INITIAL_PUNCTUATION), ("Letter", LETTER),
+  ("Letter_Number", LETTER_NUMBER), ("Line_Separator", LINE_SEPARATOR),
+  ("Lowercase_Letter", LOWERCASE_LETTER), ("Mark", MARK),
+  ("Math_Symbol", MATH_SYMBOL), ("Modifier_Letter", MODIFIER_LETTER),
+  ("Modifier_Symbol", MODIFIER_SYMBOL), ("Nonspacing_Mark", NONSPACING_MARK),
+  ("Number", NUMBER), ("Open_Punctuation", OPEN_PUNCTUATION),
+  ("Other", OTHER), ("Other_Letter", OTHER_LETTER),
+  ("Other_Number", OTHER_NUMBER), ("Other_Punctuation", OTHER_PUNCTUATION),
+  ("Other_Symbol", OTHER_SYMBOL),
+  ("Paragraph_Separator", PARAGRAPH_SEPARATOR), ("Private_Use", PRIVATE_USE),
+  ("Punctuation", PUNCTUATION), ("Separator", SEPARATOR),
+  ("Space_Separator", SPACE_SEPARATOR), ("Spacing_Mark", SPACING_MARK),
+  ("Symbol", SYMBOL), ("Titlecase_Letter", TITLECASE_LETTER),
+  ("Unassigned", UNASSIGNED), ("Uppercase_Letter", UPPERCASE_LETTER),
+];
+
+pub const CASED_LETTER: &'static [(char, char)] = &[
+  ('A', 'Z'), ('a', 'z'), ('µ', 'µ'), ('À', 'Ö'), ('Ø', 'ö'),
+  ('ø', 'ƺ'), ('Ƽ', 'ƿ'), ('DŽ', 'ʓ'), ('ʕ', 'ʯ'), ('Ͱ', 'ͳ'),
+  ('Ͷ', 'ͷ'), ('ͻ', 'ͽ'), ('Ϳ', 'Ϳ'), ('Ά', 'Ά'), ('Έ', 'Ί'),
+  ('Ό', 'Ό'), ('Ύ', 'Ρ'), ('Σ', 'ϵ'), ('Ϸ', 'ҁ'), ('Ҋ', 'ԯ'),
+  ('Ա', 'Ֆ'), ('ՠ', 'ֈ'), ('Ⴀ', 'Ⴥ'), ('Ⴧ', 'Ⴧ'), ('Ⴭ', 'Ⴭ'),
+  ('ა', 'ჺ'), ('ჽ', 'ჿ'), ('Ꭰ', 'Ᏽ'), ('ᏸ', 'ᏽ'),
+  ('ᲀ', 'ᲈ'), ('Ა', 'Ჺ'), ('Ჽ', 'Ჿ'), ('ᴀ', 'ᴫ'),
+  ('ᵫ', 'ᵷ'), ('ᵹ', 'ᶚ'), ('Ḁ', 'ἕ'), ('Ἐ', 'Ἕ'),
+  ('ἠ', 'ὅ'), ('Ὀ', 'Ὅ'), ('ὐ', 'ὗ'), ('Ὑ', 'Ὑ'),
+  ('Ὓ', 'Ὓ'), ('Ὕ', 'Ὕ'), ('Ὗ', 'ώ'), ('ᾀ', 'ᾴ'),
+  ('ᾶ', 'ᾼ'), ('ι', 'ι'), ('ῂ', 'ῄ'), ('ῆ', 'ῌ'),
+  ('ῐ', 'ΐ'), ('ῖ', 'Ί'), ('ῠ', 'Ῥ'), ('ῲ', 'ῴ'),
+  ('ῶ', 'ῼ'), ('ℂ', 'ℂ'), ('ℇ', 'ℇ'), ('ℊ', 'ℓ'),
+  ('ℕ', 'ℕ'), ('ℙ', 'ℝ'), ('ℤ', 'ℤ'), ('Ω', 'Ω'),
+  ('ℨ', 'ℨ'), ('K', 'ℭ'), ('ℯ', 'ℴ'), ('ℹ', 'ℹ'),
+  ('ℼ', 'ℿ'), ('ⅅ', 'ⅉ'), ('ⅎ', 'ⅎ'), ('Ↄ', 'ↄ'),
+  ('Ⰰ', 'Ⱞ'), ('ⰰ', 'ⱞ'), ('Ⱡ', 'ⱻ'), ('Ȿ', 'ⳤ'),
+  ('Ⳬ', 'ⳮ'), ('Ⳳ', 'ⳳ'), ('ⴀ', 'ⴥ'), ('ⴧ', 'ⴧ'),
+  ('ⴭ', 'ⴭ'), ('Ꙁ', 'ꙭ'), ('Ꚁ', 'ꚛ'), ('Ꜣ', 'ꝯ'),
+  ('ꝱ', 'ꞇ'), ('Ꞌ', 'ꞎ'), ('Ꞑ', '\u{a7bf}'),
+  ('\u{a7c2}', '\u{a7c6}'), ('ꟺ', 'ꟺ'), ('ꬰ', 'ꭚ'),
+  ('ꭠ', '\u{ab67}'), ('ꭰ', 'ꮿ'), ('ff', 'st'), ('ﬓ', 'ﬗ'),
+  ('A', 'Z'), ('a', 'z'), ('𐐀', '𐑏'), ('𐒰', '𐓓'),
+  ('𐓘', '𐓻'), ('𐲀', '𐲲'), ('𐳀', '𐳲'), ('𑢠', '𑣟'),
+  ('𖹀', '𖹿'), ('𝐀', '𝑔'), ('𝑖', '𝒜'), ('𝒞', '𝒟'),
+  ('𝒢', '𝒢'), ('𝒥', '𝒦'), ('𝒩', '𝒬'), ('𝒮', '𝒹'),
+  ('𝒻', '𝒻'), ('𝒽', '𝓃'), ('𝓅', '𝔅'), ('𝔇', '𝔊'),
+  ('𝔍', '𝔔'), ('𝔖', '𝔜'), ('𝔞', '𝔹'), ('𝔻', '𝔾'),
+  ('𝕀', '𝕄'), ('𝕆', '𝕆'), ('𝕊', '𝕐'), ('𝕒', '𝚥'),
+  ('𝚨', '𝛀'), ('𝛂', '𝛚'), ('𝛜', '𝛺'), ('𝛼', '𝜔'),
+  ('𝜖', '𝜴'), ('𝜶', '𝝎'), ('𝝐', '𝝮'), ('𝝰', '𝞈'),
+  ('𝞊', '𝞨'), ('𝞪', '𝟂'), ('𝟄', '𝟋'), ('𞤀', '𞥃'),
+];
+
+pub const CLOSE_PUNCTUATION: &'static [(char, char)] = &[
+  (')', ')'), (']', ']'), ('}', '}'), ('༻', '༻'), ('༽', '༽'),
+  ('᚜', '᚜'), ('⁆', '⁆'), ('⁾', '⁾'), ('₎', '₎'),
+  ('⌉', '⌉'), ('⌋', '⌋'), ('〉', '〉'), ('❩', '❩'),
+  ('❫', '❫'), ('❭', '❭'), ('❯', '❯'), ('❱', '❱'),
+  ('❳', '❳'), ('❵', '❵'), ('⟆', '⟆'), ('⟧', '⟧'),
+  ('⟩', '⟩'), ('⟫', '⟫'), ('⟭', '⟭'), ('⟯', '⟯'),
+  ('⦄', '⦄'), ('⦆', '⦆'), ('⦈', '⦈'), ('⦊', '⦊'),
+  ('⦌', '⦌'), ('⦎', '⦎'), ('⦐', '⦐'), ('⦒', '⦒'),
+  ('⦔', '⦔'), ('⦖', '⦖'), ('⦘', '⦘'), ('⧙', '⧙'),
+  ('⧛', '⧛'), ('⧽', '⧽'), ('⸣', '⸣'), ('⸥', '⸥'),
+  ('⸧', '⸧'), ('⸩', '⸩'), ('〉', '〉'), ('》', '》'),
+  ('」', '」'), ('』', '』'), ('】', '】'), ('〕', '〕'),
+  ('〗', '〗'), ('〙', '〙'), ('〛', '〛'), ('〞', '〟'),
+  ('﴾', '﴾'), ('︘', '︘'), ('︶', '︶'), ('︸', '︸'),
+  ('︺', '︺'), ('︼', '︼'), ('︾', '︾'), ('﹀', '﹀'),
+  ('﹂', '﹂'), ('﹄', '﹄'), ('﹈', '﹈'), ('﹚', '﹚'),
+  ('﹜', '﹜'), ('﹞', '﹞'), (')', ')'), (']', ']'),
+  ('}', '}'), ('⦆', '⦆'), ('」', '」'),
+];
+
+pub const CONNECTOR_PUNCTUATION: &'static [(char, char)] = &[
+  ('_', '_'), ('‿', '⁀'), ('⁔', '⁔'), ('︳', '︴'), ('﹍', '﹏'),
+  ('_', '_'),
+];
+
+pub const CONTROL: &'static [(char, char)] = &[
+  ('\u{0}', '\u{1f}'), ('\u{7f}', '\u{9f}'),
+];
+
+pub const CURRENCY_SYMBOL: &'static [(char, char)] = &[
+  ('$', '$'), ('¢', '¥'), ('֏', '֏'), ('؋', '؋'), ('߾', '߿'),
+  ('৲', '৳'), ('৻', '৻'), ('૱', '૱'), ('௹', '௹'),
+  ('฿', '฿'), ('៛', '៛'), ('₠', '₿'), ('꠸', '꠸'),
+  ('﷼', '﷼'), ('﹩', '﹩'), ('$', '$'), ('¢', '£'),
+  ('¥', '₩'), ('\u{11fdd}', '\u{11fe0}'), ('\u{1e2ff}', '\u{1e2ff}'),
+  ('𞲰', '𞲰'),
+];
+
+pub const DASH_PUNCTUATION: &'static [(char, char)] = &[
+  ('-', '-'), ('֊', '֊'), ('־', '־'), ('᐀', '᐀'), ('᠆', '᠆'),
+  ('‐', '―'), ('⸗', '⸗'), ('⸚', '⸚'), ('⸺', '⸻'),
+  ('⹀', '⹀'), ('〜', '〜'), ('〰', '〰'), ('゠', '゠'),
+  ('︱', '︲'), ('﹘', '﹘'), ('﹣', '﹣'), ('-', '-'),
+];
+
+pub const DECIMAL_NUMBER: &'static [(char, char)] = &[
+  ('0', '9'), ('٠', '٩'), ('۰', '۹'), ('߀', '߉'), ('०', '९'),
+  ('০', '৯'), ('੦', '੯'), ('૦', '૯'), ('୦', '୯'),
+  ('௦', '௯'), ('౦', '౯'), ('೦', '೯'), ('൦', '൯'),
+  ('෦', '෯'), ('๐', '๙'), ('໐', '໙'), ('༠', '༩'),
+  ('၀', '၉'), ('႐', '႙'), ('០', '៩'), ('᠐', '᠙'),
+  ('᥆', '᥏'), ('᧐', '᧙'), ('᪀', '᪉'), ('᪐', '᪙'),
+  ('᭐', '᭙'), ('᮰', '᮹'), ('᱀', '᱉'), ('᱐', '᱙'),
+  ('꘠', '꘩'), ('꣐', '꣙'), ('꤀', '꤉'), ('꧐', '꧙'),
+  ('꧰', '꧹'), ('꩐', '꩙'), ('꯰', '꯹'), ('0', '9'),
+  ('𐒠', '𐒩'), ('𐴰', '𐴹'), ('𑁦', '𑁯'), ('𑃰', '𑃹'),
+  ('𑄶', '𑄿'), ('𑇐', '𑇙'), ('𑋰', '𑋹'), ('𑑐', '𑑙'),
+  ('𑓐', '𑓙'), ('𑙐', '𑙙'), ('𑛀', '𑛉'), ('𑜰', '𑜹'),
+  ('𑣠', '𑣩'), ('𑱐', '𑱙'), ('𑵐', '𑵙'), ('𑶠', '𑶩'),
+  ('𖩠', '𖩩'), ('𖭐', '𖭙'), ('𝟎', '𝟿'),
+  ('\u{1e140}', '\u{1e149}'), ('\u{1e2f0}', '\u{1e2f9}'), ('𞥐', '𞥙'),
+];
+
+pub const ENCLOSING_MARK: &'static [(char, char)] = &[
+  ('\u{488}', '\u{489}'), ('\u{1abe}', '\u{1abe}'), ('\u{20dd}', '\u{20e0}'),
+  ('\u{20e2}', '\u{20e4}'), ('\u{a670}', '\u{a672}'),
+];
+
+pub const FINAL_PUNCTUATION: &'static [(char, char)] = &[
+  ('»', '»'), ('’', '’'), ('”', '”'), ('›', '›'),
+  ('⸃', '⸃'), ('⸅', '⸅'), ('⸊', '⸊'), ('⸍', '⸍'),
+  ('⸝', '⸝'), ('⸡', '⸡'),
+];
+
+pub const FORMAT: &'static [(char, char)] = &[
+  ('\u{ad}', '\u{ad}'), ('\u{600}', '\u{605}'), ('\u{61c}', '\u{61c}'),
+  ('\u{6dd}', '\u{6dd}'), ('\u{70f}', '\u{70f}'), ('\u{8e2}', '\u{8e2}'),
+  ('\u{180e}', '\u{180e}'), ('\u{200b}', '\u{200f}'),
+  ('\u{202a}', '\u{202e}'), ('\u{2060}', '\u{2064}'),
+  ('\u{2066}', '\u{206f}'), ('\u{feff}', '\u{feff}'),
+  ('\u{fff9}', '\u{fffb}'), ('\u{110bd}', '\u{110bd}'),
+  ('\u{110cd}', '\u{110cd}'), ('\u{13430}', '\u{13438}'),
+  ('\u{1bca0}', '\u{1bca3}'), ('\u{1d173}', '\u{1d17a}'),
+  ('\u{e0001}', '\u{e0001}'), ('\u{e0020}', '\u{e007f}'),
+];
+
+pub const INITIAL_PUNCTUATION: &'static [(char, char)] = &[
+  ('«', '«'), ('‘', '‘'), ('‛', '“'), ('‟', '‟'),
+  ('‹', '‹'), ('⸂', '⸂'), ('⸄', '⸄'), ('⸉', '⸉'),
+  ('⸌', '⸌'), ('⸜', '⸜'), ('⸠', '⸠'),
+];
+
+pub const LETTER: &'static [(char, char)] = &[
+  ('A', 'Z'), ('a', 'z'), ('ª', 'ª'), ('µ', 'µ'), ('º', 'º'),
+  ('À', 'Ö'), ('Ø', 'ö'), ('ø', 'ˁ'), ('ˆ', 'ˑ'), ('ˠ', 'ˤ'),
+  ('ˬ', 'ˬ'), ('ˮ', 'ˮ'), ('Ͱ', 'ʹ'), ('Ͷ', 'ͷ'), ('ͺ', 'ͽ'),
+  ('Ϳ', 'Ϳ'), ('Ά', 'Ά'), ('Έ', 'Ί'), ('Ό', 'Ό'), ('Ύ', 'Ρ'),
+  ('Σ', 'ϵ'), ('Ϸ', 'ҁ'), ('Ҋ', 'ԯ'), ('Ա', 'Ֆ'), ('ՙ', 'ՙ'),
+  ('ՠ', 'ֈ'), ('א', 'ת'), ('ׯ', 'ײ'), ('ؠ', 'ي'), ('ٮ', 'ٯ'),
+  ('ٱ', 'ۓ'), ('ە', 'ە'), ('ۥ', 'ۦ'), ('ۮ', 'ۯ'), ('ۺ', 'ۼ'),
+  ('ۿ', 'ۿ'), ('ܐ', 'ܐ'), ('ܒ', 'ܯ'), ('ݍ', 'ޥ'), ('ޱ', 'ޱ'),
+  ('ߊ', 'ߪ'), ('ߴ', 'ߵ'), ('ߺ', 'ߺ'), ('ࠀ', 'ࠕ'), ('ࠚ', 'ࠚ'),
+  ('ࠤ', 'ࠤ'), ('ࠨ', 'ࠨ'), ('ࡀ', 'ࡘ'), ('ࡠ', 'ࡪ'),
+  ('ࢠ', 'ࢴ'), ('ࢶ', 'ࢽ'), ('ऄ', 'ह'), ('ऽ', 'ऽ'),
+  ('ॐ', 'ॐ'), ('क़', 'ॡ'), ('ॱ', 'ঀ'), ('অ', 'ঌ'),
+  ('এ', 'ঐ'), ('ও', 'ন'), ('প', 'র'), ('ল', 'ল'),
+  ('শ', 'হ'), ('ঽ', 'ঽ'), ('ৎ', 'ৎ'), ('ড়', 'ঢ়'),
+  ('য়', 'ৡ'), ('ৰ', 'ৱ'), ('ৼ', 'ৼ'), ('ਅ', 'ਊ'),
+  ('ਏ', 'ਐ'), ('ਓ', 'ਨ'), ('ਪ', 'ਰ'), ('ਲ', 'ਲ਼'),
+  ('ਵ', 'ਸ਼'), ('ਸ', 'ਹ'), ('ਖ਼', 'ੜ'), ('ਫ਼', 'ਫ਼'),
+  ('ੲ', 'ੴ'), ('અ', 'ઍ'), ('એ', 'ઑ'), ('ઓ', 'ન'),
+  ('પ', 'ર'), ('લ', 'ળ'), ('વ', 'હ'), ('ઽ', 'ઽ'),
+  ('ૐ', 'ૐ'), ('ૠ', 'ૡ'), ('ૹ', 'ૹ'), ('ଅ', 'ଌ'),
+  ('ଏ', 'ଐ'), ('ଓ', 'ନ'), ('ପ', 'ର'), ('ଲ', 'ଳ'),
+  ('ଵ', 'ହ'), ('ଽ', 'ଽ'), ('ଡ଼', 'ଢ଼'), ('ୟ', 'ୡ'),
+  ('ୱ', 'ୱ'), ('ஃ', 'ஃ'), ('அ', 'ஊ'), ('எ', 'ஐ'),
+  ('ஒ', 'க'), ('ங', 'ச'), ('ஜ', 'ஜ'), ('ஞ', 'ட'),
+  ('ண', 'த'), ('ந', 'ப'), ('ம', 'ஹ'), ('ௐ', 'ௐ'),
+  ('అ', 'ఌ'), ('ఎ', 'ఐ'), ('ఒ', 'న'), ('ప', 'హ'),
+  ('ఽ', 'ఽ'), ('ౘ', 'ౚ'), ('ౠ', 'ౡ'), ('ಀ', 'ಀ'),
+  ('ಅ', 'ಌ'), ('ಎ', 'ಐ'), ('ಒ', 'ನ'), ('ಪ', 'ಳ'),
+  ('ವ', 'ಹ'), ('ಽ', 'ಽ'), ('ೞ', 'ೞ'), ('ೠ', 'ೡ'),
+  ('ೱ', 'ೲ'), ('അ', 'ഌ'), ('എ', 'ഐ'), ('ഒ', 'ഺ'),
+  ('ഽ', 'ഽ'), ('ൎ', 'ൎ'), ('ൔ', 'ൖ'), ('ൟ', 'ൡ'),
+  ('ൺ', 'ൿ'), ('අ', 'ඖ'), ('ක', 'න'), ('ඳ', 'ර'),
+  ('ල', 'ල'), ('ව', 'ෆ'), ('ก', 'ะ'), ('า', 'ำ'),
+  ('เ', 'ๆ'), ('ກ', 'ຂ'), ('ຄ', 'ຄ'), ('\u{e86}', 'ຊ'),
+  ('\u{e8c}', 'ຣ'), ('ລ', 'ລ'), ('ວ', 'ະ'), ('າ', 'ຳ'),
+  ('ຽ', 'ຽ'), ('ເ', 'ໄ'), ('ໆ', 'ໆ'), ('ໜ', 'ໟ'),
+  ('ༀ', 'ༀ'), ('ཀ', 'ཇ'), ('ཉ', 'ཬ'), ('ྈ', 'ྌ'),
+  ('က', 'ဪ'), ('ဿ', 'ဿ'), ('ၐ', 'ၕ'), ('ၚ', 'ၝ'),
+  ('ၡ', 'ၡ'), ('ၥ', 'ၦ'), ('ၮ', 'ၰ'), ('ၵ', 'ႁ'),
+  ('ႎ', 'ႎ'), ('Ⴀ', 'Ⴥ'), ('Ⴧ', 'Ⴧ'), ('Ⴭ', 'Ⴭ'),
+  ('ა', 'ჺ'), ('ჼ', 'ቈ'), ('ቊ', 'ቍ'), ('ቐ', 'ቖ'),
+  ('ቘ', 'ቘ'), ('ቚ', 'ቝ'), ('በ', 'ኈ'), ('ኊ', 'ኍ'),
+  ('ነ', 'ኰ'), ('ኲ', 'ኵ'), ('ኸ', 'ኾ'), ('ዀ', 'ዀ'),
+  ('ዂ', 'ዅ'), ('ወ', 'ዖ'), ('ዘ', 'ጐ'), ('ጒ', 'ጕ'),
+  ('ጘ', 'ፚ'), ('ᎀ', 'ᎏ'), ('Ꭰ', 'Ᏽ'), ('ᏸ', 'ᏽ'),
+  ('ᐁ', 'ᙬ'), ('ᙯ', 'ᙿ'), ('ᚁ', 'ᚚ'), ('ᚠ', 'ᛪ'),
+  ('ᛱ', 'ᛸ'), ('ᜀ', 'ᜌ'), ('ᜎ', 'ᜑ'), ('ᜠ', 'ᜱ'),
+  ('ᝀ', 'ᝑ'), ('ᝠ', 'ᝬ'), ('ᝮ', 'ᝰ'), ('ក', 'ឳ'),
+  ('ៗ', 'ៗ'), ('ៜ', 'ៜ'), ('ᠠ', 'ᡸ'), ('ᢀ', 'ᢄ'),
+  ('ᢇ', 'ᢨ'), ('ᢪ', 'ᢪ'), ('ᢰ', 'ᣵ'), ('ᤀ', 'ᤞ'),
+  ('ᥐ', 'ᥭ'), ('ᥰ', 'ᥴ'), ('ᦀ', 'ᦫ'), ('ᦰ', 'ᧉ'),
+  ('ᨀ', 'ᨖ'), ('ᨠ', 'ᩔ'), ('ᪧ', 'ᪧ'), ('ᬅ', 'ᬳ'),
+  ('ᭅ', 'ᭋ'), ('ᮃ', 'ᮠ'), ('ᮮ', 'ᮯ'), ('ᮺ', 'ᯥ'),
+  ('ᰀ', 'ᰣ'), ('ᱍ', 'ᱏ'), ('ᱚ', 'ᱽ'), ('ᲀ', 'ᲈ'),
+  ('Ა', 'Ჺ'), ('Ჽ', 'Ჿ'), ('ᳩ', 'ᳬ'), ('ᳮ', 'ᳳ'),
+  ('ᳵ', 'ᳶ'), ('\u{1cfa}', '\u{1cfa}'), ('ᴀ', 'ᶿ'), ('Ḁ', 'ἕ'),
+  ('Ἐ', 'Ἕ'), ('ἠ', 'ὅ'), ('Ὀ', 'Ὅ'), ('ὐ', 'ὗ'),
+  ('Ὑ', 'Ὑ'), ('Ὓ', 'Ὓ'), ('Ὕ', 'Ὕ'), ('Ὗ', 'ώ'),
+  ('ᾀ', 'ᾴ'), ('ᾶ', 'ᾼ'), ('ι', 'ι'), ('ῂ', 'ῄ'),
+  ('ῆ', 'ῌ'), ('ῐ', 'ΐ'), ('ῖ', 'Ί'), ('ῠ', 'Ῥ'),
+  ('ῲ', 'ῴ'), ('ῶ', 'ῼ'), ('ⁱ', 'ⁱ'), ('ⁿ', 'ⁿ'),
+  ('ₐ', 'ₜ'), ('ℂ', 'ℂ'), ('ℇ', 'ℇ'), ('ℊ', 'ℓ'),
+  ('ℕ', 'ℕ'), ('ℙ', 'ℝ'), ('ℤ', 'ℤ'), ('Ω', 'Ω'),
+  ('ℨ', 'ℨ'), ('K', 'ℭ'), ('ℯ', 'ℹ'), ('ℼ', 'ℿ'),
+  ('ⅅ', 'ⅉ'), ('ⅎ', 'ⅎ'), ('Ↄ', 'ↄ'), ('Ⰰ', 'Ⱞ'),
+  ('ⰰ', 'ⱞ'), ('Ⱡ', 'ⳤ'), ('Ⳬ', 'ⳮ'), ('Ⳳ', 'ⳳ'),
+  ('ⴀ', 'ⴥ'), ('ⴧ', 'ⴧ'), ('ⴭ', 'ⴭ'), ('ⴰ', 'ⵧ'),
+  ('ⵯ', 'ⵯ'), ('ⶀ', 'ⶖ'), ('ⶠ', 'ⶦ'), ('ⶨ', 'ⶮ'),
+  ('ⶰ', 'ⶶ'), ('ⶸ', 'ⶾ'), ('ⷀ', 'ⷆ'), ('ⷈ', 'ⷎ'),
+  ('ⷐ', 'ⷖ'), ('ⷘ', 'ⷞ'), ('ⸯ', 'ⸯ'), ('々', '〆'),
+  ('〱', '〵'), ('〻', '〼'), ('ぁ', 'ゖ'), ('ゝ', 'ゟ'),
+  ('ァ', 'ヺ'), ('ー', 'ヿ'), ('ㄅ', 'ㄯ'), ('ㄱ', 'ㆎ'),
+  ('ㆠ', 'ㆺ'), ('ㇰ', 'ㇿ'), ('㐀', '䶵'), ('一', '鿯'),
+  ('ꀀ', 'ꒌ'), ('ꓐ', 'ꓽ'), ('ꔀ', 'ꘌ'), ('ꘐ', 'ꘟ'),
+  ('ꘪ', 'ꘫ'), ('Ꙁ', 'ꙮ'), ('ꙿ', 'ꚝ'), ('ꚠ', 'ꛥ'),
+  ('ꜗ', 'ꜟ'), ('Ꜣ', 'ꞈ'), ('Ꞌ', '\u{a7bf}'),
+  ('\u{a7c2}', '\u{a7c6}'), ('ꟷ', 'ꠁ'), ('ꠃ', 'ꠅ'), ('ꠇ', 'ꠊ'),
+  ('ꠌ', 'ꠢ'), ('ꡀ', 'ꡳ'), ('ꢂ', 'ꢳ'), ('ꣲ', 'ꣷ'),
+  ('ꣻ', 'ꣻ'), ('ꣽ', 'ꣾ'), ('ꤊ', 'ꤥ'), ('ꤰ', 'ꥆ'),
+  ('ꥠ', 'ꥼ'), ('ꦄ', 'ꦲ'), ('ꧏ', 'ꧏ'), ('ꧠ', 'ꧤ'),
+  ('ꧦ', 'ꧯ'), ('ꧺ', 'ꧾ'), ('ꨀ', 'ꨨ'), ('ꩀ', 'ꩂ'),
+  ('ꩄ', 'ꩋ'), ('ꩠ', 'ꩶ'), ('ꩺ', 'ꩺ'), ('ꩾ', 'ꪯ'),
+  ('ꪱ', 'ꪱ'), ('ꪵ', 'ꪶ'), ('ꪹ', 'ꪽ'), ('ꫀ', 'ꫀ'),
+  ('ꫂ', 'ꫂ'), ('ꫛ', 'ꫝ'), ('ꫠ', 'ꫪ'), ('ꫲ', 'ꫴ'),
+  ('ꬁ', 'ꬆ'), ('ꬉ', 'ꬎ'), ('ꬑ', 'ꬖ'), ('ꬠ', 'ꬦ'),
+  ('ꬨ', 'ꬮ'), ('ꬰ', 'ꭚ'), ('ꭜ', '\u{ab67}'), ('ꭰ', 'ꯢ'),
+  ('가', '힣'), ('ힰ', 'ퟆ'), ('ퟋ', 'ퟻ'), ('豈', '舘'),
+  ('並', '龎'), ('ff', 'st'), ('ﬓ', 'ﬗ'), ('יִ', 'יִ'),
+  ('ײַ', 'ﬨ'), ('שׁ', 'זּ'), ('טּ', 'לּ'), ('מּ', 'מּ'),
+  ('נּ', 'סּ'), ('ףּ', 'פּ'), ('צּ', 'ﮱ'), ('ﯓ', 'ﴽ'),
+  ('ﵐ', 'ﶏ'), ('ﶒ', 'ﷇ'), ('ﷰ', 'ﷻ'), ('ﹰ', 'ﹴ'),
+  ('ﹶ', 'ﻼ'), ('A', 'Z'), ('a', 'z'), ('ヲ', 'ᄒ'),
+  ('ᅡ', 'ᅦ'), ('ᅧ', 'ᅬ'), ('ᅭ', 'ᅲ'), ('ᅳ', 'ᅵ'),
+  ('𐀀', '𐀋'), ('𐀍', '𐀦'), ('𐀨', '𐀺'), ('𐀼', '𐀽'),
+  ('𐀿', '𐁍'), ('𐁐', '𐁝'), ('𐂀', '𐃺'), ('𐊀', '𐊜'),
+  ('𐊠', '𐋐'), ('𐌀', '𐌟'), ('𐌭', '𐍀'), ('𐍂', '𐍉'),
+  ('𐍐', '𐍵'), ('𐎀', '𐎝'), ('𐎠', '𐏃'), ('𐏈', '𐏏'),
+  ('𐐀', '𐒝'), ('𐒰', '𐓓'), ('𐓘', '𐓻'), ('𐔀', '𐔧'),
+  ('𐔰', '𐕣'), ('𐘀', '𐜶'), ('𐝀', '𐝕'), ('𐝠', '𐝧'),
+  ('𐠀', '𐠅'), ('𐠈', '𐠈'), ('𐠊', '𐠵'), ('𐠷', '𐠸'),
+  ('𐠼', '𐠼'), ('𐠿', '𐡕'), ('𐡠', '𐡶'), ('𐢀', '𐢞'),
+  ('𐣠', '𐣲'), ('𐣴', '𐣵'), ('𐤀', '𐤕'), ('𐤠', '𐤹'),
+  ('𐦀', '𐦷'), ('𐦾', '𐦿'), ('𐨀', '𐨀'), ('𐨐', '𐨓'),
+  ('𐨕', '𐨗'), ('𐨙', '𐨵'), ('𐩠', '𐩼'), ('𐪀', '𐪜'),
+  ('𐫀', '𐫇'), ('𐫉', '𐫤'), ('𐬀', '𐬵'), ('𐭀', '𐭕'),
+  ('𐭠', '𐭲'), ('𐮀', '𐮑'), ('𐰀', '𐱈'), ('𐲀', '𐲲'),
+  ('𐳀', '𐳲'), ('𐴀', '𐴣'), ('𐼀', '𐼜'), ('𐼧', '𐼧'),
+  ('𐼰', '𐽅'), ('\u{10fe0}', '\u{10ff6}'), ('𑀃', '𑀷'),
+  ('𑂃', '𑂯'), ('𑃐', '𑃨'), ('𑄃', '𑄦'), ('𑅄', '𑅄'),
+  ('𑅐', '𑅲'), ('𑅶', '𑅶'), ('𑆃', '𑆲'), ('𑇁', '𑇄'),
+  ('𑇚', '𑇚'), ('𑇜', '𑇜'), ('𑈀', '𑈑'), ('𑈓', '𑈫'),
+  ('𑊀', '𑊆'), ('𑊈', '𑊈'), ('𑊊', '𑊍'), ('𑊏', '𑊝'),
+  ('𑊟', '𑊨'), ('𑊰', '𑋞'), ('𑌅', '𑌌'), ('𑌏', '𑌐'),
+  ('𑌓', '𑌨'), ('𑌪', '𑌰'), ('𑌲', '𑌳'), ('𑌵', '𑌹'),
+  ('𑌽', '𑌽'), ('𑍐', '𑍐'), ('𑍝', '𑍡'), ('𑐀', '𑐴'),
+  ('𑑇', '𑑊'), ('\u{1145f}', '\u{1145f}'), ('𑒀', '𑒯'),
+  ('𑓄', '𑓅'), ('𑓇', '𑓇'), ('𑖀', '𑖮'), ('𑗘', '𑗛'),
+  ('𑘀', '𑘯'), ('𑙄', '𑙄'), ('𑚀', '𑚪'),
+  ('\u{116b8}', '\u{116b8}'), ('𑜀', '𑜚'), ('𑠀', '𑠫'),
+  ('𑢠', '𑣟'), ('𑣿', '𑣿'), ('\u{119a0}', '\u{119a7}'),
+  ('\u{119aa}', '\u{119d0}'), ('\u{119e1}', '\u{119e1}'),
+  ('\u{119e3}', '\u{119e3}'), ('𑨀', '𑨀'), ('𑨋', '𑨲'),
+  ('𑨺', '𑨺'), ('𑩐', '𑩐'), ('𑩜', '𑪉'), ('𑪝', '𑪝'),
+  ('𑫀', '𑫸'), ('𑰀', '𑰈'), ('𑰊', '𑰮'), ('𑱀', '𑱀'),
+  ('𑱲', '𑲏'), ('𑴀', '𑴆'), ('𑴈', '𑴉'), ('𑴋', '𑴰'),
+  ('𑵆', '𑵆'), ('𑵠', '𑵥'), ('𑵧', '𑵨'), ('𑵪', '𑶉'),
+  ('𑶘', '𑶘'), ('𑻠', '𑻲'), ('𒀀', '𒎙'), ('𒒀', '𒕃'),
+  ('𓀀', '𓐮'), ('𔐀', '𔙆'), ('𖠀', '𖨸'), ('𖩀', '𖩞'),
+  ('𖫐', '𖫭'), ('𖬀', '𖬯'), ('𖭀', '𖭃'), ('𖭣', '𖭷'),
+  ('𖭽', '𖮏'), ('𖹀', '𖹿'), ('𖼀', '\u{16f4a}'), ('𖽐', '𖽐'),
+  ('𖾓', '𖾟'), ('𖿠', '𖿡'), ('\u{16fe3}', '\u{16fe3}'),
+  ('𗀀', '\u{187f7}'), ('𘠀', '𘫲'), ('𛀀', '𛄞'),
+  ('\u{1b150}', '\u{1b152}'), ('\u{1b164}', '\u{1b167}'), ('𛅰', '𛋻'),
+  ('𛰀', '𛱪'), ('𛱰', '𛱼'), ('𛲀', '𛲈'), ('𛲐', '𛲙'),
+  ('𝐀', '𝑔'), ('𝑖', '𝒜'), ('𝒞', '𝒟'), ('𝒢', '𝒢'),
+  ('𝒥', '𝒦'), ('𝒩', '𝒬'), ('𝒮', '𝒹'), ('𝒻', '𝒻'),
+  ('𝒽', '𝓃'), ('𝓅', '𝔅'), ('𝔇', '𝔊'), ('𝔍', '𝔔'),
+  ('𝔖', '𝔜'), ('𝔞', '𝔹'), ('𝔻', '𝔾'), ('𝕀', '𝕄'),
+  ('𝕆', '𝕆'), ('𝕊', '𝕐'), ('𝕒', '𝚥'), ('𝚨', '𝛀'),
+  ('𝛂', '𝛚'), ('𝛜', '𝛺'), ('𝛼', '𝜔'), ('𝜖', '𝜴'),
+  ('𝜶', '𝝎'), ('𝝐', '𝝮'), ('𝝰', '𝞈'), ('𝞊', '𝞨'),
+  ('𝞪', '𝟂'), ('𝟄', '𝟋'), ('\u{1e100}', '\u{1e12c}'),
+  ('\u{1e137}', '\u{1e13d}'), ('\u{1e14e}', '\u{1e14e}'),
+  ('\u{1e2c0}', '\u{1e2eb}'), ('𞠀', '𞣄'), ('𞤀', '𞥃'),
+  ('\u{1e94b}', '\u{1e94b}'), ('𞸀', '𞸃'), ('𞸅', '𞸟'),
+  ('𞸡', '𞸢'), ('𞸤', '𞸤'), ('𞸧', '𞸧'), ('𞸩', '𞸲'),
+  ('𞸴', '𞸷'), ('𞸹', '𞸹'), ('𞸻', '𞸻'), ('𞹂', '𞹂'),
+  ('𞹇', '𞹇'), ('𞹉', '𞹉'), ('𞹋', '𞹋'), ('𞹍', '𞹏'),
+  ('𞹑', '𞹒'), ('𞹔', '𞹔'), ('𞹗', '𞹗'), ('𞹙', '𞹙'),
+  ('𞹛', '𞹛'), ('𞹝', '𞹝'), ('𞹟', '𞹟'), ('𞹡', '𞹢'),
+  ('𞹤', '𞹤'), ('𞹧', '𞹪'), ('𞹬', '𞹲'), ('𞹴', '𞹷'),
+  ('𞹹', '𞹼'), ('𞹾', '𞹾'), ('𞺀', '𞺉'), ('𞺋', '𞺛'),
+  ('𞺡', '𞺣'), ('𞺥', '𞺩'), ('𞺫', '𞺻'), ('𠀀', '𪛖'),
+  ('𪜀', '𫜴'), ('𫝀', '𫠝'), ('𫠠', '𬺡'), ('𬺰', '𮯠'),
+  ('丽', '𪘀'),
+];
+
+pub const LETTER_NUMBER: &'static [(char, char)] = &[
+  ('ᛮ', 'ᛰ'), ('Ⅰ', 'ↂ'), ('ↅ', 'ↈ'), ('〇', '〇'),
+  ('〡', '〩'), ('〸', '〺'), ('ꛦ', 'ꛯ'), ('𐅀', '𐅴'),
+  ('𐍁', '𐍁'), ('𐍊', '𐍊'), ('𐏑', '𐏕'), ('𒐀', '𒑮'),
+];
+
+pub const LINE_SEPARATOR: &'static [(char, char)] = &[
+  ('\u{2028}', '\u{2028}'),
+];
+
+pub const LOWERCASE_LETTER: &'static [(char, char)] = &[
+  ('a', 'z'), ('µ', 'µ'), ('ß', 'ö'), ('ø', 'ÿ'), ('ā', 'ā'),
+  ('ă', 'ă'), ('ą', 'ą'), ('ć', 'ć'), ('ĉ', 'ĉ'), ('ċ', 'ċ'),
+  ('č', 'č'), ('ď', 'ď'), ('đ', 'đ'), ('ē', 'ē'), ('ĕ', 'ĕ'),
+  ('ė', 'ė'), ('ę', 'ę'), ('ě', 'ě'), ('ĝ', 'ĝ'), ('ğ', 'ğ'),
+  ('ġ', 'ġ'), ('ģ', 'ģ'), ('ĥ', 'ĥ'), ('ħ', 'ħ'), ('ĩ', 'ĩ'),
+  ('ī', 'ī'), ('ĭ', 'ĭ'), ('į', 'į'), ('ı', 'ı'), ('ij', 'ij'),
+  ('ĵ', 'ĵ'), ('ķ', 'ĸ'), ('ĺ', 'ĺ'), ('ļ', 'ļ'), ('ľ', 'ľ'),
+  ('ŀ', 'ŀ'), ('ł', 'ł'), ('ń', 'ń'), ('ņ', 'ņ'), ('ň', 'ʼn'),
+  ('ŋ', 'ŋ'), ('ō', 'ō'), ('ŏ', 'ŏ'), ('ő', 'ő'), ('œ', 'œ'),
+  ('ŕ', 'ŕ'), ('ŗ', 'ŗ'), ('ř', 'ř'), ('ś', 'ś'), ('ŝ', 'ŝ'),
+  ('ş', 'ş'), ('š', 'š'), ('ţ', 'ţ'), ('ť', 'ť'), ('ŧ', 'ŧ'),
+  ('ũ', 'ũ'), ('ū', 'ū'), ('ŭ', 'ŭ'), ('ů', 'ů'), ('ű', 'ű'),
+  ('ų', 'ų'), ('ŵ', 'ŵ'), ('ŷ', 'ŷ'), ('ź', 'ź'), ('ż', 'ż'),
+  ('ž', 'ƀ'), ('ƃ', 'ƃ'), ('ƅ', 'ƅ'), ('ƈ', 'ƈ'), ('ƌ', 'ƍ'),
+  ('ƒ', 'ƒ'), ('ƕ', 'ƕ'), ('ƙ', 'ƛ'), ('ƞ', 'ƞ'), ('ơ', 'ơ'),
+  ('ƣ', 'ƣ'), ('ƥ', 'ƥ'), ('ƨ', 'ƨ'), ('ƪ', 'ƫ'), ('ƭ', 'ƭ'),
+  ('ư', 'ư'), ('ƴ', 'ƴ'), ('ƶ', 'ƶ'), ('ƹ', 'ƺ'), ('ƽ', 'ƿ'),
+  ('dž', 'dž'), ('lj', 'lj'), ('nj', 'nj'), ('ǎ', 'ǎ'), ('ǐ', 'ǐ'),
+  ('ǒ', 'ǒ'), ('ǔ', 'ǔ'), ('ǖ', 'ǖ'), ('ǘ', 'ǘ'), ('ǚ', 'ǚ'),
+  ('ǜ', 'ǝ'), ('ǟ', 'ǟ'), ('ǡ', 'ǡ'), ('ǣ', 'ǣ'), ('ǥ', 'ǥ'),
+  ('ǧ', 'ǧ'), ('ǩ', 'ǩ'), ('ǫ', 'ǫ'), ('ǭ', 'ǭ'), ('ǯ', 'ǰ'),
+  ('dz', 'dz'), ('ǵ', 'ǵ'), ('ǹ', 'ǹ'), ('ǻ', 'ǻ'), ('ǽ', 'ǽ'),
+  ('ǿ', 'ǿ'), ('ȁ', 'ȁ'), ('ȃ', 'ȃ'), ('ȅ', 'ȅ'), ('ȇ', 'ȇ'),
+  ('ȉ', 'ȉ'), ('ȋ', 'ȋ'), ('ȍ', 'ȍ'), ('ȏ', 'ȏ'), ('ȑ', 'ȑ'),
+  ('ȓ', 'ȓ'), ('ȕ', 'ȕ'), ('ȗ', 'ȗ'), ('ș', 'ș'), ('ț', 'ț'),
+  ('ȝ', 'ȝ'), ('ȟ', 'ȟ'), ('ȡ', 'ȡ'), ('ȣ', 'ȣ'), ('ȥ', 'ȥ'),
+  ('ȧ', 'ȧ'), ('ȩ', 'ȩ'), ('ȫ', 'ȫ'), ('ȭ', 'ȭ'), ('ȯ', 'ȯ'),
+  ('ȱ', 'ȱ'), ('ȳ', 'ȹ'), ('ȼ', 'ȼ'), ('ȿ', 'ɀ'), ('ɂ', 'ɂ'),
+  ('ɇ', 'ɇ'), ('ɉ', 'ɉ'), ('ɋ', 'ɋ'), ('ɍ', 'ɍ'), ('ɏ', 'ʓ'),
+  ('ʕ', 'ʯ'), ('ͱ', 'ͱ'), ('ͳ', 'ͳ'), ('ͷ', 'ͷ'), ('ͻ', 'ͽ'),
+  ('ΐ', 'ΐ'), ('ά', 'ώ'), ('ϐ', 'ϑ'), ('ϕ', 'ϗ'), ('ϙ', 'ϙ'),
+  ('ϛ', 'ϛ'), ('ϝ', 'ϝ'), ('ϟ', 'ϟ'), ('ϡ', 'ϡ'), ('ϣ', 'ϣ'),
+  ('ϥ', 'ϥ'), ('ϧ', 'ϧ'), ('ϩ', 'ϩ'), ('ϫ', 'ϫ'), ('ϭ', 'ϭ'),
+  ('ϯ', 'ϳ'), ('ϵ', 'ϵ'), ('ϸ', 'ϸ'), ('ϻ', 'ϼ'), ('а', 'џ'),
+  ('ѡ', 'ѡ'), ('ѣ', 'ѣ'), ('ѥ', 'ѥ'), ('ѧ', 'ѧ'), ('ѩ', 'ѩ'),
+  ('ѫ', 'ѫ'), ('ѭ', 'ѭ'), ('ѯ', 'ѯ'), ('ѱ', 'ѱ'), ('ѳ', 'ѳ'),
+  ('ѵ', 'ѵ'), ('ѷ', 'ѷ'), ('ѹ', 'ѹ'), ('ѻ', 'ѻ'), ('ѽ', 'ѽ'),
+  ('ѿ', 'ѿ'), ('ҁ', 'ҁ'), ('ҋ', 'ҋ'), ('ҍ', 'ҍ'), ('ҏ', 'ҏ'),
+  ('ґ', 'ґ'), ('ғ', 'ғ'), ('ҕ', 'ҕ'), ('җ', 'җ'), ('ҙ', 'ҙ'),
+  ('қ', 'қ'), ('ҝ', 'ҝ'), ('ҟ', 'ҟ'), ('ҡ', 'ҡ'), ('ң', 'ң'),
+  ('ҥ', 'ҥ'), ('ҧ', 'ҧ'), ('ҩ', 'ҩ'), ('ҫ', 'ҫ'), ('ҭ', 'ҭ'),
+  ('ү', 'ү'), ('ұ', 'ұ'), ('ҳ', 'ҳ'), ('ҵ', 'ҵ'), ('ҷ', 'ҷ'),
+  ('ҹ', 'ҹ'), ('һ', 'һ'), ('ҽ', 'ҽ'), ('ҿ', 'ҿ'), ('ӂ', 'ӂ'),
+  ('ӄ', 'ӄ'), ('ӆ', 'ӆ'), ('ӈ', 'ӈ'), ('ӊ', 'ӊ'), ('ӌ', 'ӌ'),
+  ('ӎ', 'ӏ'), ('ӑ', 'ӑ'), ('ӓ', 'ӓ'), ('ӕ', 'ӕ'), ('ӗ', 'ӗ'),
+  ('ә', 'ә'), ('ӛ', 'ӛ'), ('ӝ', 'ӝ'), ('ӟ', 'ӟ'), ('ӡ', 'ӡ'),
+  ('ӣ', 'ӣ'), ('ӥ', 'ӥ'), ('ӧ', 'ӧ'), ('ө', 'ө'), ('ӫ', 'ӫ'),
+  ('ӭ', 'ӭ'), ('ӯ', 'ӯ'), ('ӱ', 'ӱ'), ('ӳ', 'ӳ'), ('ӵ', 'ӵ'),
+  ('ӷ', 'ӷ'), ('ӹ', 'ӹ'), ('ӻ', 'ӻ'), ('ӽ', 'ӽ'), ('ӿ', 'ӿ'),
+  ('ԁ', 'ԁ'), ('ԃ', 'ԃ'), ('ԅ', 'ԅ'), ('ԇ', 'ԇ'), ('ԉ', 'ԉ'),
+  ('ԋ', 'ԋ'), ('ԍ', 'ԍ'), ('ԏ', 'ԏ'), ('ԑ', 'ԑ'), ('ԓ', 'ԓ'),
+  ('ԕ', 'ԕ'), ('ԗ', 'ԗ'), ('ԙ', 'ԙ'), ('ԛ', 'ԛ'), ('ԝ', 'ԝ'),
+  ('ԟ', 'ԟ'), ('ԡ', 'ԡ'), ('ԣ', 'ԣ'), ('ԥ', 'ԥ'), ('ԧ', 'ԧ'),
+  ('ԩ', 'ԩ'), ('ԫ', 'ԫ'), ('ԭ', 'ԭ'), ('ԯ', 'ԯ'), ('ՠ', 'ֈ'),
+  ('ა', 'ჺ'), ('ჽ', 'ჿ'), ('ᏸ', 'ᏽ'), ('ᲀ', 'ᲈ'),
+  ('ᴀ', 'ᴫ'), ('ᵫ', 'ᵷ'), ('ᵹ', 'ᶚ'), ('ḁ', 'ḁ'),
+  ('ḃ', 'ḃ'), ('ḅ', 'ḅ'), ('ḇ', 'ḇ'), ('ḉ', 'ḉ'),
+  ('ḋ', 'ḋ'), ('ḍ', 'ḍ'), ('ḏ', 'ḏ'), ('ḑ', 'ḑ'),
+  ('ḓ', 'ḓ'), ('ḕ', 'ḕ'), ('ḗ', 'ḗ'), ('ḙ', 'ḙ'),
+  ('ḛ', 'ḛ'), ('ḝ', 'ḝ'), ('ḟ', 'ḟ'), ('ḡ', 'ḡ'),
+  ('ḣ', 'ḣ'), ('ḥ', 'ḥ'), ('ḧ', 'ḧ'), ('ḩ', 'ḩ'),
+  ('ḫ', 'ḫ'), ('ḭ', 'ḭ'), ('ḯ', 'ḯ'), ('ḱ', 'ḱ'),
+  ('ḳ', 'ḳ'), ('ḵ', 'ḵ'), ('ḷ', 'ḷ'), ('ḹ', 'ḹ'),
+  ('ḻ', 'ḻ'), ('ḽ', 'ḽ'), ('ḿ', 'ḿ'), ('ṁ', 'ṁ'),
+  ('ṃ', 'ṃ'), ('ṅ', 'ṅ'), ('ṇ', 'ṇ'), ('ṉ', 'ṉ'),
+  ('ṋ', 'ṋ'), ('ṍ', 'ṍ'), ('ṏ', 'ṏ'), ('ṑ', 'ṑ'),
+  ('ṓ', 'ṓ'), ('ṕ', 'ṕ'), ('ṗ', 'ṗ'), ('ṙ', 'ṙ'),
+  ('ṛ', 'ṛ'), ('ṝ', 'ṝ'), ('ṟ', 'ṟ'), ('ṡ', 'ṡ'),
+  ('ṣ', 'ṣ'), ('ṥ', 'ṥ'), ('ṧ', 'ṧ'), ('ṩ', 'ṩ'),
+  ('ṫ', 'ṫ'), ('ṭ', 'ṭ'), ('ṯ', 'ṯ'), ('ṱ', 'ṱ'),
+  ('ṳ', 'ṳ'), ('ṵ', 'ṵ'), ('ṷ', 'ṷ'), ('ṹ', 'ṹ'),
+  ('ṻ', 'ṻ'), ('ṽ', 'ṽ'), ('ṿ', 'ṿ'), ('ẁ', 'ẁ'),
+  ('ẃ', 'ẃ'), ('ẅ', 'ẅ'), ('ẇ', 'ẇ'), ('ẉ', 'ẉ'),
+  ('ẋ', 'ẋ'), ('ẍ', 'ẍ'), ('ẏ', 'ẏ'), ('ẑ', 'ẑ'),
+  ('ẓ', 'ẓ'), ('ẕ', 'ẝ'), ('ẟ', 'ẟ'), ('ạ', 'ạ'),
+  ('ả', 'ả'), ('ấ', 'ấ'), ('ầ', 'ầ'), ('ẩ', 'ẩ'),
+  ('ẫ', 'ẫ'), ('ậ', 'ậ'), ('ắ', 'ắ'), ('ằ', 'ằ'),
+  ('ẳ', 'ẳ'), ('ẵ', 'ẵ'), ('ặ', 'ặ'), ('ẹ', 'ẹ'),
+  ('ẻ', 'ẻ'), ('ẽ', 'ẽ'), ('ế', 'ế'), ('ề', 'ề'),
+  ('ể', 'ể'), ('ễ', 'ễ'), ('ệ', 'ệ'), ('ỉ', 'ỉ'),
+  ('ị', 'ị'), ('ọ', 'ọ'), ('ỏ', 'ỏ'), ('ố', 'ố'),
+  ('ồ', 'ồ'), ('ổ', 'ổ'), ('ỗ', 'ỗ'), ('ộ', 'ộ'),
+  ('ớ', 'ớ'), ('ờ', 'ờ'), ('ở', 'ở'), ('ỡ', 'ỡ'),
+  ('ợ', 'ợ'), ('ụ', 'ụ'), ('ủ', 'ủ'), ('ứ', 'ứ'),
+  ('ừ', 'ừ'), ('ử', 'ử'), ('ữ', 'ữ'), ('ự', 'ự'),
+  ('ỳ', 'ỳ'), ('ỵ', 'ỵ'), ('ỷ', 'ỷ'), ('ỹ', 'ỹ'),
+  ('ỻ', 'ỻ'), ('ỽ', 'ỽ'), ('ỿ', 'ἇ'), ('ἐ', 'ἕ'),
+  ('ἠ', 'ἧ'), ('ἰ', 'ἷ'), ('ὀ', 'ὅ'), ('ὐ', 'ὗ'),
+  ('ὠ', 'ὧ'), ('ὰ', 'ώ'), ('ᾀ', 'ᾇ'), ('ᾐ', 'ᾗ'),
+  ('ᾠ', 'ᾧ'), ('ᾰ', 'ᾴ'), ('ᾶ', 'ᾷ'), ('ι', 'ι'),
+  ('ῂ', 'ῄ'), ('ῆ', 'ῇ'), ('ῐ', 'ΐ'), ('ῖ', 'ῗ'),
+  ('ῠ', 'ῧ'), ('ῲ', 'ῴ'), ('ῶ', 'ῷ'), ('ℊ', 'ℊ'),
+  ('ℎ', 'ℏ'), ('ℓ', 'ℓ'), ('ℯ', 'ℯ'), ('ℴ', 'ℴ'),
+  ('ℹ', 'ℹ'), ('ℼ', 'ℽ'), ('ⅆ', 'ⅉ'), ('ⅎ', 'ⅎ'),
+  ('ↄ', 'ↄ'), ('ⰰ', 'ⱞ'), ('ⱡ', 'ⱡ'), ('ⱥ', 'ⱦ'),
+  ('ⱨ', 'ⱨ'), ('ⱪ', 'ⱪ'), ('ⱬ', 'ⱬ'), ('ⱱ', 'ⱱ'),
+  ('ⱳ', 'ⱴ'), ('ⱶ', 'ⱻ'), ('ⲁ', 'ⲁ'), ('ⲃ', 'ⲃ'),
+  ('ⲅ', 'ⲅ'), ('ⲇ', 'ⲇ'), ('ⲉ', 'ⲉ'), ('ⲋ', 'ⲋ'),
+  ('ⲍ', 'ⲍ'), ('ⲏ', 'ⲏ'), ('ⲑ', 'ⲑ'), ('ⲓ', 'ⲓ'),
+  ('ⲕ', 'ⲕ'), ('ⲗ', 'ⲗ'), ('ⲙ', 'ⲙ'), ('ⲛ', 'ⲛ'),
+  ('ⲝ', 'ⲝ'), ('ⲟ', 'ⲟ'), ('ⲡ', 'ⲡ'), ('ⲣ', 'ⲣ'),
+  ('ⲥ', 'ⲥ'), ('ⲧ', 'ⲧ'), ('ⲩ', 'ⲩ'), ('ⲫ', 'ⲫ'),
+  ('ⲭ', 'ⲭ'), ('ⲯ', 'ⲯ'), ('ⲱ', 'ⲱ'), ('ⲳ', 'ⲳ'),
+  ('ⲵ', 'ⲵ'), ('ⲷ', 'ⲷ'), ('ⲹ', 'ⲹ'), ('ⲻ', 'ⲻ'),
+  ('ⲽ', 'ⲽ'), ('ⲿ', 'ⲿ'), ('ⳁ', 'ⳁ'), ('ⳃ', 'ⳃ'),
+  ('ⳅ', 'ⳅ'), ('ⳇ', 'ⳇ'), ('ⳉ', 'ⳉ'), ('ⳋ', 'ⳋ'),
+  ('ⳍ', 'ⳍ'), ('ⳏ', 'ⳏ'), ('ⳑ', 'ⳑ'), ('ⳓ', 'ⳓ'),
+  ('ⳕ', 'ⳕ'), ('ⳗ', 'ⳗ'), ('ⳙ', 'ⳙ'), ('ⳛ', 'ⳛ'),
+  ('ⳝ', 'ⳝ'), ('ⳟ', 'ⳟ'), ('ⳡ', 'ⳡ'), ('ⳣ', 'ⳤ'),
+  ('ⳬ', 'ⳬ'), ('ⳮ', 'ⳮ'), ('ⳳ', 'ⳳ'), ('ⴀ', 'ⴥ'),
+  ('ⴧ', 'ⴧ'), ('ⴭ', 'ⴭ'), ('ꙁ', 'ꙁ'), ('ꙃ', 'ꙃ'),
+  ('ꙅ', 'ꙅ'), ('ꙇ', 'ꙇ'), ('ꙉ', 'ꙉ'), ('ꙋ', 'ꙋ'),
+  ('ꙍ', 'ꙍ'), ('ꙏ', 'ꙏ'), ('ꙑ', 'ꙑ'), ('ꙓ', 'ꙓ'),
+  ('ꙕ', 'ꙕ'), ('ꙗ', 'ꙗ'), ('ꙙ', 'ꙙ'), ('ꙛ', 'ꙛ'),
+  ('ꙝ', 'ꙝ'), ('ꙟ', 'ꙟ'), ('ꙡ', 'ꙡ'), ('ꙣ', 'ꙣ'),
+  ('ꙥ', 'ꙥ'), ('ꙧ', 'ꙧ'), ('ꙩ', 'ꙩ'), ('ꙫ', 'ꙫ'),
+  ('ꙭ', 'ꙭ'), ('ꚁ', 'ꚁ'), ('ꚃ', 'ꚃ'), ('ꚅ', 'ꚅ'),
+  ('ꚇ', 'ꚇ'), ('ꚉ', 'ꚉ'), ('ꚋ', 'ꚋ'), ('ꚍ', 'ꚍ'),
+  ('ꚏ', 'ꚏ'), ('ꚑ', 'ꚑ'), ('ꚓ', 'ꚓ'), ('ꚕ', 'ꚕ'),
+  ('ꚗ', 'ꚗ'), ('ꚙ', 'ꚙ'), ('ꚛ', 'ꚛ'), ('ꜣ', 'ꜣ'),
+  ('ꜥ', 'ꜥ'), ('ꜧ', 'ꜧ'), ('ꜩ', 'ꜩ'), ('ꜫ', 'ꜫ'),
+  ('ꜭ', 'ꜭ'), ('ꜯ', 'ꜱ'), ('ꜳ', 'ꜳ'), ('ꜵ', 'ꜵ'),
+  ('ꜷ', 'ꜷ'), ('ꜹ', 'ꜹ'), ('ꜻ', 'ꜻ'), ('ꜽ', 'ꜽ'),
+  ('ꜿ', 'ꜿ'), ('ꝁ', 'ꝁ'), ('ꝃ', 'ꝃ'), ('ꝅ', 'ꝅ'),
+  ('ꝇ', 'ꝇ'), ('ꝉ', 'ꝉ'), ('ꝋ', 'ꝋ'), ('ꝍ', 'ꝍ'),
+  ('ꝏ', 'ꝏ'), ('ꝑ', 'ꝑ'), ('ꝓ', 'ꝓ'), ('ꝕ', 'ꝕ'),
+  ('ꝗ', 'ꝗ'), ('ꝙ', 'ꝙ'), ('ꝛ', 'ꝛ'), ('ꝝ', 'ꝝ'),
+  ('ꝟ', 'ꝟ'), ('ꝡ', 'ꝡ'), ('ꝣ', 'ꝣ'), ('ꝥ', 'ꝥ'),
+  ('ꝧ', 'ꝧ'), ('ꝩ', 'ꝩ'), ('ꝫ', 'ꝫ'), ('ꝭ', 'ꝭ'),
+  ('ꝯ', 'ꝯ'), ('ꝱ', 'ꝸ'), ('ꝺ', 'ꝺ'), ('ꝼ', 'ꝼ'),
+  ('ꝿ', 'ꝿ'), ('ꞁ', 'ꞁ'), ('ꞃ', 'ꞃ'), ('ꞅ', 'ꞅ'),
+  ('ꞇ', 'ꞇ'), ('ꞌ', 'ꞌ'), ('ꞎ', 'ꞎ'), ('ꞑ', 'ꞑ'),
+  ('ꞓ', 'ꞕ'), ('ꞗ', 'ꞗ'), ('ꞙ', 'ꞙ'), ('ꞛ', 'ꞛ'),
+  ('ꞝ', 'ꞝ'), ('ꞟ', 'ꞟ'), ('ꞡ', 'ꞡ'), ('ꞣ', 'ꞣ'),
+  ('ꞥ', 'ꞥ'), ('ꞧ', 'ꞧ'), ('ꞩ', 'ꞩ'), ('ꞯ', 'ꞯ'),
+  ('ꞵ', 'ꞵ'), ('ꞷ', 'ꞷ'), ('ꞹ', 'ꞹ'), ('\u{a7bb}', '\u{a7bb}'),
+  ('\u{a7bd}', '\u{a7bd}'), ('\u{a7bf}', '\u{a7bf}'),
+  ('\u{a7c3}', '\u{a7c3}'), ('ꟺ', 'ꟺ'), ('ꬰ', 'ꭚ'),
+  ('ꭠ', '\u{ab67}'), ('ꭰ', 'ꮿ'), ('ff', 'st'), ('ﬓ', 'ﬗ'),
+  ('a', 'z'), ('𐐨', '𐑏'), ('𐓘', '𐓻'), ('𐳀', '𐳲'),
+  ('𑣀', '𑣟'), ('𖹠', '𖹿'), ('𝐚', '𝐳'), ('𝑎', '𝑔'),
+  ('𝑖', '𝑧'), ('𝒂', '𝒛'), ('𝒶', '𝒹'), ('𝒻', '𝒻'),
+  ('𝒽', '𝓃'), ('𝓅', '𝓏'), ('𝓪', '𝔃'), ('𝔞', '𝔷'),
+  ('𝕒', '𝕫'), ('𝖆', '𝖟'), ('𝖺', '𝗓'), ('𝗮', '𝘇'),
+  ('𝘢', '𝘻'), ('𝙖', '𝙯'), ('𝚊', '𝚥'), ('𝛂', '𝛚'),
+  ('𝛜', '𝛡'), ('𝛼', '𝜔'), ('𝜖', '𝜛'), ('𝜶', '𝝎'),
+  ('𝝐', '𝝕'), ('𝝰', '𝞈'), ('𝞊', '𝞏'), ('𝞪', '𝟂'),
+  ('𝟄', '𝟉'), ('𝟋', '𝟋'), ('𞤢', '𞥃'),
+];
+
+pub const MARK: &'static [(char, char)] = &[
+  ('\u{300}', '\u{36f}'), ('\u{483}', '\u{489}'), ('\u{591}', '\u{5bd}'),
+  ('\u{5bf}', '\u{5bf}'), ('\u{5c1}', '\u{5c2}'), ('\u{5c4}', '\u{5c5}'),
+  ('\u{5c7}', '\u{5c7}'), ('\u{610}', '\u{61a}'), ('\u{64b}', '\u{65f}'),
+  ('\u{670}', '\u{670}'), ('\u{6d6}', '\u{6dc}'), ('\u{6df}', '\u{6e4}'),
+  ('\u{6e7}', '\u{6e8}'), ('\u{6ea}', '\u{6ed}'), ('\u{711}', '\u{711}'),
+  ('\u{730}', '\u{74a}'), ('\u{7a6}', '\u{7b0}'), ('\u{7eb}', '\u{7f3}'),
+  ('\u{7fd}', '\u{7fd}'), ('\u{816}', '\u{819}'), ('\u{81b}', '\u{823}'),
+  ('\u{825}', '\u{827}'), ('\u{829}', '\u{82d}'), ('\u{859}', '\u{85b}'),
+  ('\u{8d3}', '\u{8e1}'), ('\u{8e3}', 'ः'), ('\u{93a}', '\u{93c}'),
+  ('ा', 'ॏ'), ('\u{951}', '\u{957}'), ('\u{962}', '\u{963}'),
+  ('\u{981}', 'ঃ'), ('\u{9bc}', '\u{9bc}'), ('\u{9be}', '\u{9c4}'),
+  ('ে', 'ৈ'), ('ো', '\u{9cd}'), ('\u{9d7}', '\u{9d7}'),
+  ('\u{9e2}', '\u{9e3}'), ('\u{9fe}', '\u{9fe}'), ('\u{a01}', 'ਃ'),
+  ('\u{a3c}', '\u{a3c}'), ('ਾ', '\u{a42}'), ('\u{a47}', '\u{a48}'),
+  ('\u{a4b}', '\u{a4d}'), ('\u{a51}', '\u{a51}'), ('\u{a70}', '\u{a71}'),
+  ('\u{a75}', '\u{a75}'), ('\u{a81}', 'ઃ'), ('\u{abc}', '\u{abc}'),
+  ('ા', '\u{ac5}'), ('\u{ac7}', 'ૉ'), ('ો', '\u{acd}'),
+  ('\u{ae2}', '\u{ae3}'), ('\u{afa}', '\u{aff}'), ('\u{b01}', 'ଃ'),
+  ('\u{b3c}', '\u{b3c}'), ('\u{b3e}', '\u{b44}'), ('େ', 'ୈ'),
+  ('ୋ', '\u{b4d}'), ('\u{b56}', '\u{b57}'), ('\u{b62}', '\u{b63}'),
+  ('\u{b82}', '\u{b82}'), ('\u{bbe}', 'ூ'), ('ெ', 'ை'),
+  ('ொ', '\u{bcd}'), ('\u{bd7}', '\u{bd7}'), ('\u{c00}', '\u{c04}'),
+  ('\u{c3e}', 'ౄ'), ('\u{c46}', '\u{c48}'), ('\u{c4a}', '\u{c4d}'),
+  ('\u{c55}', '\u{c56}'), ('\u{c62}', '\u{c63}'), ('\u{c81}', 'ಃ'),
+  ('\u{cbc}', '\u{cbc}'), ('ಾ', 'ೄ'), ('\u{cc6}', 'ೈ'),
+  ('ೊ', '\u{ccd}'), ('\u{cd5}', '\u{cd6}'), ('\u{ce2}', '\u{ce3}'),
+  ('\u{d00}', 'ഃ'), ('\u{d3b}', '\u{d3c}'), ('\u{d3e}', '\u{d44}'),
+  ('െ', 'ൈ'), ('ൊ', '\u{d4d}'), ('\u{d57}', '\u{d57}'),
+  ('\u{d62}', '\u{d63}'), ('ං', 'ඃ'), ('\u{dca}', '\u{dca}'),
+  ('\u{dcf}', '\u{dd4}'), ('\u{dd6}', '\u{dd6}'), ('ෘ', '\u{ddf}'),
+  ('ෲ', 'ෳ'), ('\u{e31}', '\u{e31}'), ('\u{e34}', '\u{e3a}'),
+  ('\u{e47}', '\u{e4e}'), ('\u{eb1}', '\u{eb1}'), ('\u{eb4}', '\u{ebc}'),
+  ('\u{ec8}', '\u{ecd}'), ('\u{f18}', '\u{f19}'), ('\u{f35}', '\u{f35}'),
+  ('\u{f37}', '\u{f37}'), ('\u{f39}', '\u{f39}'), ('༾', '༿'),
+  ('\u{f71}', '\u{f84}'), ('\u{f86}', '\u{f87}'), ('\u{f8d}', '\u{f97}'),
+  ('\u{f99}', '\u{fbc}'), ('\u{fc6}', '\u{fc6}'), ('ါ', '\u{103e}'),
+  ('ၖ', '\u{1059}'), ('\u{105e}', '\u{1060}'), ('ၢ', 'ၤ'),
+  ('ၧ', 'ၭ'), ('\u{1071}', '\u{1074}'), ('\u{1082}', '\u{108d}'),
+  ('ႏ', 'ႏ'), ('ႚ', '\u{109d}'), ('\u{135d}', '\u{135f}'),
+  ('\u{1712}', '\u{1714}'), ('\u{1732}', '\u{1734}'),
+  ('\u{1752}', '\u{1753}'), ('\u{1772}', '\u{1773}'),
+  ('\u{17b4}', '\u{17d3}'), ('\u{17dd}', '\u{17dd}'),
+  ('\u{180b}', '\u{180d}'), ('\u{1885}', '\u{1886}'),
+  ('\u{18a9}', '\u{18a9}'), ('\u{1920}', 'ᤫ'), ('ᤰ', '\u{193b}'),
+  ('\u{1a17}', '\u{1a1b}'), ('ᩕ', '\u{1a5e}'), ('\u{1a60}', '\u{1a7c}'),
+  ('\u{1a7f}', '\u{1a7f}'), ('\u{1ab0}', '\u{1abe}'), ('\u{1b00}', 'ᬄ'),
+  ('\u{1b34}', '᭄'), ('\u{1b6b}', '\u{1b73}'), ('\u{1b80}', 'ᮂ'),
+  ('ᮡ', '\u{1bad}'), ('\u{1be6}', '᯳'), ('ᰤ', '\u{1c37}'),
+  ('\u{1cd0}', '\u{1cd2}'), ('\u{1cd4}', '\u{1ce8}'),
+  ('\u{1ced}', '\u{1ced}'), ('\u{1cf4}', '\u{1cf4}'), ('᳷', '\u{1cf9}'),
+  ('\u{1dc0}', '\u{1df9}'), ('\u{1dfb}', '\u{1dff}'),
+  ('\u{20d0}', '\u{20f0}'), ('\u{2cef}', '\u{2cf1}'),
+  ('\u{2d7f}', '\u{2d7f}'), ('\u{2de0}', '\u{2dff}'),
+  ('\u{302a}', '\u{302f}'), ('\u{3099}', '\u{309a}'),
+  ('\u{a66f}', '\u{a672}'), ('\u{a674}', '\u{a67d}'),
+  ('\u{a69e}', '\u{a69f}'), ('\u{a6f0}', '\u{a6f1}'),
+  ('\u{a802}', '\u{a802}'), ('\u{a806}', '\u{a806}'),
+  ('\u{a80b}', '\u{a80b}'), ('ꠣ', 'ꠧ'), ('ꢀ', 'ꢁ'),
+  ('ꢴ', '\u{a8c5}'), ('\u{a8e0}', '\u{a8f1}'), ('\u{a8ff}', '\u{a8ff}'),
+  ('\u{a926}', '\u{a92d}'), ('\u{a947}', '꥓'), ('\u{a980}', 'ꦃ'),
+  ('\u{a9b3}', '꧀'), ('\u{a9e5}', '\u{a9e5}'), ('\u{aa29}', '\u{aa36}'),
+  ('\u{aa43}', '\u{aa43}'), ('\u{aa4c}', 'ꩍ'), ('ꩻ', 'ꩽ'),
+  ('\u{aab0}', '\u{aab0}'), ('\u{aab2}', '\u{aab4}'),
+  ('\u{aab7}', '\u{aab8}'), ('\u{aabe}', '\u{aabf}'),
+  ('\u{aac1}', '\u{aac1}'), ('ꫫ', 'ꫯ'), ('ꫵ', '\u{aaf6}'),
+  ('ꯣ', 'ꯪ'), ('꯬', '\u{abed}'), ('\u{fb1e}', '\u{fb1e}'),
+  ('\u{fe00}', '\u{fe0f}'), ('\u{fe20}', '\u{fe2f}'),
+  ('\u{101fd}', '\u{101fd}'), ('\u{102e0}', '\u{102e0}'),
+  ('\u{10376}', '\u{1037a}'), ('\u{10a01}', '\u{10a03}'),
+  ('\u{10a05}', '\u{10a06}'), ('\u{10a0c}', '\u{10a0f}'),
+  ('\u{10a38}', '\u{10a3a}'), ('\u{10a3f}', '\u{10a3f}'),
+  ('\u{10ae5}', '\u{10ae6}'), ('\u{10d24}', '\u{10d27}'),
+  ('\u{10f46}', '\u{10f50}'), ('𑀀', '𑀂'), ('\u{11038}', '\u{11046}'),
+  ('\u{1107f}', '𑂂'), ('𑂰', '\u{110ba}'), ('\u{11100}', '\u{11102}'),
+  ('\u{11127}', '\u{11134}'), ('𑅅', '𑅆'), ('\u{11173}', '\u{11173}'),
+  ('\u{11180}', '𑆂'), ('𑆳', '𑇀'), ('\u{111c9}', '\u{111cc}'),
+  ('𑈬', '\u{11237}'), ('\u{1123e}', '\u{1123e}'),
+  ('\u{112df}', '\u{112ea}'), ('\u{11300}', '𑌃'),
+  ('\u{1133b}', '\u{1133c}'), ('\u{1133e}', '𑍄'), ('𑍇', '𑍈'),
+  ('𑍋', '𑍍'), ('\u{11357}', '\u{11357}'), ('𑍢', '𑍣'),
+  ('\u{11366}', '\u{1136c}'), ('\u{11370}', '\u{11374}'),
+  ('𑐵', '\u{11446}'), ('\u{1145e}', '\u{1145e}'),
+  ('\u{114b0}', '\u{114c3}'), ('\u{115af}', '\u{115b5}'),
+  ('𑖸', '\u{115c0}'), ('\u{115dc}', '\u{115dd}'), ('𑘰', '\u{11640}'),
+  ('\u{116ab}', '\u{116b7}'), ('\u{1171d}', '\u{1172b}'),
+  ('𑠬', '\u{1183a}'), ('\u{119d1}', '\u{119d7}'),
+  ('\u{119da}', '\u{119e0}'), ('\u{119e4}', '\u{119e4}'),
+  ('\u{11a01}', '\u{11a0a}'), ('\u{11a33}', '𑨹'),
+  ('\u{11a3b}', '\u{11a3e}'), ('\u{11a47}', '\u{11a47}'),
+  ('\u{11a51}', '\u{11a5b}'), ('\u{11a8a}', '\u{11a99}'),
+  ('𑰯', '\u{11c36}'), ('\u{11c38}', '\u{11c3f}'),
+  ('\u{11c92}', '\u{11ca7}'), ('𑲩', '\u{11cb6}'),
+  ('\u{11d31}', '\u{11d36}'), ('\u{11d3a}', '\u{11d3a}'),
+  ('\u{11d3c}', '\u{11d3d}'), ('\u{11d3f}', '\u{11d45}'),
+  ('\u{11d47}', '\u{11d47}'), ('𑶊', '𑶎'), ('\u{11d90}', '\u{11d91}'),
+  ('𑶓', '\u{11d97}'), ('\u{11ef3}', '𑻶'), ('\u{16af0}', '\u{16af4}'),
+  ('\u{16b30}', '\u{16b36}'), ('\u{16f4f}', '\u{16f4f}'),
+  ('𖽑', '\u{16f87}'), ('\u{16f8f}', '\u{16f92}'),
+  ('\u{1bc9d}', '\u{1bc9e}'), ('\u{1d165}', '\u{1d169}'),
+  ('𝅭', '\u{1d172}'), ('\u{1d17b}', '\u{1d182}'),
+  ('\u{1d185}', '\u{1d18b}'), ('\u{1d1aa}', '\u{1d1ad}'),
+  ('\u{1d242}', '\u{1d244}'), ('\u{1da00}', '\u{1da36}'),
+  ('\u{1da3b}', '\u{1da6c}'), ('\u{1da75}', '\u{1da75}'),
+  ('\u{1da84}', '\u{1da84}'), ('\u{1da9b}', '\u{1da9f}'),
+  ('\u{1daa1}', '\u{1daaf}'), ('\u{1e000}', '\u{1e006}'),
+  ('\u{1e008}', '\u{1e018}'), ('\u{1e01b}', '\u{1e021}'),
+  ('\u{1e023}', '\u{1e024}'), ('\u{1e026}', '\u{1e02a}'),
+  ('\u{1e130}', '\u{1e136}'), ('\u{1e2ec}', '\u{1e2ef}'),
+  ('\u{1e8d0}', '\u{1e8d6}'), ('\u{1e944}', '\u{1e94a}'),
+  ('\u{e0100}', '\u{e01ef}'),
+];
+
+pub const MATH_SYMBOL: &'static [(char, char)] = &[
+  ('+', '+'), ('<', '>'), ('|', '|'), ('~', '~'), ('¬', '¬'), ('±', '±'),
+  ('×', '×'), ('÷', '÷'), ('϶', '϶'), ('؆', '؈'), ('⁄', '⁄'),
+  ('⁒', '⁒'), ('⁺', '⁼'), ('₊', '₌'), ('℘', '℘'),
+  ('⅀', '⅄'), ('⅋', '⅋'), ('←', '↔'), ('↚', '↛'),
+  ('↠', '↠'), ('↣', '↣'), ('↦', '↦'), ('↮', '↮'),
+  ('⇎', '⇏'), ('⇒', '⇒'), ('⇔', '⇔'), ('⇴', '⋿'),
+  ('⌠', '⌡'), ('⍼', '⍼'), ('⎛', '⎳'), ('⏜', '⏡'),
+  ('▷', '▷'), ('◁', '◁'), ('◸', '◿'), ('♯', '♯'),
+  ('⟀', '⟄'), ('⟇', '⟥'), ('⟰', '⟿'), ('⤀', '⦂'),
+  ('⦙', '⧗'), ('⧜', '⧻'), ('⧾', '⫿'), ('⬰', '⭄'),
+  ('⭇', '⭌'), ('﬩', '﬩'), ('﹢', '﹢'), ('﹤', '﹦'),
+  ('+', '+'), ('<', '>'), ('|', '|'), ('~', '~'),
+  ('¬', '¬'), ('←', '↓'), ('𝛁', '𝛁'), ('𝛛', '𝛛'),
+  ('𝛻', '𝛻'), ('𝜕', '𝜕'), ('𝜵', '𝜵'), ('𝝏', '𝝏'),
+  ('𝝯', '𝝯'), ('𝞉', '𝞉'), ('𝞩', '𝞩'), ('𝟃', '𝟃'),
+  ('𞻰', '𞻱'),
+];
+
+pub const MODIFIER_LETTER: &'static [(char, char)] = &[
+  ('ʰ', 'ˁ'), ('ˆ', 'ˑ'), ('ˠ', 'ˤ'), ('ˬ', 'ˬ'), ('ˮ', 'ˮ'),
+  ('ʹ', 'ʹ'), ('ͺ', 'ͺ'), ('ՙ', 'ՙ'), ('ـ', 'ـ'), ('ۥ', 'ۦ'),
+  ('ߴ', 'ߵ'), ('ߺ', 'ߺ'), ('ࠚ', 'ࠚ'), ('ࠤ', 'ࠤ'), ('ࠨ', 'ࠨ'),
+  ('ॱ', 'ॱ'), ('ๆ', 'ๆ'), ('ໆ', 'ໆ'), ('ჼ', 'ჼ'),
+  ('ៗ', 'ៗ'), ('ᡃ', 'ᡃ'), ('ᪧ', 'ᪧ'), ('ᱸ', 'ᱽ'),
+  ('ᴬ', 'ᵪ'), ('ᵸ', 'ᵸ'), ('ᶛ', 'ᶿ'), ('ⁱ', 'ⁱ'),
+  ('ⁿ', 'ⁿ'), ('ₐ', 'ₜ'), ('ⱼ', 'ⱽ'), ('ⵯ', 'ⵯ'),
+  ('ⸯ', 'ⸯ'), ('々', '々'), ('〱', '〵'), ('〻', '〻'),
+  ('ゝ', 'ゞ'), ('ー', 'ヾ'), ('ꀕ', 'ꀕ'), ('ꓸ', 'ꓽ'),
+  ('ꘌ', 'ꘌ'), ('ꙿ', 'ꙿ'), ('ꚜ', 'ꚝ'), ('ꜗ', 'ꜟ'),
+  ('ꝰ', 'ꝰ'), ('ꞈ', 'ꞈ'), ('ꟸ', 'ꟹ'), ('ꧏ', 'ꧏ'),
+  ('ꧦ', 'ꧦ'), ('ꩰ', 'ꩰ'), ('ꫝ', 'ꫝ'), ('ꫳ', 'ꫴ'),
+  ('ꭜ', 'ꭟ'), ('ー', 'ー'), ('\u{ff9e}', '\u{ff9f}'), ('𖭀', '𖭃'),
+  ('𖾓', '𖾟'), ('𖿠', '𖿡'), ('\u{16fe3}', '\u{16fe3}'),
+  ('\u{1e137}', '\u{1e13d}'), ('\u{1e94b}', '\u{1e94b}'),
+];
+
+pub const MODIFIER_SYMBOL: &'static [(char, char)] = &[
+  ('^', '^'), ('`', '`'), ('¨', '¨'), ('¯', '¯'), ('´', '´'),
+  ('¸', '¸'), ('˂', '˅'), ('˒', '˟'), ('˥', '˫'), ('˭', '˭'),
+  ('˯', '˿'), ('͵', '͵'), ('΄', '΅'), ('᾽', '᾽'), ('᾿', '῁'),
+  ('῍', '῏'), ('῝', '῟'), ('῭', '`'), ('´', '῾'),
+  ('゛', '゜'), ('꜀', '꜖'), ('꜠', '꜡'), ('꞉', '꞊'),
+  ('꭛', '꭛'), ('﮲', '﯁'), ('^', '^'), ('`', '`'),
+  (' ̄', ' ̄'), ('🏻', '🏿'),
+];
+
+pub const NONSPACING_MARK: &'static [(char, char)] = &[
+  ('\u{300}', '\u{36f}'), ('\u{483}', '\u{487}'), ('\u{591}', '\u{5bd}'),
+  ('\u{5bf}', '\u{5bf}'), ('\u{5c1}', '\u{5c2}'), ('\u{5c4}', '\u{5c5}'),
+  ('\u{5c7}', '\u{5c7}'), ('\u{610}', '\u{61a}'), ('\u{64b}', '\u{65f}'),
+  ('\u{670}', '\u{670}'), ('\u{6d6}', '\u{6dc}'), ('\u{6df}', '\u{6e4}'),
+  ('\u{6e7}', '\u{6e8}'), ('\u{6ea}', '\u{6ed}'), ('\u{711}', '\u{711}'),
+  ('\u{730}', '\u{74a}'), ('\u{7a6}', '\u{7b0}'), ('\u{7eb}', '\u{7f3}'),
+  ('\u{7fd}', '\u{7fd}'), ('\u{816}', '\u{819}'), ('\u{81b}', '\u{823}'),
+  ('\u{825}', '\u{827}'), ('\u{829}', '\u{82d}'), ('\u{859}', '\u{85b}'),
+  ('\u{8d3}', '\u{8e1}'), ('\u{8e3}', '\u{902}'), ('\u{93a}', '\u{93a}'),
+  ('\u{93c}', '\u{93c}'), ('\u{941}', '\u{948}'), ('\u{94d}', '\u{94d}'),
+  ('\u{951}', '\u{957}'), ('\u{962}', '\u{963}'), ('\u{981}', '\u{981}'),
+  ('\u{9bc}', '\u{9bc}'), ('\u{9c1}', '\u{9c4}'), ('\u{9cd}', '\u{9cd}'),
+  ('\u{9e2}', '\u{9e3}'), ('\u{9fe}', '\u{9fe}'), ('\u{a01}', '\u{a02}'),
+  ('\u{a3c}', '\u{a3c}'), ('\u{a41}', '\u{a42}'), ('\u{a47}', '\u{a48}'),
+  ('\u{a4b}', '\u{a4d}'), ('\u{a51}', '\u{a51}'), ('\u{a70}', '\u{a71}'),
+  ('\u{a75}', '\u{a75}'), ('\u{a81}', '\u{a82}'), ('\u{abc}', '\u{abc}'),
+  ('\u{ac1}', '\u{ac5}'), ('\u{ac7}', '\u{ac8}'), ('\u{acd}', '\u{acd}'),
+  ('\u{ae2}', '\u{ae3}'), ('\u{afa}', '\u{aff}'), ('\u{b01}', '\u{b01}'),
+  ('\u{b3c}', '\u{b3c}'), ('\u{b3f}', '\u{b3f}'), ('\u{b41}', '\u{b44}'),
+  ('\u{b4d}', '\u{b4d}'), ('\u{b56}', '\u{b56}'), ('\u{b62}', '\u{b63}'),
+  ('\u{b82}', '\u{b82}'), ('\u{bc0}', '\u{bc0}'), ('\u{bcd}', '\u{bcd}'),
+  ('\u{c00}', '\u{c00}'), ('\u{c04}', '\u{c04}'), ('\u{c3e}', '\u{c40}'),
+  ('\u{c46}', '\u{c48}'), ('\u{c4a}', '\u{c4d}'), ('\u{c55}', '\u{c56}'),
+  ('\u{c62}', '\u{c63}'), ('\u{c81}', '\u{c81}'), ('\u{cbc}', '\u{cbc}'),
+  ('\u{cbf}', '\u{cbf}'), ('\u{cc6}', '\u{cc6}'), ('\u{ccc}', '\u{ccd}'),
+  ('\u{ce2}', '\u{ce3}'), ('\u{d00}', '\u{d01}'), ('\u{d3b}', '\u{d3c}'),
+  ('\u{d41}', '\u{d44}'), ('\u{d4d}', '\u{d4d}'), ('\u{d62}', '\u{d63}'),
+  ('\u{dca}', '\u{dca}'), ('\u{dd2}', '\u{dd4}'), ('\u{dd6}', '\u{dd6}'),
+  ('\u{e31}', '\u{e31}'), ('\u{e34}', '\u{e3a}'), ('\u{e47}', '\u{e4e}'),
+  ('\u{eb1}', '\u{eb1}'), ('\u{eb4}', '\u{ebc}'), ('\u{ec8}', '\u{ecd}'),
+  ('\u{f18}', '\u{f19}'), ('\u{f35}', '\u{f35}'), ('\u{f37}', '\u{f37}'),
+  ('\u{f39}', '\u{f39}'), ('\u{f71}', '\u{f7e}'), ('\u{f80}', '\u{f84}'),
+  ('\u{f86}', '\u{f87}'), ('\u{f8d}', '\u{f97}'), ('\u{f99}', '\u{fbc}'),
+  ('\u{fc6}', '\u{fc6}'), ('\u{102d}', '\u{1030}'), ('\u{1032}', '\u{1037}'),
+  ('\u{1039}', '\u{103a}'), ('\u{103d}', '\u{103e}'),
+  ('\u{1058}', '\u{1059}'), ('\u{105e}', '\u{1060}'),
+  ('\u{1071}', '\u{1074}'), ('\u{1082}', '\u{1082}'),
+  ('\u{1085}', '\u{1086}'), ('\u{108d}', '\u{108d}'),
+  ('\u{109d}', '\u{109d}'), ('\u{135d}', '\u{135f}'),
+  ('\u{1712}', '\u{1714}'), ('\u{1732}', '\u{1734}'),
+  ('\u{1752}', '\u{1753}'), ('\u{1772}', '\u{1773}'),
+  ('\u{17b4}', '\u{17b5}'), ('\u{17b7}', '\u{17bd}'),
+  ('\u{17c6}', '\u{17c6}'), ('\u{17c9}', '\u{17d3}'),
+  ('\u{17dd}', '\u{17dd}'), ('\u{180b}', '\u{180d}'),
+  ('\u{1885}', '\u{1886}'), ('\u{18a9}', '\u{18a9}'),
+  ('\u{1920}', '\u{1922}'), ('\u{1927}', '\u{1928}'),
+  ('\u{1932}', '\u{1932}'), ('\u{1939}', '\u{193b}'),
+  ('\u{1a17}', '\u{1a18}'), ('\u{1a1b}', '\u{1a1b}'),
+  ('\u{1a56}', '\u{1a56}'), ('\u{1a58}', '\u{1a5e}'),
+  ('\u{1a60}', '\u{1a60}'), ('\u{1a62}', '\u{1a62}'),
+  ('\u{1a65}', '\u{1a6c}'), ('\u{1a73}', '\u{1a7c}'),
+  ('\u{1a7f}', '\u{1a7f}'), ('\u{1ab0}', '\u{1abd}'),
+  ('\u{1b00}', '\u{1b03}'), ('\u{1b34}', '\u{1b34}'),
+  ('\u{1b36}', '\u{1b3a}'), ('\u{1b3c}', '\u{1b3c}'),
+  ('\u{1b42}', '\u{1b42}'), ('\u{1b6b}', '\u{1b73}'),
+  ('\u{1b80}', '\u{1b81}'), ('\u{1ba2}', '\u{1ba5}'),
+  ('\u{1ba8}', '\u{1ba9}'), ('\u{1bab}', '\u{1bad}'),
+  ('\u{1be6}', '\u{1be6}'), ('\u{1be8}', '\u{1be9}'),
+  ('\u{1bed}', '\u{1bed}'), ('\u{1bef}', '\u{1bf1}'),
+  ('\u{1c2c}', '\u{1c33}'), ('\u{1c36}', '\u{1c37}'),
+  ('\u{1cd0}', '\u{1cd2}'), ('\u{1cd4}', '\u{1ce0}'),
+  ('\u{1ce2}', '\u{1ce8}'), ('\u{1ced}', '\u{1ced}'),
+  ('\u{1cf4}', '\u{1cf4}'), ('\u{1cf8}', '\u{1cf9}'),
+  ('\u{1dc0}', '\u{1df9}'), ('\u{1dfb}', '\u{1dff}'),
+  ('\u{20d0}', '\u{20dc}'), ('\u{20e1}', '\u{20e1}'),
+  ('\u{20e5}', '\u{20f0}'), ('\u{2cef}', '\u{2cf1}'),
+  ('\u{2d7f}', '\u{2d7f}'), ('\u{2de0}', '\u{2dff}'),
+  ('\u{302a}', '\u{302d}'), ('\u{3099}', '\u{309a}'),
+  ('\u{a66f}', '\u{a66f}'), ('\u{a674}', '\u{a67d}'),
+  ('\u{a69e}', '\u{a69f}'), ('\u{a6f0}', '\u{a6f1}'),
+  ('\u{a802}', '\u{a802}'), ('\u{a806}', '\u{a806}'),
+  ('\u{a80b}', '\u{a80b}'), ('\u{a825}', '\u{a826}'),
+  ('\u{a8c4}', '\u{a8c5}'), ('\u{a8e0}', '\u{a8f1}'),
+  ('\u{a8ff}', '\u{a8ff}'), ('\u{a926}', '\u{a92d}'),
+  ('\u{a947}', '\u{a951}'), ('\u{a980}', '\u{a982}'),
+  ('\u{a9b3}', '\u{a9b3}'), ('\u{a9b6}', '\u{a9b9}'), ('\u{a9bc}', 'ꦽ'),
+  ('\u{a9e5}', '\u{a9e5}'), ('\u{aa29}', '\u{aa2e}'),
+  ('\u{aa31}', '\u{aa32}'), ('\u{aa35}', '\u{aa36}'),
+  ('\u{aa43}', '\u{aa43}'), ('\u{aa4c}', '\u{aa4c}'),
+  ('\u{aa7c}', '\u{aa7c}'), ('\u{aab0}', '\u{aab0}'),
+  ('\u{aab2}', '\u{aab4}'), ('\u{aab7}', '\u{aab8}'),
+  ('\u{aabe}', '\u{aabf}'), ('\u{aac1}', '\u{aac1}'),
+  ('\u{aaec}', '\u{aaed}'), ('\u{aaf6}', '\u{aaf6}'),
+  ('\u{abe5}', '\u{abe5}'), ('\u{abe8}', '\u{abe8}'),
+  ('\u{abed}', '\u{abed}'), ('\u{fb1e}', '\u{fb1e}'),
+  ('\u{fe00}', '\u{fe0f}'), ('\u{fe20}', '\u{fe2f}'),
+  ('\u{101fd}', '\u{101fd}'), ('\u{102e0}', '\u{102e0}'),
+  ('\u{10376}', '\u{1037a}'), ('\u{10a01}', '\u{10a03}'),
+  ('\u{10a05}', '\u{10a06}'), ('\u{10a0c}', '\u{10a0f}'),
+  ('\u{10a38}', '\u{10a3a}'), ('\u{10a3f}', '\u{10a3f}'),
+  ('\u{10ae5}', '\u{10ae6}'), ('\u{10d24}', '\u{10d27}'),
+  ('\u{10f46}', '\u{10f50}'), ('\u{11001}', '\u{11001}'),
+  ('\u{11038}', '\u{11046}'), ('\u{1107f}', '\u{11081}'),
+  ('\u{110b3}', '\u{110b6}'), ('\u{110b9}', '\u{110ba}'),
+  ('\u{11100}', '\u{11102}'), ('\u{11127}', '\u{1112b}'),
+  ('\u{1112d}', '\u{11134}'), ('\u{11173}', '\u{11173}'),
+  ('\u{11180}', '\u{11181}'), ('\u{111b6}', '\u{111be}'),
+  ('\u{111c9}', '\u{111cc}'), ('\u{1122f}', '\u{11231}'),
+  ('\u{11234}', '\u{11234}'), ('\u{11236}', '\u{11237}'),
+  ('\u{1123e}', '\u{1123e}'), ('\u{112df}', '\u{112df}'),
+  ('\u{112e3}', '\u{112ea}'), ('\u{11300}', '\u{11301}'),
+  ('\u{1133b}', '\u{1133c}'), ('\u{11340}', '\u{11340}'),
+  ('\u{11366}', '\u{1136c}'), ('\u{11370}', '\u{11374}'),
+  ('\u{11438}', '\u{1143f}'), ('\u{11442}', '\u{11444}'),
+  ('\u{11446}', '\u{11446}'), ('\u{1145e}', '\u{1145e}'),
+  ('\u{114b3}', '\u{114b8}'), ('\u{114ba}', '\u{114ba}'),
+  ('\u{114bf}', '\u{114c0}'), ('\u{114c2}', '\u{114c3}'),
+  ('\u{115b2}', '\u{115b5}'), ('\u{115bc}', '\u{115bd}'),
+  ('\u{115bf}', '\u{115c0}'), ('\u{115dc}', '\u{115dd}'),
+  ('\u{11633}', '\u{1163a}'), ('\u{1163d}', '\u{1163d}'),
+  ('\u{1163f}', '\u{11640}'), ('\u{116ab}', '\u{116ab}'),
+  ('\u{116ad}', '\u{116ad}'), ('\u{116b0}', '\u{116b5}'),
+  ('\u{116b7}', '\u{116b7}'), ('\u{1171d}', '\u{1171f}'),
+  ('\u{11722}', '\u{11725}'), ('\u{11727}', '\u{1172b}'),
+  ('\u{1182f}', '\u{11837}'), ('\u{11839}', '\u{1183a}'),
+  ('\u{119d4}', '\u{119d7}'), ('\u{119da}', '\u{119db}'),
+  ('\u{119e0}', '\u{119e0}'), ('\u{11a01}', '\u{11a0a}'),
+  ('\u{11a33}', '\u{11a38}'), ('\u{11a3b}', '\u{11a3e}'),
+  ('\u{11a47}', '\u{11a47}'), ('\u{11a51}', '\u{11a56}'),
+  ('\u{11a59}', '\u{11a5b}'), ('\u{11a8a}', '\u{11a96}'),
+  ('\u{11a98}', '\u{11a99}'), ('\u{11c30}', '\u{11c36}'),
+  ('\u{11c38}', '\u{11c3d}'), ('\u{11c3f}', '\u{11c3f}'),
+  ('\u{11c92}', '\u{11ca7}'), ('\u{11caa}', '\u{11cb0}'),
+  ('\u{11cb2}', '\u{11cb3}'), ('\u{11cb5}', '\u{11cb6}'),
+  ('\u{11d31}', '\u{11d36}'), ('\u{11d3a}', '\u{11d3a}'),
+  ('\u{11d3c}', '\u{11d3d}'), ('\u{11d3f}', '\u{11d45}'),
+  ('\u{11d47}', '\u{11d47}'), ('\u{11d90}', '\u{11d91}'),
+  ('\u{11d95}', '\u{11d95}'), ('\u{11d97}', '\u{11d97}'),
+  ('\u{11ef3}', '\u{11ef4}'), ('\u{16af0}', '\u{16af4}'),
+  ('\u{16b30}', '\u{16b36}'), ('\u{16f4f}', '\u{16f4f}'),
+  ('\u{16f8f}', '\u{16f92}'), ('\u{1bc9d}', '\u{1bc9e}'),
+  ('\u{1d167}', '\u{1d169}'), ('\u{1d17b}', '\u{1d182}'),
+  ('\u{1d185}', '\u{1d18b}'), ('\u{1d1aa}', '\u{1d1ad}'),
+  ('\u{1d242}', '\u{1d244}'), ('\u{1da00}', '\u{1da36}'),
+  ('\u{1da3b}', '\u{1da6c}'), ('\u{1da75}', '\u{1da75}'),
+  ('\u{1da84}', '\u{1da84}'), ('\u{1da9b}', '\u{1da9f}'),
+  ('\u{1daa1}', '\u{1daaf}'), ('\u{1e000}', '\u{1e006}'),
+  ('\u{1e008}', '\u{1e018}'), ('\u{1e01b}', '\u{1e021}'),
+  ('\u{1e023}', '\u{1e024}'), ('\u{1e026}', '\u{1e02a}'),
+  ('\u{1e130}', '\u{1e136}'), ('\u{1e2ec}', '\u{1e2ef}'),
+  ('\u{1e8d0}', '\u{1e8d6}'), ('\u{1e944}', '\u{1e94a}'),
+  ('\u{e0100}', '\u{e01ef}'),
+];
+
+pub const NUMBER: &'static [(char, char)] = &[
+  ('0', '9'), ('²', '³'), ('¹', '¹'), ('¼', '¾'), ('٠', '٩'),
+  ('۰', '۹'), ('߀', '߉'), ('०', '९'), ('০', '৯'), ('৴', '৹'),
+  ('੦', '੯'), ('૦', '૯'), ('୦', '୯'), ('୲', '୷'),
+  ('௦', '௲'), ('౦', '౯'), ('౸', '౾'), ('೦', '೯'),
+  ('൘', '൞'), ('൦', '൸'), ('෦', '෯'), ('๐', '๙'),
+  ('໐', '໙'), ('༠', '༳'), ('၀', '၉'), ('႐', '႙'),
+  ('፩', '፼'), ('ᛮ', 'ᛰ'), ('០', '៩'), ('៰', '៹'),
+  ('᠐', '᠙'), ('᥆', '᥏'), ('᧐', '᧚'), ('᪀', '᪉'),
+  ('᪐', '᪙'), ('᭐', '᭙'), ('᮰', '᮹'), ('᱀', '᱉'),
+  ('᱐', '᱙'), ('⁰', '⁰'), ('⁴', '⁹'), ('₀', '₉'),
+  ('⅐', 'ↂ'), ('ↅ', '↉'), ('①', '⒛'), ('⓪', '⓿'),
+  ('❶', '➓'), ('⳽', '⳽'), ('〇', '〇'), ('〡', '〩'),
+  ('〸', '〺'), ('㆒', '㆕'), ('㈠', '㈩'), ('㉈', '㉏'),
+  ('㉑', '㉟'), ('㊀', '㊉'), ('㊱', '㊿'), ('꘠', '꘩'),
+  ('ꛦ', 'ꛯ'), ('꠰', '꠵'), ('꣐', '꣙'), ('꤀', '꤉'),
+  ('꧐', '꧙'), ('꧰', '꧹'), ('꩐', '꩙'), ('꯰', '꯹'),
+  ('0', '9'), ('𐄇', '𐄳'), ('𐅀', '𐅸'), ('𐆊', '𐆋'),
+  ('𐋡', '𐋻'), ('𐌠', '𐌣'), ('𐍁', '𐍁'), ('𐍊', '𐍊'),
+  ('𐏑', '𐏕'), ('𐒠', '𐒩'), ('𐡘', '𐡟'), ('𐡹', '𐡿'),
+  ('𐢧', '𐢯'), ('𐣻', '𐣿'), ('𐤖', '𐤛'), ('𐦼', '𐦽'),
+  ('𐧀', '𐧏'), ('𐧒', '𐧿'), ('𐩀', '𐩈'), ('𐩽', '𐩾'),
+  ('𐪝', '𐪟'), ('𐫫', '𐫯'), ('𐭘', '𐭟'), ('𐭸', '𐭿'),
+  ('𐮩', '𐮯'), ('𐳺', '𐳿'), ('𐴰', '𐴹'), ('𐹠', '𐹾'),
+  ('𐼝', '𐼦'), ('𐽑', '𐽔'), ('𑁒', '𑁯'), ('𑃰', '𑃹'),
+  ('𑄶', '𑄿'), ('𑇐', '𑇙'), ('𑇡', '𑇴'), ('𑋰', '𑋹'),
+  ('𑑐', '𑑙'), ('𑓐', '𑓙'), ('𑙐', '𑙙'), ('𑛀', '𑛉'),
+  ('𑜰', '𑜻'), ('𑣠', '𑣲'), ('𑱐', '𑱬'), ('𑵐', '𑵙'),
+  ('𑶠', '𑶩'), ('\u{11fc0}', '\u{11fd4}'), ('𒐀', '𒑮'),
+  ('𖩠', '𖩩'), ('𖭐', '𖭙'), ('𖭛', '𖭡'), ('𖺀', '𖺖'),
+  ('𝋠', '𝋳'), ('𝍠', '𝍸'), ('𝟎', '𝟿'),
+  ('\u{1e140}', '\u{1e149}'), ('\u{1e2f0}', '\u{1e2f9}'), ('𞣇', '𞣏'),
+  ('𞥐', '𞥙'), ('𞱱', '𞲫'), ('𞲭', '𞲯'), ('𞲱', '𞲴'),
+  ('\u{1ed01}', '\u{1ed2d}'), ('\u{1ed2f}', '\u{1ed3d}'), ('🄀', '🄌'),
+];
+
+pub const OPEN_PUNCTUATION: &'static [(char, char)] = &[
+  ('(', '('), ('[', '['), ('{', '{'), ('༺', '༺'), ('༼', '༼'),
+  ('᚛', '᚛'), ('‚', '‚'), ('„', '„'), ('⁅', '⁅'),
+  ('⁽', '⁽'), ('₍', '₍'), ('⌈', '⌈'), ('⌊', '⌊'),
+  ('〈', '〈'), ('❨', '❨'), ('❪', '❪'), ('❬', '❬'),
+  ('❮', '❮'), ('❰', '❰'), ('❲', '❲'), ('❴', '❴'),
+  ('⟅', '⟅'), ('⟦', '⟦'), ('⟨', '⟨'), ('⟪', '⟪'),
+  ('⟬', '⟬'), ('⟮', '⟮'), ('⦃', '⦃'), ('⦅', '⦅'),
+  ('⦇', '⦇'), ('⦉', '⦉'), ('⦋', '⦋'), ('⦍', '⦍'),
+  ('⦏', '⦏'), ('⦑', '⦑'), ('⦓', '⦓'), ('⦕', '⦕'),
+  ('⦗', '⦗'), ('⧘', '⧘'), ('⧚', '⧚'), ('⧼', '⧼'),
+  ('⸢', '⸢'), ('⸤', '⸤'), ('⸦', '⸦'), ('⸨', '⸨'),
+  ('⹂', '⹂'), ('〈', '〈'), ('《', '《'), ('「', '「'),
+  ('『', '『'), ('【', '【'), ('〔', '〔'), ('〖', '〖'),
+  ('〘', '〘'), ('〚', '〚'), ('〝', '〝'), ('﴿', '﴿'),
+  ('︗', '︗'), ('︵', '︵'), ('︷', '︷'), ('︹', '︹'),
+  ('︻', '︻'), ('︽', '︽'), ('︿', '︿'), ('﹁', '﹁'),
+  ('﹃', '﹃'), ('﹇', '﹇'), ('﹙', '﹙'), ('﹛', '﹛'),
+  ('﹝', '﹝'), ('(', '('), ('[', '['), ('{', '{'),
+  ('⦅', '⦅'), ('「', '「'),
+];
+
+pub const OTHER: &'static [(char, char)] = &[
+  ('\u{0}', '\u{1f}'), ('\u{7f}', '\u{9f}'), ('\u{ad}', '\u{ad}'),
+  ('\u{378}', '\u{379}'), ('\u{380}', '\u{383}'), ('\u{38b}', '\u{38b}'),
+  ('\u{38d}', '\u{38d}'), ('\u{3a2}', '\u{3a2}'), ('\u{530}', '\u{530}'),
+  ('\u{557}', '\u{558}'), ('\u{58b}', '\u{58c}'), ('\u{590}', '\u{590}'),
+  ('\u{5c8}', '\u{5cf}'), ('\u{5eb}', '\u{5ee}'), ('\u{5f5}', '\u{605}'),
+  ('\u{61c}', '\u{61d}'), ('\u{6dd}', '\u{6dd}'), ('\u{70e}', '\u{70f}'),
+  ('\u{74b}', '\u{74c}'), ('\u{7b2}', '\u{7bf}'), ('\u{7fb}', '\u{7fc}'),
+  ('\u{82e}', '\u{82f}'), ('\u{83f}', '\u{83f}'), ('\u{85c}', '\u{85d}'),
+  ('\u{85f}', '\u{85f}'), ('\u{86b}', '\u{89f}'), ('\u{8b5}', '\u{8b5}'),
+  ('\u{8be}', '\u{8d2}'), ('\u{8e2}', '\u{8e2}'), ('\u{984}', '\u{984}'),
+  ('\u{98d}', '\u{98e}'), ('\u{991}', '\u{992}'), ('\u{9a9}', '\u{9a9}'),
+  ('\u{9b1}', '\u{9b1}'), ('\u{9b3}', '\u{9b5}'), ('\u{9ba}', '\u{9bb}'),
+  ('\u{9c5}', '\u{9c6}'), ('\u{9c9}', '\u{9ca}'), ('\u{9cf}', '\u{9d6}'),
+  ('\u{9d8}', '\u{9db}'), ('\u{9de}', '\u{9de}'), ('\u{9e4}', '\u{9e5}'),
+  ('\u{9ff}', '\u{a00}'), ('\u{a04}', '\u{a04}'), ('\u{a0b}', '\u{a0e}'),
+  ('\u{a11}', '\u{a12}'), ('\u{a29}', '\u{a29}'), ('\u{a31}', '\u{a31}'),
+  ('\u{a34}', '\u{a34}'), ('\u{a37}', '\u{a37}'), ('\u{a3a}', '\u{a3b}'),
+  ('\u{a3d}', '\u{a3d}'), ('\u{a43}', '\u{a46}'), ('\u{a49}', '\u{a4a}'),
+  ('\u{a4e}', '\u{a50}'), ('\u{a52}', '\u{a58}'), ('\u{a5d}', '\u{a5d}'),
+  ('\u{a5f}', '\u{a65}'), ('\u{a77}', '\u{a80}'), ('\u{a84}', '\u{a84}'),
+  ('\u{a8e}', '\u{a8e}'), ('\u{a92}', '\u{a92}'), ('\u{aa9}', '\u{aa9}'),
+  ('\u{ab1}', '\u{ab1}'), ('\u{ab4}', '\u{ab4}'), ('\u{aba}', '\u{abb}'),
+  ('\u{ac6}', '\u{ac6}'), ('\u{aca}', '\u{aca}'), ('\u{ace}', '\u{acf}'),
+  ('\u{ad1}', '\u{adf}'), ('\u{ae4}', '\u{ae5}'), ('\u{af2}', '\u{af8}'),
+  ('\u{b00}', '\u{b00}'), ('\u{b04}', '\u{b04}'), ('\u{b0d}', '\u{b0e}'),
+  ('\u{b11}', '\u{b12}'), ('\u{b29}', '\u{b29}'), ('\u{b31}', '\u{b31}'),
+  ('\u{b34}', '\u{b34}'), ('\u{b3a}', '\u{b3b}'), ('\u{b45}', '\u{b46}'),
+  ('\u{b49}', '\u{b4a}'), ('\u{b4e}', '\u{b55}'), ('\u{b58}', '\u{b5b}'),
+  ('\u{b5e}', '\u{b5e}'), ('\u{b64}', '\u{b65}'), ('\u{b78}', '\u{b81}'),
+  ('\u{b84}', '\u{b84}'), ('\u{b8b}', '\u{b8d}'), ('\u{b91}', '\u{b91}'),
+  ('\u{b96}', '\u{b98}'), ('\u{b9b}', '\u{b9b}'), ('\u{b9d}', '\u{b9d}'),
+  ('\u{ba0}', '\u{ba2}'), ('\u{ba5}', '\u{ba7}'), ('\u{bab}', '\u{bad}'),
+  ('\u{bba}', '\u{bbd}'), ('\u{bc3}', '\u{bc5}'), ('\u{bc9}', '\u{bc9}'),
+  ('\u{bce}', '\u{bcf}'), ('\u{bd1}', '\u{bd6}'), ('\u{bd8}', '\u{be5}'),
+  ('\u{bfb}', '\u{bff}'), ('\u{c0d}', '\u{c0d}'), ('\u{c11}', '\u{c11}'),
+  ('\u{c29}', '\u{c29}'), ('\u{c3a}', '\u{c3c}'), ('\u{c45}', '\u{c45}'),
+  ('\u{c49}', '\u{c49}'), ('\u{c4e}', '\u{c54}'), ('\u{c57}', '\u{c57}'),
+  ('\u{c5b}', '\u{c5f}'), ('\u{c64}', '\u{c65}'), ('\u{c70}', '\u{c76}'),
+  ('\u{c8d}', '\u{c8d}'), ('\u{c91}', '\u{c91}'), ('\u{ca9}', '\u{ca9}'),
+  ('\u{cb4}', '\u{cb4}'), ('\u{cba}', '\u{cbb}'), ('\u{cc5}', '\u{cc5}'),
+  ('\u{cc9}', '\u{cc9}'), ('\u{cce}', '\u{cd4}'), ('\u{cd7}', '\u{cdd}'),
+  ('\u{cdf}', '\u{cdf}'), ('\u{ce4}', '\u{ce5}'), ('\u{cf0}', '\u{cf0}'),
+  ('\u{cf3}', '\u{cff}'), ('\u{d04}', '\u{d04}'), ('\u{d0d}', '\u{d0d}'),
+  ('\u{d11}', '\u{d11}'), ('\u{d45}', '\u{d45}'), ('\u{d49}', '\u{d49}'),
+  ('\u{d50}', '\u{d53}'), ('\u{d64}', '\u{d65}'), ('\u{d80}', '\u{d81}'),
+  ('\u{d84}', '\u{d84}'), ('\u{d97}', '\u{d99}'), ('\u{db2}', '\u{db2}'),
+  ('\u{dbc}', '\u{dbc}'), ('\u{dbe}', '\u{dbf}'), ('\u{dc7}', '\u{dc9}'),
+  ('\u{dcb}', '\u{dce}'), ('\u{dd5}', '\u{dd5}'), ('\u{dd7}', '\u{dd7}'),
+  ('\u{de0}', '\u{de5}'), ('\u{df0}', '\u{df1}'), ('\u{df5}', '\u{e00}'),
+  ('\u{e3b}', '\u{e3e}'), ('\u{e5c}', '\u{e80}'), ('\u{e83}', '\u{e83}'),
+  ('\u{e85}', '\u{e85}'), ('\u{e8b}', '\u{e8b}'), ('\u{ea4}', '\u{ea4}'),
+  ('\u{ea6}', '\u{ea6}'), ('\u{ebe}', '\u{ebf}'), ('\u{ec5}', '\u{ec5}'),
+  ('\u{ec7}', '\u{ec7}'), ('\u{ece}', '\u{ecf}'), ('\u{eda}', '\u{edb}'),
+  ('\u{ee0}', '\u{eff}'), ('\u{f48}', '\u{f48}'), ('\u{f6d}', '\u{f70}'),
+  ('\u{f98}', '\u{f98}'), ('\u{fbd}', '\u{fbd}'), ('\u{fcd}', '\u{fcd}'),
+  ('\u{fdb}', '\u{fff}'), ('\u{10c6}', '\u{10c6}'), ('\u{10c8}', '\u{10cc}'),
+  ('\u{10ce}', '\u{10cf}'), ('\u{1249}', '\u{1249}'),
+  ('\u{124e}', '\u{124f}'), ('\u{1257}', '\u{1257}'),
+  ('\u{1259}', '\u{1259}'), ('\u{125e}', '\u{125f}'),
+  ('\u{1289}', '\u{1289}'), ('\u{128e}', '\u{128f}'),
+  ('\u{12b1}', '\u{12b1}'), ('\u{12b6}', '\u{12b7}'),
+  ('\u{12bf}', '\u{12bf}'), ('\u{12c1}', '\u{12c1}'),
+  ('\u{12c6}', '\u{12c7}'), ('\u{12d7}', '\u{12d7}'),
+  ('\u{1311}', '\u{1311}'), ('\u{1316}', '\u{1317}'),
+  ('\u{135b}', '\u{135c}'), ('\u{137d}', '\u{137f}'),
+  ('\u{139a}', '\u{139f}'), ('\u{13f6}', '\u{13f7}'),
+  ('\u{13fe}', '\u{13ff}'), ('\u{169d}', '\u{169f}'),
+  ('\u{16f9}', '\u{16ff}'), ('\u{170d}', '\u{170d}'),
+  ('\u{1715}', '\u{171f}'), ('\u{1737}', '\u{173f}'),
+  ('\u{1754}', '\u{175f}'), ('\u{176d}', '\u{176d}'),
+  ('\u{1771}', '\u{1771}'), ('\u{1774}', '\u{177f}'),
+  ('\u{17de}', '\u{17df}'), ('\u{17ea}', '\u{17ef}'),
+  ('\u{17fa}', '\u{17ff}'), ('\u{180e}', '\u{180f}'),
+  ('\u{181a}', '\u{181f}'), ('\u{1879}', '\u{187f}'),
+  ('\u{18ab}', '\u{18af}'), ('\u{18f6}', '\u{18ff}'),
+  ('\u{191f}', '\u{191f}'), ('\u{192c}', '\u{192f}'),
+  ('\u{193c}', '\u{193f}'), ('\u{1941}', '\u{1943}'),
+  ('\u{196e}', '\u{196f}'), ('\u{1975}', '\u{197f}'),
+  ('\u{19ac}', '\u{19af}'), ('\u{19ca}', '\u{19cf}'),
+  ('\u{19db}', '\u{19dd}'), ('\u{1a1c}', '\u{1a1d}'),
+  ('\u{1a5f}', '\u{1a5f}'), ('\u{1a7d}', '\u{1a7e}'),
+  ('\u{1a8a}', '\u{1a8f}'), ('\u{1a9a}', '\u{1a9f}'),
+  ('\u{1aae}', '\u{1aaf}'), ('\u{1abf}', '\u{1aff}'),
+  ('\u{1b4c}', '\u{1b4f}'), ('\u{1b7d}', '\u{1b7f}'),
+  ('\u{1bf4}', '\u{1bfb}'), ('\u{1c38}', '\u{1c3a}'),
+  ('\u{1c4a}', '\u{1c4c}'), ('\u{1c89}', '\u{1c8f}'),
+  ('\u{1cbb}', '\u{1cbc}'), ('\u{1cc8}', '\u{1ccf}'),
+  ('\u{1cfb}', '\u{1cff}'), ('\u{1dfa}', '\u{1dfa}'),
+  ('\u{1f16}', '\u{1f17}'), ('\u{1f1e}', '\u{1f1f}'),
+  ('\u{1f46}', '\u{1f47}'), ('\u{1f4e}', '\u{1f4f}'),
+  ('\u{1f58}', '\u{1f58}'), ('\u{1f5a}', '\u{1f5a}'),
+  ('\u{1f5c}', '\u{1f5c}'), ('\u{1f5e}', '\u{1f5e}'),
+  ('\u{1f7e}', '\u{1f7f}'), ('\u{1fb5}', '\u{1fb5}'),
+  ('\u{1fc5}', '\u{1fc5}'), ('\u{1fd4}', '\u{1fd5}'),
+  ('\u{1fdc}', '\u{1fdc}'), ('\u{1ff0}', '\u{1ff1}'),
+  ('\u{1ff5}', '\u{1ff5}'), ('\u{1fff}', '\u{1fff}'),
+  ('\u{200b}', '\u{200f}'), ('\u{202a}', '\u{202e}'),
+  ('\u{2060}', '\u{206f}'), ('\u{2072}', '\u{2073}'),
+  ('\u{208f}', '\u{208f}'), ('\u{209d}', '\u{209f}'),
+  ('\u{20c0}', '\u{20cf}'), ('\u{20f1}', '\u{20ff}'),
+  ('\u{218c}', '\u{218f}'), ('\u{2427}', '\u{243f}'),
+  ('\u{244b}', '\u{245f}'), ('\u{2b74}', '\u{2b75}'),
+  ('\u{2b96}', '\u{2b97}'), ('\u{2c2f}', '\u{2c2f}'),
+  ('\u{2c5f}', '\u{2c5f}'), ('\u{2cf4}', '\u{2cf8}'),
+  ('\u{2d26}', '\u{2d26}'), ('\u{2d28}', '\u{2d2c}'),
+  ('\u{2d2e}', '\u{2d2f}'), ('\u{2d68}', '\u{2d6e}'),
+  ('\u{2d71}', '\u{2d7e}'), ('\u{2d97}', '\u{2d9f}'),
+  ('\u{2da7}', '\u{2da7}'), ('\u{2daf}', '\u{2daf}'),
+  ('\u{2db7}', '\u{2db7}'), ('\u{2dbf}', '\u{2dbf}'),
+  ('\u{2dc7}', '\u{2dc7}'), ('\u{2dcf}', '\u{2dcf}'),
+  ('\u{2dd7}', '\u{2dd7}'), ('\u{2ddf}', '\u{2ddf}'),
+  ('\u{2e50}', '\u{2e7f}'), ('\u{2e9a}', '\u{2e9a}'),
+  ('\u{2ef4}', '\u{2eff}'), ('\u{2fd6}', '\u{2fef}'),
+  ('\u{2ffc}', '\u{2fff}'), ('\u{3040}', '\u{3040}'),
+  ('\u{3097}', '\u{3098}'), ('\u{3100}', '\u{3104}'),
+  ('\u{3130}', '\u{3130}'), ('\u{318f}', '\u{318f}'),
+  ('\u{31bb}', '\u{31bf}'), ('\u{31e4}', '\u{31ef}'),
+  ('\u{321f}', '\u{321f}'), ('\u{4db6}', '\u{4dbf}'),
+  ('\u{9ff0}', '\u{9fff}'), ('\u{a48d}', '\u{a48f}'),
+  ('\u{a4c7}', '\u{a4cf}'), ('\u{a62c}', '\u{a63f}'),
+  ('\u{a6f8}', '\u{a6ff}'), ('\u{a7c0}', '\u{a7c1}'),
+  ('\u{a7c7}', '\u{a7f6}'), ('\u{a82c}', '\u{a82f}'),
+  ('\u{a83a}', '\u{a83f}'), ('\u{a878}', '\u{a87f}'),
+  ('\u{a8c6}', '\u{a8cd}'), ('\u{a8da}', '\u{a8df}'),
+  ('\u{a954}', '\u{a95e}'), ('\u{a97d}', '\u{a97f}'),
+  ('\u{a9ce}', '\u{a9ce}'), ('\u{a9da}', '\u{a9dd}'),
+  ('\u{a9ff}', '\u{a9ff}'), ('\u{aa37}', '\u{aa3f}'),
+  ('\u{aa4e}', '\u{aa4f}'), ('\u{aa5a}', '\u{aa5b}'),
+  ('\u{aac3}', '\u{aada}'), ('\u{aaf7}', '\u{ab00}'),
+  ('\u{ab07}', '\u{ab08}'), ('\u{ab0f}', '\u{ab10}'),
+  ('\u{ab17}', '\u{ab1f}'), ('\u{ab27}', '\u{ab27}'),
+  ('\u{ab2f}', '\u{ab2f}'), ('\u{ab68}', '\u{ab6f}'),
+  ('\u{abee}', '\u{abef}'), ('\u{abfa}', '\u{abff}'),
+  ('\u{d7a4}', '\u{d7af}'), ('\u{d7c7}', '\u{d7ca}'),
+  ('\u{d7fc}', '\u{f8ff}'), ('\u{fa6e}', '\u{fa6f}'),
+  ('\u{fada}', '\u{faff}'), ('\u{fb07}', '\u{fb12}'),
+  ('\u{fb18}', '\u{fb1c}'), ('\u{fb37}', '\u{fb37}'),
+  ('\u{fb3d}', '\u{fb3d}'), ('\u{fb3f}', '\u{fb3f}'),
+  ('\u{fb42}', '\u{fb42}'), ('\u{fb45}', '\u{fb45}'),
+  ('\u{fbc2}', '\u{fbd2}'), ('\u{fd40}', '\u{fd4f}'),
+  ('\u{fd90}', '\u{fd91}'), ('\u{fdc8}', '\u{fdef}'),
+  ('\u{fdfe}', '\u{fdff}'), ('\u{fe1a}', '\u{fe1f}'),
+  ('\u{fe53}', '\u{fe53}'), ('\u{fe67}', '\u{fe67}'),
+  ('\u{fe6c}', '\u{fe6f}'), ('\u{fe75}', '\u{fe75}'),
+  ('\u{fefd}', '\u{ff00}'), ('\u{ffbf}', '\u{ffc1}'),
+  ('\u{ffc8}', '\u{ffc9}'), ('\u{ffd0}', '\u{ffd1}'),
+  ('\u{ffd8}', '\u{ffd9}'), ('\u{ffdd}', '\u{ffdf}'),
+  ('\u{ffe7}', '\u{ffe7}'), ('\u{ffef}', '\u{fffb}'),
+  ('\u{fffe}', '\u{ffff}'), ('\u{1000c}', '\u{1000c}'),
+  ('\u{10027}', '\u{10027}'), ('\u{1003b}', '\u{1003b}'),
+  ('\u{1003e}', '\u{1003e}'), ('\u{1004e}', '\u{1004f}'),
+  ('\u{1005e}', '\u{1007f}'), ('\u{100fb}', '\u{100ff}'),
+  ('\u{10103}', '\u{10106}'), ('\u{10134}', '\u{10136}'),
+  ('\u{1018f}', '\u{1018f}'), ('\u{1019c}', '\u{1019f}'),
+  ('\u{101a1}', '\u{101cf}'), ('\u{101fe}', '\u{1027f}'),
+  ('\u{1029d}', '\u{1029f}'), ('\u{102d1}', '\u{102df}'),
+  ('\u{102fc}', '\u{102ff}'), ('\u{10324}', '\u{1032c}'),
+  ('\u{1034b}', '\u{1034f}'), ('\u{1037b}', '\u{1037f}'),
+  ('\u{1039e}', '\u{1039e}'), ('\u{103c4}', '\u{103c7}'),
+  ('\u{103d6}', '\u{103ff}'), ('\u{1049e}', '\u{1049f}'),
+  ('\u{104aa}', '\u{104af}'), ('\u{104d4}', '\u{104d7}'),
+  ('\u{104fc}', '\u{104ff}'), ('\u{10528}', '\u{1052f}'),
+  ('\u{10564}', '\u{1056e}'), ('\u{10570}', '\u{105ff}'),
+  ('\u{10737}', '\u{1073f}'), ('\u{10756}', '\u{1075f}'),
+  ('\u{10768}', '\u{107ff}'), ('\u{10806}', '\u{10807}'),
+  ('\u{10809}', '\u{10809}'), ('\u{10836}', '\u{10836}'),
+  ('\u{10839}', '\u{1083b}'), ('\u{1083d}', '\u{1083e}'),
+  ('\u{10856}', '\u{10856}'), ('\u{1089f}', '\u{108a6}'),
+  ('\u{108b0}', '\u{108df}'), ('\u{108f3}', '\u{108f3}'),
+  ('\u{108f6}', '\u{108fa}'), ('\u{1091c}', '\u{1091e}'),
+  ('\u{1093a}', '\u{1093e}'), ('\u{10940}', '\u{1097f}'),
+  ('\u{109b8}', '\u{109bb}'), ('\u{109d0}', '\u{109d1}'),
+  ('\u{10a04}', '\u{10a04}'), ('\u{10a07}', '\u{10a0b}'),
+  ('\u{10a14}', '\u{10a14}'), ('\u{10a18}', '\u{10a18}'),
+  ('\u{10a36}', '\u{10a37}'), ('\u{10a3b}', '\u{10a3e}'),
+  ('\u{10a49}', '\u{10a4f}'), ('\u{10a59}', '\u{10a5f}'),
+  ('\u{10aa0}', '\u{10abf}'), ('\u{10ae7}', '\u{10aea}'),
+  ('\u{10af7}', '\u{10aff}'), ('\u{10b36}', '\u{10b38}'),
+  ('\u{10b56}', '\u{10b57}'), ('\u{10b73}', '\u{10b77}'),
+  ('\u{10b92}', '\u{10b98}'), ('\u{10b9d}', '\u{10ba8}'),
+  ('\u{10bb0}', '\u{10bff}'), ('\u{10c49}', '\u{10c7f}'),
+  ('\u{10cb3}', '\u{10cbf}'), ('\u{10cf3}', '\u{10cf9}'),
+  ('\u{10d28}', '\u{10d2f}'), ('\u{10d3a}', '\u{10e5f}'),
+  ('\u{10e7f}', '\u{10eff}'), ('\u{10f28}', '\u{10f2f}'),
+  ('\u{10f5a}', '\u{10fdf}'), ('\u{10ff7}', '\u{10fff}'),
+  ('\u{1104e}', '\u{11051}'), ('\u{11070}', '\u{1107e}'),
+  ('\u{110bd}', '\u{110bd}'), ('\u{110c2}', '\u{110cf}'),
+  ('\u{110e9}', '\u{110ef}'), ('\u{110fa}', '\u{110ff}'),
+  ('\u{11135}', '\u{11135}'), ('\u{11147}', '\u{1114f}'),
+  ('\u{11177}', '\u{1117f}'), ('\u{111ce}', '\u{111cf}'),
+  ('\u{111e0}', '\u{111e0}'), ('\u{111f5}', '\u{111ff}'),
+  ('\u{11212}', '\u{11212}'), ('\u{1123f}', '\u{1127f}'),
+  ('\u{11287}', '\u{11287}'), ('\u{11289}', '\u{11289}'),
+  ('\u{1128e}', '\u{1128e}'), ('\u{1129e}', '\u{1129e}'),
+  ('\u{112aa}', '\u{112af}'), ('\u{112eb}', '\u{112ef}'),
+  ('\u{112fa}', '\u{112ff}'), ('\u{11304}', '\u{11304}'),
+  ('\u{1130d}', '\u{1130e}'), ('\u{11311}', '\u{11312}'),
+  ('\u{11329}', '\u{11329}'), ('\u{11331}', '\u{11331}'),
+  ('\u{11334}', '\u{11334}'), ('\u{1133a}', '\u{1133a}'),
+  ('\u{11345}', '\u{11346}'), ('\u{11349}', '\u{1134a}'),
+  ('\u{1134e}', '\u{1134f}'), ('\u{11351}', '\u{11356}'),
+  ('\u{11358}', '\u{1135c}'), ('\u{11364}', '\u{11365}'),
+  ('\u{1136d}', '\u{1136f}'), ('\u{11375}', '\u{113ff}'),
+  ('\u{1145a}', '\u{1145a}'), ('\u{1145c}', '\u{1145c}'),
+  ('\u{11460}', '\u{1147f}'), ('\u{114c8}', '\u{114cf}'),
+  ('\u{114da}', '\u{1157f}'), ('\u{115b6}', '\u{115b7}'),
+  ('\u{115de}', '\u{115ff}'), ('\u{11645}', '\u{1164f}'),
+  ('\u{1165a}', '\u{1165f}'), ('\u{1166d}', '\u{1167f}'),
+  ('\u{116b9}', '\u{116bf}'), ('\u{116ca}', '\u{116ff}'),
+  ('\u{1171b}', '\u{1171c}'), ('\u{1172c}', '\u{1172f}'),
+  ('\u{11740}', '\u{117ff}'), ('\u{1183c}', '\u{1189f}'),
+  ('\u{118f3}', '\u{118fe}'), ('\u{11900}', '\u{1199f}'),
+  ('\u{119a8}', '\u{119a9}'), ('\u{119d8}', '\u{119d9}'),
+  ('\u{119e5}', '\u{119ff}'), ('\u{11a48}', '\u{11a4f}'),
+  ('\u{11aa3}', '\u{11abf}'), ('\u{11af9}', '\u{11bff}'),
+  ('\u{11c09}', '\u{11c09}'), ('\u{11c37}', '\u{11c37}'),
+  ('\u{11c46}', '\u{11c4f}'), ('\u{11c6d}', '\u{11c6f}'),
+  ('\u{11c90}', '\u{11c91}'), ('\u{11ca8}', '\u{11ca8}'),
+  ('\u{11cb7}', '\u{11cff}'), ('\u{11d07}', '\u{11d07}'),
+  ('\u{11d0a}', '\u{11d0a}'), ('\u{11d37}', '\u{11d39}'),
+  ('\u{11d3b}', '\u{11d3b}'), ('\u{11d3e}', '\u{11d3e}'),
+  ('\u{11d48}', '\u{11d4f}'), ('\u{11d5a}', '\u{11d5f}'),
+  ('\u{11d66}', '\u{11d66}'), ('\u{11d69}', '\u{11d69}'),
+  ('\u{11d8f}', '\u{11d8f}'), ('\u{11d92}', '\u{11d92}'),
+  ('\u{11d99}', '\u{11d9f}'), ('\u{11daa}', '\u{11edf}'),
+  ('\u{11ef9}', '\u{11fbf}'), ('\u{11ff2}', '\u{11ffe}'),
+  ('\u{1239a}', '\u{123ff}'), ('\u{1246f}', '\u{1246f}'),
+  ('\u{12475}', '\u{1247f}'), ('\u{12544}', '\u{12fff}'),
+  ('\u{1342f}', '\u{143ff}'), ('\u{14647}', '\u{167ff}'),
+  ('\u{16a39}', '\u{16a3f}'), ('\u{16a5f}', '\u{16a5f}'),
+  ('\u{16a6a}', '\u{16a6d}'), ('\u{16a70}', '\u{16acf}'),
+  ('\u{16aee}', '\u{16aef}'), ('\u{16af6}', '\u{16aff}'),
+  ('\u{16b46}', '\u{16b4f}'), ('\u{16b5a}', '\u{16b5a}'),
+  ('\u{16b62}', '\u{16b62}'), ('\u{16b78}', '\u{16b7c}'),
+  ('\u{16b90}', '\u{16e3f}'), ('\u{16e9b}', '\u{16eff}'),
+  ('\u{16f4b}', '\u{16f4e}'), ('\u{16f88}', '\u{16f8e}'),
+  ('\u{16fa0}', '\u{16fdf}'), ('\u{16fe4}', '\u{16fff}'),
+  ('\u{187f8}', '\u{187ff}'), ('\u{18af3}', '\u{1afff}'),
+  ('\u{1b11f}', '\u{1b14f}'), ('\u{1b153}', '\u{1b163}'),
+  ('\u{1b168}', '\u{1b16f}'), ('\u{1b2fc}', '\u{1bbff}'),
+  ('\u{1bc6b}', '\u{1bc6f}'), ('\u{1bc7d}', '\u{1bc7f}'),
+  ('\u{1bc89}', '\u{1bc8f}'), ('\u{1bc9a}', '\u{1bc9b}'),
+  ('\u{1bca0}', '\u{1cfff}'), ('\u{1d0f6}', '\u{1d0ff}'),
+  ('\u{1d127}', '\u{1d128}'), ('\u{1d173}', '\u{1d17a}'),
+  ('\u{1d1e9}', '\u{1d1ff}'), ('\u{1d246}', '\u{1d2df}'),
+  ('\u{1d2f4}', '\u{1d2ff}'), ('\u{1d357}', '\u{1d35f}'),
+  ('\u{1d379}', '\u{1d3ff}'), ('\u{1d455}', '\u{1d455}'),
+  ('\u{1d49d}', '\u{1d49d}'), ('\u{1d4a0}', '\u{1d4a1}'),
+  ('\u{1d4a3}', '\u{1d4a4}'), ('\u{1d4a7}', '\u{1d4a8}'),
+  ('\u{1d4ad}', '\u{1d4ad}'), ('\u{1d4ba}', '\u{1d4ba}'),
+  ('\u{1d4bc}', '\u{1d4bc}'), ('\u{1d4c4}', '\u{1d4c4}'),
+  ('\u{1d506}', '\u{1d506}'), ('\u{1d50b}', '\u{1d50c}'),
+  ('\u{1d515}', '\u{1d515}'), ('\u{1d51d}', '\u{1d51d}'),
+  ('\u{1d53a}', '\u{1d53a}'), ('\u{1d53f}', '\u{1d53f}'),
+  ('\u{1d545}', '\u{1d545}'), ('\u{1d547}', '\u{1d549}'),
+  ('\u{1d551}', '\u{1d551}'), ('\u{1d6a6}', '\u{1d6a7}'),
+  ('\u{1d7cc}', '\u{1d7cd}'), ('\u{1da8c}', '\u{1da9a}'),
+  ('\u{1daa0}', '\u{1daa0}'), ('\u{1dab0}', '\u{1dfff}'),
+  ('\u{1e007}', '\u{1e007}'), ('\u{1e019}', '\u{1e01a}'),
+  ('\u{1e022}', '\u{1e022}'), ('\u{1e025}', '\u{1e025}'),
+  ('\u{1e02b}', '\u{1e0ff}'), ('\u{1e12d}', '\u{1e12f}'),
+  ('\u{1e13e}', '\u{1e13f}'), ('\u{1e14a}', '\u{1e14d}'),
+  ('\u{1e150}', '\u{1e2bf}'), ('\u{1e2fa}', '\u{1e2fe}'),
+  ('\u{1e300}', '\u{1e7ff}'), ('\u{1e8c5}', '\u{1e8c6}'),
+  ('\u{1e8d7}', '\u{1e8ff}'), ('\u{1e94c}', '\u{1e94f}'),
+  ('\u{1e95a}', '\u{1e95d}'), ('\u{1e960}', '\u{1ec70}'),
+  ('\u{1ecb5}', '\u{1ed00}'), ('\u{1ed3e}', '\u{1edff}'),
+  ('\u{1ee04}', '\u{1ee04}'), ('\u{1ee20}', '\u{1ee20}'),
+  ('\u{1ee23}', '\u{1ee23}'), ('\u{1ee25}', '\u{1ee26}'),
+  ('\u{1ee28}', '\u{1ee28}'), ('\u{1ee33}', '\u{1ee33}'),
+  ('\u{1ee38}', '\u{1ee38}'), ('\u{1ee3a}', '\u{1ee3a}'),
+  ('\u{1ee3c}', '\u{1ee41}'), ('\u{1ee43}', '\u{1ee46}'),
+  ('\u{1ee48}', '\u{1ee48}'), ('\u{1ee4a}', '\u{1ee4a}'),
+  ('\u{1ee4c}', '\u{1ee4c}'), ('\u{1ee50}', '\u{1ee50}'),
+  ('\u{1ee53}', '\u{1ee53}'), ('\u{1ee55}', '\u{1ee56}'),
+  ('\u{1ee58}', '\u{1ee58}'), ('\u{1ee5a}', '\u{1ee5a}'),
+  ('\u{1ee5c}', '\u{1ee5c}'), ('\u{1ee5e}', '\u{1ee5e}'),
+  ('\u{1ee60}', '\u{1ee60}'), ('\u{1ee63}', '\u{1ee63}'),
+  ('\u{1ee65}', '\u{1ee66}'), ('\u{1ee6b}', '\u{1ee6b}'),
+  ('\u{1ee73}', '\u{1ee73}'), ('\u{1ee78}', '\u{1ee78}'),
+  ('\u{1ee7d}', '\u{1ee7d}'), ('\u{1ee7f}', '\u{1ee7f}'),
+  ('\u{1ee8a}', '\u{1ee8a}'), ('\u{1ee9c}', '\u{1eea0}'),
+  ('\u{1eea4}', '\u{1eea4}'), ('\u{1eeaa}', '\u{1eeaa}'),
+  ('\u{1eebc}', '\u{1eeef}'), ('\u{1eef2}', '\u{1efff}'),
+  ('\u{1f02c}', '\u{1f02f}'), ('\u{1f094}', '\u{1f09f}'),
+  ('\u{1f0af}', '\u{1f0b0}'), ('\u{1f0c0}', '\u{1f0c0}'),
+  ('\u{1f0d0}', '\u{1f0d0}'), ('\u{1f0f6}', '\u{1f0ff}'),
+  ('\u{1f10d}', '\u{1f10f}'), ('\u{1f16d}', '\u{1f16f}'),
+  ('\u{1f1ad}', '\u{1f1e5}'), ('\u{1f203}', '\u{1f20f}'),
+  ('\u{1f23c}', '\u{1f23f}'), ('\u{1f249}', '\u{1f24f}'),
+  ('\u{1f252}', '\u{1f25f}'), ('\u{1f266}', '\u{1f2ff}'),
+  ('\u{1f6d6}', '\u{1f6df}'), ('\u{1f6ed}', '\u{1f6ef}'),
+  ('\u{1f6fb}', '\u{1f6ff}'), ('\u{1f774}', '\u{1f77f}'),
+  ('\u{1f7d9}', '\u{1f7df}'), ('\u{1f7ec}', '\u{1f7ff}'),
+  ('\u{1f80c}', '\u{1f80f}'), ('\u{1f848}', '\u{1f84f}'),
+  ('\u{1f85a}', '\u{1f85f}'), ('\u{1f888}', '\u{1f88f}'),
+  ('\u{1f8ae}', '\u{1f8ff}'), ('\u{1f90c}', '\u{1f90c}'),
+  ('\u{1f972}', '\u{1f972}'), ('\u{1f977}', '\u{1f979}'),
+  ('\u{1f9a3}', '\u{1f9a4}'), ('\u{1f9ab}', '\u{1f9ad}'),
+  ('\u{1f9cb}', '\u{1f9cc}'), ('\u{1fa54}', '\u{1fa5f}'),
+  ('\u{1fa6e}', '\u{1fa6f}'), ('\u{1fa74}', '\u{1fa77}'),
+  ('\u{1fa7b}', '\u{1fa7f}'), ('\u{1fa83}', '\u{1fa8f}'),
+  ('\u{1fa96}', '\u{1ffff}'), ('\u{2a6d7}', '\u{2a6ff}'),
+  ('\u{2b735}', '\u{2b73f}'), ('\u{2b81e}', '\u{2b81f}'),
+  ('\u{2cea2}', '\u{2ceaf}'), ('\u{2ebe1}', '\u{2f7ff}'),
+  ('\u{2fa1e}', '\u{e00ff}'), ('\u{e01f0}', '\u{10ffff}'),
+];
+
+pub const OTHER_LETTER: &'static [(char, char)] = &[
+  ('ª', 'ª'), ('º', 'º'), ('ƻ', 'ƻ'), ('ǀ', 'ǃ'), ('ʔ', 'ʔ'),
+  ('א', 'ת'), ('ׯ', 'ײ'), ('ؠ', 'ؿ'), ('ف', 'ي'), ('ٮ', 'ٯ'),
+  ('ٱ', 'ۓ'), ('ە', 'ە'), ('ۮ', 'ۯ'), ('ۺ', 'ۼ'), ('ۿ', 'ۿ'),
+  ('ܐ', 'ܐ'), ('ܒ', 'ܯ'), ('ݍ', 'ޥ'), ('ޱ', 'ޱ'), ('ߊ', 'ߪ'),
+  ('ࠀ', 'ࠕ'), ('ࡀ', 'ࡘ'), ('ࡠ', 'ࡪ'), ('ࢠ', 'ࢴ'),
+  ('ࢶ', 'ࢽ'), ('ऄ', 'ह'), ('ऽ', 'ऽ'), ('ॐ', 'ॐ'),
+  ('क़', 'ॡ'), ('ॲ', 'ঀ'), ('অ', 'ঌ'), ('এ', 'ঐ'),
+  ('ও', 'ন'), ('প', 'র'), ('ল', 'ল'), ('শ', 'হ'),
+  ('ঽ', 'ঽ'), ('ৎ', 'ৎ'), ('ড়', 'ঢ়'), ('য়', 'ৡ'),
+  ('ৰ', 'ৱ'), ('ৼ', 'ৼ'), ('ਅ', 'ਊ'), ('ਏ', 'ਐ'),
+  ('ਓ', 'ਨ'), ('ਪ', 'ਰ'), ('ਲ', 'ਲ਼'), ('ਵ', 'ਸ਼'),
+  ('ਸ', 'ਹ'), ('ਖ਼', 'ੜ'), ('ਫ਼', 'ਫ਼'), ('ੲ', 'ੴ'),
+  ('અ', 'ઍ'), ('એ', 'ઑ'), ('ઓ', 'ન'), ('પ', 'ર'),
+  ('લ', 'ળ'), ('વ', 'હ'), ('ઽ', 'ઽ'), ('ૐ', 'ૐ'),
+  ('ૠ', 'ૡ'), ('ૹ', 'ૹ'), ('ଅ', 'ଌ'), ('ଏ', 'ଐ'),
+  ('ଓ', 'ନ'), ('ପ', 'ର'), ('ଲ', 'ଳ'), ('ଵ', 'ହ'),
+  ('ଽ', 'ଽ'), ('ଡ଼', 'ଢ଼'), ('ୟ', 'ୡ'), ('ୱ', 'ୱ'),
+  ('ஃ', 'ஃ'), ('அ', 'ஊ'), ('எ', 'ஐ'), ('ஒ', 'க'),
+  ('ங', 'ச'), ('ஜ', 'ஜ'), ('ஞ', 'ட'), ('ண', 'த'),
+  ('ந', 'ப'), ('ம', 'ஹ'), ('ௐ', 'ௐ'), ('అ', 'ఌ'),
+  ('ఎ', 'ఐ'), ('ఒ', 'న'), ('ప', 'హ'), ('ఽ', 'ఽ'),
+  ('ౘ', 'ౚ'), ('ౠ', 'ౡ'), ('ಀ', 'ಀ'), ('ಅ', 'ಌ'),
+  ('ಎ', 'ಐ'), ('ಒ', 'ನ'), ('ಪ', 'ಳ'), ('ವ', 'ಹ'),
+  ('ಽ', 'ಽ'), ('ೞ', 'ೞ'), ('ೠ', 'ೡ'), ('ೱ', 'ೲ'),
+  ('അ', 'ഌ'), ('എ', 'ഐ'), ('ഒ', 'ഺ'), ('ഽ', 'ഽ'),
+  ('ൎ', 'ൎ'), ('ൔ', 'ൖ'), ('ൟ', 'ൡ'), ('ൺ', 'ൿ'),
+  ('අ', 'ඖ'), ('ක', 'න'), ('ඳ', 'ර'), ('ල', 'ල'),
+  ('ව', 'ෆ'), ('ก', 'ะ'), ('า', 'ำ'), ('เ', 'ๅ'),
+  ('ກ', 'ຂ'), ('ຄ', 'ຄ'), ('\u{e86}', 'ຊ'), ('\u{e8c}', 'ຣ'),
+  ('ລ', 'ລ'), ('ວ', 'ະ'), ('າ', 'ຳ'), ('ຽ', 'ຽ'),
+  ('ເ', 'ໄ'), ('ໜ', 'ໟ'), ('ༀ', 'ༀ'), ('ཀ', 'ཇ'),
+  ('ཉ', 'ཬ'), ('ྈ', 'ྌ'), ('က', 'ဪ'), ('ဿ', 'ဿ'),
+  ('ၐ', 'ၕ'), ('ၚ', 'ၝ'), ('ၡ', 'ၡ'), ('ၥ', 'ၦ'),
+  ('ၮ', 'ၰ'), ('ၵ', 'ႁ'), ('ႎ', 'ႎ'), ('ᄀ', 'ቈ'),
+  ('ቊ', 'ቍ'), ('ቐ', 'ቖ'), ('ቘ', 'ቘ'), ('ቚ', 'ቝ'),
+  ('በ', 'ኈ'), ('ኊ', 'ኍ'), ('ነ', 'ኰ'), ('ኲ', 'ኵ'),
+  ('ኸ', 'ኾ'), ('ዀ', 'ዀ'), ('ዂ', 'ዅ'), ('ወ', 'ዖ'),
+  ('ዘ', 'ጐ'), ('ጒ', 'ጕ'), ('ጘ', 'ፚ'), ('ᎀ', 'ᎏ'),
+  ('ᐁ', 'ᙬ'), ('ᙯ', 'ᙿ'), ('ᚁ', 'ᚚ'), ('ᚠ', 'ᛪ'),
+  ('ᛱ', 'ᛸ'), ('ᜀ', 'ᜌ'), ('ᜎ', 'ᜑ'), ('ᜠ', 'ᜱ'),
+  ('ᝀ', 'ᝑ'), ('ᝠ', 'ᝬ'), ('ᝮ', 'ᝰ'), ('ក', 'ឳ'),
+  ('ៜ', 'ៜ'), ('ᠠ', 'ᡂ'), ('ᡄ', 'ᡸ'), ('ᢀ', 'ᢄ'),
+  ('ᢇ', 'ᢨ'), ('ᢪ', 'ᢪ'), ('ᢰ', 'ᣵ'), ('ᤀ', 'ᤞ'),
+  ('ᥐ', 'ᥭ'), ('ᥰ', 'ᥴ'), ('ᦀ', 'ᦫ'), ('ᦰ', 'ᧉ'),
+  ('ᨀ', 'ᨖ'), ('ᨠ', 'ᩔ'), ('ᬅ', 'ᬳ'), ('ᭅ', 'ᭋ'),
+  ('ᮃ', 'ᮠ'), ('ᮮ', 'ᮯ'), ('ᮺ', 'ᯥ'), ('ᰀ', 'ᰣ'),
+  ('ᱍ', 'ᱏ'), ('ᱚ', 'ᱷ'), ('ᳩ', 'ᳬ'), ('ᳮ', 'ᳳ'),
+  ('ᳵ', 'ᳶ'), ('\u{1cfa}', '\u{1cfa}'), ('ℵ', 'ℸ'), ('ⴰ', 'ⵧ'),
+  ('ⶀ', 'ⶖ'), ('ⶠ', 'ⶦ'), ('ⶨ', 'ⶮ'), ('ⶰ', 'ⶶ'),
+  ('ⶸ', 'ⶾ'), ('ⷀ', 'ⷆ'), ('ⷈ', 'ⷎ'), ('ⷐ', 'ⷖ'),
+  ('ⷘ', 'ⷞ'), ('〆', '〆'), ('〼', '〼'), ('ぁ', 'ゖ'),
+  ('ゟ', 'ゟ'), ('ァ', 'ヺ'), ('ヿ', 'ヿ'), ('ㄅ', 'ㄯ'),
+  ('ㄱ', 'ㆎ'), ('ㆠ', 'ㆺ'), ('ㇰ', 'ㇿ'), ('㐀', '䶵'),
+  ('一', '鿯'), ('ꀀ', 'ꀔ'), ('ꀖ', 'ꒌ'), ('ꓐ', 'ꓷ'),
+  ('ꔀ', 'ꘋ'), ('ꘐ', 'ꘟ'), ('ꘪ', 'ꘫ'), ('ꙮ', 'ꙮ'),
+  ('ꚠ', 'ꛥ'), ('ꞏ', 'ꞏ'), ('ꟷ', 'ꟷ'), ('ꟻ', 'ꠁ'),
+  ('ꠃ', 'ꠅ'), ('ꠇ', 'ꠊ'), ('ꠌ', 'ꠢ'), ('ꡀ', 'ꡳ'),
+  ('ꢂ', 'ꢳ'), ('ꣲ', 'ꣷ'), ('ꣻ', 'ꣻ'), ('ꣽ', 'ꣾ'),
+  ('ꤊ', 'ꤥ'), ('ꤰ', 'ꥆ'), ('ꥠ', 'ꥼ'), ('ꦄ', 'ꦲ'),
+  ('ꧠ', 'ꧤ'), ('ꧧ', 'ꧯ'), ('ꧺ', 'ꧾ'), ('ꨀ', 'ꨨ'),
+  ('ꩀ', 'ꩂ'), ('ꩄ', 'ꩋ'), ('ꩠ', 'ꩯ'), ('ꩱ', 'ꩶ'),
+  ('ꩺ', 'ꩺ'), ('ꩾ', 'ꪯ'), ('ꪱ', 'ꪱ'), ('ꪵ', 'ꪶ'),
+  ('ꪹ', 'ꪽ'), ('ꫀ', 'ꫀ'), ('ꫂ', 'ꫂ'), ('ꫛ', 'ꫜ'),
+  ('ꫠ', 'ꫪ'), ('ꫲ', 'ꫲ'), ('ꬁ', 'ꬆ'), ('ꬉ', 'ꬎ'),
+  ('ꬑ', 'ꬖ'), ('ꬠ', 'ꬦ'), ('ꬨ', 'ꬮ'), ('ꯀ', 'ꯢ'),
+  ('가', '힣'), ('ힰ', 'ퟆ'), ('ퟋ', 'ퟻ'), ('豈', '舘'),
+  ('並', '龎'), ('יִ', 'יִ'), ('ײַ', 'ﬨ'), ('שׁ', 'זּ'),
+  ('טּ', 'לּ'), ('מּ', 'מּ'), ('נּ', 'סּ'), ('ףּ', 'פּ'),
+  ('צּ', 'ﮱ'), ('ﯓ', 'ﴽ'), ('ﵐ', 'ﶏ'), ('ﶒ', 'ﷇ'),
+  ('ﷰ', 'ﷻ'), ('ﹰ', 'ﹴ'), ('ﹶ', 'ﻼ'), ('ヲ', 'ッ'),
+  ('ア', 'ン'), ('ᅠ', 'ᄒ'), ('ᅡ', 'ᅦ'), ('ᅧ', 'ᅬ'),
+  ('ᅭ', 'ᅲ'), ('ᅳ', 'ᅵ'), ('𐀀', '𐀋'), ('𐀍', '𐀦'),
+  ('𐀨', '𐀺'), ('𐀼', '𐀽'), ('𐀿', '𐁍'), ('𐁐', '𐁝'),
+  ('𐂀', '𐃺'), ('𐊀', '𐊜'), ('𐊠', '𐋐'), ('𐌀', '𐌟'),
+  ('𐌭', '𐍀'), ('𐍂', '𐍉'), ('𐍐', '𐍵'), ('𐎀', '𐎝'),
+  ('𐎠', '𐏃'), ('𐏈', '𐏏'), ('𐑐', '𐒝'), ('𐔀', '𐔧'),
+  ('𐔰', '𐕣'), ('𐘀', '𐜶'), ('𐝀', '𐝕'), ('𐝠', '𐝧'),
+  ('𐠀', '𐠅'), ('𐠈', '𐠈'), ('𐠊', '𐠵'), ('𐠷', '𐠸'),
+  ('𐠼', '𐠼'), ('𐠿', '𐡕'), ('𐡠', '𐡶'), ('𐢀', '𐢞'),
+  ('𐣠', '𐣲'), ('𐣴', '𐣵'), ('𐤀', '𐤕'), ('𐤠', '𐤹'),
+  ('𐦀', '𐦷'), ('𐦾', '𐦿'), ('𐨀', '𐨀'), ('𐨐', '𐨓'),
+  ('𐨕', '𐨗'), ('𐨙', '𐨵'), ('𐩠', '𐩼'), ('𐪀', '𐪜'),
+  ('𐫀', '𐫇'), ('𐫉', '𐫤'), ('𐬀', '𐬵'), ('𐭀', '𐭕'),
+  ('𐭠', '𐭲'), ('𐮀', '𐮑'), ('𐰀', '𐱈'), ('𐴀', '𐴣'),
+  ('𐼀', '𐼜'), ('𐼧', '𐼧'), ('𐼰', '𐽅'),
+  ('\u{10fe0}', '\u{10ff6}'), ('𑀃', '𑀷'), ('𑂃', '𑂯'),
+  ('𑃐', '𑃨'), ('𑄃', '𑄦'), ('𑅄', '𑅄'), ('𑅐', '𑅲'),
+  ('𑅶', '𑅶'), ('𑆃', '𑆲'), ('𑇁', '𑇄'), ('𑇚', '𑇚'),
+  ('𑇜', '𑇜'), ('𑈀', '𑈑'), ('𑈓', '𑈫'), ('𑊀', '𑊆'),
+  ('𑊈', '𑊈'), ('𑊊', '𑊍'), ('𑊏', '𑊝'), ('𑊟', '𑊨'),
+  ('𑊰', '𑋞'), ('𑌅', '𑌌'), ('𑌏', '𑌐'), ('𑌓', '𑌨'),
+  ('𑌪', '𑌰'), ('𑌲', '𑌳'), ('𑌵', '𑌹'), ('𑌽', '𑌽'),
+  ('𑍐', '𑍐'), ('𑍝', '𑍡'), ('𑐀', '𑐴'), ('𑑇', '𑑊'),
+  ('\u{1145f}', '\u{1145f}'), ('𑒀', '𑒯'), ('𑓄', '𑓅'),
+  ('𑓇', '𑓇'), ('𑖀', '𑖮'), ('𑗘', '𑗛'), ('𑘀', '𑘯'),
+  ('𑙄', '𑙄'), ('𑚀', '𑚪'), ('\u{116b8}', '\u{116b8}'),
+  ('𑜀', '𑜚'), ('𑠀', '𑠫'), ('𑣿', '𑣿'),
+  ('\u{119a0}', '\u{119a7}'), ('\u{119aa}', '\u{119d0}'),
+  ('\u{119e1}', '\u{119e1}'), ('\u{119e3}', '\u{119e3}'), ('𑨀', '𑨀'),
+  ('𑨋', '𑨲'), ('𑨺', '𑨺'), ('𑩐', '𑩐'), ('𑩜', '𑪉'),
+  ('𑪝', '𑪝'), ('𑫀', '𑫸'), ('𑰀', '𑰈'), ('𑰊', '𑰮'),
+  ('𑱀', '𑱀'), ('𑱲', '𑲏'), ('𑴀', '𑴆'), ('𑴈', '𑴉'),
+  ('𑴋', '𑴰'), ('𑵆', '𑵆'), ('𑵠', '𑵥'), ('𑵧', '𑵨'),
+  ('𑵪', '𑶉'), ('𑶘', '𑶘'), ('𑻠', '𑻲'), ('𒀀', '𒎙'),
+  ('𒒀', '𒕃'), ('𓀀', '𓐮'), ('𔐀', '𔙆'), ('𖠀', '𖨸'),
+  ('𖩀', '𖩞'), ('𖫐', '𖫭'), ('𖬀', '𖬯'), ('𖭣', '𖭷'),
+  ('𖭽', '𖮏'), ('𖼀', '\u{16f4a}'), ('𖽐', '𖽐'),
+  ('𗀀', '\u{187f7}'), ('𘠀', '𘫲'), ('𛀀', '𛄞'),
+  ('\u{1b150}', '\u{1b152}'), ('\u{1b164}', '\u{1b167}'), ('𛅰', '𛋻'),
+  ('𛰀', '𛱪'), ('𛱰', '𛱼'), ('𛲀', '𛲈'), ('𛲐', '𛲙'),
+  ('\u{1e100}', '\u{1e12c}'), ('\u{1e14e}', '\u{1e14e}'),
+  ('\u{1e2c0}', '\u{1e2eb}'), ('𞠀', '𞣄'), ('𞸀', '𞸃'),
+  ('𞸅', '𞸟'), ('𞸡', '𞸢'), ('𞸤', '𞸤'), ('𞸧', '𞸧'),
+  ('𞸩', '𞸲'), ('𞸴', '𞸷'), ('𞸹', '𞸹'), ('𞸻', '𞸻'),
+  ('𞹂', '𞹂'), ('𞹇', '𞹇'), ('𞹉', '𞹉'), ('𞹋', '𞹋'),
+  ('𞹍', '𞹏'), ('𞹑', '𞹒'), ('𞹔', '𞹔'), ('𞹗', '𞹗'),
+  ('𞹙', '𞹙'), ('𞹛', '𞹛'), ('𞹝', '𞹝'), ('𞹟', '𞹟'),
+  ('𞹡', '𞹢'), ('𞹤', '𞹤'), ('𞹧', '𞹪'), ('𞹬', '𞹲'),
+  ('𞹴', '𞹷'), ('𞹹', '𞹼'), ('𞹾', '𞹾'), ('𞺀', '𞺉'),
+  ('𞺋', '𞺛'), ('𞺡', '𞺣'), ('𞺥', '𞺩'), ('𞺫', '𞺻'),
+  ('𠀀', '𪛖'), ('𪜀', '𫜴'), ('𫝀', '𫠝'), ('𫠠', '𬺡'),
+  ('𬺰', '𮯠'), ('丽', '𪘀'),
+];
+
+pub const OTHER_NUMBER: &'static [(char, char)] = &[
+  ('²', '³'), ('¹', '¹'), ('¼', '¾'), ('৴', '৹'), ('୲', '୷'),
+  ('௰', '௲'), ('౸', '౾'), ('൘', '൞'), ('൰', '൸'),
+  ('༪', '༳'), ('፩', '፼'), ('៰', '៹'), ('᧚', '᧚'),
+  ('⁰', '⁰'), ('⁴', '⁹'), ('₀', '₉'), ('⅐', '⅟'),
+  ('↉', '↉'), ('①', '⒛'), ('⓪', '⓿'), ('❶', '➓'),
+  ('⳽', '⳽'), ('㆒', '㆕'), ('㈠', '㈩'), ('㉈', '㉏'),
+  ('㉑', '㉟'), ('㊀', '㊉'), ('㊱', '㊿'), ('꠰', '꠵'),
+  ('𐄇', '𐄳'), ('𐅵', '𐅸'), ('𐆊', '𐆋'), ('𐋡', '𐋻'),
+  ('𐌠', '𐌣'), ('𐡘', '𐡟'), ('𐡹', '𐡿'), ('𐢧', '𐢯'),
+  ('𐣻', '𐣿'), ('𐤖', '𐤛'), ('𐦼', '𐦽'), ('𐧀', '𐧏'),
+  ('𐧒', '𐧿'), ('𐩀', '𐩈'), ('𐩽', '𐩾'), ('𐪝', '𐪟'),
+  ('𐫫', '𐫯'), ('𐭘', '𐭟'), ('𐭸', '𐭿'), ('𐮩', '𐮯'),
+  ('𐳺', '𐳿'), ('𐹠', '𐹾'), ('𐼝', '𐼦'), ('𐽑', '𐽔'),
+  ('𑁒', '𑁥'), ('𑇡', '𑇴'), ('𑜺', '𑜻'), ('𑣪', '𑣲'),
+  ('𑱚', '𑱬'), ('\u{11fc0}', '\u{11fd4}'), ('𖭛', '𖭡'),
+  ('𖺀', '𖺖'), ('𝋠', '𝋳'), ('𝍠', '𝍸'), ('𞣇', '𞣏'),
+  ('𞱱', '𞲫'), ('𞲭', '𞲯'), ('𞲱', '𞲴'),
+  ('\u{1ed01}', '\u{1ed2d}'), ('\u{1ed2f}', '\u{1ed3d}'), ('🄀', '🄌'),
+];
+
+pub const OTHER_PUNCTUATION: &'static [(char, char)] = &[
+  ('!', '#'), ('%', '\''), ('*', '*'), (',', ','), ('.', '/'), (':', ';'),
+  ('?', '@'), ('\\', '\\'), ('¡', '¡'), ('§', '§'), ('¶', '·'),
+  ('¿', '¿'), (';', ';'), ('·', '·'), ('՚', '՟'), ('։', '։'),
+  ('׀', '׀'), ('׃', '׃'), ('׆', '׆'), ('׳', '״'), ('؉', '؊'),
+  ('،', '؍'), ('؛', '؛'), ('؞', '؟'), ('٪', '٭'), ('۔', '۔'),
+  ('܀', '܍'), ('߷', '߹'), ('࠰', '࠾'), ('࡞', '࡞'), ('।', '॥'),
+  ('॰', '॰'), ('৽', '৽'), ('੶', '੶'), ('૰', '૰'),
+  ('\u{c77}', '\u{c77}'), ('಄', '಄'), ('෴', '෴'), ('๏', '๏'),
+  ('๚', '๛'), ('༄', '༒'), ('༔', '༔'), ('྅', '྅'),
+  ('࿐', '࿔'), ('࿙', '࿚'), ('၊', '၏'), ('჻', '჻'),
+  ('፠', '፨'), ('᙮', '᙮'), ('᛫', '᛭'), ('᜵', '᜶'),
+  ('។', '៖'), ('៘', '៚'), ('᠀', '᠅'), ('᠇', '᠊'),
+  ('᥄', '᥅'), ('᨞', '᨟'), ('᪠', '᪦'), ('᪨', '᪭'),
+  ('᭚', '᭠'), ('᯼', '᯿'), ('᰻', '᰿'), ('᱾', '᱿'),
+  ('᳀', '᳇'), ('᳓', '᳓'), ('‖', '‗'), ('†', '‧'),
+  ('‰', '‸'), ('※', '‾'), ('⁁', '⁃'), ('⁇', '⁑'),
+  ('⁓', '⁓'), ('⁕', '⁞'), ('⳹', '⳼'), ('⳾', '⳿'),
+  ('⵰', '⵰'), ('⸀', '⸁'), ('⸆', '⸈'), ('⸋', '⸋'),
+  ('⸎', '⸖'), ('⸘', '⸙'), ('⸛', '⸛'), ('⸞', '⸟'),
+  ('⸪', '⸮'), ('⸰', '⸹'), ('⸼', '⸿'), ('⹁', '⹁'),
+  ('⹃', '\u{2e4f}'), ('、', '〃'), ('〽', '〽'), ('・', '・'),
+  ('꓾', '꓿'), ('꘍', '꘏'), ('꙳', '꙳'), ('꙾', '꙾'),
+  ('꛲', '꛷'), ('꡴', '꡷'), ('꣎', '꣏'), ('꣸', '꣺'),
+  ('꣼', '꣼'), ('꤮', '꤯'), ('꥟', '꥟'), ('꧁', '꧍'),
+  ('꧞', '꧟'), ('꩜', '꩟'), ('꫞', '꫟'), ('꫰', '꫱'),
+  ('꯫', '꯫'), ('︐', '︖'), ('︙', '︙'), ('︰', '︰'),
+  ('﹅', '﹆'), ('﹉', '﹌'), ('﹐', '﹒'), ('﹔', '﹗'),
+  ('﹟', '﹡'), ('﹨', '﹨'), ('﹪', '﹫'), ('!', '#'),
+  ('%', '''), ('*', '*'), (',', ','), ('.', '/'),
+  (':', ';'), ('?', '@'), ('\', '\'), ('。', '。'),
+  ('、', '・'), ('𐄀', '𐄂'), ('𐎟', '𐎟'), ('𐏐', '𐏐'),
+  ('𐕯', '𐕯'), ('𐡗', '𐡗'), ('𐤟', '𐤟'), ('𐤿', '𐤿'),
+  ('𐩐', '𐩘'), ('𐩿', '𐩿'), ('𐫰', '𐫶'), ('𐬹', '𐬿'),
+  ('𐮙', '𐮜'), ('𐽕', '𐽙'), ('𑁇', '𑁍'), ('𑂻', '𑂼'),
+  ('𑂾', '𑃁'), ('𑅀', '𑅃'), ('𑅴', '𑅵'), ('𑇅', '𑇈'),
+  ('𑇍', '𑇍'), ('𑇛', '𑇛'), ('𑇝', '𑇟'), ('𑈸', '𑈽'),
+  ('𑊩', '𑊩'), ('𑑋', '𑑏'), ('𑑛', '𑑛'), ('𑑝', '𑑝'),
+  ('𑓆', '𑓆'), ('𑗁', '𑗗'), ('𑙁', '𑙃'), ('𑙠', '𑙬'),
+  ('𑜼', '𑜾'), ('𑠻', '𑠻'), ('\u{119e2}', '\u{119e2}'),
+  ('𑨿', '𑩆'), ('𑪚', '𑪜'), ('𑪞', '𑪢'), ('𑱁', '𑱅'),
+  ('𑱰', '𑱱'), ('𑻷', '𑻸'), ('\u{11fff}', '\u{11fff}'),
+  ('𒑰', '𒑴'), ('𖩮', '𖩯'), ('𖫵', '𖫵'), ('𖬷', '𖬻'),
+  ('𖭄', '𖭄'), ('𖺗', '𖺚'), ('\u{16fe2}', '\u{16fe2}'),
+  ('𛲟', '𛲟'), ('𝪇', '𝪋'), ('𞥞', '𞥟'),
+];
+
+pub const OTHER_SYMBOL: &'static [(char, char)] = &[
+  ('¦', '¦'), ('©', '©'), ('®', '®'), ('°', '°'), ('҂', '҂'),
+  ('֍', '֎'), ('؎', '؏'), ('۞', '۞'), ('۩', '۩'), ('۽', '۾'),
+  ('߶', '߶'), ('৺', '৺'), ('୰', '୰'), ('௳', '௸'),
+  ('௺', '௺'), ('౿', '౿'), ('൏', '൏'), ('൹', '൹'),
+  ('༁', '༃'), ('༓', '༓'), ('༕', '༗'), ('༚', '༟'),
+  ('༴', '༴'), ('༶', '༶'), ('༸', '༸'), ('྾', '࿅'),
+  ('࿇', '࿌'), ('࿎', '࿏'), ('࿕', '࿘'), ('႞', '႟'),
+  ('᎐', '᎙'), ('᙭', '᙭'), ('᥀', '᥀'), ('᧞', '᧿'),
+  ('᭡', '᭪'), ('᭴', '᭼'), ('℀', '℁'), ('℃', '℆'),
+  ('℈', '℉'), ('℔', '℔'), ('№', '℗'), ('℞', '℣'),
+  ('℥', '℥'), ('℧', '℧'), ('℩', '℩'), ('℮', '℮'),
+  ('℺', '℻'), ('⅊', '⅊'), ('⅌', '⅍'), ('⅏', '⅏'),
+  ('↊', '↋'), ('↕', '↙'), ('↜', '↟'), ('↡', '↢'),
+  ('↤', '↥'), ('↧', '↭'), ('↯', '⇍'), ('⇐', '⇑'),
+  ('⇓', '⇓'), ('⇕', '⇳'), ('⌀', '⌇'), ('⌌', '⌟'),
+  ('⌢', '⌨'), ('⌫', '⍻'), ('⍽', '⎚'), ('⎴', '⏛'),
+  ('⏢', '␦'), ('⑀', '⑊'), ('⒜', 'ⓩ'), ('─', '▶'),
+  ('▸', '◀'), ('◂', '◷'), ('☀', '♮'), ('♰', '❧'),
+  ('➔', '➿'), ('⠀', '⣿'), ('⬀', '⬯'), ('⭅', '⭆'),
+  ('⭍', '⭳'), ('⭶', '⮕'), ('⮘', '\u{2bff}'), ('⳥', '⳪'),
+  ('⺀', '⺙'), ('⺛', '⻳'), ('⼀', '⿕'), ('⿰', '⿻'),
+  ('〄', '〄'), ('〒', '〓'), ('〠', '〠'), ('〶', '〷'),
+  ('〾', '〿'), ('㆐', '㆑'), ('㆖', '㆟'), ('㇀', '㇣'),
+  ('㈀', '㈞'), ('㈪', '㉇'), ('㉐', '㉐'), ('㉠', '㉿'),
+  ('㊊', '㊰'), ('㋀', '㏿'), ('䷀', '䷿'), ('꒐', '꓆'),
+  ('꠨', '꠫'), ('꠶', '꠷'), ('꠹', '꠹'), ('꩷', '꩹'),
+  ('﷽', '﷽'), ('¦', '¦'), ('│', '│'), ('■', '○'),
+  ('', '�'), ('𐄷', '𐄿'), ('𐅹', '𐆉'), ('𐆌', '𐆎'),
+  ('𐆐', '𐆛'), ('𐆠', '𐆠'), ('𐇐', '𐇼'), ('𐡷', '𐡸'),
+  ('𐫈', '𐫈'), ('𑜿', '𑜿'), ('\u{11fd5}', '\u{11fdc}'),
+  ('\u{11fe1}', '\u{11ff1}'), ('𖬼', '𖬿'), ('𖭅', '𖭅'),
+  ('𛲜', '𛲜'), ('𝀀', '𝃵'), ('𝄀', '𝄦'), ('𝄩', '𝅘𝅥𝅲'),
+  ('𝅪', '𝅬'), ('𝆃', '𝆄'), ('𝆌', '𝆩'), ('𝆮', '𝇨'),
+  ('𝈀', '𝉁'), ('𝉅', '𝉅'), ('𝌀', '𝍖'), ('𝠀', '𝧿'),
+  ('𝨷', '𝨺'), ('𝩭', '𝩴'), ('𝩶', '𝪃'), ('𝪅', '𝪆'),
+  ('\u{1e14f}', '\u{1e14f}'), ('𞲬', '𞲬'), ('\u{1ed2e}', '\u{1ed2e}'),
+  ('🀀', '🀫'), ('🀰', '🂓'), ('🂠', '🂮'), ('🂱', '🂿'),
+  ('🃁', '🃏'), ('🃑', '🃵'), ('🄐', '\u{1f16c}'), ('🅰', '🆬'),
+  ('🇦', '🈂'), ('🈐', '🈻'), ('🉀', '🉈'), ('🉐', '🉑'),
+  ('🉠', '🉥'), ('🌀', '🏺'), ('🐀', '\u{1f6d5}'), ('🛠', '🛬'),
+  ('🛰', '\u{1f6fa}'), ('🜀', '🝳'), ('🞀', '🟘'),
+  ('\u{1f7e0}', '\u{1f7eb}'), ('🠀', '🠋'), ('🠐', '🡇'),
+  ('🡐', '🡙'), ('🡠', '🢇'), ('🢐', '🢭'), ('🤀', '🤋'),
+  ('\u{1f90d}', '\u{1f971}'), ('🥳', '🥶'), ('🥺', '🦢'),
+  ('\u{1f9a5}', '\u{1f9aa}'), ('\u{1f9ae}', '\u{1f9ca}'),
+  ('\u{1f9cd}', '\u{1fa53}'), ('🩠', '🩭'), ('\u{1fa70}', '\u{1fa73}'),
+  ('\u{1fa78}', '\u{1fa7a}'), ('\u{1fa80}', '\u{1fa82}'),
+  ('\u{1fa90}', '\u{1fa95}'),
+];
+
+pub const PARAGRAPH_SEPARATOR: &'static [(char, char)] = &[
+  ('\u{2029}', '\u{2029}'),
+];
+
+pub const PRIVATE_USE: &'static [(char, char)] = &[
+  ('\u{e000}', '\u{f8ff}'), ('\u{f0000}', '\u{ffffd}'),
+  ('\u{100000}', '\u{10fffd}'),
+];
+
+pub const PUNCTUATION: &'static [(char, char)] = &[
+  ('!', '#'), ('%', '*'), (',', '/'), (':', ';'), ('?', '@'), ('[', ']'),
+  ('_', '_'), ('{', '{'), ('}', '}'), ('¡', '¡'), ('§', '§'),
+  ('«', '«'), ('¶', '·'), ('»', '»'), ('¿', '¿'), (';', ';'),
+  ('·', '·'), ('՚', '՟'), ('։', '֊'), ('־', '־'), ('׀', '׀'),
+  ('׃', '׃'), ('׆', '׆'), ('׳', '״'), ('؉', '؊'), ('،', '؍'),
+  ('؛', '؛'), ('؞', '؟'), ('٪', '٭'), ('۔', '۔'), ('܀', '܍'),
+  ('߷', '߹'), ('࠰', '࠾'), ('࡞', '࡞'), ('।', '॥'),
+  ('॰', '॰'), ('৽', '৽'), ('੶', '੶'), ('૰', '૰'),
+  ('\u{c77}', '\u{c77}'), ('಄', '಄'), ('෴', '෴'), ('๏', '๏'),
+  ('๚', '๛'), ('༄', '༒'), ('༔', '༔'), ('༺', '༽'),
+  ('྅', '྅'), ('࿐', '࿔'), ('࿙', '࿚'), ('၊', '၏'),
+  ('჻', '჻'), ('፠', '፨'), ('᐀', '᐀'), ('᙮', '᙮'),
+  ('᚛', '᚜'), ('᛫', '᛭'), ('᜵', '᜶'), ('។', '៖'),
+  ('៘', '៚'), ('᠀', '᠊'), ('᥄', '᥅'), ('᨞', '᨟'),
+  ('᪠', '᪦'), ('᪨', '᪭'), ('᭚', '᭠'), ('᯼', '᯿'),
+  ('᰻', '᰿'), ('᱾', '᱿'), ('᳀', '᳇'), ('᳓', '᳓'),
+  ('‐', '‧'), ('‰', '⁃'), ('⁅', '⁑'), ('⁓', '⁞'),
+  ('⁽', '⁾'), ('₍', '₎'), ('⌈', '⌋'), ('〈', '〉'),
+  ('❨', '❵'), ('⟅', '⟆'), ('⟦', '⟯'), ('⦃', '⦘'),
+  ('⧘', '⧛'), ('⧼', '⧽'), ('⳹', '⳼'), ('⳾', '⳿'),
+  ('⵰', '⵰'), ('⸀', '⸮'), ('⸰', '\u{2e4f}'), ('、', '〃'),
+  ('〈', '】'), ('〔', '〟'), ('〰', '〰'), ('〽', '〽'),
+  ('゠', '゠'), ('・', '・'), ('꓾', '꓿'), ('꘍', '꘏'),
+  ('꙳', '꙳'), ('꙾', '꙾'), ('꛲', '꛷'), ('꡴', '꡷'),
+  ('꣎', '꣏'), ('꣸', '꣺'), ('꣼', '꣼'), ('꤮', '꤯'),
+  ('꥟', '꥟'), ('꧁', '꧍'), ('꧞', '꧟'), ('꩜', '꩟'),
+  ('꫞', '꫟'), ('꫰', '꫱'), ('꯫', '꯫'), ('﴾', '﴿'),
+  ('︐', '︙'), ('︰', '﹒'), ('﹔', '﹡'), ('﹣', '﹣'),
+  ('﹨', '﹨'), ('﹪', '﹫'), ('!', '#'), ('%', '*'),
+  (',', '/'), (':', ';'), ('?', '@'), ('[', ']'),
+  ('_', '_'), ('{', '{'), ('}', '}'), ('⦅', '・'),
+  ('𐄀', '𐄂'), ('𐎟', '𐎟'), ('𐏐', '𐏐'), ('𐕯', '𐕯'),
+  ('𐡗', '𐡗'), ('𐤟', '𐤟'), ('𐤿', '𐤿'), ('𐩐', '𐩘'),
+  ('𐩿', '𐩿'), ('𐫰', '𐫶'), ('𐬹', '𐬿'), ('𐮙', '𐮜'),
+  ('𐽕', '𐽙'), ('𑁇', '𑁍'), ('𑂻', '𑂼'), ('𑂾', '𑃁'),
+  ('𑅀', '𑅃'), ('𑅴', '𑅵'), ('𑇅', '𑇈'), ('𑇍', '𑇍'),
+  ('𑇛', '𑇛'), ('𑇝', '𑇟'), ('𑈸', '𑈽'), ('𑊩', '𑊩'),
+  ('𑑋', '𑑏'), ('𑑛', '𑑛'), ('𑑝', '𑑝'), ('𑓆', '𑓆'),
+  ('𑗁', '𑗗'), ('𑙁', '𑙃'), ('𑙠', '𑙬'), ('𑜼', '𑜾'),
+  ('𑠻', '𑠻'), ('\u{119e2}', '\u{119e2}'), ('𑨿', '𑩆'),
+  ('𑪚', '𑪜'), ('𑪞', '𑪢'), ('𑱁', '𑱅'), ('𑱰', '𑱱'),
+  ('𑻷', '𑻸'), ('\u{11fff}', '\u{11fff}'), ('𒑰', '𒑴'),
+  ('𖩮', '𖩯'), ('𖫵', '𖫵'), ('𖬷', '𖬻'), ('𖭄', '𖭄'),
+  ('𖺗', '𖺚'), ('\u{16fe2}', '\u{16fe2}'), ('𛲟', '𛲟'),
+  ('𝪇', '𝪋'), ('𞥞', '𞥟'),
+];
+
+pub const SEPARATOR: &'static [(char, char)] = &[
+  (' ', ' '), ('\u{a0}', '\u{a0}'), ('\u{1680}', '\u{1680}'),
+  ('\u{2000}', '\u{200a}'), ('\u{2028}', '\u{2029}'),
+  ('\u{202f}', '\u{202f}'), ('\u{205f}', '\u{205f}'),
+  ('\u{3000}', '\u{3000}'),
+];
+
+pub const SPACE_SEPARATOR: &'static [(char, char)] = &[
+  (' ', ' '), ('\u{a0}', '\u{a0}'), ('\u{1680}', '\u{1680}'),
+  ('\u{2000}', '\u{200a}'), ('\u{202f}', '\u{202f}'),
+  ('\u{205f}', '\u{205f}'), ('\u{3000}', '\u{3000}'),
+];
+
+pub const SPACING_MARK: &'static [(char, char)] = &[
+  ('ः', 'ः'), ('ऻ', 'ऻ'), ('ा', 'ी'), ('ॉ', 'ौ'),
+  ('ॎ', 'ॏ'), ('ং', 'ঃ'), ('\u{9be}', 'ী'), ('ে', 'ৈ'),
+  ('ো', 'ৌ'), ('\u{9d7}', '\u{9d7}'), ('ਃ', 'ਃ'), ('ਾ', 'ੀ'),
+  ('ઃ', 'ઃ'), ('ા', 'ી'), ('ૉ', 'ૉ'), ('ો', 'ૌ'),
+  ('ଂ', 'ଃ'), ('\u{b3e}', '\u{b3e}'), ('ୀ', 'ୀ'), ('େ', 'ୈ'),
+  ('ୋ', 'ୌ'), ('\u{b57}', '\u{b57}'), ('\u{bbe}', 'ி'), ('ு', 'ூ'),
+  ('ெ', 'ை'), ('ொ', 'ௌ'), ('\u{bd7}', '\u{bd7}'), ('ఁ', 'ః'),
+  ('ు', 'ౄ'), ('ಂ', 'ಃ'), ('ಾ', 'ಾ'), ('ೀ', 'ೄ'),
+  ('ೇ', 'ೈ'), ('ೊ', 'ೋ'), ('\u{cd5}', '\u{cd6}'), ('ം', 'ഃ'),
+  ('\u{d3e}', 'ീ'), ('െ', 'ൈ'), ('ൊ', 'ൌ'), ('\u{d57}', '\u{d57}'),
+  ('ං', 'ඃ'), ('\u{dcf}', 'ෑ'), ('ෘ', '\u{ddf}'), ('ෲ', 'ෳ'),
+  ('༾', '༿'), ('ཿ', 'ཿ'), ('ါ', 'ာ'), ('ေ', 'ေ'),
+  ('း', 'း'), ('ျ', 'ြ'), ('ၖ', 'ၗ'), ('ၢ', 'ၤ'),
+  ('ၧ', 'ၭ'), ('ႃ', 'ႄ'), ('ႇ', 'ႌ'), ('ႏ', 'ႏ'),
+  ('ႚ', 'ႜ'), ('ា', 'ា'), ('ើ', 'ៅ'), ('ះ', 'ៈ'),
+  ('ᤣ', 'ᤦ'), ('ᤩ', 'ᤫ'), ('ᤰ', 'ᤱ'), ('ᤳ', 'ᤸ'),
+  ('ᨙ', 'ᨚ'), ('ᩕ', 'ᩕ'), ('ᩗ', 'ᩗ'), ('ᩡ', 'ᩡ'),
+  ('ᩣ', 'ᩤ'), ('ᩭ', 'ᩲ'), ('ᬄ', 'ᬄ'), ('ᬵ', 'ᬵ'),
+  ('ᬻ', 'ᬻ'), ('ᬽ', 'ᭁ'), ('ᭃ', '᭄'), ('ᮂ', 'ᮂ'),
+  ('ᮡ', 'ᮡ'), ('ᮦ', 'ᮧ'), ('᮪', '᮪'), ('ᯧ', 'ᯧ'),
+  ('ᯪ', 'ᯬ'), ('ᯮ', 'ᯮ'), ('᯲', '᯳'), ('ᰤ', 'ᰫ'),
+  ('ᰴ', 'ᰵ'), ('᳡', '᳡'), ('᳷', '᳷'), ('\u{302e}', '\u{302f}'),
+  ('ꠣ', 'ꠤ'), ('ꠧ', 'ꠧ'), ('ꢀ', 'ꢁ'), ('ꢴ', 'ꣃ'),
+  ('ꥒ', '꥓'), ('ꦃ', 'ꦃ'), ('ꦴ', 'ꦵ'), ('ꦺ', 'ꦻ'),
+  ('ꦾ', '꧀'), ('ꨯ', 'ꨰ'), ('ꨳ', 'ꨴ'), ('ꩍ', 'ꩍ'),
+  ('ꩻ', 'ꩻ'), ('ꩽ', 'ꩽ'), ('ꫫ', 'ꫫ'), ('ꫮ', 'ꫯ'),
+  ('ꫵ', 'ꫵ'), ('ꯣ', 'ꯤ'), ('ꯦ', 'ꯧ'), ('ꯩ', 'ꯪ'),
+  ('꯬', '꯬'), ('𑀀', '𑀀'), ('𑀂', '𑀂'), ('𑂂', '𑂂'),
+  ('𑂰', '𑂲'), ('𑂷', '𑂸'), ('𑄬', '𑄬'), ('𑅅', '𑅆'),
+  ('𑆂', '𑆂'), ('𑆳', '𑆵'), ('𑆿', '𑇀'), ('𑈬', '𑈮'),
+  ('𑈲', '𑈳'), ('𑈵', '𑈵'), ('𑋠', '𑋢'), ('𑌂', '𑌃'),
+  ('\u{1133e}', '𑌿'), ('𑍁', '𑍄'), ('𑍇', '𑍈'), ('𑍋', '𑍍'),
+  ('\u{11357}', '\u{11357}'), ('𑍢', '𑍣'), ('𑐵', '𑐷'),
+  ('𑑀', '𑑁'), ('𑑅', '𑑅'), ('\u{114b0}', '𑒲'), ('𑒹', '𑒹'),
+  ('𑒻', '𑒾'), ('𑓁', '𑓁'), ('\u{115af}', '𑖱'), ('𑖸', '𑖻'),
+  ('𑖾', '𑖾'), ('𑘰', '𑘲'), ('𑘻', '𑘼'), ('𑘾', '𑘾'),
+  ('𑚬', '𑚬'), ('𑚮', '𑚯'), ('𑚶', '𑚶'), ('𑜠', '𑜡'),
+  ('𑜦', '𑜦'), ('𑠬', '𑠮'), ('𑠸', '𑠸'),
+  ('\u{119d1}', '\u{119d3}'), ('\u{119dc}', '\u{119df}'),
+  ('\u{119e4}', '\u{119e4}'), ('𑨹', '𑨹'), ('𑩗', '𑩘'),
+  ('𑪗', '𑪗'), ('𑰯', '𑰯'), ('𑰾', '𑰾'), ('𑲩', '𑲩'),
+  ('𑲱', '𑲱'), ('𑲴', '𑲴'), ('𑶊', '𑶎'), ('𑶓', '𑶔'),
+  ('𑶖', '𑶖'), ('𑻵', '𑻶'), ('𖽑', '\u{16f87}'),
+  ('\u{1d165}', '𝅦'), ('𝅭', '\u{1d172}'),
+];
+
+pub const SYMBOL: &'static [(char, char)] = &[
+  ('$', '$'), ('+', '+'), ('<', '>'), ('^', '^'), ('`', '`'), ('|', '|'),
+  ('~', '~'), ('¢', '¦'), ('¨', '©'), ('¬', '¬'), ('®', '±'),
+  ('´', '´'), ('¸', '¸'), ('×', '×'), ('÷', '÷'), ('˂', '˅'),
+  ('˒', '˟'), ('˥', '˫'), ('˭', '˭'), ('˯', '˿'), ('͵', '͵'),
+  ('΄', '΅'), ('϶', '϶'), ('҂', '҂'), ('֍', '֏'), ('؆', '؈'),
+  ('؋', '؋'), ('؎', '؏'), ('۞', '۞'), ('۩', '۩'), ('۽', '۾'),
+  ('߶', '߶'), ('߾', '߿'), ('৲', '৳'), ('৺', '৻'), ('૱', '૱'),
+  ('୰', '୰'), ('௳', '௺'), ('౿', '౿'), ('൏', '൏'),
+  ('൹', '൹'), ('฿', '฿'), ('༁', '༃'), ('༓', '༓'),
+  ('༕', '༗'), ('༚', '༟'), ('༴', '༴'), ('༶', '༶'),
+  ('༸', '༸'), ('྾', '࿅'), ('࿇', '࿌'), ('࿎', '࿏'),
+  ('࿕', '࿘'), ('႞', '႟'), ('᎐', '᎙'), ('᙭', '᙭'),
+  ('៛', '៛'), ('᥀', '᥀'), ('᧞', '᧿'), ('᭡', '᭪'),
+  ('᭴', '᭼'), ('᾽', '᾽'), ('᾿', '῁'), ('῍', '῏'),
+  ('῝', '῟'), ('῭', '`'), ('´', '῾'), ('⁄', '⁄'),
+  ('⁒', '⁒'), ('⁺', '⁼'), ('₊', '₌'), ('₠', '₿'),
+  ('℀', '℁'), ('℃', '℆'), ('℈', '℉'), ('℔', '℔'),
+  ('№', '℘'), ('℞', '℣'), ('℥', '℥'), ('℧', '℧'),
+  ('℩', '℩'), ('℮', '℮'), ('℺', '℻'), ('⅀', '⅄'),
+  ('⅊', '⅍'), ('⅏', '⅏'), ('↊', '↋'), ('←', '⌇'),
+  ('⌌', '⌨'), ('⌫', '␦'), ('⑀', '⑊'), ('⒜', 'ⓩ'),
+  ('─', '❧'), ('➔', '⟄'), ('⟇', '⟥'), ('⟰', '⦂'),
+  ('⦙', '⧗'), ('⧜', '⧻'), ('⧾', '⭳'), ('⭶', '⮕'),
+  ('⮘', '\u{2bff}'), ('⳥', '⳪'), ('⺀', '⺙'), ('⺛', '⻳'),
+  ('⼀', '⿕'), ('⿰', '⿻'), ('〄', '〄'), ('〒', '〓'),
+  ('〠', '〠'), ('〶', '〷'), ('〾', '〿'), ('゛', '゜'),
+  ('㆐', '㆑'), ('㆖', '㆟'), ('㇀', '㇣'), ('㈀', '㈞'),
+  ('㈪', '㉇'), ('㉐', '㉐'), ('㉠', '㉿'), ('㊊', '㊰'),
+  ('㋀', '㏿'), ('䷀', '䷿'), ('꒐', '꓆'), ('꜀', '꜖'),
+  ('꜠', '꜡'), ('꞉', '꞊'), ('꠨', '꠫'), ('꠶', '꠹'),
+  ('꩷', '꩹'), ('꭛', '꭛'), ('﬩', '﬩'), ('﮲', '﯁'),
+  ('﷼', '﷽'), ('﹢', '﹢'), ('﹤', '﹦'), ('﹩', '﹩'),
+  ('$', '$'), ('+', '+'), ('<', '>'), ('^', '^'),
+  ('`', '`'), ('|', '|'), ('~', '~'), ('¢', '₩'),
+  ('│', '○'), ('', '�'), ('𐄷', '𐄿'), ('𐅹', '𐆉'),
+  ('𐆌', '𐆎'), ('𐆐', '𐆛'), ('𐆠', '𐆠'), ('𐇐', '𐇼'),
+  ('𐡷', '𐡸'), ('𐫈', '𐫈'), ('𑜿', '𑜿'),
+  ('\u{11fd5}', '\u{11ff1}'), ('𖬼', '𖬿'), ('𖭅', '𖭅'),
+  ('𛲜', '𛲜'), ('𝀀', '𝃵'), ('𝄀', '𝄦'), ('𝄩', '𝅘𝅥𝅲'),
+  ('𝅪', '𝅬'), ('𝆃', '𝆄'), ('𝆌', '𝆩'), ('𝆮', '𝇨'),
+  ('𝈀', '𝉁'), ('𝉅', '𝉅'), ('𝌀', '𝍖'), ('𝛁', '𝛁'),
+  ('𝛛', '𝛛'), ('𝛻', '𝛻'), ('𝜕', '𝜕'), ('𝜵', '𝜵'),
+  ('𝝏', '𝝏'), ('𝝯', '𝝯'), ('𝞉', '𝞉'), ('𝞩', '𝞩'),
+  ('𝟃', '𝟃'), ('𝠀', '𝧿'), ('𝨷', '𝨺'), ('𝩭', '𝩴'),
+  ('𝩶', '𝪃'), ('𝪅', '𝪆'), ('\u{1e14f}', '\u{1e14f}'),
+  ('\u{1e2ff}', '\u{1e2ff}'), ('𞲬', '𞲬'), ('𞲰', '𞲰'),
+  ('\u{1ed2e}', '\u{1ed2e}'), ('𞻰', '𞻱'), ('🀀', '🀫'),
+  ('🀰', '🂓'), ('🂠', '🂮'), ('🂱', '🂿'), ('🃁', '🃏'),
+  ('🃑', '🃵'), ('🄐', '\u{1f16c}'), ('🅰', '🆬'), ('🇦', '🈂'),
+  ('🈐', '🈻'), ('🉀', '🉈'), ('🉐', '🉑'), ('🉠', '🉥'),
+  ('🌀', '\u{1f6d5}'), ('🛠', '🛬'), ('🛰', '\u{1f6fa}'),
+  ('🜀', '🝳'), ('🞀', '🟘'), ('\u{1f7e0}', '\u{1f7eb}'),
+  ('🠀', '🠋'), ('🠐', '🡇'), ('🡐', '🡙'), ('🡠', '🢇'),
+  ('🢐', '🢭'), ('🤀', '🤋'), ('\u{1f90d}', '\u{1f971}'),
+  ('🥳', '🥶'), ('🥺', '🦢'), ('\u{1f9a5}', '\u{1f9aa}'),
+  ('\u{1f9ae}', '\u{1f9ca}'), ('\u{1f9cd}', '\u{1fa53}'), ('🩠', '🩭'),
+  ('\u{1fa70}', '\u{1fa73}'), ('\u{1fa78}', '\u{1fa7a}'),
+  ('\u{1fa80}', '\u{1fa82}'), ('\u{1fa90}', '\u{1fa95}'),
+];
+
+pub const TITLECASE_LETTER: &'static [(char, char)] = &[
+  ('Dž', 'Dž'), ('Lj', 'Lj'), ('Nj', 'Nj'), ('Dz', 'Dz'), ('ᾈ', 'ᾏ'),
+  ('ᾘ', 'ᾟ'), ('ᾨ', 'ᾯ'), ('ᾼ', 'ᾼ'), ('ῌ', 'ῌ'),
+  ('ῼ', 'ῼ'),
+];
+
+pub const UNASSIGNED: &'static [(char, char)] = &[
+  ('\u{378}', '\u{379}'), ('\u{380}', '\u{383}'), ('\u{38b}', '\u{38b}'),
+  ('\u{38d}', '\u{38d}'), ('\u{3a2}', '\u{3a2}'), ('\u{530}', '\u{530}'),
+  ('\u{557}', '\u{558}'), ('\u{58b}', '\u{58c}'), ('\u{590}', '\u{590}'),
+  ('\u{5c8}', '\u{5cf}'), ('\u{5eb}', '\u{5ee}'), ('\u{5f5}', '\u{5ff}'),
+  ('\u{61d}', '\u{61d}'), ('\u{70e}', '\u{70e}'), ('\u{74b}', '\u{74c}'),
+  ('\u{7b2}', '\u{7bf}'), ('\u{7fb}', '\u{7fc}'), ('\u{82e}', '\u{82f}'),
+  ('\u{83f}', '\u{83f}'), ('\u{85c}', '\u{85d}'), ('\u{85f}', '\u{85f}'),
+  ('\u{86b}', '\u{89f}'), ('\u{8b5}', '\u{8b5}'), ('\u{8be}', '\u{8d2}'),
+  ('\u{984}', '\u{984}'), ('\u{98d}', '\u{98e}'), ('\u{991}', '\u{992}'),
+  ('\u{9a9}', '\u{9a9}'), ('\u{9b1}', '\u{9b1}'), ('\u{9b3}', '\u{9b5}'),
+  ('\u{9ba}', '\u{9bb}'), ('\u{9c5}', '\u{9c6}'), ('\u{9c9}', '\u{9ca}'),
+  ('\u{9cf}', '\u{9d6}'), ('\u{9d8}', '\u{9db}'), ('\u{9de}', '\u{9de}'),
+  ('\u{9e4}', '\u{9e5}'), ('\u{9ff}', '\u{a00}'), ('\u{a04}', '\u{a04}'),
+  ('\u{a0b}', '\u{a0e}'), ('\u{a11}', '\u{a12}'), ('\u{a29}', '\u{a29}'),
+  ('\u{a31}', '\u{a31}'), ('\u{a34}', '\u{a34}'), ('\u{a37}', '\u{a37}'),
+  ('\u{a3a}', '\u{a3b}'), ('\u{a3d}', '\u{a3d}'), ('\u{a43}', '\u{a46}'),
+  ('\u{a49}', '\u{a4a}'), ('\u{a4e}', '\u{a50}'), ('\u{a52}', '\u{a58}'),
+  ('\u{a5d}', '\u{a5d}'), ('\u{a5f}', '\u{a65}'), ('\u{a77}', '\u{a80}'),
+  ('\u{a84}', '\u{a84}'), ('\u{a8e}', '\u{a8e}'), ('\u{a92}', '\u{a92}'),
+  ('\u{aa9}', '\u{aa9}'), ('\u{ab1}', '\u{ab1}'), ('\u{ab4}', '\u{ab4}'),
+  ('\u{aba}', '\u{abb}'), ('\u{ac6}', '\u{ac6}'), ('\u{aca}', '\u{aca}'),
+  ('\u{ace}', '\u{acf}'), ('\u{ad1}', '\u{adf}'), ('\u{ae4}', '\u{ae5}'),
+  ('\u{af2}', '\u{af8}'), ('\u{b00}', '\u{b00}'), ('\u{b04}', '\u{b04}'),
+  ('\u{b0d}', '\u{b0e}'), ('\u{b11}', '\u{b12}'), ('\u{b29}', '\u{b29}'),
+  ('\u{b31}', '\u{b31}'), ('\u{b34}', '\u{b34}'), ('\u{b3a}', '\u{b3b}'),
+  ('\u{b45}', '\u{b46}'), ('\u{b49}', '\u{b4a}'), ('\u{b4e}', '\u{b55}'),
+  ('\u{b58}', '\u{b5b}'), ('\u{b5e}', '\u{b5e}'), ('\u{b64}', '\u{b65}'),
+  ('\u{b78}', '\u{b81}'), ('\u{b84}', '\u{b84}'), ('\u{b8b}', '\u{b8d}'),
+  ('\u{b91}', '\u{b91}'), ('\u{b96}', '\u{b98}'), ('\u{b9b}', '\u{b9b}'),
+  ('\u{b9d}', '\u{b9d}'), ('\u{ba0}', '\u{ba2}'), ('\u{ba5}', '\u{ba7}'),
+  ('\u{bab}', '\u{bad}'), ('\u{bba}', '\u{bbd}'), ('\u{bc3}', '\u{bc5}'),
+  ('\u{bc9}', '\u{bc9}'), ('\u{bce}', '\u{bcf}'), ('\u{bd1}', '\u{bd6}'),
+  ('\u{bd8}', '\u{be5}'), ('\u{bfb}', '\u{bff}'), ('\u{c0d}', '\u{c0d}'),
+  ('\u{c11}', '\u{c11}'), ('\u{c29}', '\u{c29}'), ('\u{c3a}', '\u{c3c}'),
+  ('\u{c45}', '\u{c45}'), ('\u{c49}', '\u{c49}'), ('\u{c4e}', '\u{c54}'),
+  ('\u{c57}', '\u{c57}'), ('\u{c5b}', '\u{c5f}'), ('\u{c64}', '\u{c65}'),
+  ('\u{c70}', '\u{c76}'), ('\u{c8d}', '\u{c8d}'), ('\u{c91}', '\u{c91}'),
+  ('\u{ca9}', '\u{ca9}'), ('\u{cb4}', '\u{cb4}'), ('\u{cba}', '\u{cbb}'),
+  ('\u{cc5}', '\u{cc5}'), ('\u{cc9}', '\u{cc9}'), ('\u{cce}', '\u{cd4}'),
+  ('\u{cd7}', '\u{cdd}'), ('\u{cdf}', '\u{cdf}'), ('\u{ce4}', '\u{ce5}'),
+  ('\u{cf0}', '\u{cf0}'), ('\u{cf3}', '\u{cff}'), ('\u{d04}', '\u{d04}'),
+  ('\u{d0d}', '\u{d0d}'), ('\u{d11}', '\u{d11}'), ('\u{d45}', '\u{d45}'),
+  ('\u{d49}', '\u{d49}'), ('\u{d50}', '\u{d53}'), ('\u{d64}', '\u{d65}'),
+  ('\u{d80}', '\u{d81}'), ('\u{d84}', '\u{d84}'), ('\u{d97}', '\u{d99}'),
+  ('\u{db2}', '\u{db2}'), ('\u{dbc}', '\u{dbc}'), ('\u{dbe}', '\u{dbf}'),
+  ('\u{dc7}', '\u{dc9}'), ('\u{dcb}', '\u{dce}'), ('\u{dd5}', '\u{dd5}'),
+  ('\u{dd7}', '\u{dd7}'), ('\u{de0}', '\u{de5}'), ('\u{df0}', '\u{df1}'),
+  ('\u{df5}', '\u{e00}'), ('\u{e3b}', '\u{e3e}'), ('\u{e5c}', '\u{e80}'),
+  ('\u{e83}', '\u{e83}'), ('\u{e85}', '\u{e85}'), ('\u{e8b}', '\u{e8b}'),
+  ('\u{ea4}', '\u{ea4}'), ('\u{ea6}', '\u{ea6}'), ('\u{ebe}', '\u{ebf}'),
+  ('\u{ec5}', '\u{ec5}'), ('\u{ec7}', '\u{ec7}'), ('\u{ece}', '\u{ecf}'),
+  ('\u{eda}', '\u{edb}'), ('\u{ee0}', '\u{eff}'), ('\u{f48}', '\u{f48}'),
+  ('\u{f6d}', '\u{f70}'), ('\u{f98}', '\u{f98}'), ('\u{fbd}', '\u{fbd}'),
+  ('\u{fcd}', '\u{fcd}'), ('\u{fdb}', '\u{fff}'), ('\u{10c6}', '\u{10c6}'),
+  ('\u{10c8}', '\u{10cc}'), ('\u{10ce}', '\u{10cf}'),
+  ('\u{1249}', '\u{1249}'), ('\u{124e}', '\u{124f}'),
+  ('\u{1257}', '\u{1257}'), ('\u{1259}', '\u{1259}'),
+  ('\u{125e}', '\u{125f}'), ('\u{1289}', '\u{1289}'),
+  ('\u{128e}', '\u{128f}'), ('\u{12b1}', '\u{12b1}'),
+  ('\u{12b6}', '\u{12b7}'), ('\u{12bf}', '\u{12bf}'),
+  ('\u{12c1}', '\u{12c1}'), ('\u{12c6}', '\u{12c7}'),
+  ('\u{12d7}', '\u{12d7}'), ('\u{1311}', '\u{1311}'),
+  ('\u{1316}', '\u{1317}'), ('\u{135b}', '\u{135c}'),
+  ('\u{137d}', '\u{137f}'), ('\u{139a}', '\u{139f}'),
+  ('\u{13f6}', '\u{13f7}'), ('\u{13fe}', '\u{13ff}'),
+  ('\u{169d}', '\u{169f}'), ('\u{16f9}', '\u{16ff}'),
+  ('\u{170d}', '\u{170d}'), ('\u{1715}', '\u{171f}'),
+  ('\u{1737}', '\u{173f}'), ('\u{1754}', '\u{175f}'),
+  ('\u{176d}', '\u{176d}'), ('\u{1771}', '\u{1771}'),
+  ('\u{1774}', '\u{177f}'), ('\u{17de}', '\u{17df}'),
+  ('\u{17ea}', '\u{17ef}'), ('\u{17fa}', '\u{17ff}'),
+  ('\u{180f}', '\u{180f}'), ('\u{181a}', '\u{181f}'),
+  ('\u{1879}', '\u{187f}'), ('\u{18ab}', '\u{18af}'),
+  ('\u{18f6}', '\u{18ff}'), ('\u{191f}', '\u{191f}'),
+  ('\u{192c}', '\u{192f}'), ('\u{193c}', '\u{193f}'),
+  ('\u{1941}', '\u{1943}'), ('\u{196e}', '\u{196f}'),
+  ('\u{1975}', '\u{197f}'), ('\u{19ac}', '\u{19af}'),
+  ('\u{19ca}', '\u{19cf}'), ('\u{19db}', '\u{19dd}'),
+  ('\u{1a1c}', '\u{1a1d}'), ('\u{1a5f}', '\u{1a5f}'),
+  ('\u{1a7d}', '\u{1a7e}'), ('\u{1a8a}', '\u{1a8f}'),
+  ('\u{1a9a}', '\u{1a9f}'), ('\u{1aae}', '\u{1aaf}'),
+  ('\u{1abf}', '\u{1aff}'), ('\u{1b4c}', '\u{1b4f}'),
+  ('\u{1b7d}', '\u{1b7f}'), ('\u{1bf4}', '\u{1bfb}'),
+  ('\u{1c38}', '\u{1c3a}'), ('\u{1c4a}', '\u{1c4c}'),
+  ('\u{1c89}', '\u{1c8f}'), ('\u{1cbb}', '\u{1cbc}'),
+  ('\u{1cc8}', '\u{1ccf}'), ('\u{1cfb}', '\u{1cff}'),
+  ('\u{1dfa}', '\u{1dfa}'), ('\u{1f16}', '\u{1f17}'),
+  ('\u{1f1e}', '\u{1f1f}'), ('\u{1f46}', '\u{1f47}'),
+  ('\u{1f4e}', '\u{1f4f}'), ('\u{1f58}', '\u{1f58}'),
+  ('\u{1f5a}', '\u{1f5a}'), ('\u{1f5c}', '\u{1f5c}'),
+  ('\u{1f5e}', '\u{1f5e}'), ('\u{1f7e}', '\u{1f7f}'),
+  ('\u{1fb5}', '\u{1fb5}'), ('\u{1fc5}', '\u{1fc5}'),
+  ('\u{1fd4}', '\u{1fd5}'), ('\u{1fdc}', '\u{1fdc}'),
+  ('\u{1ff0}', '\u{1ff1}'), ('\u{1ff5}', '\u{1ff5}'),
+  ('\u{1fff}', '\u{1fff}'), ('\u{2065}', '\u{2065}'),
+  ('\u{2072}', '\u{2073}'), ('\u{208f}', '\u{208f}'),
+  ('\u{209d}', '\u{209f}'), ('\u{20c0}', '\u{20cf}'),
+  ('\u{20f1}', '\u{20ff}'), ('\u{218c}', '\u{218f}'),
+  ('\u{2427}', '\u{243f}'), ('\u{244b}', '\u{245f}'),
+  ('\u{2b74}', '\u{2b75}'), ('\u{2b96}', '\u{2b97}'),
+  ('\u{2c2f}', '\u{2c2f}'), ('\u{2c5f}', '\u{2c5f}'),
+  ('\u{2cf4}', '\u{2cf8}'), ('\u{2d26}', '\u{2d26}'),
+  ('\u{2d28}', '\u{2d2c}'), ('\u{2d2e}', '\u{2d2f}'),
+  ('\u{2d68}', '\u{2d6e}'), ('\u{2d71}', '\u{2d7e}'),
+  ('\u{2d97}', '\u{2d9f}'), ('\u{2da7}', '\u{2da7}'),
+  ('\u{2daf}', '\u{2daf}'), ('\u{2db7}', '\u{2db7}'),
+  ('\u{2dbf}', '\u{2dbf}'), ('\u{2dc7}', '\u{2dc7}'),
+  ('\u{2dcf}', '\u{2dcf}'), ('\u{2dd7}', '\u{2dd7}'),
+  ('\u{2ddf}', '\u{2ddf}'), ('\u{2e50}', '\u{2e7f}'),
+  ('\u{2e9a}', '\u{2e9a}'), ('\u{2ef4}', '\u{2eff}'),
+  ('\u{2fd6}', '\u{2fef}'), ('\u{2ffc}', '\u{2fff}'),
+  ('\u{3040}', '\u{3040}'), ('\u{3097}', '\u{3098}'),
+  ('\u{3100}', '\u{3104}'), ('\u{3130}', '\u{3130}'),
+  ('\u{318f}', '\u{318f}'), ('\u{31bb}', '\u{31bf}'),
+  ('\u{31e4}', '\u{31ef}'), ('\u{321f}', '\u{321f}'),
+  ('\u{4db6}', '\u{4dbf}'), ('\u{9ff0}', '\u{9fff}'),
+  ('\u{a48d}', '\u{a48f}'), ('\u{a4c7}', '\u{a4cf}'),
+  ('\u{a62c}', '\u{a63f}'), ('\u{a6f8}', '\u{a6ff}'),
+  ('\u{a7c0}', '\u{a7c1}'), ('\u{a7c7}', '\u{a7f6}'),
+  ('\u{a82c}', '\u{a82f}'), ('\u{a83a}', '\u{a83f}'),
+  ('\u{a878}', '\u{a87f}'), ('\u{a8c6}', '\u{a8cd}'),
+  ('\u{a8da}', '\u{a8df}'), ('\u{a954}', '\u{a95e}'),
+  ('\u{a97d}', '\u{a97f}'), ('\u{a9ce}', '\u{a9ce}'),
+  ('\u{a9da}', '\u{a9dd}'), ('\u{a9ff}', '\u{a9ff}'),
+  ('\u{aa37}', '\u{aa3f}'), ('\u{aa4e}', '\u{aa4f}'),
+  ('\u{aa5a}', '\u{aa5b}'), ('\u{aac3}', '\u{aada}'),
+  ('\u{aaf7}', '\u{ab00}'), ('\u{ab07}', '\u{ab08}'),
+  ('\u{ab0f}', '\u{ab10}'), ('\u{ab17}', '\u{ab1f}'),
+  ('\u{ab27}', '\u{ab27}'), ('\u{ab2f}', '\u{ab2f}'),
+  ('\u{ab68}', '\u{ab6f}'), ('\u{abee}', '\u{abef}'),
+  ('\u{abfa}', '\u{abff}'), ('\u{d7a4}', '\u{d7af}'),
+  ('\u{d7c7}', '\u{d7ca}'), ('\u{d7fc}', '\u{d7ff}'),
+  ('\u{fa6e}', '\u{fa6f}'), ('\u{fada}', '\u{faff}'),
+  ('\u{fb07}', '\u{fb12}'), ('\u{fb18}', '\u{fb1c}'),
+  ('\u{fb37}', '\u{fb37}'), ('\u{fb3d}', '\u{fb3d}'),
+  ('\u{fb3f}', '\u{fb3f}'), ('\u{fb42}', '\u{fb42}'),
+  ('\u{fb45}', '\u{fb45}'), ('\u{fbc2}', '\u{fbd2}'),
+  ('\u{fd40}', '\u{fd4f}'), ('\u{fd90}', '\u{fd91}'),
+  ('\u{fdc8}', '\u{fdef}'), ('\u{fdfe}', '\u{fdff}'),
+  ('\u{fe1a}', '\u{fe1f}'), ('\u{fe53}', '\u{fe53}'),
+  ('\u{fe67}', '\u{fe67}'), ('\u{fe6c}', '\u{fe6f}'),
+  ('\u{fe75}', '\u{fe75}'), ('\u{fefd}', '\u{fefe}'),
+  ('\u{ff00}', '\u{ff00}'), ('\u{ffbf}', '\u{ffc1}'),
+  ('\u{ffc8}', '\u{ffc9}'), ('\u{ffd0}', '\u{ffd1}'),
+  ('\u{ffd8}', '\u{ffd9}'), ('\u{ffdd}', '\u{ffdf}'),
+  ('\u{ffe7}', '\u{ffe7}'), ('\u{ffef}', '\u{fff8}'),
+  ('\u{fffe}', '\u{ffff}'), ('\u{1000c}', '\u{1000c}'),
+  ('\u{10027}', '\u{10027}'), ('\u{1003b}', '\u{1003b}'),
+  ('\u{1003e}', '\u{1003e}'), ('\u{1004e}', '\u{1004f}'),
+  ('\u{1005e}', '\u{1007f}'), ('\u{100fb}', '\u{100ff}'),
+  ('\u{10103}', '\u{10106}'), ('\u{10134}', '\u{10136}'),
+  ('\u{1018f}', '\u{1018f}'), ('\u{1019c}', '\u{1019f}'),
+  ('\u{101a1}', '\u{101cf}'), ('\u{101fe}', '\u{1027f}'),
+  ('\u{1029d}', '\u{1029f}'), ('\u{102d1}', '\u{102df}'),
+  ('\u{102fc}', '\u{102ff}'), ('\u{10324}', '\u{1032c}'),
+  ('\u{1034b}', '\u{1034f}'), ('\u{1037b}', '\u{1037f}'),
+  ('\u{1039e}', '\u{1039e}'), ('\u{103c4}', '\u{103c7}'),
+  ('\u{103d6}', '\u{103ff}'), ('\u{1049e}', '\u{1049f}'),
+  ('\u{104aa}', '\u{104af}'), ('\u{104d4}', '\u{104d7}'),
+  ('\u{104fc}', '\u{104ff}'), ('\u{10528}', '\u{1052f}'),
+  ('\u{10564}', '\u{1056e}'), ('\u{10570}', '\u{105ff}'),
+  ('\u{10737}', '\u{1073f}'), ('\u{10756}', '\u{1075f}'),
+  ('\u{10768}', '\u{107ff}'), ('\u{10806}', '\u{10807}'),
+  ('\u{10809}', '\u{10809}'), ('\u{10836}', '\u{10836}'),
+  ('\u{10839}', '\u{1083b}'), ('\u{1083d}', '\u{1083e}'),
+  ('\u{10856}', '\u{10856}'), ('\u{1089f}', '\u{108a6}'),
+  ('\u{108b0}', '\u{108df}'), ('\u{108f3}', '\u{108f3}'),
+  ('\u{108f6}', '\u{108fa}'), ('\u{1091c}', '\u{1091e}'),
+  ('\u{1093a}', '\u{1093e}'), ('\u{10940}', '\u{1097f}'),
+  ('\u{109b8}', '\u{109bb}'), ('\u{109d0}', '\u{109d1}'),
+  ('\u{10a04}', '\u{10a04}'), ('\u{10a07}', '\u{10a0b}'),
+  ('\u{10a14}', '\u{10a14}'), ('\u{10a18}', '\u{10a18}'),
+  ('\u{10a36}', '\u{10a37}'), ('\u{10a3b}', '\u{10a3e}'),
+  ('\u{10a49}', '\u{10a4f}'), ('\u{10a59}', '\u{10a5f}'),
+  ('\u{10aa0}', '\u{10abf}'), ('\u{10ae7}', '\u{10aea}'),
+  ('\u{10af7}', '\u{10aff}'), ('\u{10b36}', '\u{10b38}'),
+  ('\u{10b56}', '\u{10b57}'), ('\u{10b73}', '\u{10b77}'),
+  ('\u{10b92}', '\u{10b98}'), ('\u{10b9d}', '\u{10ba8}'),
+  ('\u{10bb0}', '\u{10bff}'), ('\u{10c49}', '\u{10c7f}'),
+  ('\u{10cb3}', '\u{10cbf}'), ('\u{10cf3}', '\u{10cf9}'),
+  ('\u{10d28}', '\u{10d2f}'), ('\u{10d3a}', '\u{10e5f}'),
+  ('\u{10e7f}', '\u{10eff}'), ('\u{10f28}', '\u{10f2f}'),
+  ('\u{10f5a}', '\u{10fdf}'), ('\u{10ff7}', '\u{10fff}'),
+  ('\u{1104e}', '\u{11051}'), ('\u{11070}', '\u{1107e}'),
+  ('\u{110c2}', '\u{110cc}'), ('\u{110ce}', '\u{110cf}'),
+  ('\u{110e9}', '\u{110ef}'), ('\u{110fa}', '\u{110ff}'),
+  ('\u{11135}', '\u{11135}'), ('\u{11147}', '\u{1114f}'),
+  ('\u{11177}', '\u{1117f}'), ('\u{111ce}', '\u{111cf}'),
+  ('\u{111e0}', '\u{111e0}'), ('\u{111f5}', '\u{111ff}'),
+  ('\u{11212}', '\u{11212}'), ('\u{1123f}', '\u{1127f}'),
+  ('\u{11287}', '\u{11287}'), ('\u{11289}', '\u{11289}'),
+  ('\u{1128e}', '\u{1128e}'), ('\u{1129e}', '\u{1129e}'),
+  ('\u{112aa}', '\u{112af}'), ('\u{112eb}', '\u{112ef}'),
+  ('\u{112fa}', '\u{112ff}'), ('\u{11304}', '\u{11304}'),
+  ('\u{1130d}', '\u{1130e}'), ('\u{11311}', '\u{11312}'),
+  ('\u{11329}', '\u{11329}'), ('\u{11331}', '\u{11331}'),
+  ('\u{11334}', '\u{11334}'), ('\u{1133a}', '\u{1133a}'),
+  ('\u{11345}', '\u{11346}'), ('\u{11349}', '\u{1134a}'),
+  ('\u{1134e}', '\u{1134f}'), ('\u{11351}', '\u{11356}'),
+  ('\u{11358}', '\u{1135c}'), ('\u{11364}', '\u{11365}'),
+  ('\u{1136d}', '\u{1136f}'), ('\u{11375}', '\u{113ff}'),
+  ('\u{1145a}', '\u{1145a}'), ('\u{1145c}', '\u{1145c}'),
+  ('\u{11460}', '\u{1147f}'), ('\u{114c8}', '\u{114cf}'),
+  ('\u{114da}', '\u{1157f}'), ('\u{115b6}', '\u{115b7}'),
+  ('\u{115de}', '\u{115ff}'), ('\u{11645}', '\u{1164f}'),
+  ('\u{1165a}', '\u{1165f}'), ('\u{1166d}', '\u{1167f}'),
+  ('\u{116b9}', '\u{116bf}'), ('\u{116ca}', '\u{116ff}'),
+  ('\u{1171b}', '\u{1171c}'), ('\u{1172c}', '\u{1172f}'),
+  ('\u{11740}', '\u{117ff}'), ('\u{1183c}', '\u{1189f}'),
+  ('\u{118f3}', '\u{118fe}'), ('\u{11900}', '\u{1199f}'),
+  ('\u{119a8}', '\u{119a9}'), ('\u{119d8}', '\u{119d9}'),
+  ('\u{119e5}', '\u{119ff}'), ('\u{11a48}', '\u{11a4f}'),
+  ('\u{11aa3}', '\u{11abf}'), ('\u{11af9}', '\u{11bff}'),
+  ('\u{11c09}', '\u{11c09}'), ('\u{11c37}', '\u{11c37}'),
+  ('\u{11c46}', '\u{11c4f}'), ('\u{11c6d}', '\u{11c6f}'),
+  ('\u{11c90}', '\u{11c91}'), ('\u{11ca8}', '\u{11ca8}'),
+  ('\u{11cb7}', '\u{11cff}'), ('\u{11d07}', '\u{11d07}'),
+  ('\u{11d0a}', '\u{11d0a}'), ('\u{11d37}', '\u{11d39}'),
+  ('\u{11d3b}', '\u{11d3b}'), ('\u{11d3e}', '\u{11d3e}'),
+  ('\u{11d48}', '\u{11d4f}'), ('\u{11d5a}', '\u{11d5f}'),
+  ('\u{11d66}', '\u{11d66}'), ('\u{11d69}', '\u{11d69}'),
+  ('\u{11d8f}', '\u{11d8f}'), ('\u{11d92}', '\u{11d92}'),
+  ('\u{11d99}', '\u{11d9f}'), ('\u{11daa}', '\u{11edf}'),
+  ('\u{11ef9}', '\u{11fbf}'), ('\u{11ff2}', '\u{11ffe}'),
+  ('\u{1239a}', '\u{123ff}'), ('\u{1246f}', '\u{1246f}'),
+  ('\u{12475}', '\u{1247f}'), ('\u{12544}', '\u{12fff}'),
+  ('\u{1342f}', '\u{1342f}'), ('\u{13439}', '\u{143ff}'),
+  ('\u{14647}', '\u{167ff}'), ('\u{16a39}', '\u{16a3f}'),
+  ('\u{16a5f}', '\u{16a5f}'), ('\u{16a6a}', '\u{16a6d}'),
+  ('\u{16a70}', '\u{16acf}'), ('\u{16aee}', '\u{16aef}'),
+  ('\u{16af6}', '\u{16aff}'), ('\u{16b46}', '\u{16b4f}'),
+  ('\u{16b5a}', '\u{16b5a}'), ('\u{16b62}', '\u{16b62}'),
+  ('\u{16b78}', '\u{16b7c}'), ('\u{16b90}', '\u{16e3f}'),
+  ('\u{16e9b}', '\u{16eff}'), ('\u{16f4b}', '\u{16f4e}'),
+  ('\u{16f88}', '\u{16f8e}'), ('\u{16fa0}', '\u{16fdf}'),
+  ('\u{16fe4}', '\u{16fff}'), ('\u{187f8}', '\u{187ff}'),
+  ('\u{18af3}', '\u{1afff}'), ('\u{1b11f}', '\u{1b14f}'),
+  ('\u{1b153}', '\u{1b163}'), ('\u{1b168}', '\u{1b16f}'),
+  ('\u{1b2fc}', '\u{1bbff}'), ('\u{1bc6b}', '\u{1bc6f}'),
+  ('\u{1bc7d}', '\u{1bc7f}'), ('\u{1bc89}', '\u{1bc8f}'),
+  ('\u{1bc9a}', '\u{1bc9b}'), ('\u{1bca4}', '\u{1cfff}'),
+  ('\u{1d0f6}', '\u{1d0ff}'), ('\u{1d127}', '\u{1d128}'),
+  ('\u{1d1e9}', '\u{1d1ff}'), ('\u{1d246}', '\u{1d2df}'),
+  ('\u{1d2f4}', '\u{1d2ff}'), ('\u{1d357}', '\u{1d35f}'),
+  ('\u{1d379}', '\u{1d3ff}'), ('\u{1d455}', '\u{1d455}'),
+  ('\u{1d49d}', '\u{1d49d}'), ('\u{1d4a0}', '\u{1d4a1}'),
+  ('\u{1d4a3}', '\u{1d4a4}'), ('\u{1d4a7}', '\u{1d4a8}'),
+  ('\u{1d4ad}', '\u{1d4ad}'), ('\u{1d4ba}', '\u{1d4ba}'),
+  ('\u{1d4bc}', '\u{1d4bc}'), ('\u{1d4c4}', '\u{1d4c4}'),
+  ('\u{1d506}', '\u{1d506}'), ('\u{1d50b}', '\u{1d50c}'),
+  ('\u{1d515}', '\u{1d515}'), ('\u{1d51d}', '\u{1d51d}'),
+  ('\u{1d53a}', '\u{1d53a}'), ('\u{1d53f}', '\u{1d53f}'),
+  ('\u{1d545}', '\u{1d545}'), ('\u{1d547}', '\u{1d549}'),
+  ('\u{1d551}', '\u{1d551}'), ('\u{1d6a6}', '\u{1d6a7}'),
+  ('\u{1d7cc}', '\u{1d7cd}'), ('\u{1da8c}', '\u{1da9a}'),
+  ('\u{1daa0}', '\u{1daa0}'), ('\u{1dab0}', '\u{1dfff}'),
+  ('\u{1e007}', '\u{1e007}'), ('\u{1e019}', '\u{1e01a}'),
+  ('\u{1e022}', '\u{1e022}'), ('\u{1e025}', '\u{1e025}'),
+  ('\u{1e02b}', '\u{1e0ff}'), ('\u{1e12d}', '\u{1e12f}'),
+  ('\u{1e13e}', '\u{1e13f}'), ('\u{1e14a}', '\u{1e14d}'),
+  ('\u{1e150}', '\u{1e2bf}'), ('\u{1e2fa}', '\u{1e2fe}'),
+  ('\u{1e300}', '\u{1e7ff}'), ('\u{1e8c5}', '\u{1e8c6}'),
+  ('\u{1e8d7}', '\u{1e8ff}'), ('\u{1e94c}', '\u{1e94f}'),
+  ('\u{1e95a}', '\u{1e95d}'), ('\u{1e960}', '\u{1ec70}'),
+  ('\u{1ecb5}', '\u{1ed00}'), ('\u{1ed3e}', '\u{1edff}'),
+  ('\u{1ee04}', '\u{1ee04}'), ('\u{1ee20}', '\u{1ee20}'),
+  ('\u{1ee23}', '\u{1ee23}'), ('\u{1ee25}', '\u{1ee26}'),
+  ('\u{1ee28}', '\u{1ee28}'), ('\u{1ee33}', '\u{1ee33}'),
+  ('\u{1ee38}', '\u{1ee38}'), ('\u{1ee3a}', '\u{1ee3a}'),
+  ('\u{1ee3c}', '\u{1ee41}'), ('\u{1ee43}', '\u{1ee46}'),
+  ('\u{1ee48}', '\u{1ee48}'), ('\u{1ee4a}', '\u{1ee4a}'),
+  ('\u{1ee4c}', '\u{1ee4c}'), ('\u{1ee50}', '\u{1ee50}'),
+  ('\u{1ee53}', '\u{1ee53}'), ('\u{1ee55}', '\u{1ee56}'),
+  ('\u{1ee58}', '\u{1ee58}'), ('\u{1ee5a}', '\u{1ee5a}'),
+  ('\u{1ee5c}', '\u{1ee5c}'), ('\u{1ee5e}', '\u{1ee5e}'),
+  ('\u{1ee60}', '\u{1ee60}'), ('\u{1ee63}', '\u{1ee63}'),
+  ('\u{1ee65}', '\u{1ee66}'), ('\u{1ee6b}', '\u{1ee6b}'),
+  ('\u{1ee73}', '\u{1ee73}'), ('\u{1ee78}', '\u{1ee78}'),
+  ('\u{1ee7d}', '\u{1ee7d}'), ('\u{1ee7f}', '\u{1ee7f}'),
+  ('\u{1ee8a}', '\u{1ee8a}'), ('\u{1ee9c}', '\u{1eea0}'),
+  ('\u{1eea4}', '\u{1eea4}'), ('\u{1eeaa}', '\u{1eeaa}'),
+  ('\u{1eebc}', '\u{1eeef}'), ('\u{1eef2}', '\u{1efff}'),
+  ('\u{1f02c}', '\u{1f02f}'), ('\u{1f094}', '\u{1f09f}'),
+  ('\u{1f0af}', '\u{1f0b0}'), ('\u{1f0c0}', '\u{1f0c0}'),
+  ('\u{1f0d0}', '\u{1f0d0}'), ('\u{1f0f6}', '\u{1f0ff}'),
+  ('\u{1f10d}', '\u{1f10f}'), ('\u{1f16d}', '\u{1f16f}'),
+  ('\u{1f1ad}', '\u{1f1e5}'), ('\u{1f203}', '\u{1f20f}'),
+  ('\u{1f23c}', '\u{1f23f}'), ('\u{1f249}', '\u{1f24f}'),
+  ('\u{1f252}', '\u{1f25f}'), ('\u{1f266}', '\u{1f2ff}'),
+  ('\u{1f6d6}', '\u{1f6df}'), ('\u{1f6ed}', '\u{1f6ef}'),
+  ('\u{1f6fb}', '\u{1f6ff}'), ('\u{1f774}', '\u{1f77f}'),
+  ('\u{1f7d9}', '\u{1f7df}'), ('\u{1f7ec}', '\u{1f7ff}'),
+  ('\u{1f80c}', '\u{1f80f}'), ('\u{1f848}', '\u{1f84f}'),
+  ('\u{1f85a}', '\u{1f85f}'), ('\u{1f888}', '\u{1f88f}'),
+  ('\u{1f8ae}', '\u{1f8ff}'), ('\u{1f90c}', '\u{1f90c}'),
+  ('\u{1f972}', '\u{1f972}'), ('\u{1f977}', '\u{1f979}'),
+  ('\u{1f9a3}', '\u{1f9a4}'), ('\u{1f9ab}', '\u{1f9ad}'),
+  ('\u{1f9cb}', '\u{1f9cc}'), ('\u{1fa54}', '\u{1fa5f}'),
+  ('\u{1fa6e}', '\u{1fa6f}'), ('\u{1fa74}', '\u{1fa77}'),
+  ('\u{1fa7b}', '\u{1fa7f}'), ('\u{1fa83}', '\u{1fa8f}'),
+  ('\u{1fa96}', '\u{1ffff}'), ('\u{2a6d7}', '\u{2a6ff}'),
+  ('\u{2b735}', '\u{2b73f}'), ('\u{2b81e}', '\u{2b81f}'),
+  ('\u{2cea2}', '\u{2ceaf}'), ('\u{2ebe1}', '\u{2f7ff}'),
+  ('\u{2fa1e}', '\u{e0000}'), ('\u{e0002}', '\u{e001f}'),
+  ('\u{e0080}', '\u{e00ff}'), ('\u{e01f0}', '\u{effff}'),
+  ('\u{ffffe}', '\u{fffff}'), ('\u{10fffe}', '\u{10ffff}'),
+];
+
+pub const UPPERCASE_LETTER: &'static [(char, char)] = &[
+  ('A', 'Z'), ('À', 'Ö'), ('Ø', 'Þ'), ('Ā', 'Ā'), ('Ă', 'Ă'),
+  ('Ą', 'Ą'), ('Ć', 'Ć'), ('Ĉ', 'Ĉ'), ('Ċ', 'Ċ'), ('Č', 'Č'),
+  ('Ď', 'Ď'), ('Đ', 'Đ'), ('Ē', 'Ē'), ('Ĕ', 'Ĕ'), ('Ė', 'Ė'),
+  ('Ę', 'Ę'), ('Ě', 'Ě'), ('Ĝ', 'Ĝ'), ('Ğ', 'Ğ'), ('Ġ', 'Ġ'),
+  ('Ģ', 'Ģ'), ('Ĥ', 'Ĥ'), ('Ħ', 'Ħ'), ('Ĩ', 'Ĩ'), ('Ī', 'Ī'),
+  ('Ĭ', 'Ĭ'), ('Į', 'Į'), ('İ', 'İ'), ('IJ', 'IJ'), ('Ĵ', 'Ĵ'),
+  ('Ķ', 'Ķ'), ('Ĺ', 'Ĺ'), ('Ļ', 'Ļ'), ('Ľ', 'Ľ'), ('Ŀ', 'Ŀ'),
+  ('Ł', 'Ł'), ('Ń', 'Ń'), ('Ņ', 'Ņ'), ('Ň', 'Ň'), ('Ŋ', 'Ŋ'),
+  ('Ō', 'Ō'), ('Ŏ', 'Ŏ'), ('Ő', 'Ő'), ('Œ', 'Œ'), ('Ŕ', 'Ŕ'),
+  ('Ŗ', 'Ŗ'), ('Ř', 'Ř'), ('Ś', 'Ś'), ('Ŝ', 'Ŝ'), ('Ş', 'Ş'),
+  ('Š', 'Š'), ('Ţ', 'Ţ'), ('Ť', 'Ť'), ('Ŧ', 'Ŧ'), ('Ũ', 'Ũ'),
+  ('Ū', 'Ū'), ('Ŭ', 'Ŭ'), ('Ů', 'Ů'), ('Ű', 'Ű'), ('Ų', 'Ų'),
+  ('Ŵ', 'Ŵ'), ('Ŷ', 'Ŷ'), ('Ÿ', 'Ź'), ('Ż', 'Ż'), ('Ž', 'Ž'),
+  ('Ɓ', 'Ƃ'), ('Ƅ', 'Ƅ'), ('Ɔ', 'Ƈ'), ('Ɖ', 'Ƌ'), ('Ǝ', 'Ƒ'),
+  ('Ɠ', 'Ɣ'), ('Ɩ', 'Ƙ'), ('Ɯ', 'Ɲ'), ('Ɵ', 'Ơ'), ('Ƣ', 'Ƣ'),
+  ('Ƥ', 'Ƥ'), ('Ʀ', 'Ƨ'), ('Ʃ', 'Ʃ'), ('Ƭ', 'Ƭ'), ('Ʈ', 'Ư'),
+  ('Ʊ', 'Ƴ'), ('Ƶ', 'Ƶ'), ('Ʒ', 'Ƹ'), ('Ƽ', 'Ƽ'), ('DŽ', 'DŽ'),
+  ('LJ', 'LJ'), ('NJ', 'NJ'), ('Ǎ', 'Ǎ'), ('Ǐ', 'Ǐ'), ('Ǒ', 'Ǒ'),
+  ('Ǔ', 'Ǔ'), ('Ǖ', 'Ǖ'), ('Ǘ', 'Ǘ'), ('Ǚ', 'Ǚ'), ('Ǜ', 'Ǜ'),
+  ('Ǟ', 'Ǟ'), ('Ǡ', 'Ǡ'), ('Ǣ', 'Ǣ'), ('Ǥ', 'Ǥ'), ('Ǧ', 'Ǧ'),
+  ('Ǩ', 'Ǩ'), ('Ǫ', 'Ǫ'), ('Ǭ', 'Ǭ'), ('Ǯ', 'Ǯ'), ('DZ', 'DZ'),
+  ('Ǵ', 'Ǵ'), ('Ƕ', 'Ǹ'), ('Ǻ', 'Ǻ'), ('Ǽ', 'Ǽ'), ('Ǿ', 'Ǿ'),
+  ('Ȁ', 'Ȁ'), ('Ȃ', 'Ȃ'), ('Ȅ', 'Ȅ'), ('Ȇ', 'Ȇ'), ('Ȉ', 'Ȉ'),
+  ('Ȋ', 'Ȋ'), ('Ȍ', 'Ȍ'), ('Ȏ', 'Ȏ'), ('Ȑ', 'Ȑ'), ('Ȓ', 'Ȓ'),
+  ('Ȕ', 'Ȕ'), ('Ȗ', 'Ȗ'), ('Ș', 'Ș'), ('Ț', 'Ț'), ('Ȝ', 'Ȝ'),
+  ('Ȟ', 'Ȟ'), ('Ƞ', 'Ƞ'), ('Ȣ', 'Ȣ'), ('Ȥ', 'Ȥ'), ('Ȧ', 'Ȧ'),
+  ('Ȩ', 'Ȩ'), ('Ȫ', 'Ȫ'), ('Ȭ', 'Ȭ'), ('Ȯ', 'Ȯ'), ('Ȱ', 'Ȱ'),
+  ('Ȳ', 'Ȳ'), ('Ⱥ', 'Ȼ'), ('Ƚ', 'Ⱦ'), ('Ɂ', 'Ɂ'), ('Ƀ', 'Ɇ'),
+  ('Ɉ', 'Ɉ'), ('Ɋ', 'Ɋ'), ('Ɍ', 'Ɍ'), ('Ɏ', 'Ɏ'), ('Ͱ', 'Ͱ'),
+  ('Ͳ', 'Ͳ'), ('Ͷ', 'Ͷ'), ('Ϳ', 'Ϳ'), ('Ά', 'Ά'), ('Έ', 'Ί'),
+  ('Ό', 'Ό'), ('Ύ', 'Ώ'), ('Α', 'Ρ'), ('Σ', 'Ϋ'), ('Ϗ', 'Ϗ'),
+  ('ϒ', 'ϔ'), ('Ϙ', 'Ϙ'), ('Ϛ', 'Ϛ'), ('Ϝ', 'Ϝ'), ('Ϟ', 'Ϟ'),
+  ('Ϡ', 'Ϡ'), ('Ϣ', 'Ϣ'), ('Ϥ', 'Ϥ'), ('Ϧ', 'Ϧ'), ('Ϩ', 'Ϩ'),
+  ('Ϫ', 'Ϫ'), ('Ϭ', 'Ϭ'), ('Ϯ', 'Ϯ'), ('ϴ', 'ϴ'), ('Ϸ', 'Ϸ'),
+  ('Ϲ', 'Ϻ'), ('Ͻ', 'Я'), ('Ѡ', 'Ѡ'), ('Ѣ', 'Ѣ'), ('Ѥ', 'Ѥ'),
+  ('Ѧ', 'Ѧ'), ('Ѩ', 'Ѩ'), ('Ѫ', 'Ѫ'), ('Ѭ', 'Ѭ'), ('Ѯ', 'Ѯ'),
+  ('Ѱ', 'Ѱ'), ('Ѳ', 'Ѳ'), ('Ѵ', 'Ѵ'), ('Ѷ', 'Ѷ'), ('Ѹ', 'Ѹ'),
+  ('Ѻ', 'Ѻ'), ('Ѽ', 'Ѽ'), ('Ѿ', 'Ѿ'), ('Ҁ', 'Ҁ'), ('Ҋ', 'Ҋ'),
+  ('Ҍ', 'Ҍ'), ('Ҏ', 'Ҏ'), ('Ґ', 'Ґ'), ('Ғ', 'Ғ'), ('Ҕ', 'Ҕ'),
+  ('Җ', 'Җ'), ('Ҙ', 'Ҙ'), ('Қ', 'Қ'), ('Ҝ', 'Ҝ'), ('Ҟ', 'Ҟ'),
+  ('Ҡ', 'Ҡ'), ('Ң', 'Ң'), ('Ҥ', 'Ҥ'), ('Ҧ', 'Ҧ'), ('Ҩ', 'Ҩ'),
+  ('Ҫ', 'Ҫ'), ('Ҭ', 'Ҭ'), ('Ү', 'Ү'), ('Ұ', 'Ұ'), ('Ҳ', 'Ҳ'),
+  ('Ҵ', 'Ҵ'), ('Ҷ', 'Ҷ'), ('Ҹ', 'Ҹ'), ('Һ', 'Һ'), ('Ҽ', 'Ҽ'),
+  ('Ҿ', 'Ҿ'), ('Ӏ', 'Ӂ'), ('Ӄ', 'Ӄ'), ('Ӆ', 'Ӆ'), ('Ӈ', 'Ӈ'),
+  ('Ӊ', 'Ӊ'), ('Ӌ', 'Ӌ'), ('Ӎ', 'Ӎ'), ('Ӑ', 'Ӑ'), ('Ӓ', 'Ӓ'),
+  ('Ӕ', 'Ӕ'), ('Ӗ', 'Ӗ'), ('Ә', 'Ә'), ('Ӛ', 'Ӛ'), ('Ӝ', 'Ӝ'),
+  ('Ӟ', 'Ӟ'), ('Ӡ', 'Ӡ'), ('Ӣ', 'Ӣ'), ('Ӥ', 'Ӥ'), ('Ӧ', 'Ӧ'),
+  ('Ө', 'Ө'), ('Ӫ', 'Ӫ'), ('Ӭ', 'Ӭ'), ('Ӯ', 'Ӯ'), ('Ӱ', 'Ӱ'),
+  ('Ӳ', 'Ӳ'), ('Ӵ', 'Ӵ'), ('Ӷ', 'Ӷ'), ('Ӹ', 'Ӹ'), ('Ӻ', 'Ӻ'),
+  ('Ӽ', 'Ӽ'), ('Ӿ', 'Ӿ'), ('Ԁ', 'Ԁ'), ('Ԃ', 'Ԃ'), ('Ԅ', 'Ԅ'),
+  ('Ԇ', 'Ԇ'), ('Ԉ', 'Ԉ'), ('Ԋ', 'Ԋ'), ('Ԍ', 'Ԍ'), ('Ԏ', 'Ԏ'),
+  ('Ԑ', 'Ԑ'), ('Ԓ', 'Ԓ'), ('Ԕ', 'Ԕ'), ('Ԗ', 'Ԗ'), ('Ԙ', 'Ԙ'),
+  ('Ԛ', 'Ԛ'), ('Ԝ', 'Ԝ'), ('Ԟ', 'Ԟ'), ('Ԡ', 'Ԡ'), ('Ԣ', 'Ԣ'),
+  ('Ԥ', 'Ԥ'), ('Ԧ', 'Ԧ'), ('Ԩ', 'Ԩ'), ('Ԫ', 'Ԫ'), ('Ԭ', 'Ԭ'),
+  ('Ԯ', 'Ԯ'), ('Ա', 'Ֆ'), ('Ⴀ', 'Ⴥ'), ('Ⴧ', 'Ⴧ'), ('Ⴭ', 'Ⴭ'),
+  ('Ꭰ', 'Ᏽ'), ('Ა', 'Ჺ'), ('Ჽ', 'Ჿ'), ('Ḁ', 'Ḁ'),
+  ('Ḃ', 'Ḃ'), ('Ḅ', 'Ḅ'), ('Ḇ', 'Ḇ'), ('Ḉ', 'Ḉ'),
+  ('Ḋ', 'Ḋ'), ('Ḍ', 'Ḍ'), ('Ḏ', 'Ḏ'), ('Ḑ', 'Ḑ'),
+  ('Ḓ', 'Ḓ'), ('Ḕ', 'Ḕ'), ('Ḗ', 'Ḗ'), ('Ḙ', 'Ḙ'),
+  ('Ḛ', 'Ḛ'), ('Ḝ', 'Ḝ'), ('Ḟ', 'Ḟ'), ('Ḡ', 'Ḡ'),
+  ('Ḣ', 'Ḣ'), ('Ḥ', 'Ḥ'), ('Ḧ', 'Ḧ'), ('Ḩ', 'Ḩ'),
+  ('Ḫ', 'Ḫ'), ('Ḭ', 'Ḭ'), ('Ḯ', 'Ḯ'), ('Ḱ', 'Ḱ'),
+  ('Ḳ', 'Ḳ'), ('Ḵ', 'Ḵ'), ('Ḷ', 'Ḷ'), ('Ḹ', 'Ḹ'),
+  ('Ḻ', 'Ḻ'), ('Ḽ', 'Ḽ'), ('Ḿ', 'Ḿ'), ('Ṁ', 'Ṁ'),
+  ('Ṃ', 'Ṃ'), ('Ṅ', 'Ṅ'), ('Ṇ', 'Ṇ'), ('Ṉ', 'Ṉ'),
+  ('Ṋ', 'Ṋ'), ('Ṍ', 'Ṍ'), ('Ṏ', 'Ṏ'), ('Ṑ', 'Ṑ'),
+  ('Ṓ', 'Ṓ'), ('Ṕ', 'Ṕ'), ('Ṗ', 'Ṗ'), ('Ṙ', 'Ṙ'),
+  ('Ṛ', 'Ṛ'), ('Ṝ', 'Ṝ'), ('Ṟ', 'Ṟ'), ('Ṡ', 'Ṡ'),
+  ('Ṣ', 'Ṣ'), ('Ṥ', 'Ṥ'), ('Ṧ', 'Ṧ'), ('Ṩ', 'Ṩ'),
+  ('Ṫ', 'Ṫ'), ('Ṭ', 'Ṭ'), ('Ṯ', 'Ṯ'), ('Ṱ', 'Ṱ'),
+  ('Ṳ', 'Ṳ'), ('Ṵ', 'Ṵ'), ('Ṷ', 'Ṷ'), ('Ṹ', 'Ṹ'),
+  ('Ṻ', 'Ṻ'), ('Ṽ', 'Ṽ'), ('Ṿ', 'Ṿ'), ('Ẁ', 'Ẁ'),
+  ('Ẃ', 'Ẃ'), ('Ẅ', 'Ẅ'), ('Ẇ', 'Ẇ'), ('Ẉ', 'Ẉ'),
+  ('Ẋ', 'Ẋ'), ('Ẍ', 'Ẍ'), ('Ẏ', 'Ẏ'), ('Ẑ', 'Ẑ'),
+  ('Ẓ', 'Ẓ'), ('Ẕ', 'Ẕ'), ('ẞ', 'ẞ'), ('Ạ', 'Ạ'),
+  ('Ả', 'Ả'), ('Ấ', 'Ấ'), ('Ầ', 'Ầ'), ('Ẩ', 'Ẩ'),
+  ('Ẫ', 'Ẫ'), ('Ậ', 'Ậ'), ('Ắ', 'Ắ'), ('Ằ', 'Ằ'),
+  ('Ẳ', 'Ẳ'), ('Ẵ', 'Ẵ'), ('Ặ', 'Ặ'), ('Ẹ', 'Ẹ'),
+  ('Ẻ', 'Ẻ'), ('Ẽ', 'Ẽ'), ('Ế', 'Ế'), ('Ề', 'Ề'),
+  ('Ể', 'Ể'), ('Ễ', 'Ễ'), ('Ệ', 'Ệ'), ('Ỉ', 'Ỉ'),
+  ('Ị', 'Ị'), ('Ọ', 'Ọ'), ('Ỏ', 'Ỏ'), ('Ố', 'Ố'),
+  ('Ồ', 'Ồ'), ('Ổ', 'Ổ'), ('Ỗ', 'Ỗ'), ('Ộ', 'Ộ'),
+  ('Ớ', 'Ớ'), ('Ờ', 'Ờ'), ('Ở', 'Ở'), ('Ỡ', 'Ỡ'),
+  ('Ợ', 'Ợ'), ('Ụ', 'Ụ'), ('Ủ', 'Ủ'), ('Ứ', 'Ứ'),
+  ('Ừ', 'Ừ'), ('Ử', 'Ử'), ('Ữ', 'Ữ'), ('Ự', 'Ự'),
+  ('Ỳ', 'Ỳ'), ('Ỵ', 'Ỵ'), ('Ỷ', 'Ỷ'), ('Ỹ', 'Ỹ'),
+  ('Ỻ', 'Ỻ'), ('Ỽ', 'Ỽ'), ('Ỿ', 'Ỿ'), ('Ἀ', 'Ἇ'),
+  ('Ἐ', 'Ἕ'), ('Ἠ', 'Ἧ'), ('Ἰ', 'Ἷ'), ('Ὀ', 'Ὅ'),
+  ('Ὑ', 'Ὑ'), ('Ὓ', 'Ὓ'), ('Ὕ', 'Ὕ'), ('Ὗ', 'Ὗ'),
+  ('Ὠ', 'Ὧ'), ('Ᾰ', 'Ά'), ('Ὲ', 'Ή'), ('Ῐ', 'Ί'),
+  ('Ῠ', 'Ῥ'), ('Ὸ', 'Ώ'), ('ℂ', 'ℂ'), ('ℇ', 'ℇ'),
+  ('ℋ', 'ℍ'), ('ℐ', 'ℒ'), ('ℕ', 'ℕ'), ('ℙ', 'ℝ'),
+  ('ℤ', 'ℤ'), ('Ω', 'Ω'), ('ℨ', 'ℨ'), ('K', 'ℭ'),
+  ('ℰ', 'ℳ'), ('ℾ', 'ℿ'), ('ⅅ', 'ⅅ'), ('Ↄ', 'Ↄ'),
+  ('Ⰰ', 'Ⱞ'), ('Ⱡ', 'Ⱡ'), ('Ɫ', 'Ɽ'), ('Ⱨ', 'Ⱨ'),
+  ('Ⱪ', 'Ⱪ'), ('Ⱬ', 'Ⱬ'), ('Ɑ', 'Ɒ'), ('Ⱳ', 'Ⱳ'),
+  ('Ⱶ', 'Ⱶ'), ('Ȿ', 'Ⲁ'), ('Ⲃ', 'Ⲃ'), ('Ⲅ', 'Ⲅ'),
+  ('Ⲇ', 'Ⲇ'), ('Ⲉ', 'Ⲉ'), ('Ⲋ', 'Ⲋ'), ('Ⲍ', 'Ⲍ'),
+  ('Ⲏ', 'Ⲏ'), ('Ⲑ', 'Ⲑ'), ('Ⲓ', 'Ⲓ'), ('Ⲕ', 'Ⲕ'),
+  ('Ⲗ', 'Ⲗ'), ('Ⲙ', 'Ⲙ'), ('Ⲛ', 'Ⲛ'), ('Ⲝ', 'Ⲝ'),
+  ('Ⲟ', 'Ⲟ'), ('Ⲡ', 'Ⲡ'), ('Ⲣ', 'Ⲣ'), ('Ⲥ', 'Ⲥ'),
+  ('Ⲧ', 'Ⲧ'), ('Ⲩ', 'Ⲩ'), ('Ⲫ', 'Ⲫ'), ('Ⲭ', 'Ⲭ'),
+  ('Ⲯ', 'Ⲯ'), ('Ⲱ', 'Ⲱ'), ('Ⲳ', 'Ⲳ'), ('Ⲵ', 'Ⲵ'),
+  ('Ⲷ', 'Ⲷ'), ('Ⲹ', 'Ⲹ'), ('Ⲻ', 'Ⲻ'), ('Ⲽ', 'Ⲽ'),
+  ('Ⲿ', 'Ⲿ'), ('Ⳁ', 'Ⳁ'), ('Ⳃ', 'Ⳃ'), ('Ⳅ', 'Ⳅ'),
+  ('Ⳇ', 'Ⳇ'), ('Ⳉ', 'Ⳉ'), ('Ⳋ', 'Ⳋ'), ('Ⳍ', 'Ⳍ'),
+  ('Ⳏ', 'Ⳏ'), ('Ⳑ', 'Ⳑ'), ('Ⳓ', 'Ⳓ'), ('Ⳕ', 'Ⳕ'),
+  ('Ⳗ', 'Ⳗ'), ('Ⳙ', 'Ⳙ'), ('Ⳛ', 'Ⳛ'), ('Ⳝ', 'Ⳝ'),
+  ('Ⳟ', 'Ⳟ'), ('Ⳡ', 'Ⳡ'), ('Ⳣ', 'Ⳣ'), ('Ⳬ', 'Ⳬ'),
+  ('Ⳮ', 'Ⳮ'), ('Ⳳ', 'Ⳳ'), ('Ꙁ', 'Ꙁ'), ('Ꙃ', 'Ꙃ'),
+  ('Ꙅ', 'Ꙅ'), ('Ꙇ', 'Ꙇ'), ('Ꙉ', 'Ꙉ'), ('Ꙋ', 'Ꙋ'),
+  ('Ꙍ', 'Ꙍ'), ('Ꙏ', 'Ꙏ'), ('Ꙑ', 'Ꙑ'), ('Ꙓ', 'Ꙓ'),
+  ('Ꙕ', 'Ꙕ'), ('Ꙗ', 'Ꙗ'), ('Ꙙ', 'Ꙙ'), ('Ꙛ', 'Ꙛ'),
+  ('Ꙝ', 'Ꙝ'), ('Ꙟ', 'Ꙟ'), ('Ꙡ', 'Ꙡ'), ('Ꙣ', 'Ꙣ'),
+  ('Ꙥ', 'Ꙥ'), ('Ꙧ', 'Ꙧ'), ('Ꙩ', 'Ꙩ'), ('Ꙫ', 'Ꙫ'),
+  ('Ꙭ', 'Ꙭ'), ('Ꚁ', 'Ꚁ'), ('Ꚃ', 'Ꚃ'), ('Ꚅ', 'Ꚅ'),
+  ('Ꚇ', 'Ꚇ'), ('Ꚉ', 'Ꚉ'), ('Ꚋ', 'Ꚋ'), ('Ꚍ', 'Ꚍ'),
+  ('Ꚏ', 'Ꚏ'), ('Ꚑ', 'Ꚑ'), ('Ꚓ', 'Ꚓ'), ('Ꚕ', 'Ꚕ'),
+  ('Ꚗ', 'Ꚗ'), ('Ꚙ', 'Ꚙ'), ('Ꚛ', 'Ꚛ'), ('Ꜣ', 'Ꜣ'),
+  ('Ꜥ', 'Ꜥ'), ('Ꜧ', 'Ꜧ'), ('Ꜩ', 'Ꜩ'), ('Ꜫ', 'Ꜫ'),
+  ('Ꜭ', 'Ꜭ'), ('Ꜯ', 'Ꜯ'), ('Ꜳ', 'Ꜳ'), ('Ꜵ', 'Ꜵ'),
+  ('Ꜷ', 'Ꜷ'), ('Ꜹ', 'Ꜹ'), ('Ꜻ', 'Ꜻ'), ('Ꜽ', 'Ꜽ'),
+  ('Ꜿ', 'Ꜿ'), ('Ꝁ', 'Ꝁ'), ('Ꝃ', 'Ꝃ'), ('Ꝅ', 'Ꝅ'),
+  ('Ꝇ', 'Ꝇ'), ('Ꝉ', 'Ꝉ'), ('Ꝋ', 'Ꝋ'), ('Ꝍ', 'Ꝍ'),
+  ('Ꝏ', 'Ꝏ'), ('Ꝑ', 'Ꝑ'), ('Ꝓ', 'Ꝓ'), ('Ꝕ', 'Ꝕ'),
+  ('Ꝗ', 'Ꝗ'), ('Ꝙ', 'Ꝙ'), ('Ꝛ', 'Ꝛ'), ('Ꝝ', 'Ꝝ'),
+  ('Ꝟ', 'Ꝟ'), ('Ꝡ', 'Ꝡ'), ('Ꝣ', 'Ꝣ'), ('Ꝥ', 'Ꝥ'),
+  ('Ꝧ', 'Ꝧ'), ('Ꝩ', 'Ꝩ'), ('Ꝫ', 'Ꝫ'), ('Ꝭ', 'Ꝭ'),
+  ('Ꝯ', 'Ꝯ'), ('Ꝺ', 'Ꝺ'), ('Ꝼ', 'Ꝼ'), ('Ᵹ', 'Ꝿ'),
+  ('Ꞁ', 'Ꞁ'), ('Ꞃ', 'Ꞃ'), ('Ꞅ', 'Ꞅ'), ('Ꞇ', 'Ꞇ'),
+  ('Ꞌ', 'Ꞌ'), ('Ɥ', 'Ɥ'), ('Ꞑ', 'Ꞑ'), ('Ꞓ', 'Ꞓ'),
+  ('Ꞗ', 'Ꞗ'), ('Ꞙ', 'Ꞙ'), ('Ꞛ', 'Ꞛ'), ('Ꞝ', 'Ꞝ'),
+  ('Ꞟ', 'Ꞟ'), ('Ꞡ', 'Ꞡ'), ('Ꞣ', 'Ꞣ'), ('Ꞥ', 'Ꞥ'),
+  ('Ꞧ', 'Ꞧ'), ('Ꞩ', 'Ꞩ'), ('Ɦ', 'Ɪ'), ('Ʞ', 'Ꞵ'),
+  ('Ꞷ', 'Ꞷ'), ('Ꞹ', 'Ꞹ'), ('\u{a7ba}', '\u{a7ba}'),
+  ('\u{a7bc}', '\u{a7bc}'), ('\u{a7be}', '\u{a7be}'),
+  ('\u{a7c2}', '\u{a7c2}'), ('\u{a7c4}', '\u{a7c6}'), ('A', 'Z'),
+  ('𐐀', '𐐧'), ('𐒰', '𐓓'), ('𐲀', '𐲲'), ('𑢠', '𑢿'),
+  ('𖹀', '𖹟'), ('𝐀', '𝐙'), ('𝐴', '𝑍'), ('𝑨', '𝒁'),
+  ('𝒜', '𝒜'), ('𝒞', '𝒟'), ('𝒢', '𝒢'), ('𝒥', '𝒦'),
+  ('𝒩', '𝒬'), ('𝒮', '𝒵'), ('𝓐', '𝓩'), ('𝔄', '𝔅'),
+  ('𝔇', '𝔊'), ('𝔍', '𝔔'), ('𝔖', '𝔜'), ('𝔸', '𝔹'),
+  ('𝔻', '𝔾'), ('𝕀', '𝕄'), ('𝕆', '𝕆'), ('𝕊', '𝕐'),
+  ('𝕬', '𝖅'), ('𝖠', '𝖹'), ('𝗔', '𝗭'), ('𝘈', '𝘡'),
+  ('𝘼', '𝙕'), ('𝙰', '𝚉'), ('𝚨', '𝛀'), ('𝛢', '𝛺'),
+  ('𝜜', '𝜴'), ('𝝖', '𝝮'), ('𝞐', '𝞨'), ('𝟊', '𝟊'),
+  ('𞤀', '𞤡'),
+];
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/unicode_tables/grapheme_cluster_break.rs.html b/target/doc/src/regex_syntax/unicode_tables/grapheme_cluster_break.rs.html new file mode 100644 index 0000000..fe86796 --- /dev/null +++ b/target/doc/src/regex_syntax/unicode_tables/grapheme_cluster_break.rs.html @@ -0,0 +1,921 @@ +grapheme_cluster_break.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+
+// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
+//
+//  ucd-generate grapheme-cluster-break /tmp/ucd-12.1.0/ --chars
+//
+// ucd-generate is available on crates.io.
+
+pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
+  ("CR", CR), ("Control", CONTROL), ("Extend", EXTEND), ("L", L), ("LF", LF),
+  ("LV", LV), ("LVT", LVT), ("Prepend", PREPEND),
+  ("Regional_Indicator", REGIONAL_INDICATOR), ("SpacingMark", SPACINGMARK),
+  ("T", T), ("V", V), ("ZWJ", ZWJ),
+];
+
+pub const CR: &'static [(char, char)] = &[
+  ('\r', '\r'),
+];
+
+pub const CONTROL: &'static [(char, char)] = &[
+  ('\u{0}', '\t'), ('\u{b}', '\u{c}'), ('\u{e}', '\u{1f}'),
+  ('\u{7f}', '\u{9f}'), ('\u{ad}', '\u{ad}'), ('\u{61c}', '\u{61c}'),
+  ('\u{180e}', '\u{180e}'), ('\u{200b}', '\u{200b}'),
+  ('\u{200e}', '\u{200f}'), ('\u{2028}', '\u{202e}'),
+  ('\u{2060}', '\u{206f}'), ('\u{feff}', '\u{feff}'),
+  ('\u{fff0}', '\u{fffb}'), ('\u{13430}', '\u{13438}'),
+  ('\u{1bca0}', '\u{1bca3}'), ('\u{1d173}', '\u{1d17a}'),
+  ('\u{e0000}', '\u{e001f}'), ('\u{e0080}', '\u{e00ff}'),
+  ('\u{e01f0}', '\u{e0fff}'),
+];
+
+pub const EXTEND: &'static [(char, char)] = &[
+  ('\u{300}', '\u{36f}'), ('\u{483}', '\u{489}'), ('\u{591}', '\u{5bd}'),
+  ('\u{5bf}', '\u{5bf}'), ('\u{5c1}', '\u{5c2}'), ('\u{5c4}', '\u{5c5}'),
+  ('\u{5c7}', '\u{5c7}'), ('\u{610}', '\u{61a}'), ('\u{64b}', '\u{65f}'),
+  ('\u{670}', '\u{670}'), ('\u{6d6}', '\u{6dc}'), ('\u{6df}', '\u{6e4}'),
+  ('\u{6e7}', '\u{6e8}'), ('\u{6ea}', '\u{6ed}'), ('\u{711}', '\u{711}'),
+  ('\u{730}', '\u{74a}'), ('\u{7a6}', '\u{7b0}'), ('\u{7eb}', '\u{7f3}'),
+  ('\u{7fd}', '\u{7fd}'), ('\u{816}', '\u{819}'), ('\u{81b}', '\u{823}'),
+  ('\u{825}', '\u{827}'), ('\u{829}', '\u{82d}'), ('\u{859}', '\u{85b}'),
+  ('\u{8d3}', '\u{8e1}'), ('\u{8e3}', '\u{902}'), ('\u{93a}', '\u{93a}'),
+  ('\u{93c}', '\u{93c}'), ('\u{941}', '\u{948}'), ('\u{94d}', '\u{94d}'),
+  ('\u{951}', '\u{957}'), ('\u{962}', '\u{963}'), ('\u{981}', '\u{981}'),
+  ('\u{9bc}', '\u{9bc}'), ('\u{9be}', '\u{9be}'), ('\u{9c1}', '\u{9c4}'),
+  ('\u{9cd}', '\u{9cd}'), ('\u{9d7}', '\u{9d7}'), ('\u{9e2}', '\u{9e3}'),
+  ('\u{9fe}', '\u{9fe}'), ('\u{a01}', '\u{a02}'), ('\u{a3c}', '\u{a3c}'),
+  ('\u{a41}', '\u{a42}'), ('\u{a47}', '\u{a48}'), ('\u{a4b}', '\u{a4d}'),
+  ('\u{a51}', '\u{a51}'), ('\u{a70}', '\u{a71}'), ('\u{a75}', '\u{a75}'),
+  ('\u{a81}', '\u{a82}'), ('\u{abc}', '\u{abc}'), ('\u{ac1}', '\u{ac5}'),
+  ('\u{ac7}', '\u{ac8}'), ('\u{acd}', '\u{acd}'), ('\u{ae2}', '\u{ae3}'),
+  ('\u{afa}', '\u{aff}'), ('\u{b01}', '\u{b01}'), ('\u{b3c}', '\u{b3c}'),
+  ('\u{b3e}', '\u{b3f}'), ('\u{b41}', '\u{b44}'), ('\u{b4d}', '\u{b4d}'),
+  ('\u{b56}', '\u{b57}'), ('\u{b62}', '\u{b63}'), ('\u{b82}', '\u{b82}'),
+  ('\u{bbe}', '\u{bbe}'), ('\u{bc0}', '\u{bc0}'), ('\u{bcd}', '\u{bcd}'),
+  ('\u{bd7}', '\u{bd7}'), ('\u{c00}', '\u{c00}'), ('\u{c04}', '\u{c04}'),
+  ('\u{c3e}', '\u{c40}'), ('\u{c46}', '\u{c48}'), ('\u{c4a}', '\u{c4d}'),
+  ('\u{c55}', '\u{c56}'), ('\u{c62}', '\u{c63}'), ('\u{c81}', '\u{c81}'),
+  ('\u{cbc}', '\u{cbc}'), ('\u{cbf}', '\u{cbf}'), ('\u{cc2}', '\u{cc2}'),
+  ('\u{cc6}', '\u{cc6}'), ('\u{ccc}', '\u{ccd}'), ('\u{cd5}', '\u{cd6}'),
+  ('\u{ce2}', '\u{ce3}'), ('\u{d00}', '\u{d01}'), ('\u{d3b}', '\u{d3c}'),
+  ('\u{d3e}', '\u{d3e}'), ('\u{d41}', '\u{d44}'), ('\u{d4d}', '\u{d4d}'),
+  ('\u{d57}', '\u{d57}'), ('\u{d62}', '\u{d63}'), ('\u{dca}', '\u{dca}'),
+  ('\u{dcf}', '\u{dcf}'), ('\u{dd2}', '\u{dd4}'), ('\u{dd6}', '\u{dd6}'),
+  ('\u{ddf}', '\u{ddf}'), ('\u{e31}', '\u{e31}'), ('\u{e34}', '\u{e3a}'),
+  ('\u{e47}', '\u{e4e}'), ('\u{eb1}', '\u{eb1}'), ('\u{eb4}', '\u{ebc}'),
+  ('\u{ec8}', '\u{ecd}'), ('\u{f18}', '\u{f19}'), ('\u{f35}', '\u{f35}'),
+  ('\u{f37}', '\u{f37}'), ('\u{f39}', '\u{f39}'), ('\u{f71}', '\u{f7e}'),
+  ('\u{f80}', '\u{f84}'), ('\u{f86}', '\u{f87}'), ('\u{f8d}', '\u{f97}'),
+  ('\u{f99}', '\u{fbc}'), ('\u{fc6}', '\u{fc6}'), ('\u{102d}', '\u{1030}'),
+  ('\u{1032}', '\u{1037}'), ('\u{1039}', '\u{103a}'),
+  ('\u{103d}', '\u{103e}'), ('\u{1058}', '\u{1059}'),
+  ('\u{105e}', '\u{1060}'), ('\u{1071}', '\u{1074}'),
+  ('\u{1082}', '\u{1082}'), ('\u{1085}', '\u{1086}'),
+  ('\u{108d}', '\u{108d}'), ('\u{109d}', '\u{109d}'),
+  ('\u{135d}', '\u{135f}'), ('\u{1712}', '\u{1714}'),
+  ('\u{1732}', '\u{1734}'), ('\u{1752}', '\u{1753}'),
+  ('\u{1772}', '\u{1773}'), ('\u{17b4}', '\u{17b5}'),
+  ('\u{17b7}', '\u{17bd}'), ('\u{17c6}', '\u{17c6}'),
+  ('\u{17c9}', '\u{17d3}'), ('\u{17dd}', '\u{17dd}'),
+  ('\u{180b}', '\u{180d}'), ('\u{1885}', '\u{1886}'),
+  ('\u{18a9}', '\u{18a9}'), ('\u{1920}', '\u{1922}'),
+  ('\u{1927}', '\u{1928}'), ('\u{1932}', '\u{1932}'),
+  ('\u{1939}', '\u{193b}'), ('\u{1a17}', '\u{1a18}'),
+  ('\u{1a1b}', '\u{1a1b}'), ('\u{1a56}', '\u{1a56}'),
+  ('\u{1a58}', '\u{1a5e}'), ('\u{1a60}', '\u{1a60}'),
+  ('\u{1a62}', '\u{1a62}'), ('\u{1a65}', '\u{1a6c}'),
+  ('\u{1a73}', '\u{1a7c}'), ('\u{1a7f}', '\u{1a7f}'),
+  ('\u{1ab0}', '\u{1abe}'), ('\u{1b00}', '\u{1b03}'),
+  ('\u{1b34}', '\u{1b3a}'), ('\u{1b3c}', '\u{1b3c}'),
+  ('\u{1b42}', '\u{1b42}'), ('\u{1b6b}', '\u{1b73}'),
+  ('\u{1b80}', '\u{1b81}'), ('\u{1ba2}', '\u{1ba5}'),
+  ('\u{1ba8}', '\u{1ba9}'), ('\u{1bab}', '\u{1bad}'),
+  ('\u{1be6}', '\u{1be6}'), ('\u{1be8}', '\u{1be9}'),
+  ('\u{1bed}', '\u{1bed}'), ('\u{1bef}', '\u{1bf1}'),
+  ('\u{1c2c}', '\u{1c33}'), ('\u{1c36}', '\u{1c37}'),
+  ('\u{1cd0}', '\u{1cd2}'), ('\u{1cd4}', '\u{1ce0}'),
+  ('\u{1ce2}', '\u{1ce8}'), ('\u{1ced}', '\u{1ced}'),
+  ('\u{1cf4}', '\u{1cf4}'), ('\u{1cf8}', '\u{1cf9}'),
+  ('\u{1dc0}', '\u{1df9}'), ('\u{1dfb}', '\u{1dff}'),
+  ('\u{200c}', '\u{200c}'), ('\u{20d0}', '\u{20f0}'),
+  ('\u{2cef}', '\u{2cf1}'), ('\u{2d7f}', '\u{2d7f}'),
+  ('\u{2de0}', '\u{2dff}'), ('\u{302a}', '\u{302f}'),
+  ('\u{3099}', '\u{309a}'), ('\u{a66f}', '\u{a672}'),
+  ('\u{a674}', '\u{a67d}'), ('\u{a69e}', '\u{a69f}'),
+  ('\u{a6f0}', '\u{a6f1}'), ('\u{a802}', '\u{a802}'),
+  ('\u{a806}', '\u{a806}'), ('\u{a80b}', '\u{a80b}'),
+  ('\u{a825}', '\u{a826}'), ('\u{a8c4}', '\u{a8c5}'),
+  ('\u{a8e0}', '\u{a8f1}'), ('\u{a8ff}', '\u{a8ff}'),
+  ('\u{a926}', '\u{a92d}'), ('\u{a947}', '\u{a951}'),
+  ('\u{a980}', '\u{a982}'), ('\u{a9b3}', '\u{a9b3}'),
+  ('\u{a9b6}', '\u{a9b9}'), ('\u{a9bc}', 'ꦽ'), ('\u{a9e5}', '\u{a9e5}'),
+  ('\u{aa29}', '\u{aa2e}'), ('\u{aa31}', '\u{aa32}'),
+  ('\u{aa35}', '\u{aa36}'), ('\u{aa43}', '\u{aa43}'),
+  ('\u{aa4c}', '\u{aa4c}'), ('\u{aa7c}', '\u{aa7c}'),
+  ('\u{aab0}', '\u{aab0}'), ('\u{aab2}', '\u{aab4}'),
+  ('\u{aab7}', '\u{aab8}'), ('\u{aabe}', '\u{aabf}'),
+  ('\u{aac1}', '\u{aac1}'), ('\u{aaec}', '\u{aaed}'),
+  ('\u{aaf6}', '\u{aaf6}'), ('\u{abe5}', '\u{abe5}'),
+  ('\u{abe8}', '\u{abe8}'), ('\u{abed}', '\u{abed}'),
+  ('\u{fb1e}', '\u{fb1e}'), ('\u{fe00}', '\u{fe0f}'),
+  ('\u{fe20}', '\u{fe2f}'), ('\u{ff9e}', '\u{ff9f}'),
+  ('\u{101fd}', '\u{101fd}'), ('\u{102e0}', '\u{102e0}'),
+  ('\u{10376}', '\u{1037a}'), ('\u{10a01}', '\u{10a03}'),
+  ('\u{10a05}', '\u{10a06}'), ('\u{10a0c}', '\u{10a0f}'),
+  ('\u{10a38}', '\u{10a3a}'), ('\u{10a3f}', '\u{10a3f}'),
+  ('\u{10ae5}', '\u{10ae6}'), ('\u{10d24}', '\u{10d27}'),
+  ('\u{10f46}', '\u{10f50}'), ('\u{11001}', '\u{11001}'),
+  ('\u{11038}', '\u{11046}'), ('\u{1107f}', '\u{11081}'),
+  ('\u{110b3}', '\u{110b6}'), ('\u{110b9}', '\u{110ba}'),
+  ('\u{11100}', '\u{11102}'), ('\u{11127}', '\u{1112b}'),
+  ('\u{1112d}', '\u{11134}'), ('\u{11173}', '\u{11173}'),
+  ('\u{11180}', '\u{11181}'), ('\u{111b6}', '\u{111be}'),
+  ('\u{111c9}', '\u{111cc}'), ('\u{1122f}', '\u{11231}'),
+  ('\u{11234}', '\u{11234}'), ('\u{11236}', '\u{11237}'),
+  ('\u{1123e}', '\u{1123e}'), ('\u{112df}', '\u{112df}'),
+  ('\u{112e3}', '\u{112ea}'), ('\u{11300}', '\u{11301}'),
+  ('\u{1133b}', '\u{1133c}'), ('\u{1133e}', '\u{1133e}'),
+  ('\u{11340}', '\u{11340}'), ('\u{11357}', '\u{11357}'),
+  ('\u{11366}', '\u{1136c}'), ('\u{11370}', '\u{11374}'),
+  ('\u{11438}', '\u{1143f}'), ('\u{11442}', '\u{11444}'),
+  ('\u{11446}', '\u{11446}'), ('\u{1145e}', '\u{1145e}'),
+  ('\u{114b0}', '\u{114b0}'), ('\u{114b3}', '\u{114b8}'),
+  ('\u{114ba}', '\u{114ba}'), ('\u{114bd}', '\u{114bd}'),
+  ('\u{114bf}', '\u{114c0}'), ('\u{114c2}', '\u{114c3}'),
+  ('\u{115af}', '\u{115af}'), ('\u{115b2}', '\u{115b5}'),
+  ('\u{115bc}', '\u{115bd}'), ('\u{115bf}', '\u{115c0}'),
+  ('\u{115dc}', '\u{115dd}'), ('\u{11633}', '\u{1163a}'),
+  ('\u{1163d}', '\u{1163d}'), ('\u{1163f}', '\u{11640}'),
+  ('\u{116ab}', '\u{116ab}'), ('\u{116ad}', '\u{116ad}'),
+  ('\u{116b0}', '\u{116b5}'), ('\u{116b7}', '\u{116b7}'),
+  ('\u{1171d}', '\u{1171f}'), ('\u{11722}', '\u{11725}'),
+  ('\u{11727}', '\u{1172b}'), ('\u{1182f}', '\u{11837}'),
+  ('\u{11839}', '\u{1183a}'), ('\u{119d4}', '\u{119d7}'),
+  ('\u{119da}', '\u{119db}'), ('\u{119e0}', '\u{119e0}'),
+  ('\u{11a01}', '\u{11a0a}'), ('\u{11a33}', '\u{11a38}'),
+  ('\u{11a3b}', '\u{11a3e}'), ('\u{11a47}', '\u{11a47}'),
+  ('\u{11a51}', '\u{11a56}'), ('\u{11a59}', '\u{11a5b}'),
+  ('\u{11a8a}', '\u{11a96}'), ('\u{11a98}', '\u{11a99}'),
+  ('\u{11c30}', '\u{11c36}'), ('\u{11c38}', '\u{11c3d}'),
+  ('\u{11c3f}', '\u{11c3f}'), ('\u{11c92}', '\u{11ca7}'),
+  ('\u{11caa}', '\u{11cb0}'), ('\u{11cb2}', '\u{11cb3}'),
+  ('\u{11cb5}', '\u{11cb6}'), ('\u{11d31}', '\u{11d36}'),
+  ('\u{11d3a}', '\u{11d3a}'), ('\u{11d3c}', '\u{11d3d}'),
+  ('\u{11d3f}', '\u{11d45}'), ('\u{11d47}', '\u{11d47}'),
+  ('\u{11d90}', '\u{11d91}'), ('\u{11d95}', '\u{11d95}'),
+  ('\u{11d97}', '\u{11d97}'), ('\u{11ef3}', '\u{11ef4}'),
+  ('\u{16af0}', '\u{16af4}'), ('\u{16b30}', '\u{16b36}'),
+  ('\u{16f4f}', '\u{16f4f}'), ('\u{16f8f}', '\u{16f92}'),
+  ('\u{1bc9d}', '\u{1bc9e}'), ('\u{1d165}', '\u{1d165}'),
+  ('\u{1d167}', '\u{1d169}'), ('\u{1d16e}', '\u{1d172}'),
+  ('\u{1d17b}', '\u{1d182}'), ('\u{1d185}', '\u{1d18b}'),
+  ('\u{1d1aa}', '\u{1d1ad}'), ('\u{1d242}', '\u{1d244}'),
+  ('\u{1da00}', '\u{1da36}'), ('\u{1da3b}', '\u{1da6c}'),
+  ('\u{1da75}', '\u{1da75}'), ('\u{1da84}', '\u{1da84}'),
+  ('\u{1da9b}', '\u{1da9f}'), ('\u{1daa1}', '\u{1daaf}'),
+  ('\u{1e000}', '\u{1e006}'), ('\u{1e008}', '\u{1e018}'),
+  ('\u{1e01b}', '\u{1e021}'), ('\u{1e023}', '\u{1e024}'),
+  ('\u{1e026}', '\u{1e02a}'), ('\u{1e130}', '\u{1e136}'),
+  ('\u{1e2ec}', '\u{1e2ef}'), ('\u{1e8d0}', '\u{1e8d6}'),
+  ('\u{1e944}', '\u{1e94a}'), ('🏻', '🏿'), ('\u{e0020}', '\u{e007f}'),
+  ('\u{e0100}', '\u{e01ef}'),
+];
+
+pub const L: &'static [(char, char)] = &[
+  ('ᄀ', 'ᅟ'), ('ꥠ', 'ꥼ'),
+];
+
+pub const LF: &'static [(char, char)] = &[
+  ('\n', '\n'),
+];
+
+pub const LV: &'static [(char, char)] = &[
+  ('가', '가'), ('개', '개'), ('갸', '갸'), ('걔', '걔'),
+  ('거', '거'), ('게', '게'), ('겨', '겨'), ('계', '계'),
+  ('고', '고'), ('과', '과'), ('괘', '괘'), ('괴', '괴'),
+  ('교', '교'), ('구', '구'), ('궈', '궈'), ('궤', '궤'),
+  ('귀', '귀'), ('규', '규'), ('그', '그'), ('긔', '긔'),
+  ('기', '기'), ('까', '까'), ('깨', '깨'), ('꺄', '꺄'),
+  ('꺠', '꺠'), ('꺼', '꺼'), ('께', '께'), ('껴', '껴'),
+  ('꼐', '꼐'), ('꼬', '꼬'), ('꽈', '꽈'), ('꽤', '꽤'),
+  ('꾀', '꾀'), ('꾜', '꾜'), ('꾸', '꾸'), ('꿔', '꿔'),
+  ('꿰', '꿰'), ('뀌', '뀌'), ('뀨', '뀨'), ('끄', '끄'),
+  ('끠', '끠'), ('끼', '끼'), ('나', '나'), ('내', '내'),
+  ('냐', '냐'), ('냬', '냬'), ('너', '너'), ('네', '네'),
+  ('녀', '녀'), ('녜', '녜'), ('노', '노'), ('놔', '놔'),
+  ('놰', '놰'), ('뇌', '뇌'), ('뇨', '뇨'), ('누', '누'),
+  ('눠', '눠'), ('눼', '눼'), ('뉘', '뉘'), ('뉴', '뉴'),
+  ('느', '느'), ('늬', '늬'), ('니', '니'), ('다', '다'),
+  ('대', '대'), ('댜', '댜'), ('댸', '댸'), ('더', '더'),
+  ('데', '데'), ('뎌', '뎌'), ('뎨', '뎨'), ('도', '도'),
+  ('돠', '돠'), ('돼', '돼'), ('되', '되'), ('됴', '됴'),
+  ('두', '두'), ('둬', '둬'), ('뒈', '뒈'), ('뒤', '뒤'),
+  ('듀', '듀'), ('드', '드'), ('듸', '듸'), ('디', '디'),
+  ('따', '따'), ('때', '때'), ('땨', '땨'), ('떄', '떄'),
+  ('떠', '떠'), ('떼', '떼'), ('뗘', '뗘'), ('뗴', '뗴'),
+  ('또', '또'), ('똬', '똬'), ('뙈', '뙈'), ('뙤', '뙤'),
+  ('뚀', '뚀'), ('뚜', '뚜'), ('뚸', '뚸'), ('뛔', '뛔'),
+  ('뛰', '뛰'), ('뜌', '뜌'), ('뜨', '뜨'), ('띄', '띄'),
+  ('띠', '띠'), ('라', '라'), ('래', '래'), ('랴', '랴'),
+  ('럐', '럐'), ('러', '러'), ('레', '레'), ('려', '려'),
+  ('례', '례'), ('로', '로'), ('롸', '롸'), ('뢔', '뢔'),
+  ('뢰', '뢰'), ('료', '료'), ('루', '루'), ('뤄', '뤄'),
+  ('뤠', '뤠'), ('뤼', '뤼'), ('류', '류'), ('르', '르'),
+  ('릐', '릐'), ('리', '리'), ('마', '마'), ('매', '매'),
+  ('먀', '먀'), ('먜', '먜'), ('머', '머'), ('메', '메'),
+  ('며', '며'), ('몌', '몌'), ('모', '모'), ('뫄', '뫄'),
+  ('뫠', '뫠'), ('뫼', '뫼'), ('묘', '묘'), ('무', '무'),
+  ('뭐', '뭐'), ('뭬', '뭬'), ('뮈', '뮈'), ('뮤', '뮤'),
+  ('므', '므'), ('믜', '믜'), ('미', '미'), ('바', '바'),
+  ('배', '배'), ('뱌', '뱌'), ('뱨', '뱨'), ('버', '버'),
+  ('베', '베'), ('벼', '벼'), ('볘', '볘'), ('보', '보'),
+  ('봐', '봐'), ('봬', '봬'), ('뵈', '뵈'), ('뵤', '뵤'),
+  ('부', '부'), ('붜', '붜'), ('붸', '붸'), ('뷔', '뷔'),
+  ('뷰', '뷰'), ('브', '브'), ('븨', '븨'), ('비', '비'),
+  ('빠', '빠'), ('빼', '빼'), ('뺘', '뺘'), ('뺴', '뺴'),
+  ('뻐', '뻐'), ('뻬', '뻬'), ('뼈', '뼈'), ('뼤', '뼤'),
+  ('뽀', '뽀'), ('뽜', '뽜'), ('뽸', '뽸'), ('뾔', '뾔'),
+  ('뾰', '뾰'), ('뿌', '뿌'), ('뿨', '뿨'), ('쀄', '쀄'),
+  ('쀠', '쀠'), ('쀼', '쀼'), ('쁘', '쁘'), ('쁴', '쁴'),
+  ('삐', '삐'), ('사', '사'), ('새', '새'), ('샤', '샤'),
+  ('섀', '섀'), ('서', '서'), ('세', '세'), ('셔', '셔'),
+  ('셰', '셰'), ('소', '소'), ('솨', '솨'), ('쇄', '쇄'),
+  ('쇠', '쇠'), ('쇼', '쇼'), ('수', '수'), ('숴', '숴'),
+  ('쉐', '쉐'), ('쉬', '쉬'), ('슈', '슈'), ('스', '스'),
+  ('싀', '싀'), ('시', '시'), ('싸', '싸'), ('쌔', '쌔'),
+  ('쌰', '쌰'), ('썌', '썌'), ('써', '써'), ('쎄', '쎄'),
+  ('쎠', '쎠'), ('쎼', '쎼'), ('쏘', '쏘'), ('쏴', '쏴'),
+  ('쐐', '쐐'), ('쐬', '쐬'), ('쑈', '쑈'), ('쑤', '쑤'),
+  ('쒀', '쒀'), ('쒜', '쒜'), ('쒸', '쒸'), ('쓔', '쓔'),
+  ('쓰', '쓰'), ('씌', '씌'), ('씨', '씨'), ('아', '아'),
+  ('애', '애'), ('야', '야'), ('얘', '얘'), ('어', '어'),
+  ('에', '에'), ('여', '여'), ('예', '예'), ('오', '오'),
+  ('와', '와'), ('왜', '왜'), ('외', '외'), ('요', '요'),
+  ('우', '우'), ('워', '워'), ('웨', '웨'), ('위', '위'),
+  ('유', '유'), ('으', '으'), ('의', '의'), ('이', '이'),
+  ('자', '자'), ('재', '재'), ('쟈', '쟈'), ('쟤', '쟤'),
+  ('저', '저'), ('제', '제'), ('져', '져'), ('졔', '졔'),
+  ('조', '조'), ('좌', '좌'), ('좨', '좨'), ('죄', '죄'),
+  ('죠', '죠'), ('주', '주'), ('줘', '줘'), ('줴', '줴'),
+  ('쥐', '쥐'), ('쥬', '쥬'), ('즈', '즈'), ('즤', '즤'),
+  ('지', '지'), ('짜', '짜'), ('째', '째'), ('쨔', '쨔'),
+  ('쨰', '쨰'), ('쩌', '쩌'), ('쩨', '쩨'), ('쪄', '쪄'),
+  ('쪠', '쪠'), ('쪼', '쪼'), ('쫘', '쫘'), ('쫴', '쫴'),
+  ('쬐', '쬐'), ('쬬', '쬬'), ('쭈', '쭈'), ('쭤', '쭤'),
+  ('쮀', '쮀'), ('쮜', '쮜'), ('쮸', '쮸'), ('쯔', '쯔'),
+  ('쯰', '쯰'), ('찌', '찌'), ('차', '차'), ('채', '채'),
+  ('챠', '챠'), ('챼', '챼'), ('처', '처'), ('체', '체'),
+  ('쳐', '쳐'), ('쳬', '쳬'), ('초', '초'), ('촤', '촤'),
+  ('쵀', '쵀'), ('최', '최'), ('쵸', '쵸'), ('추', '추'),
+  ('춰', '춰'), ('췌', '췌'), ('취', '취'), ('츄', '츄'),
+  ('츠', '츠'), ('츼', '츼'), ('치', '치'), ('카', '카'),
+  ('캐', '캐'), ('캬', '캬'), ('컈', '컈'), ('커', '커'),
+  ('케', '케'), ('켜', '켜'), ('켸', '켸'), ('코', '코'),
+  ('콰', '콰'), ('쾌', '쾌'), ('쾨', '쾨'), ('쿄', '쿄'),
+  ('쿠', '쿠'), ('쿼', '쿼'), ('퀘', '퀘'), ('퀴', '퀴'),
+  ('큐', '큐'), ('크', '크'), ('킈', '킈'), ('키', '키'),
+  ('타', '타'), ('태', '태'), ('탸', '탸'), ('턔', '턔'),
+  ('터', '터'), ('테', '테'), ('텨', '텨'), ('톄', '톄'),
+  ('토', '토'), ('톼', '톼'), ('퇘', '퇘'), ('퇴', '퇴'),
+  ('툐', '툐'), ('투', '투'), ('퉈', '퉈'), ('퉤', '퉤'),
+  ('튀', '튀'), ('튜', '튜'), ('트', '트'), ('틔', '틔'),
+  ('티', '티'), ('파', '파'), ('패', '패'), ('퍄', '퍄'),
+  ('퍠', '퍠'), ('퍼', '퍼'), ('페', '페'), ('펴', '펴'),
+  ('폐', '폐'), ('포', '포'), ('퐈', '퐈'), ('퐤', '퐤'),
+  ('푀', '푀'), ('표', '표'), ('푸', '푸'), ('풔', '풔'),
+  ('풰', '풰'), ('퓌', '퓌'), ('퓨', '퓨'), ('프', '프'),
+  ('픠', '픠'), ('피', '피'), ('하', '하'), ('해', '해'),
+  ('햐', '햐'), ('햬', '햬'), ('허', '허'), ('헤', '헤'),
+  ('혀', '혀'), ('혜', '혜'), ('호', '호'), ('화', '화'),
+  ('홰', '홰'), ('회', '회'), ('효', '효'), ('후', '후'),
+  ('훠', '훠'), ('훼', '훼'), ('휘', '휘'), ('휴', '휴'),
+  ('흐', '흐'), ('희', '희'), ('히', '히'),
+];
+
+pub const LVT: &'static [(char, char)] = &[
+  ('각', '갛'), ('객', '갷'), ('갹', '걓'), ('걕', '걯'),
+  ('걱', '겋'), ('겍', '겧'), ('격', '곃'), ('곅', '곟'),
+  ('곡', '곻'), ('곽', '괗'), ('괙', '괳'), ('괵', '굏'),
+  ('굑', '굫'), ('국', '궇'), ('궉', '궣'), ('궥', '궿'),
+  ('귁', '귛'), ('귝', '귷'), ('극', '긓'), ('긕', '긯'),
+  ('긱', '깋'), ('깍', '깧'), ('깩', '꺃'), ('꺅', '꺟'),
+  ('꺡', '꺻'), ('꺽', '껗'), ('껙', '껳'), ('껵', '꼏'),
+  ('꼑', '꼫'), ('꼭', '꽇'), ('꽉', '꽣'), ('꽥', '꽿'),
+  ('꾁', '꾛'), ('꾝', '꾷'), ('꾹', '꿓'), ('꿕', '꿯'),
+  ('꿱', '뀋'), ('뀍', '뀧'), ('뀩', '끃'), ('끅', '끟'),
+  ('끡', '끻'), ('끽', '낗'), ('낙', '낳'), ('낵', '냏'),
+  ('냑', '냫'), ('냭', '넇'), ('넉', '넣'), ('넥', '넿'),
+  ('녁', '녛'), ('녝', '녷'), ('녹', '놓'), ('놕', '놯'),
+  ('놱', '뇋'), ('뇍', '뇧'), ('뇩', '눃'), ('눅', '눟'),
+  ('눡', '눻'), ('눽', '뉗'), ('뉙', '뉳'), ('뉵', '늏'),
+  ('늑', '늫'), ('늭', '닇'), ('닉', '닣'), ('닥', '닿'),
+  ('댁', '댛'), ('댝', '댷'), ('댹', '덓'), ('덕', '덯'),
+  ('덱', '뎋'), ('뎍', '뎧'), ('뎩', '돃'), ('독', '돟'),
+  ('돡', '돻'), ('돽', '됗'), ('됙', '됳'), ('됵', '둏'),
+  ('둑', '둫'), ('둭', '뒇'), ('뒉', '뒣'), ('뒥', '뒿'),
+  ('듁', '듛'), ('득', '듷'), ('듹', '딓'), ('딕', '딯'),
+  ('딱', '땋'), ('땍', '땧'), ('땩', '떃'), ('떅', '떟'),
+  ('떡', '떻'), ('떽', '뗗'), ('뗙', '뗳'), ('뗵', '똏'),
+  ('똑', '똫'), ('똭', '뙇'), ('뙉', '뙣'), ('뙥', '뙿'),
+  ('뚁', '뚛'), ('뚝', '뚷'), ('뚹', '뛓'), ('뛕', '뛯'),
+  ('뛱', '뜋'), ('뜍', '뜧'), ('뜩', '띃'), ('띅', '띟'),
+  ('띡', '띻'), ('락', '랗'), ('랙', '랳'), ('략', '럏'),
+  ('럑', '럫'), ('럭', '렇'), ('렉', '렣'), ('력', '렿'),
+  ('롁', '롛'), ('록', '롷'), ('롹', '뢓'), ('뢕', '뢯'),
+  ('뢱', '룋'), ('룍', '룧'), ('룩', '뤃'), ('뤅', '뤟'),
+  ('뤡', '뤻'), ('뤽', '륗'), ('륙', '륳'), ('륵', '릏'),
+  ('릑', '릫'), ('릭', '맇'), ('막', '맣'), ('맥', '맿'),
+  ('먁', '먛'), ('먝', '먷'), ('먹', '멓'), ('멕', '멯'),
+  ('멱', '몋'), ('몍', '몧'), ('목', '뫃'), ('뫅', '뫟'),
+  ('뫡', '뫻'), ('뫽', '묗'), ('묙', '묳'), ('묵', '뭏'),
+  ('뭑', '뭫'), ('뭭', '뮇'), ('뮉', '뮣'), ('뮥', '뮿'),
+  ('믁', '믛'), ('믝', '믷'), ('믹', '밓'), ('박', '밯'),
+  ('백', '뱋'), ('뱍', '뱧'), ('뱩', '벃'), ('벅', '벟'),
+  ('벡', '벻'), ('벽', '볗'), ('볙', '볳'), ('복', '봏'),
+  ('봑', '봫'), ('봭', '뵇'), ('뵉', '뵣'), ('뵥', '뵿'),
+  ('북', '붛'), ('붝', '붷'), ('붹', '뷓'), ('뷕', '뷯'),
+  ('뷱', '븋'), ('븍', '븧'), ('븩', '빃'), ('빅', '빟'),
+  ('빡', '빻'), ('빽', '뺗'), ('뺙', '뺳'), ('뺵', '뻏'),
+  ('뻑', '뻫'), ('뻭', '뼇'), ('뼉', '뼣'), ('뼥', '뼿'),
+  ('뽁', '뽛'), ('뽝', '뽷'), ('뽹', '뾓'), ('뾕', '뾯'),
+  ('뾱', '뿋'), ('뿍', '뿧'), ('뿩', '쀃'), ('쀅', '쀟'),
+  ('쀡', '쀻'), ('쀽', '쁗'), ('쁙', '쁳'), ('쁵', '삏'),
+  ('삑', '삫'), ('삭', '샇'), ('색', '샣'), ('샥', '샿'),
+  ('섁', '섛'), ('석', '섷'), ('섹', '셓'), ('셕', '셯'),
+  ('셱', '솋'), ('속', '솧'), ('솩', '쇃'), ('쇅', '쇟'),
+  ('쇡', '쇻'), ('쇽', '숗'), ('숙', '숳'), ('숵', '쉏'),
+  ('쉑', '쉫'), ('쉭', '슇'), ('슉', '슣'), ('슥', '슿'),
+  ('싁', '싛'), ('식', '싷'), ('싹', '쌓'), ('쌕', '쌯'),
+  ('쌱', '썋'), ('썍', '썧'), ('썩', '쎃'), ('쎅', '쎟'),
+  ('쎡', '쎻'), ('쎽', '쏗'), ('쏙', '쏳'), ('쏵', '쐏'),
+  ('쐑', '쐫'), ('쐭', '쑇'), ('쑉', '쑣'), ('쑥', '쑿'),
+  ('쒁', '쒛'), ('쒝', '쒷'), ('쒹', '쓓'), ('쓕', '쓯'),
+  ('쓱', '씋'), ('씍', '씧'), ('씩', '앃'), ('악', '앟'),
+  ('액', '앻'), ('약', '얗'), ('얙', '얳'), ('억', '엏'),
+  ('엑', '엫'), ('역', '옇'), ('옉', '옣'), ('옥', '옿'),
+  ('왁', '왛'), ('왝', '왷'), ('왹', '욓'), ('욕', '욯'),
+  ('욱', '웋'), ('웍', '웧'), ('웩', '윃'), ('윅', '윟'),
+  ('육', '윻'), ('윽', '읗'), ('읙', '읳'), ('익', '잏'),
+  ('작', '잫'), ('잭', '쟇'), ('쟉', '쟣'), ('쟥', '쟿'),
+  ('적', '젛'), ('젝', '젷'), ('젹', '졓'), ('졕', '졯'),
+  ('족', '좋'), ('좍', '좧'), ('좩', '죃'), ('죅', '죟'),
+  ('죡', '죻'), ('죽', '줗'), ('줙', '줳'), ('줵', '쥏'),
+  ('쥑', '쥫'), ('쥭', '즇'), ('즉', '즣'), ('즥', '즿'),
+  ('직', '짛'), ('짝', '짷'), ('짹', '쨓'), ('쨕', '쨯'),
+  ('쨱', '쩋'), ('쩍', '쩧'), ('쩩', '쪃'), ('쪅', '쪟'),
+  ('쪡', '쪻'), ('쪽', '쫗'), ('쫙', '쫳'), ('쫵', '쬏'),
+  ('쬑', '쬫'), ('쬭', '쭇'), ('쭉', '쭣'), ('쭥', '쭿'),
+  ('쮁', '쮛'), ('쮝', '쮷'), ('쮹', '쯓'), ('쯕', '쯯'),
+  ('쯱', '찋'), ('찍', '찧'), ('착', '챃'), ('책', '챟'),
+  ('챡', '챻'), ('챽', '첗'), ('척', '첳'), ('첵', '쳏'),
+  ('쳑', '쳫'), ('쳭', '촇'), ('촉', '촣'), ('촥', '촿'),
+  ('쵁', '쵛'), ('쵝', '쵷'), ('쵹', '춓'), ('축', '춯'),
+  ('춱', '췋'), ('췍', '췧'), ('췩', '츃'), ('츅', '츟'),
+  ('측', '츻'), ('츽', '칗'), ('칙', '칳'), ('칵', '캏'),
+  ('캑', '캫'), ('캭', '컇'), ('컉', '컣'), ('컥', '컿'),
+  ('켁', '켛'), ('켝', '켷'), ('켹', '콓'), ('콕', '콯'),
+  ('콱', '쾋'), ('쾍', '쾧'), ('쾩', '쿃'), ('쿅', '쿟'),
+  ('쿡', '쿻'), ('쿽', '퀗'), ('퀙', '퀳'), ('퀵', '큏'),
+  ('큑', '큫'), ('큭', '킇'), ('킉', '킣'), ('킥', '킿'),
+  ('탁', '탛'), ('택', '탷'), ('탹', '턓'), ('턕', '턯'),
+  ('턱', '텋'), ('텍', '텧'), ('텩', '톃'), ('톅', '톟'),
+  ('톡', '톻'), ('톽', '퇗'), ('퇙', '퇳'), ('퇵', '툏'),
+  ('툑', '툫'), ('툭', '퉇'), ('퉉', '퉣'), ('퉥', '퉿'),
+  ('튁', '튛'), ('튝', '튷'), ('특', '틓'), ('틕', '틯'),
+  ('틱', '팋'), ('팍', '팧'), ('팩', '퍃'), ('퍅', '퍟'),
+  ('퍡', '퍻'), ('퍽', '펗'), ('펙', '펳'), ('펵', '폏'),
+  ('폑', '폫'), ('폭', '퐇'), ('퐉', '퐣'), ('퐥', '퐿'),
+  ('푁', '푛'), ('푝', '푷'), ('푹', '풓'), ('풕', '풯'),
+  ('풱', '퓋'), ('퓍', '퓧'), ('퓩', '픃'), ('픅', '픟'),
+  ('픡', '픻'), ('픽', '핗'), ('학', '핳'), ('핵', '햏'),
+  ('햑', '햫'), ('햭', '헇'), ('헉', '헣'), ('헥', '헿'),
+  ('혁', '혛'), ('혝', '혷'), ('혹', '홓'), ('확', '홯'),
+  ('홱', '횋'), ('획', '횧'), ('횩', '훃'), ('훅', '훟'),
+  ('훡', '훻'), ('훽', '휗'), ('휙', '휳'), ('휵', '흏'),
+  ('흑', '흫'), ('흭', '힇'), ('힉', '힣'),
+];
+
+pub const PREPEND: &'static [(char, char)] = &[
+  ('\u{600}', '\u{605}'), ('\u{6dd}', '\u{6dd}'), ('\u{70f}', '\u{70f}'),
+  ('\u{8e2}', '\u{8e2}'), ('ൎ', 'ൎ'), ('\u{110bd}', '\u{110bd}'),
+  ('\u{110cd}', '\u{110cd}'), ('𑇂', '𑇃'), ('𑨺', '𑨺'),
+  ('\u{11a84}', '𑪉'), ('𑵆', '𑵆'),
+];
+
+pub const REGIONAL_INDICATOR: &'static [(char, char)] = &[
+  ('🇦', '🇿'),
+];
+
+pub const SPACINGMARK: &'static [(char, char)] = &[
+  ('ः', 'ः'), ('ऻ', 'ऻ'), ('ा', 'ी'), ('ॉ', 'ौ'),
+  ('ॎ', 'ॏ'), ('ং', 'ঃ'), ('ি', 'ী'), ('ে', 'ৈ'),
+  ('ো', 'ৌ'), ('ਃ', 'ਃ'), ('ਾ', 'ੀ'), ('ઃ', 'ઃ'),
+  ('ા', 'ી'), ('ૉ', 'ૉ'), ('ો', 'ૌ'), ('ଂ', 'ଃ'),
+  ('ୀ', 'ୀ'), ('େ', 'ୈ'), ('ୋ', 'ୌ'), ('ி', 'ி'),
+  ('ு', 'ூ'), ('ெ', 'ை'), ('ொ', 'ௌ'), ('ఁ', 'ః'),
+  ('ు', 'ౄ'), ('ಂ', 'ಃ'), ('ಾ', 'ಾ'), ('ೀ', 'ು'),
+  ('ೃ', 'ೄ'), ('ೇ', 'ೈ'), ('ೊ', 'ೋ'), ('ം', 'ഃ'),
+  ('ി', 'ീ'), ('െ', 'ൈ'), ('ൊ', 'ൌ'), ('ං', 'ඃ'),
+  ('ැ', 'ෑ'), ('ෘ', 'ෞ'), ('ෲ', 'ෳ'), ('ำ', 'ำ'),
+  ('ຳ', 'ຳ'), ('༾', '༿'), ('ཿ', 'ཿ'), ('ေ', 'ေ'),
+  ('ျ', 'ြ'), ('ၖ', 'ၗ'), ('ႄ', 'ႄ'), ('ា', 'ា'),
+  ('ើ', 'ៅ'), ('ះ', 'ៈ'), ('ᤣ', 'ᤦ'), ('ᤩ', 'ᤫ'),
+  ('ᤰ', 'ᤱ'), ('ᤳ', 'ᤸ'), ('ᨙ', 'ᨚ'), ('ᩕ', 'ᩕ'),
+  ('ᩗ', 'ᩗ'), ('ᩭ', 'ᩲ'), ('ᬄ', 'ᬄ'), ('ᬻ', 'ᬻ'),
+  ('ᬽ', 'ᭁ'), ('ᭃ', '᭄'), ('ᮂ', 'ᮂ'), ('ᮡ', 'ᮡ'),
+  ('ᮦ', 'ᮧ'), ('᮪', '᮪'), ('ᯧ', 'ᯧ'), ('ᯪ', 'ᯬ'),
+  ('ᯮ', 'ᯮ'), ('᯲', '᯳'), ('ᰤ', 'ᰫ'), ('ᰴ', 'ᰵ'),
+  ('᳡', '᳡'), ('᳷', '᳷'), ('ꠣ', 'ꠤ'), ('ꠧ', 'ꠧ'),
+  ('ꢀ', 'ꢁ'), ('ꢴ', 'ꣃ'), ('ꥒ', '꥓'), ('ꦃ', 'ꦃ'),
+  ('ꦴ', 'ꦵ'), ('ꦺ', 'ꦻ'), ('ꦾ', '꧀'), ('ꨯ', 'ꨰ'),
+  ('ꨳ', 'ꨴ'), ('ꩍ', 'ꩍ'), ('ꫫ', 'ꫫ'), ('ꫮ', 'ꫯ'),
+  ('ꫵ', 'ꫵ'), ('ꯣ', 'ꯤ'), ('ꯦ', 'ꯧ'), ('ꯩ', 'ꯪ'),
+  ('꯬', '꯬'), ('𑀀', '𑀀'), ('𑀂', '𑀂'), ('𑂂', '𑂂'),
+  ('𑂰', '𑂲'), ('𑂷', '𑂸'), ('𑄬', '𑄬'), ('𑅅', '𑅆'),
+  ('𑆂', '𑆂'), ('𑆳', '𑆵'), ('𑆿', '𑇀'), ('𑈬', '𑈮'),
+  ('𑈲', '𑈳'), ('𑈵', '𑈵'), ('𑋠', '𑋢'), ('𑌂', '𑌃'),
+  ('𑌿', '𑌿'), ('𑍁', '𑍄'), ('𑍇', '𑍈'), ('𑍋', '𑍍'),
+  ('𑍢', '𑍣'), ('𑐵', '𑐷'), ('𑑀', '𑑁'), ('𑑅', '𑑅'),
+  ('𑒱', '𑒲'), ('𑒹', '𑒹'), ('𑒻', '𑒼'), ('𑒾', '𑒾'),
+  ('𑓁', '𑓁'), ('𑖰', '𑖱'), ('𑖸', '𑖻'), ('𑖾', '𑖾'),
+  ('𑘰', '𑘲'), ('𑘻', '𑘼'), ('𑘾', '𑘾'), ('𑚬', '𑚬'),
+  ('𑚮', '𑚯'), ('𑚶', '𑚶'), ('𑜠', '𑜡'), ('𑜦', '𑜦'),
+  ('𑠬', '𑠮'), ('𑠸', '𑠸'), ('\u{119d1}', '\u{119d3}'),
+  ('\u{119dc}', '\u{119df}'), ('\u{119e4}', '\u{119e4}'), ('𑨹', '𑨹'),
+  ('𑩗', '𑩘'), ('𑪗', '𑪗'), ('𑰯', '𑰯'), ('𑰾', '𑰾'),
+  ('𑲩', '𑲩'), ('𑲱', '𑲱'), ('𑲴', '𑲴'), ('𑶊', '𑶎'),
+  ('𑶓', '𑶔'), ('𑶖', '𑶖'), ('𑻵', '𑻶'), ('𖽑', '\u{16f87}'),
+  ('𝅦', '𝅦'), ('𝅭', '𝅭'),
+];
+
+pub const T: &'static [(char, char)] = &[
+  ('ᆨ', 'ᇿ'), ('ퟋ', 'ퟻ'),
+];
+
+pub const V: &'static [(char, char)] = &[
+  ('ᅠ', 'ᆧ'), ('ힰ', 'ퟆ'),
+];
+
+pub const ZWJ: &'static [(char, char)] = &[
+  ('\u{200d}', '\u{200d}'),
+];
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/unicode_tables/mod.rs.html b/target/doc/src/regex_syntax/unicode_tables/mod.rs.html new file mode 100644 index 0000000..c40c806 --- /dev/null +++ b/target/doc/src/regex_syntax/unicode_tables/mod.rs.html @@ -0,0 +1,27 @@ +mod.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+
+pub mod age;
+pub mod case_folding_simple;
+pub mod general_category;
+pub mod grapheme_cluster_break;
+pub mod perl_word;
+pub mod property_bool;
+pub mod property_names;
+pub mod property_values;
+pub mod script_extension;
+pub mod script;
+pub mod sentence_break;
+pub mod word_break;
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/unicode_tables/perl_word.rs.html b/target/doc/src/regex_syntax/unicode_tables/perl_word.rs.html new file mode 100644 index 0000000..c5bd322 --- /dev/null +++ b/target/doc/src/regex_syntax/unicode_tables/perl_word.rs.html @@ -0,0 +1,415 @@ +perl_word.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+
+// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
+//
+//  ucd-generate perl-word /tmp/ucd-12.1.0/ --chars
+//
+// ucd-generate is available on crates.io.
+
+pub const PERL_WORD: &'static [(char, char)] = &[
+  ('0', '9'), ('A', 'Z'), ('_', '_'), ('a', 'z'), ('ª', 'ª'), ('µ', 'µ'),
+  ('º', 'º'), ('À', 'Ö'), ('Ø', 'ö'), ('ø', 'ˁ'), ('ˆ', 'ˑ'),
+  ('ˠ', 'ˤ'), ('ˬ', 'ˬ'), ('ˮ', 'ˮ'), ('\u{300}', 'ʹ'), ('Ͷ', 'ͷ'),
+  ('ͺ', 'ͽ'), ('Ϳ', 'Ϳ'), ('Ά', 'Ά'), ('Έ', 'Ί'), ('Ό', 'Ό'),
+  ('Ύ', 'Ρ'), ('Σ', 'ϵ'), ('Ϸ', 'ҁ'), ('\u{483}', 'ԯ'), ('Ա', 'Ֆ'),
+  ('ՙ', 'ՙ'), ('ՠ', 'ֈ'), ('\u{591}', '\u{5bd}'), ('\u{5bf}', '\u{5bf}'),
+  ('\u{5c1}', '\u{5c2}'), ('\u{5c4}', '\u{5c5}'), ('\u{5c7}', '\u{5c7}'),
+  ('א', 'ת'), ('ׯ', 'ײ'), ('\u{610}', '\u{61a}'), ('ؠ', '٩'),
+  ('ٮ', 'ۓ'), ('ە', '\u{6dc}'), ('\u{6df}', '\u{6e8}'), ('\u{6ea}', 'ۼ'),
+  ('ۿ', 'ۿ'), ('ܐ', '\u{74a}'), ('ݍ', 'ޱ'), ('߀', 'ߵ'), ('ߺ', 'ߺ'),
+  ('\u{7fd}', '\u{7fd}'), ('ࠀ', '\u{82d}'), ('ࡀ', '\u{85b}'),
+  ('ࡠ', 'ࡪ'), ('ࢠ', 'ࢴ'), ('ࢶ', 'ࢽ'), ('\u{8d3}', '\u{8e1}'),
+  ('\u{8e3}', '\u{963}'), ('०', '९'), ('ॱ', 'ঃ'), ('অ', 'ঌ'),
+  ('এ', 'ঐ'), ('ও', 'ন'), ('প', 'র'), ('ল', 'ল'),
+  ('শ', 'হ'), ('\u{9bc}', '\u{9c4}'), ('ে', 'ৈ'), ('ো', 'ৎ'),
+  ('\u{9d7}', '\u{9d7}'), ('ড়', 'ঢ়'), ('য়', '\u{9e3}'), ('০', 'ৱ'),
+  ('ৼ', 'ৼ'), ('\u{9fe}', '\u{9fe}'), ('\u{a01}', 'ਃ'), ('ਅ', 'ਊ'),
+  ('ਏ', 'ਐ'), ('ਓ', 'ਨ'), ('ਪ', 'ਰ'), ('ਲ', 'ਲ਼'),
+  ('ਵ', 'ਸ਼'), ('ਸ', 'ਹ'), ('\u{a3c}', '\u{a3c}'), ('ਾ', '\u{a42}'),
+  ('\u{a47}', '\u{a48}'), ('\u{a4b}', '\u{a4d}'), ('\u{a51}', '\u{a51}'),
+  ('ਖ਼', 'ੜ'), ('ਫ਼', 'ਫ਼'), ('੦', '\u{a75}'), ('\u{a81}', 'ઃ'),
+  ('અ', 'ઍ'), ('એ', 'ઑ'), ('ઓ', 'ન'), ('પ', 'ર'),
+  ('લ', 'ળ'), ('વ', 'હ'), ('\u{abc}', '\u{ac5}'), ('\u{ac7}', 'ૉ'),
+  ('ો', '\u{acd}'), ('ૐ', 'ૐ'), ('ૠ', '\u{ae3}'), ('૦', '૯'),
+  ('ૹ', '\u{aff}'), ('\u{b01}', 'ଃ'), ('ଅ', 'ଌ'), ('ଏ', 'ଐ'),
+  ('ଓ', 'ନ'), ('ପ', 'ର'), ('ଲ', 'ଳ'), ('ଵ', 'ହ'),
+  ('\u{b3c}', '\u{b44}'), ('େ', 'ୈ'), ('ୋ', '\u{b4d}'),
+  ('\u{b56}', '\u{b57}'), ('ଡ଼', 'ଢ଼'), ('ୟ', '\u{b63}'), ('୦', '୯'),
+  ('ୱ', 'ୱ'), ('\u{b82}', 'ஃ'), ('அ', 'ஊ'), ('எ', 'ஐ'),
+  ('ஒ', 'க'), ('ங', 'ச'), ('ஜ', 'ஜ'), ('ஞ', 'ட'),
+  ('ண', 'த'), ('ந', 'ப'), ('ம', 'ஹ'), ('\u{bbe}', 'ூ'),
+  ('ெ', 'ை'), ('ொ', '\u{bcd}'), ('ௐ', 'ௐ'), ('\u{bd7}', '\u{bd7}'),
+  ('௦', '௯'), ('\u{c00}', 'ఌ'), ('ఎ', 'ఐ'), ('ఒ', 'న'),
+  ('ప', 'హ'), ('ఽ', 'ౄ'), ('\u{c46}', '\u{c48}'),
+  ('\u{c4a}', '\u{c4d}'), ('\u{c55}', '\u{c56}'), ('ౘ', 'ౚ'),
+  ('ౠ', '\u{c63}'), ('౦', '౯'), ('ಀ', 'ಃ'), ('ಅ', 'ಌ'),
+  ('ಎ', 'ಐ'), ('ಒ', 'ನ'), ('ಪ', 'ಳ'), ('ವ', 'ಹ'),
+  ('\u{cbc}', 'ೄ'), ('\u{cc6}', 'ೈ'), ('ೊ', '\u{ccd}'),
+  ('\u{cd5}', '\u{cd6}'), ('ೞ', 'ೞ'), ('ೠ', '\u{ce3}'), ('೦', '೯'),
+  ('ೱ', 'ೲ'), ('\u{d00}', 'ഃ'), ('അ', 'ഌ'), ('എ', 'ഐ'),
+  ('ഒ', '\u{d44}'), ('െ', 'ൈ'), ('ൊ', 'ൎ'), ('ൔ', '\u{d57}'),
+  ('ൟ', '\u{d63}'), ('൦', '൯'), ('ൺ', 'ൿ'), ('ං', 'ඃ'),
+  ('අ', 'ඖ'), ('ක', 'න'), ('ඳ', 'ර'), ('ල', 'ල'),
+  ('ව', 'ෆ'), ('\u{dca}', '\u{dca}'), ('\u{dcf}', '\u{dd4}'),
+  ('\u{dd6}', '\u{dd6}'), ('ෘ', '\u{ddf}'), ('෦', '෯'), ('ෲ', 'ෳ'),
+  ('ก', '\u{e3a}'), ('เ', '\u{e4e}'), ('๐', '๙'), ('ກ', 'ຂ'),
+  ('ຄ', 'ຄ'), ('\u{e86}', 'ຊ'), ('\u{e8c}', 'ຣ'), ('ລ', 'ລ'),
+  ('ວ', 'ຽ'), ('ເ', 'ໄ'), ('ໆ', 'ໆ'), ('\u{ec8}', '\u{ecd}'),
+  ('໐', '໙'), ('ໜ', 'ໟ'), ('ༀ', 'ༀ'), ('\u{f18}', '\u{f19}'),
+  ('༠', '༩'), ('\u{f35}', '\u{f35}'), ('\u{f37}', '\u{f37}'),
+  ('\u{f39}', '\u{f39}'), ('༾', 'ཇ'), ('ཉ', 'ཬ'),
+  ('\u{f71}', '\u{f84}'), ('\u{f86}', '\u{f97}'), ('\u{f99}', '\u{fbc}'),
+  ('\u{fc6}', '\u{fc6}'), ('က', '၉'), ('ၐ', '\u{109d}'), ('Ⴀ', 'Ⴥ'),
+  ('Ⴧ', 'Ⴧ'), ('Ⴭ', 'Ⴭ'), ('ა', 'ჺ'), ('ჼ', 'ቈ'),
+  ('ቊ', 'ቍ'), ('ቐ', 'ቖ'), ('ቘ', 'ቘ'), ('ቚ', 'ቝ'),
+  ('በ', 'ኈ'), ('ኊ', 'ኍ'), ('ነ', 'ኰ'), ('ኲ', 'ኵ'),
+  ('ኸ', 'ኾ'), ('ዀ', 'ዀ'), ('ዂ', 'ዅ'), ('ወ', 'ዖ'),
+  ('ዘ', 'ጐ'), ('ጒ', 'ጕ'), ('ጘ', 'ፚ'), ('\u{135d}', '\u{135f}'),
+  ('ᎀ', 'ᎏ'), ('Ꭰ', 'Ᏽ'), ('ᏸ', 'ᏽ'), ('ᐁ', 'ᙬ'),
+  ('ᙯ', 'ᙿ'), ('ᚁ', 'ᚚ'), ('ᚠ', 'ᛪ'), ('ᛮ', 'ᛸ'),
+  ('ᜀ', 'ᜌ'), ('ᜎ', '\u{1714}'), ('ᜠ', '\u{1734}'),
+  ('ᝀ', '\u{1753}'), ('ᝠ', 'ᝬ'), ('ᝮ', 'ᝰ'),
+  ('\u{1772}', '\u{1773}'), ('ក', '\u{17d3}'), ('ៗ', 'ៗ'),
+  ('ៜ', '\u{17dd}'), ('០', '៩'), ('\u{180b}', '\u{180d}'),
+  ('᠐', '᠙'), ('ᠠ', 'ᡸ'), ('ᢀ', 'ᢪ'), ('ᢰ', 'ᣵ'),
+  ('ᤀ', 'ᤞ'), ('\u{1920}', 'ᤫ'), ('ᤰ', '\u{193b}'), ('᥆', 'ᥭ'),
+  ('ᥰ', 'ᥴ'), ('ᦀ', 'ᦫ'), ('ᦰ', 'ᧉ'), ('᧐', '᧙'),
+  ('ᨀ', '\u{1a1b}'), ('ᨠ', '\u{1a5e}'), ('\u{1a60}', '\u{1a7c}'),
+  ('\u{1a7f}', '᪉'), ('᪐', '᪙'), ('ᪧ', 'ᪧ'),
+  ('\u{1ab0}', '\u{1abe}'), ('\u{1b00}', 'ᭋ'), ('᭐', '᭙'),
+  ('\u{1b6b}', '\u{1b73}'), ('\u{1b80}', '᯳'), ('ᰀ', '\u{1c37}'),
+  ('᱀', '᱉'), ('ᱍ', 'ᱽ'), ('ᲀ', 'ᲈ'), ('Ა', 'Ჺ'),
+  ('Ჽ', 'Ჿ'), ('\u{1cd0}', '\u{1cd2}'), ('\u{1cd4}', '\u{1cfa}'),
+  ('ᴀ', '\u{1df9}'), ('\u{1dfb}', 'ἕ'), ('Ἐ', 'Ἕ'), ('ἠ', 'ὅ'),
+  ('Ὀ', 'Ὅ'), ('ὐ', 'ὗ'), ('Ὑ', 'Ὑ'), ('Ὓ', 'Ὓ'),
+  ('Ὕ', 'Ὕ'), ('Ὗ', 'ώ'), ('ᾀ', 'ᾴ'), ('ᾶ', 'ᾼ'),
+  ('ι', 'ι'), ('ῂ', 'ῄ'), ('ῆ', 'ῌ'), ('ῐ', 'ΐ'),
+  ('ῖ', 'Ί'), ('ῠ', 'Ῥ'), ('ῲ', 'ῴ'), ('ῶ', 'ῼ'),
+  ('\u{200c}', '\u{200d}'), ('‿', '⁀'), ('⁔', '⁔'), ('ⁱ', 'ⁱ'),
+  ('ⁿ', 'ⁿ'), ('ₐ', 'ₜ'), ('\u{20d0}', '\u{20f0}'), ('ℂ', 'ℂ'),
+  ('ℇ', 'ℇ'), ('ℊ', 'ℓ'), ('ℕ', 'ℕ'), ('ℙ', 'ℝ'),
+  ('ℤ', 'ℤ'), ('Ω', 'Ω'), ('ℨ', 'ℨ'), ('K', 'ℭ'),
+  ('ℯ', 'ℹ'), ('ℼ', 'ℿ'), ('ⅅ', 'ⅉ'), ('ⅎ', 'ⅎ'),
+  ('Ⅰ', 'ↈ'), ('Ⓐ', 'ⓩ'), ('Ⰰ', 'Ⱞ'), ('ⰰ', 'ⱞ'),
+  ('Ⱡ', 'ⳤ'), ('Ⳬ', 'ⳳ'), ('ⴀ', 'ⴥ'), ('ⴧ', 'ⴧ'),
+  ('ⴭ', 'ⴭ'), ('ⴰ', 'ⵧ'), ('ⵯ', 'ⵯ'), ('\u{2d7f}', 'ⶖ'),
+  ('ⶠ', 'ⶦ'), ('ⶨ', 'ⶮ'), ('ⶰ', 'ⶶ'), ('ⶸ', 'ⶾ'),
+  ('ⷀ', 'ⷆ'), ('ⷈ', 'ⷎ'), ('ⷐ', 'ⷖ'), ('ⷘ', 'ⷞ'),
+  ('\u{2de0}', '\u{2dff}'), ('ⸯ', 'ⸯ'), ('々', '〇'),
+  ('〡', '\u{302f}'), ('〱', '〵'), ('〸', '〼'), ('ぁ', 'ゖ'),
+  ('\u{3099}', '\u{309a}'), ('ゝ', 'ゟ'), ('ァ', 'ヺ'), ('ー', 'ヿ'),
+  ('ㄅ', 'ㄯ'), ('ㄱ', 'ㆎ'), ('ㆠ', 'ㆺ'), ('ㇰ', 'ㇿ'),
+  ('㐀', '䶵'), ('一', '鿯'), ('ꀀ', 'ꒌ'), ('ꓐ', 'ꓽ'),
+  ('ꔀ', 'ꘌ'), ('ꘐ', 'ꘫ'), ('Ꙁ', '\u{a672}'),
+  ('\u{a674}', '\u{a67d}'), ('ꙿ', '\u{a6f1}'), ('ꜗ', 'ꜟ'),
+  ('Ꜣ', 'ꞈ'), ('Ꞌ', '\u{a7bf}'), ('\u{a7c2}', '\u{a7c6}'),
+  ('ꟷ', 'ꠧ'), ('ꡀ', 'ꡳ'), ('ꢀ', '\u{a8c5}'), ('꣐', '꣙'),
+  ('\u{a8e0}', 'ꣷ'), ('ꣻ', 'ꣻ'), ('ꣽ', '\u{a92d}'), ('ꤰ', '꥓'),
+  ('ꥠ', 'ꥼ'), ('\u{a980}', '꧀'), ('ꧏ', '꧙'), ('ꧠ', 'ꧾ'),
+  ('ꨀ', '\u{aa36}'), ('ꩀ', 'ꩍ'), ('꩐', '꩙'), ('ꩠ', 'ꩶ'),
+  ('ꩺ', 'ꫂ'), ('ꫛ', 'ꫝ'), ('ꫠ', 'ꫯ'), ('ꫲ', '\u{aaf6}'),
+  ('ꬁ', 'ꬆ'), ('ꬉ', 'ꬎ'), ('ꬑ', 'ꬖ'), ('ꬠ', 'ꬦ'),
+  ('ꬨ', 'ꬮ'), ('ꬰ', 'ꭚ'), ('ꭜ', '\u{ab67}'), ('ꭰ', 'ꯪ'),
+  ('꯬', '\u{abed}'), ('꯰', '꯹'), ('가', '힣'), ('ힰ', 'ퟆ'),
+  ('ퟋ', 'ퟻ'), ('豈', '舘'), ('並', '龎'), ('ff', 'st'),
+  ('ﬓ', 'ﬗ'), ('יִ', 'ﬨ'), ('שׁ', 'זּ'), ('טּ', 'לּ'),
+  ('מּ', 'מּ'), ('נּ', 'סּ'), ('ףּ', 'פּ'), ('צּ', 'ﮱ'),
+  ('ﯓ', 'ﴽ'), ('ﵐ', 'ﶏ'), ('ﶒ', 'ﷇ'), ('ﷰ', 'ﷻ'),
+  ('\u{fe00}', '\u{fe0f}'), ('\u{fe20}', '\u{fe2f}'), ('︳', '︴'),
+  ('﹍', '﹏'), ('ﹰ', 'ﹴ'), ('ﹶ', 'ﻼ'), ('0', '9'),
+  ('A', 'Z'), ('_', '_'), ('a', 'z'), ('ヲ', 'ᄒ'),
+  ('ᅡ', 'ᅦ'), ('ᅧ', 'ᅬ'), ('ᅭ', 'ᅲ'), ('ᅳ', 'ᅵ'),
+  ('𐀀', '𐀋'), ('𐀍', '𐀦'), ('𐀨', '𐀺'), ('𐀼', '𐀽'),
+  ('𐀿', '𐁍'), ('𐁐', '𐁝'), ('𐂀', '𐃺'), ('𐅀', '𐅴'),
+  ('\u{101fd}', '\u{101fd}'), ('𐊀', '𐊜'), ('𐊠', '𐋐'),
+  ('\u{102e0}', '\u{102e0}'), ('𐌀', '𐌟'), ('𐌭', '𐍊'),
+  ('𐍐', '\u{1037a}'), ('𐎀', '𐎝'), ('𐎠', '𐏃'), ('𐏈', '𐏏'),
+  ('𐏑', '𐏕'), ('𐐀', '𐒝'), ('𐒠', '𐒩'), ('𐒰', '𐓓'),
+  ('𐓘', '𐓻'), ('𐔀', '𐔧'), ('𐔰', '𐕣'), ('𐘀', '𐜶'),
+  ('𐝀', '𐝕'), ('𐝠', '𐝧'), ('𐠀', '𐠅'), ('𐠈', '𐠈'),
+  ('𐠊', '𐠵'), ('𐠷', '𐠸'), ('𐠼', '𐠼'), ('𐠿', '𐡕'),
+  ('𐡠', '𐡶'), ('𐢀', '𐢞'), ('𐣠', '𐣲'), ('𐣴', '𐣵'),
+  ('𐤀', '𐤕'), ('𐤠', '𐤹'), ('𐦀', '𐦷'), ('𐦾', '𐦿'),
+  ('𐨀', '\u{10a03}'), ('\u{10a05}', '\u{10a06}'), ('\u{10a0c}', '𐨓'),
+  ('𐨕', '𐨗'), ('𐨙', '𐨵'), ('\u{10a38}', '\u{10a3a}'),
+  ('\u{10a3f}', '\u{10a3f}'), ('𐩠', '𐩼'), ('𐪀', '𐪜'),
+  ('𐫀', '𐫇'), ('𐫉', '\u{10ae6}'), ('𐬀', '𐬵'), ('𐭀', '𐭕'),
+  ('𐭠', '𐭲'), ('𐮀', '𐮑'), ('𐰀', '𐱈'), ('𐲀', '𐲲'),
+  ('𐳀', '𐳲'), ('𐴀', '\u{10d27}'), ('𐴰', '𐴹'), ('𐼀', '𐼜'),
+  ('𐼧', '𐼧'), ('𐼰', '\u{10f50}'), ('\u{10fe0}', '\u{10ff6}'),
+  ('𑀀', '\u{11046}'), ('𑁦', '𑁯'), ('\u{1107f}', '\u{110ba}'),
+  ('𑃐', '𑃨'), ('𑃰', '𑃹'), ('\u{11100}', '\u{11134}'),
+  ('𑄶', '𑄿'), ('𑅄', '𑅆'), ('𑅐', '\u{11173}'), ('𑅶', '𑅶'),
+  ('\u{11180}', '𑇄'), ('\u{111c9}', '\u{111cc}'), ('𑇐', '𑇚'),
+  ('𑇜', '𑇜'), ('𑈀', '𑈑'), ('𑈓', '\u{11237}'),
+  ('\u{1123e}', '\u{1123e}'), ('𑊀', '𑊆'), ('𑊈', '𑊈'),
+  ('𑊊', '𑊍'), ('𑊏', '𑊝'), ('𑊟', '𑊨'), ('𑊰', '\u{112ea}'),
+  ('𑋰', '𑋹'), ('\u{11300}', '𑌃'), ('𑌅', '𑌌'), ('𑌏', '𑌐'),
+  ('𑌓', '𑌨'), ('𑌪', '𑌰'), ('𑌲', '𑌳'), ('𑌵', '𑌹'),
+  ('\u{1133b}', '𑍄'), ('𑍇', '𑍈'), ('𑍋', '𑍍'), ('𑍐', '𑍐'),
+  ('\u{11357}', '\u{11357}'), ('𑍝', '𑍣'), ('\u{11366}', '\u{1136c}'),
+  ('\u{11370}', '\u{11374}'), ('𑐀', '𑑊'), ('𑑐', '𑑙'),
+  ('\u{1145e}', '\u{1145f}'), ('𑒀', '𑓅'), ('𑓇', '𑓇'),
+  ('𑓐', '𑓙'), ('𑖀', '\u{115b5}'), ('𑖸', '\u{115c0}'),
+  ('𑗘', '\u{115dd}'), ('𑘀', '\u{11640}'), ('𑙄', '𑙄'),
+  ('𑙐', '𑙙'), ('𑚀', '\u{116b8}'), ('𑛀', '𑛉'), ('𑜀', '𑜚'),
+  ('\u{1171d}', '\u{1172b}'), ('𑜰', '𑜹'), ('𑠀', '\u{1183a}'),
+  ('𑢠', '𑣩'), ('𑣿', '𑣿'), ('\u{119a0}', '\u{119a7}'),
+  ('\u{119aa}', '\u{119d7}'), ('\u{119da}', '\u{119e1}'),
+  ('\u{119e3}', '\u{119e4}'), ('𑨀', '\u{11a3e}'),
+  ('\u{11a47}', '\u{11a47}'), ('𑩐', '\u{11a99}'), ('𑪝', '𑪝'),
+  ('𑫀', '𑫸'), ('𑰀', '𑰈'), ('𑰊', '\u{11c36}'),
+  ('\u{11c38}', '𑱀'), ('𑱐', '𑱙'), ('𑱲', '𑲏'),
+  ('\u{11c92}', '\u{11ca7}'), ('𑲩', '\u{11cb6}'), ('𑴀', '𑴆'),
+  ('𑴈', '𑴉'), ('𑴋', '\u{11d36}'), ('\u{11d3a}', '\u{11d3a}'),
+  ('\u{11d3c}', '\u{11d3d}'), ('\u{11d3f}', '\u{11d47}'), ('𑵐', '𑵙'),
+  ('𑵠', '𑵥'), ('𑵧', '𑵨'), ('𑵪', '𑶎'),
+  ('\u{11d90}', '\u{11d91}'), ('𑶓', '𑶘'), ('𑶠', '𑶩'),
+  ('𑻠', '𑻶'), ('𒀀', '𒎙'), ('𒐀', '𒑮'), ('𒒀', '𒕃'),
+  ('𓀀', '𓐮'), ('𔐀', '𔙆'), ('𖠀', '𖨸'), ('𖩀', '𖩞'),
+  ('𖩠', '𖩩'), ('𖫐', '𖫭'), ('\u{16af0}', '\u{16af4}'),
+  ('𖬀', '\u{16b36}'), ('𖭀', '𖭃'), ('𖭐', '𖭙'), ('𖭣', '𖭷'),
+  ('𖭽', '𖮏'), ('𖹀', '𖹿'), ('𖼀', '\u{16f4a}'),
+  ('\u{16f4f}', '\u{16f87}'), ('\u{16f8f}', '𖾟'), ('𖿠', '𖿡'),
+  ('\u{16fe3}', '\u{16fe3}'), ('𗀀', '\u{187f7}'), ('𘠀', '𘫲'),
+  ('𛀀', '𛄞'), ('\u{1b150}', '\u{1b152}'), ('\u{1b164}', '\u{1b167}'),
+  ('𛅰', '𛋻'), ('𛰀', '𛱪'), ('𛱰', '𛱼'), ('𛲀', '𛲈'),
+  ('𛲐', '𛲙'), ('\u{1bc9d}', '\u{1bc9e}'), ('\u{1d165}', '\u{1d169}'),
+  ('𝅭', '\u{1d172}'), ('\u{1d17b}', '\u{1d182}'),
+  ('\u{1d185}', '\u{1d18b}'), ('\u{1d1aa}', '\u{1d1ad}'),
+  ('\u{1d242}', '\u{1d244}'), ('𝐀', '𝑔'), ('𝑖', '𝒜'),
+  ('𝒞', '𝒟'), ('𝒢', '𝒢'), ('𝒥', '𝒦'), ('𝒩', '𝒬'),
+  ('𝒮', '𝒹'), ('𝒻', '𝒻'), ('𝒽', '𝓃'), ('𝓅', '𝔅'),
+  ('𝔇', '𝔊'), ('𝔍', '𝔔'), ('𝔖', '𝔜'), ('𝔞', '𝔹'),
+  ('𝔻', '𝔾'), ('𝕀', '𝕄'), ('𝕆', '𝕆'), ('𝕊', '𝕐'),
+  ('𝕒', '𝚥'), ('𝚨', '𝛀'), ('𝛂', '𝛚'), ('𝛜', '𝛺'),
+  ('𝛼', '𝜔'), ('𝜖', '𝜴'), ('𝜶', '𝝎'), ('𝝐', '𝝮'),
+  ('𝝰', '𝞈'), ('𝞊', '𝞨'), ('𝞪', '𝟂'), ('𝟄', '𝟋'),
+  ('𝟎', '𝟿'), ('\u{1da00}', '\u{1da36}'), ('\u{1da3b}', '\u{1da6c}'),
+  ('\u{1da75}', '\u{1da75}'), ('\u{1da84}', '\u{1da84}'),
+  ('\u{1da9b}', '\u{1da9f}'), ('\u{1daa1}', '\u{1daaf}'),
+  ('\u{1e000}', '\u{1e006}'), ('\u{1e008}', '\u{1e018}'),
+  ('\u{1e01b}', '\u{1e021}'), ('\u{1e023}', '\u{1e024}'),
+  ('\u{1e026}', '\u{1e02a}'), ('\u{1e100}', '\u{1e12c}'),
+  ('\u{1e130}', '\u{1e13d}'), ('\u{1e140}', '\u{1e149}'),
+  ('\u{1e14e}', '\u{1e14e}'), ('\u{1e2c0}', '\u{1e2f9}'), ('𞠀', '𞣄'),
+  ('\u{1e8d0}', '\u{1e8d6}'), ('𞤀', '\u{1e94b}'), ('𞥐', '𞥙'),
+  ('𞸀', '𞸃'), ('𞸅', '𞸟'), ('𞸡', '𞸢'), ('𞸤', '𞸤'),
+  ('𞸧', '𞸧'), ('𞸩', '𞸲'), ('𞸴', '𞸷'), ('𞸹', '𞸹'),
+  ('𞸻', '𞸻'), ('𞹂', '𞹂'), ('𞹇', '𞹇'), ('𞹉', '𞹉'),
+  ('𞹋', '𞹋'), ('𞹍', '𞹏'), ('𞹑', '𞹒'), ('𞹔', '𞹔'),
+  ('𞹗', '𞹗'), ('𞹙', '𞹙'), ('𞹛', '𞹛'), ('𞹝', '𞹝'),
+  ('𞹟', '𞹟'), ('𞹡', '𞹢'), ('𞹤', '𞹤'), ('𞹧', '𞹪'),
+  ('𞹬', '𞹲'), ('𞹴', '𞹷'), ('𞹹', '𞹼'), ('𞹾', '𞹾'),
+  ('𞺀', '𞺉'), ('𞺋', '𞺛'), ('𞺡', '𞺣'), ('𞺥', '𞺩'),
+  ('𞺫', '𞺻'), ('🄰', '🅉'), ('🅐', '🅩'), ('🅰', '🆉'),
+  ('𠀀', '𪛖'), ('𪜀', '𫜴'), ('𫝀', '𫠝'), ('𫠠', '𬺡'),
+  ('𬺰', '𮯠'), ('丽', '𪘀'), ('\u{e0100}', '\u{e01ef}'),
+];
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/unicode_tables/property_bool.rs.html b/target/doc/src/regex_syntax/unicode_tables/property_bool.rs.html new file mode 100644 index 0000000..f9180af --- /dev/null +++ b/target/doc/src/regex_syntax/unicode_tables/property_bool.rs.html @@ -0,0 +1,6071 @@ +property_bool.rs.html -- source
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+2035
+2036
+2037
+2038
+2039
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2047
+2048
+2049
+2050
+2051
+2052
+2053
+2054
+2055
+2056
+2057
+2058
+2059
+2060
+2061
+2062
+2063
+2064
+2065
+2066
+2067
+2068
+2069
+2070
+2071
+2072
+2073
+2074
+2075
+2076
+2077
+2078
+2079
+2080
+2081
+2082
+2083
+2084
+2085
+2086
+2087
+2088
+2089
+2090
+2091
+2092
+2093
+2094
+2095
+2096
+2097
+2098
+2099
+2100
+2101
+2102
+2103
+2104
+2105
+2106
+2107
+2108
+2109
+2110
+2111
+2112
+2113
+2114
+2115
+2116
+2117
+2118
+2119
+2120
+2121
+2122
+2123
+2124
+2125
+2126
+2127
+2128
+2129
+2130
+2131
+2132
+2133
+2134
+2135
+2136
+2137
+2138
+2139
+2140
+2141
+2142
+2143
+2144
+2145
+2146
+2147
+2148
+2149
+2150
+2151
+2152
+2153
+2154
+2155
+2156
+2157
+2158
+2159
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
+2178
+2179
+2180
+2181
+2182
+2183
+2184
+2185
+2186
+2187
+2188
+2189
+2190
+2191
+2192
+2193
+2194
+2195
+2196
+2197
+2198
+2199
+2200
+2201
+2202
+2203
+2204
+2205
+2206
+2207
+2208
+2209
+2210
+2211
+2212
+2213
+2214
+2215
+2216
+2217
+2218
+2219
+2220
+2221
+2222
+2223
+2224
+2225
+2226
+2227
+2228
+2229
+2230
+2231
+2232
+2233
+2234
+2235
+2236
+2237
+2238
+2239
+2240
+2241
+2242
+2243
+2244
+2245
+2246
+2247
+2248
+2249
+2250
+2251
+2252
+2253
+2254
+2255
+2256
+2257
+2258
+2259
+2260
+2261
+2262
+2263
+2264
+2265
+2266
+2267
+2268
+2269
+2270
+2271
+2272
+2273
+2274
+2275
+2276
+2277
+2278
+2279
+2280
+2281
+2282
+2283
+2284
+2285
+2286
+2287
+2288
+2289
+2290
+2291
+2292
+2293
+2294
+2295
+2296
+2297
+2298
+2299
+2300
+2301
+2302
+2303
+2304
+2305
+2306
+2307
+2308
+2309
+2310
+2311
+2312
+2313
+2314
+2315
+2316
+2317
+2318
+2319
+2320
+2321
+2322
+2323
+2324
+2325
+2326
+2327
+2328
+2329
+2330
+2331
+2332
+2333
+2334
+2335
+2336
+2337
+2338
+2339
+2340
+2341
+2342
+2343
+2344
+2345
+2346
+2347
+2348
+2349
+2350
+2351
+2352
+2353
+2354
+2355
+2356
+2357
+2358
+2359
+2360
+2361
+2362
+2363
+2364
+2365
+2366
+2367
+2368
+2369
+2370
+2371
+2372
+2373
+2374
+2375
+2376
+2377
+2378
+2379
+2380
+2381
+2382
+2383
+2384
+2385
+2386
+2387
+2388
+2389
+2390
+2391
+2392
+2393
+2394
+2395
+2396
+2397
+2398
+2399
+2400
+2401
+2402
+2403
+2404
+2405
+2406
+2407
+2408
+2409
+2410
+2411
+2412
+2413
+2414
+2415
+2416
+2417
+2418
+2419
+2420
+2421
+2422
+2423
+2424
+2425
+2426
+2427
+2428
+2429
+2430
+2431
+2432
+2433
+2434
+2435
+2436
+2437
+2438
+2439
+2440
+2441
+2442
+2443
+2444
+2445
+2446
+2447
+2448
+2449
+2450
+2451
+2452
+2453
+2454
+2455
+2456
+2457
+2458
+2459
+2460
+2461
+2462
+2463
+2464
+2465
+2466
+2467
+2468
+2469
+2470
+2471
+2472
+2473
+2474
+2475
+2476
+2477
+2478
+2479
+2480
+2481
+2482
+2483
+2484
+2485
+2486
+2487
+2488
+2489
+2490
+2491
+2492
+2493
+2494
+2495
+2496
+2497
+2498
+2499
+2500
+2501
+2502
+2503
+2504
+2505
+2506
+2507
+2508
+2509
+2510
+2511
+2512
+2513
+2514
+2515
+2516
+2517
+2518
+2519
+2520
+2521
+2522
+2523
+2524
+2525
+2526
+2527
+2528
+2529
+2530
+2531
+2532
+2533
+2534
+2535
+2536
+2537
+2538
+2539
+2540
+2541
+2542
+2543
+2544
+2545
+2546
+2547
+2548
+2549
+2550
+2551
+2552
+2553
+2554
+2555
+2556
+2557
+2558
+2559
+2560
+2561
+2562
+2563
+2564
+2565
+2566
+2567
+2568
+2569
+2570
+2571
+2572
+2573
+2574
+2575
+2576
+2577
+2578
+2579
+2580
+2581
+2582
+2583
+2584
+2585
+2586
+2587
+2588
+2589
+2590
+2591
+2592
+2593
+2594
+2595
+2596
+2597
+2598
+2599
+2600
+2601
+2602
+2603
+2604
+2605
+2606
+2607
+2608
+2609
+2610
+2611
+2612
+2613
+2614
+2615
+2616
+2617
+2618
+2619
+2620
+2621
+2622
+2623
+2624
+2625
+2626
+2627
+2628
+2629
+2630
+2631
+2632
+2633
+2634
+2635
+2636
+2637
+2638
+2639
+2640
+2641
+2642
+2643
+2644
+2645
+2646
+2647
+2648
+2649
+2650
+2651
+2652
+2653
+2654
+2655
+2656
+2657
+2658
+2659
+2660
+2661
+2662
+2663
+2664
+2665
+2666
+2667
+2668
+2669
+2670
+2671
+2672
+2673
+2674
+2675
+2676
+2677
+2678
+2679
+2680
+2681
+2682
+2683
+2684
+2685
+2686
+2687
+2688
+2689
+2690
+2691
+2692
+2693
+2694
+2695
+2696
+2697
+2698
+2699
+2700
+2701
+2702
+2703
+2704
+2705
+2706
+2707
+2708
+2709
+2710
+2711
+2712
+2713
+2714
+2715
+2716
+2717
+2718
+2719
+2720
+2721
+2722
+2723
+2724
+2725
+2726
+2727
+2728
+2729
+2730
+2731
+2732
+2733
+2734
+2735
+2736
+2737
+2738
+2739
+2740
+2741
+2742
+2743
+2744
+2745
+2746
+2747
+2748
+2749
+2750
+2751
+2752
+2753
+2754
+2755
+2756
+2757
+2758
+2759
+2760
+2761
+2762
+2763
+2764
+2765
+2766
+2767
+2768
+2769
+2770
+2771
+2772
+2773
+2774
+2775
+2776
+2777
+2778
+2779
+2780
+2781
+2782
+2783
+2784
+2785
+2786
+2787
+2788
+2789
+2790
+2791
+2792
+2793
+2794
+2795
+2796
+2797
+2798
+2799
+2800
+2801
+2802
+2803
+2804
+2805
+2806
+2807
+2808
+2809
+2810
+2811
+2812
+2813
+2814
+2815
+2816
+2817
+2818
+2819
+2820
+2821
+2822
+2823
+2824
+2825
+2826
+2827
+2828
+2829
+2830
+2831
+2832
+2833
+2834
+2835
+2836
+2837
+2838
+2839
+2840
+2841
+2842
+2843
+2844
+2845
+2846
+2847
+2848
+2849
+2850
+2851
+2852
+2853
+2854
+2855
+2856
+2857
+2858
+2859
+2860
+2861
+2862
+2863
+2864
+2865
+2866
+2867
+2868
+2869
+2870
+2871
+2872
+2873
+2874
+2875
+2876
+2877
+2878
+2879
+2880
+2881
+2882
+2883
+2884
+2885
+2886
+2887
+2888
+2889
+2890
+2891
+2892
+2893
+2894
+2895
+2896
+2897
+2898
+2899
+2900
+2901
+2902
+2903
+2904
+2905
+2906
+2907
+2908
+2909
+2910
+2911
+2912
+2913
+2914
+2915
+2916
+2917
+2918
+2919
+2920
+2921
+2922
+2923
+2924
+2925
+2926
+2927
+2928
+2929
+2930
+2931
+2932
+2933
+2934
+2935
+2936
+2937
+2938
+2939
+2940
+2941
+2942
+2943
+2944
+2945
+2946
+2947
+2948
+2949
+2950
+2951
+2952
+2953
+2954
+2955
+2956
+2957
+2958
+2959
+2960
+2961
+2962
+2963
+2964
+2965
+2966
+2967
+2968
+2969
+2970
+2971
+2972
+2973
+2974
+2975
+2976
+2977
+2978
+2979
+2980
+2981
+2982
+2983
+2984
+2985
+2986
+2987
+2988
+2989
+2990
+2991
+2992
+2993
+2994
+2995
+2996
+2997
+2998
+2999
+3000
+3001
+3002
+3003
+3004
+3005
+3006
+3007
+3008
+3009
+3010
+3011
+3012
+3013
+3014
+3015
+3016
+3017
+3018
+3019
+3020
+3021
+3022
+3023
+3024
+3025
+3026
+3027
+3028
+3029
+3030
+3031
+3032
+3033
+3034
+
+// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
+//
+//  ucd-generate property-bool /tmp/ucd-12.1.0/ --chars
+//
+// ucd-generate is available on crates.io.
+
+pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
+  ("ASCII_Hex_Digit", ASCII_HEX_DIGIT), ("Alphabetic", ALPHABETIC),
+  ("Bidi_Control", BIDI_CONTROL), ("Case_Ignorable", CASE_IGNORABLE),
+  ("Cased", CASED), ("Changes_When_Casefolded", CHANGES_WHEN_CASEFOLDED),
+  ("Changes_When_Casemapped", CHANGES_WHEN_CASEMAPPED),
+  ("Changes_When_Lowercased", CHANGES_WHEN_LOWERCASED),
+  ("Changes_When_Titlecased", CHANGES_WHEN_TITLECASED),
+  ("Changes_When_Uppercased", CHANGES_WHEN_UPPERCASED), ("Dash", DASH),
+  ("Default_Ignorable_Code_Point", DEFAULT_IGNORABLE_CODE_POINT),
+  ("Deprecated", DEPRECATED), ("Diacritic", DIACRITIC), ("Emoji", EMOJI),
+  ("Emoji_Component", EMOJI_COMPONENT), ("Emoji_Modifier", EMOJI_MODIFIER),
+  ("Emoji_Modifier_Base", EMOJI_MODIFIER_BASE),
+  ("Emoji_Presentation", EMOJI_PRESENTATION),
+  ("Extended_Pictographic", EXTENDED_PICTOGRAPHIC), ("Extender", EXTENDER),
+  ("Grapheme_Base", GRAPHEME_BASE), ("Grapheme_Extend", GRAPHEME_EXTEND),
+  ("Grapheme_Link", GRAPHEME_LINK), ("Hex_Digit", HEX_DIGIT),
+  ("Hyphen", HYPHEN), ("IDS_Binary_Operator", IDS_BINARY_OPERATOR),
+  ("IDS_Trinary_Operator", IDS_TRINARY_OPERATOR),
+  ("ID_Continue", ID_CONTINUE), ("ID_Start", ID_START),
+  ("Ideographic", IDEOGRAPHIC), ("Join_Control", JOIN_CONTROL),
+  ("Logical_Order_Exception", LOGICAL_ORDER_EXCEPTION),
+  ("Lowercase", LOWERCASE), ("Math", MATH),
+  ("Noncharacter_Code_Point", NONCHARACTER_CODE_POINT),
+  ("Other_Alphabetic", OTHER_ALPHABETIC),
+  ("Other_Default_Ignorable_Code_Point", OTHER_DEFAULT_IGNORABLE_CODE_POINT),
+  ("Other_Grapheme_Extend", OTHER_GRAPHEME_EXTEND),
+  ("Other_ID_Continue", OTHER_ID_CONTINUE),
+  ("Other_ID_Start", OTHER_ID_START), ("Other_Lowercase", OTHER_LOWERCASE),
+  ("Other_Math", OTHER_MATH), ("Other_Uppercase", OTHER_UPPERCASE),
+  ("Pattern_Syntax", PATTERN_SYNTAX),
+  ("Pattern_White_Space", PATTERN_WHITE_SPACE),
+  ("Prepended_Concatenation_Mark", PREPENDED_CONCATENATION_MARK),
+  ("Quotation_Mark", QUOTATION_MARK), ("Radical", RADICAL),
+  ("Regional_Indicator", REGIONAL_INDICATOR),
+  ("Sentence_Terminal", SENTENCE_TERMINAL), ("Soft_Dotted", SOFT_DOTTED),
+  ("Terminal_Punctuation", TERMINAL_PUNCTUATION),
+  ("Unified_Ideograph", UNIFIED_IDEOGRAPH), ("Uppercase", UPPERCASE),
+  ("Variation_Selector", VARIATION_SELECTOR), ("White_Space", WHITE_SPACE),
+  ("XID_Continue", XID_CONTINUE), ("XID_Start", XID_START),
+];
+
+pub const ASCII_HEX_DIGIT: &'static [(char, char)] = &[
+  ('0', '9'), ('A', 'F'), ('a', 'f'),
+];
+
+pub const ALPHABETIC: &'static [(char, char)] = &[
+  ('A', 'Z'), ('a', 'z'), ('ª', 'ª'), ('µ', 'µ'), ('º', 'º'),
+  ('À', 'Ö'), ('Ø', 'ö'), ('ø', 'ˁ'), ('ˆ', 'ˑ'), ('ˠ', 'ˤ'),
+  ('ˬ', 'ˬ'), ('ˮ', 'ˮ'), ('\u{345}', '\u{345}'), ('Ͱ', 'ʹ'),
+  ('Ͷ', 'ͷ'), ('ͺ', 'ͽ'), ('Ϳ', 'Ϳ'), ('Ά', 'Ά'), ('Έ', 'Ί'),
+  ('Ό', 'Ό'), ('Ύ', 'Ρ'), ('Σ', 'ϵ'), ('Ϸ', 'ҁ'), ('Ҋ', 'ԯ'),
+  ('Ա', 'Ֆ'), ('ՙ', 'ՙ'), ('ՠ', 'ֈ'), ('\u{5b0}', '\u{5bd}'),
+  ('\u{5bf}', '\u{5bf}'), ('\u{5c1}', '\u{5c2}'), ('\u{5c4}', '\u{5c5}'),
+  ('\u{5c7}', '\u{5c7}'), ('א', 'ת'), ('ׯ', 'ײ'), ('\u{610}', '\u{61a}'),
+  ('ؠ', '\u{657}'), ('\u{659}', '\u{65f}'), ('ٮ', 'ۓ'), ('ە', '\u{6dc}'),
+  ('\u{6e1}', '\u{6e8}'), ('\u{6ed}', 'ۯ'), ('ۺ', 'ۼ'), ('ۿ', 'ۿ'),
+  ('ܐ', '\u{73f}'), ('ݍ', 'ޱ'), ('ߊ', 'ߪ'), ('ߴ', 'ߵ'), ('ߺ', 'ߺ'),
+  ('ࠀ', '\u{817}'), ('ࠚ', '\u{82c}'), ('ࡀ', 'ࡘ'), ('ࡠ', 'ࡪ'),
+  ('ࢠ', 'ࢴ'), ('ࢶ', 'ࢽ'), ('\u{8d4}', '\u{8df}'),
+  ('\u{8e3}', '\u{8e9}'), ('\u{8f0}', 'ऻ'), ('ऽ', 'ौ'), ('ॎ', 'ॐ'),
+  ('\u{955}', '\u{963}'), ('ॱ', 'ঃ'), ('অ', 'ঌ'), ('এ', 'ঐ'),
+  ('ও', 'ন'), ('প', 'র'), ('ল', 'ল'), ('শ', 'হ'),
+  ('ঽ', '\u{9c4}'), ('ে', 'ৈ'), ('ো', 'ৌ'), ('ৎ', 'ৎ'),
+  ('\u{9d7}', '\u{9d7}'), ('ড়', 'ঢ়'), ('য়', '\u{9e3}'), ('ৰ', 'ৱ'),
+  ('ৼ', 'ৼ'), ('\u{a01}', 'ਃ'), ('ਅ', 'ਊ'), ('ਏ', 'ਐ'),
+  ('ਓ', 'ਨ'), ('ਪ', 'ਰ'), ('ਲ', 'ਲ਼'), ('ਵ', 'ਸ਼'),
+  ('ਸ', 'ਹ'), ('ਾ', '\u{a42}'), ('\u{a47}', '\u{a48}'),
+  ('\u{a4b}', '\u{a4c}'), ('\u{a51}', '\u{a51}'), ('ਖ਼', 'ੜ'),
+  ('ਫ਼', 'ਫ਼'), ('\u{a70}', '\u{a75}'), ('\u{a81}', 'ઃ'), ('અ', 'ઍ'),
+  ('એ', 'ઑ'), ('ઓ', 'ન'), ('પ', 'ર'), ('લ', 'ળ'),
+  ('વ', 'હ'), ('ઽ', '\u{ac5}'), ('\u{ac7}', 'ૉ'), ('ો', 'ૌ'),
+  ('ૐ', 'ૐ'), ('ૠ', '\u{ae3}'), ('ૹ', '\u{afc}'), ('\u{b01}', 'ଃ'),
+  ('ଅ', 'ଌ'), ('ଏ', 'ଐ'), ('ଓ', 'ନ'), ('ପ', 'ର'),
+  ('ଲ', 'ଳ'), ('ଵ', 'ହ'), ('ଽ', '\u{b44}'), ('େ', 'ୈ'),
+  ('ୋ', 'ୌ'), ('\u{b56}', '\u{b57}'), ('ଡ଼', 'ଢ଼'), ('ୟ', '\u{b63}'),
+  ('ୱ', 'ୱ'), ('\u{b82}', 'ஃ'), ('அ', 'ஊ'), ('எ', 'ஐ'),
+  ('ஒ', 'க'), ('ங', 'ச'), ('ஜ', 'ஜ'), ('ஞ', 'ட'),
+  ('ண', 'த'), ('ந', 'ப'), ('ம', 'ஹ'), ('\u{bbe}', 'ூ'),
+  ('ெ', 'ை'), ('ொ', 'ௌ'), ('ௐ', 'ௐ'), ('\u{bd7}', '\u{bd7}'),
+  ('\u{c00}', 'ః'), ('అ', 'ఌ'), ('ఎ', 'ఐ'), ('ఒ', 'న'),
+  ('ప', 'హ'), ('ఽ', 'ౄ'), ('\u{c46}', '\u{c48}'),
+  ('\u{c4a}', '\u{c4c}'), ('\u{c55}', '\u{c56}'), ('ౘ', 'ౚ'),
+  ('ౠ', '\u{c63}'), ('ಀ', 'ಃ'), ('ಅ', 'ಌ'), ('ಎ', 'ಐ'),
+  ('ಒ', 'ನ'), ('ಪ', 'ಳ'), ('ವ', 'ಹ'), ('ಽ', 'ೄ'),
+  ('\u{cc6}', 'ೈ'), ('ೊ', '\u{ccc}'), ('\u{cd5}', '\u{cd6}'),
+  ('ೞ', 'ೞ'), ('ೠ', '\u{ce3}'), ('ೱ', 'ೲ'), ('\u{d00}', 'ഃ'),
+  ('അ', 'ഌ'), ('എ', 'ഐ'), ('ഒ', 'ഺ'), ('ഽ', '\u{d44}'),
+  ('െ', 'ൈ'), ('ൊ', 'ൌ'), ('ൎ', 'ൎ'), ('ൔ', '\u{d57}'),
+  ('ൟ', '\u{d63}'), ('ൺ', 'ൿ'), ('ං', 'ඃ'), ('අ', 'ඖ'),
+  ('ක', 'න'), ('ඳ', 'ර'), ('ල', 'ල'), ('ව', 'ෆ'),
+  ('\u{dcf}', '\u{dd4}'), ('\u{dd6}', '\u{dd6}'), ('ෘ', '\u{ddf}'),
+  ('ෲ', 'ෳ'), ('ก', '\u{e3a}'), ('เ', 'ๆ'), ('\u{e4d}', '\u{e4d}'),
+  ('ກ', 'ຂ'), ('ຄ', 'ຄ'), ('\u{e86}', 'ຊ'), ('\u{e8c}', 'ຣ'),
+  ('ລ', 'ລ'), ('ວ', '\u{eb9}'), ('\u{ebb}', 'ຽ'), ('ເ', 'ໄ'),
+  ('ໆ', 'ໆ'), ('\u{ecd}', '\u{ecd}'), ('ໜ', 'ໟ'), ('ༀ', 'ༀ'),
+  ('ཀ', 'ཇ'), ('ཉ', 'ཬ'), ('\u{f71}', '\u{f81}'), ('ྈ', '\u{f97}'),
+  ('\u{f99}', '\u{fbc}'), ('က', '\u{1036}'), ('း', 'း'), ('ျ', 'ဿ'),
+  ('ၐ', 'ႏ'), ('ႚ', '\u{109d}'), ('Ⴀ', 'Ⴥ'), ('Ⴧ', 'Ⴧ'),
+  ('Ⴭ', 'Ⴭ'), ('ა', 'ჺ'), ('ჼ', 'ቈ'), ('ቊ', 'ቍ'),
+  ('ቐ', 'ቖ'), ('ቘ', 'ቘ'), ('ቚ', 'ቝ'), ('በ', 'ኈ'),
+  ('ኊ', 'ኍ'), ('ነ', 'ኰ'), ('ኲ', 'ኵ'), ('ኸ', 'ኾ'),
+  ('ዀ', 'ዀ'), ('ዂ', 'ዅ'), ('ወ', 'ዖ'), ('ዘ', 'ጐ'),
+  ('ጒ', 'ጕ'), ('ጘ', 'ፚ'), ('ᎀ', 'ᎏ'), ('Ꭰ', 'Ᏽ'),
+  ('ᏸ', 'ᏽ'), ('ᐁ', 'ᙬ'), ('ᙯ', 'ᙿ'), ('ᚁ', 'ᚚ'),
+  ('ᚠ', 'ᛪ'), ('ᛮ', 'ᛸ'), ('ᜀ', 'ᜌ'), ('ᜎ', '\u{1713}'),
+  ('ᜠ', '\u{1733}'), ('ᝀ', '\u{1753}'), ('ᝠ', 'ᝬ'), ('ᝮ', 'ᝰ'),
+  ('\u{1772}', '\u{1773}'), ('ក', 'ឳ'), ('ា', 'ៈ'), ('ៗ', 'ៗ'),
+  ('ៜ', 'ៜ'), ('ᠠ', 'ᡸ'), ('ᢀ', 'ᢪ'), ('ᢰ', 'ᣵ'),
+  ('ᤀ', 'ᤞ'), ('\u{1920}', 'ᤫ'), ('ᤰ', 'ᤸ'), ('ᥐ', 'ᥭ'),
+  ('ᥰ', 'ᥴ'), ('ᦀ', 'ᦫ'), ('ᦰ', 'ᧉ'), ('ᨀ', '\u{1a1b}'),
+  ('ᨠ', '\u{1a5e}'), ('ᩡ', '\u{1a74}'), ('ᪧ', 'ᪧ'),
+  ('\u{1b00}', 'ᬳ'), ('ᬵ', 'ᭃ'), ('ᭅ', 'ᭋ'),
+  ('\u{1b80}', '\u{1ba9}'), ('\u{1bac}', 'ᮯ'), ('ᮺ', 'ᯥ'),
+  ('ᯧ', '\u{1bf1}'), ('ᰀ', '\u{1c36}'), ('ᱍ', 'ᱏ'), ('ᱚ', 'ᱽ'),
+  ('ᲀ', 'ᲈ'), ('Ა', 'Ჺ'), ('Ჽ', 'Ჿ'), ('ᳩ', 'ᳬ'),
+  ('ᳮ', 'ᳳ'), ('ᳵ', 'ᳶ'), ('\u{1cfa}', '\u{1cfa}'), ('ᴀ', 'ᶿ'),
+  ('\u{1de7}', '\u{1df4}'), ('Ḁ', 'ἕ'), ('Ἐ', 'Ἕ'), ('ἠ', 'ὅ'),
+  ('Ὀ', 'Ὅ'), ('ὐ', 'ὗ'), ('Ὑ', 'Ὑ'), ('Ὓ', 'Ὓ'),
+  ('Ὕ', 'Ὕ'), ('Ὗ', 'ώ'), ('ᾀ', 'ᾴ'), ('ᾶ', 'ᾼ'),
+  ('ι', 'ι'), ('ῂ', 'ῄ'), ('ῆ', 'ῌ'), ('ῐ', 'ΐ'),
+  ('ῖ', 'Ί'), ('ῠ', 'Ῥ'), ('ῲ', 'ῴ'), ('ῶ', 'ῼ'),
+  ('ⁱ', 'ⁱ'), ('ⁿ', 'ⁿ'), ('ₐ', 'ₜ'), ('ℂ', 'ℂ'),
+  ('ℇ', 'ℇ'), ('ℊ', 'ℓ'), ('ℕ', 'ℕ'), ('ℙ', 'ℝ'),
+  ('ℤ', 'ℤ'), ('Ω', 'Ω'), ('ℨ', 'ℨ'), ('K', 'ℭ'),
+  ('ℯ', 'ℹ'), ('ℼ', 'ℿ'), ('ⅅ', 'ⅉ'), ('ⅎ', 'ⅎ'),
+  ('Ⅰ', 'ↈ'), ('Ⓐ', 'ⓩ'), ('Ⰰ', 'Ⱞ'), ('ⰰ', 'ⱞ'),
+  ('Ⱡ', 'ⳤ'), ('Ⳬ', 'ⳮ'), ('Ⳳ', 'ⳳ'), ('ⴀ', 'ⴥ'),
+  ('ⴧ', 'ⴧ'), ('ⴭ', 'ⴭ'), ('ⴰ', 'ⵧ'), ('ⵯ', 'ⵯ'),
+  ('ⶀ', 'ⶖ'), ('ⶠ', 'ⶦ'), ('ⶨ', 'ⶮ'), ('ⶰ', 'ⶶ'),
+  ('ⶸ', 'ⶾ'), ('ⷀ', 'ⷆ'), ('ⷈ', 'ⷎ'), ('ⷐ', 'ⷖ'),
+  ('ⷘ', 'ⷞ'), ('\u{2de0}', '\u{2dff}'), ('ⸯ', 'ⸯ'), ('々', '〇'),
+  ('〡', '〩'), ('〱', '〵'), ('〸', '〼'), ('ぁ', 'ゖ'),
+  ('ゝ', 'ゟ'), ('ァ', 'ヺ'), ('ー', 'ヿ'), ('ㄅ', 'ㄯ'),
+  ('ㄱ', 'ㆎ'), ('ㆠ', 'ㆺ'), ('ㇰ', 'ㇿ'), ('㐀', '䶵'),
+  ('一', '鿯'), ('ꀀ', 'ꒌ'), ('ꓐ', 'ꓽ'), ('ꔀ', 'ꘌ'),
+  ('ꘐ', 'ꘟ'), ('ꘪ', 'ꘫ'), ('Ꙁ', 'ꙮ'), ('\u{a674}', '\u{a67b}'),
+  ('ꙿ', 'ꛯ'), ('ꜗ', 'ꜟ'), ('Ꜣ', 'ꞈ'), ('Ꞌ', '\u{a7bf}'),
+  ('\u{a7c2}', '\u{a7c6}'), ('ꟷ', 'ꠅ'), ('ꠇ', 'ꠧ'), ('ꡀ', 'ꡳ'),
+  ('ꢀ', 'ꣃ'), ('\u{a8c5}', '\u{a8c5}'), ('ꣲ', 'ꣷ'), ('ꣻ', 'ꣻ'),
+  ('ꣽ', '\u{a8ff}'), ('ꤊ', '\u{a92a}'), ('ꤰ', 'ꥒ'), ('ꥠ', 'ꥼ'),
+  ('\u{a980}', 'ꦲ'), ('ꦴ', 'ꦿ'), ('ꧏ', 'ꧏ'), ('ꧠ', 'ꧯ'),
+  ('ꧺ', 'ꧾ'), ('ꨀ', '\u{aa36}'), ('ꩀ', 'ꩍ'), ('ꩠ', 'ꩶ'),
+  ('ꩺ', '\u{aabe}'), ('ꫀ', 'ꫀ'), ('ꫂ', 'ꫂ'), ('ꫛ', 'ꫝ'),
+  ('ꫠ', 'ꫯ'), ('ꫲ', 'ꫵ'), ('ꬁ', 'ꬆ'), ('ꬉ', 'ꬎ'),
+  ('ꬑ', 'ꬖ'), ('ꬠ', 'ꬦ'), ('ꬨ', 'ꬮ'), ('ꬰ', 'ꭚ'),
+  ('ꭜ', '\u{ab67}'), ('ꭰ', 'ꯪ'), ('가', '힣'), ('ힰ', 'ퟆ'),
+  ('ퟋ', 'ퟻ'), ('豈', '舘'), ('並', '龎'), ('ff', 'st'),
+  ('ﬓ', 'ﬗ'), ('יִ', 'ﬨ'), ('שׁ', 'זּ'), ('טּ', 'לּ'),
+  ('מּ', 'מּ'), ('נּ', 'סּ'), ('ףּ', 'פּ'), ('צּ', 'ﮱ'),
+  ('ﯓ', 'ﴽ'), ('ﵐ', 'ﶏ'), ('ﶒ', 'ﷇ'), ('ﷰ', 'ﷻ'),
+  ('ﹰ', 'ﹴ'), ('ﹶ', 'ﻼ'), ('A', 'Z'), ('a', 'z'),
+  ('ヲ', 'ᄒ'), ('ᅡ', 'ᅦ'), ('ᅧ', 'ᅬ'), ('ᅭ', 'ᅲ'),
+  ('ᅳ', 'ᅵ'), ('𐀀', '𐀋'), ('𐀍', '𐀦'), ('𐀨', '𐀺'),
+  ('𐀼', '𐀽'), ('𐀿', '𐁍'), ('𐁐', '𐁝'), ('𐂀', '𐃺'),
+  ('𐅀', '𐅴'), ('𐊀', '𐊜'), ('𐊠', '𐋐'), ('𐌀', '𐌟'),
+  ('𐌭', '𐍊'), ('𐍐', '\u{1037a}'), ('𐎀', '𐎝'), ('𐎠', '𐏃'),
+  ('𐏈', '𐏏'), ('𐏑', '𐏕'), ('𐐀', '𐒝'), ('𐒰', '𐓓'),
+  ('𐓘', '𐓻'), ('𐔀', '𐔧'), ('𐔰', '𐕣'), ('𐘀', '𐜶'),
+  ('𐝀', '𐝕'), ('𐝠', '𐝧'), ('𐠀', '𐠅'), ('𐠈', '𐠈'),
+  ('𐠊', '𐠵'), ('𐠷', '𐠸'), ('𐠼', '𐠼'), ('𐠿', '𐡕'),
+  ('𐡠', '𐡶'), ('𐢀', '𐢞'), ('𐣠', '𐣲'), ('𐣴', '𐣵'),
+  ('𐤀', '𐤕'), ('𐤠', '𐤹'), ('𐦀', '𐦷'), ('𐦾', '𐦿'),
+  ('𐨀', '\u{10a03}'), ('\u{10a05}', '\u{10a06}'), ('\u{10a0c}', '𐨓'),
+  ('𐨕', '𐨗'), ('𐨙', '𐨵'), ('𐩠', '𐩼'), ('𐪀', '𐪜'),
+  ('𐫀', '𐫇'), ('𐫉', '𐫤'), ('𐬀', '𐬵'), ('𐭀', '𐭕'),
+  ('𐭠', '𐭲'), ('𐮀', '𐮑'), ('𐰀', '𐱈'), ('𐲀', '𐲲'),
+  ('𐳀', '𐳲'), ('𐴀', '\u{10d27}'), ('𐼀', '𐼜'), ('𐼧', '𐼧'),
+  ('𐼰', '𐽅'), ('\u{10fe0}', '\u{10ff6}'), ('𑀀', '\u{11045}'),
+  ('𑂂', '𑂸'), ('𑃐', '𑃨'), ('\u{11100}', '\u{11132}'),
+  ('𑅄', '𑅆'), ('𑅐', '𑅲'), ('𑅶', '𑅶'), ('\u{11180}', '𑆿'),
+  ('𑇁', '𑇄'), ('𑇚', '𑇚'), ('𑇜', '𑇜'), ('𑈀', '𑈑'),
+  ('𑈓', '\u{11234}'), ('\u{11237}', '\u{11237}'),
+  ('\u{1123e}', '\u{1123e}'), ('𑊀', '𑊆'), ('𑊈', '𑊈'),
+  ('𑊊', '𑊍'), ('𑊏', '𑊝'), ('𑊟', '𑊨'), ('𑊰', '\u{112e8}'),
+  ('\u{11300}', '𑌃'), ('𑌅', '𑌌'), ('𑌏', '𑌐'), ('𑌓', '𑌨'),
+  ('𑌪', '𑌰'), ('𑌲', '𑌳'), ('𑌵', '𑌹'), ('𑌽', '𑍄'),
+  ('𑍇', '𑍈'), ('𑍋', '𑍌'), ('𑍐', '𑍐'),
+  ('\u{11357}', '\u{11357}'), ('𑍝', '𑍣'), ('𑐀', '𑑁'),
+  ('\u{11443}', '𑑅'), ('𑑇', '𑑊'), ('\u{1145f}', '\u{1145f}'),
+  ('𑒀', '𑓁'), ('𑓄', '𑓅'), ('𑓇', '𑓇'), ('𑖀', '\u{115b5}'),
+  ('𑖸', '𑖾'), ('𑗘', '\u{115dd}'), ('𑘀', '𑘾'),
+  ('\u{11640}', '\u{11640}'), ('𑙄', '𑙄'), ('𑚀', '\u{116b5}'),
+  ('\u{116b8}', '\u{116b8}'), ('𑜀', '𑜚'), ('\u{1171d}', '\u{1172a}'),
+  ('𑠀', '𑠸'), ('𑢠', '𑣟'), ('𑣿', '𑣿'),
+  ('\u{119a0}', '\u{119a7}'), ('\u{119aa}', '\u{119d7}'),
+  ('\u{119da}', '\u{119df}'), ('\u{119e1}', '\u{119e1}'),
+  ('\u{119e3}', '\u{119e4}'), ('𑨀', '𑨲'), ('\u{11a35}', '\u{11a3e}'),
+  ('𑩐', '𑪗'), ('𑪝', '𑪝'), ('𑫀', '𑫸'), ('𑰀', '𑰈'),
+  ('𑰊', '\u{11c36}'), ('\u{11c38}', '𑰾'), ('𑱀', '𑱀'),
+  ('𑱲', '𑲏'), ('\u{11c92}', '\u{11ca7}'), ('𑲩', '\u{11cb6}'),
+  ('𑴀', '𑴆'), ('𑴈', '𑴉'), ('𑴋', '\u{11d36}'),
+  ('\u{11d3a}', '\u{11d3a}'), ('\u{11d3c}', '\u{11d3d}'),
+  ('\u{11d3f}', '\u{11d41}'), ('\u{11d43}', '\u{11d43}'),
+  ('𑵆', '\u{11d47}'), ('𑵠', '𑵥'), ('𑵧', '𑵨'), ('𑵪', '𑶎'),
+  ('\u{11d90}', '\u{11d91}'), ('𑶓', '𑶖'), ('𑶘', '𑶘'),
+  ('𑻠', '𑻶'), ('𒀀', '𒎙'), ('𒐀', '𒑮'), ('𒒀', '𒕃'),
+  ('𓀀', '𓐮'), ('𔐀', '𔙆'), ('𖠀', '𖨸'), ('𖩀', '𖩞'),
+  ('𖫐', '𖫭'), ('𖬀', '𖬯'), ('𖭀', '𖭃'), ('𖭣', '𖭷'),
+  ('𖭽', '𖮏'), ('𖹀', '𖹿'), ('𖼀', '\u{16f4a}'),
+  ('\u{16f4f}', '\u{16f87}'), ('\u{16f8f}', '𖾟'), ('𖿠', '𖿡'),
+  ('\u{16fe3}', '\u{16fe3}'), ('𗀀', '\u{187f7}'), ('𘠀', '𘫲'),
+  ('𛀀', '𛄞'), ('\u{1b150}', '\u{1b152}'), ('\u{1b164}', '\u{1b167}'),
+  ('𛅰', '𛋻'), ('𛰀', '𛱪'), ('𛱰', '𛱼'), ('𛲀', '𛲈'),
+  ('𛲐', '𛲙'), ('\u{1bc9e}', '\u{1bc9e}'), ('𝐀', '𝑔'),
+  ('𝑖', '𝒜'), ('𝒞', '𝒟'), ('𝒢', '𝒢'), ('𝒥', '𝒦'),
+  ('𝒩', '𝒬'), ('𝒮', '𝒹'), ('𝒻', '𝒻'), ('𝒽', '𝓃'),
+  ('𝓅', '𝔅'), ('𝔇', '𝔊'), ('𝔍', '𝔔'), ('𝔖', '𝔜'),
+  ('𝔞', '𝔹'), ('𝔻', '𝔾'), ('𝕀', '𝕄'), ('𝕆', '𝕆'),
+  ('𝕊', '𝕐'), ('𝕒', '𝚥'), ('𝚨', '𝛀'), ('𝛂', '𝛚'),
+  ('𝛜', '𝛺'), ('𝛼', '𝜔'), ('𝜖', '𝜴'), ('𝜶', '𝝎'),
+  ('𝝐', '𝝮'), ('𝝰', '𝞈'), ('𝞊', '𝞨'), ('𝞪', '𝟂'),
+  ('𝟄', '𝟋'), ('\u{1e000}', '\u{1e006}'), ('\u{1e008}', '\u{1e018}'),
+  ('\u{1e01b}', '\u{1e021}'), ('\u{1e023}', '\u{1e024}'),
+  ('\u{1e026}', '\u{1e02a}'), ('\u{1e100}', '\u{1e12c}'),
+  ('\u{1e137}', '\u{1e13d}'), ('\u{1e14e}', '\u{1e14e}'),
+  ('\u{1e2c0}', '\u{1e2eb}'), ('𞠀', '𞣄'), ('𞤀', '𞥃'),
+  ('\u{1e947}', '\u{1e947}'), ('\u{1e94b}', '\u{1e94b}'), ('𞸀', '𞸃'),
+  ('𞸅', '𞸟'), ('𞸡', '𞸢'), ('𞸤', '𞸤'), ('𞸧', '𞸧'),
+  ('𞸩', '𞸲'), ('𞸴', '𞸷'), ('𞸹', '𞸹'), ('𞸻', '𞸻'),
+  ('𞹂', '𞹂'), ('𞹇', '𞹇'), ('𞹉', '𞹉'), ('𞹋', '𞹋'),
+  ('𞹍', '𞹏'), ('𞹑', '𞹒'), ('𞹔', '𞹔'), ('𞹗', '𞹗'),
+  ('𞹙', '𞹙'), ('𞹛', '𞹛'), ('𞹝', '𞹝'), ('𞹟', '𞹟'),
+  ('𞹡', '𞹢'), ('𞹤', '𞹤'), ('𞹧', '𞹪'), ('𞹬', '𞹲'),
+  ('𞹴', '𞹷'), ('𞹹', '𞹼'), ('𞹾', '𞹾'), ('𞺀', '𞺉'),
+  ('𞺋', '𞺛'), ('𞺡', '𞺣'), ('𞺥', '𞺩'), ('𞺫', '𞺻'),
+  ('🄰', '🅉'), ('🅐', '🅩'), ('🅰', '🆉'), ('𠀀', '𪛖'),
+  ('𪜀', '𫜴'), ('𫝀', '𫠝'), ('𫠠', '𬺡'), ('𬺰', '𮯠'),
+  ('丽', '𪘀'),
+];
+
+pub const BIDI_CONTROL: &'static [(char, char)] = &[
+  ('\u{61c}', '\u{61c}'), ('\u{200e}', '\u{200f}'), ('\u{202a}', '\u{202e}'),
+  ('\u{2066}', '\u{2069}'),
+];
+
+pub const CASE_IGNORABLE: &'static [(char, char)] = &[
+  ('\'', '\''), ('.', '.'), (':', ':'), ('^', '^'), ('`', '`'), ('¨', '¨'),
+  ('\u{ad}', '\u{ad}'), ('¯', '¯'), ('´', '´'), ('·', '¸'),
+  ('ʰ', '\u{36f}'), ('ʹ', '͵'), ('ͺ', 'ͺ'), ('΄', '΅'), ('·', '·'),
+  ('\u{483}', '\u{489}'), ('ՙ', 'ՙ'), ('\u{591}', '\u{5bd}'),
+  ('\u{5bf}', '\u{5bf}'), ('\u{5c1}', '\u{5c2}'), ('\u{5c4}', '\u{5c5}'),
+  ('\u{5c7}', '\u{5c7}'), ('״', '״'), ('\u{600}', '\u{605}'),
+  ('\u{610}', '\u{61a}'), ('\u{61c}', '\u{61c}'), ('ـ', 'ـ'),
+  ('\u{64b}', '\u{65f}'), ('\u{670}', '\u{670}'), ('\u{6d6}', '\u{6dd}'),
+  ('\u{6df}', '\u{6e8}'), ('\u{6ea}', '\u{6ed}'), ('\u{70f}', '\u{70f}'),
+  ('\u{711}', '\u{711}'), ('\u{730}', '\u{74a}'), ('\u{7a6}', '\u{7b0}'),
+  ('\u{7eb}', 'ߵ'), ('ߺ', 'ߺ'), ('\u{7fd}', '\u{7fd}'),
+  ('\u{816}', '\u{82d}'), ('\u{859}', '\u{85b}'), ('\u{8d3}', '\u{902}'),
+  ('\u{93a}', '\u{93a}'), ('\u{93c}', '\u{93c}'), ('\u{941}', '\u{948}'),
+  ('\u{94d}', '\u{94d}'), ('\u{951}', '\u{957}'), ('\u{962}', '\u{963}'),
+  ('ॱ', 'ॱ'), ('\u{981}', '\u{981}'), ('\u{9bc}', '\u{9bc}'),
+  ('\u{9c1}', '\u{9c4}'), ('\u{9cd}', '\u{9cd}'), ('\u{9e2}', '\u{9e3}'),
+  ('\u{9fe}', '\u{9fe}'), ('\u{a01}', '\u{a02}'), ('\u{a3c}', '\u{a3c}'),
+  ('\u{a41}', '\u{a42}'), ('\u{a47}', '\u{a48}'), ('\u{a4b}', '\u{a4d}'),
+  ('\u{a51}', '\u{a51}'), ('\u{a70}', '\u{a71}'), ('\u{a75}', '\u{a75}'),
+  ('\u{a81}', '\u{a82}'), ('\u{abc}', '\u{abc}'), ('\u{ac1}', '\u{ac5}'),
+  ('\u{ac7}', '\u{ac8}'), ('\u{acd}', '\u{acd}'), ('\u{ae2}', '\u{ae3}'),
+  ('\u{afa}', '\u{aff}'), ('\u{b01}', '\u{b01}'), ('\u{b3c}', '\u{b3c}'),
+  ('\u{b3f}', '\u{b3f}'), ('\u{b41}', '\u{b44}'), ('\u{b4d}', '\u{b4d}'),
+  ('\u{b56}', '\u{b56}'), ('\u{b62}', '\u{b63}'), ('\u{b82}', '\u{b82}'),
+  ('\u{bc0}', '\u{bc0}'), ('\u{bcd}', '\u{bcd}'), ('\u{c00}', '\u{c00}'),
+  ('\u{c04}', '\u{c04}'), ('\u{c3e}', '\u{c40}'), ('\u{c46}', '\u{c48}'),
+  ('\u{c4a}', '\u{c4d}'), ('\u{c55}', '\u{c56}'), ('\u{c62}', '\u{c63}'),
+  ('\u{c81}', '\u{c81}'), ('\u{cbc}', '\u{cbc}'), ('\u{cbf}', '\u{cbf}'),
+  ('\u{cc6}', '\u{cc6}'), ('\u{ccc}', '\u{ccd}'), ('\u{ce2}', '\u{ce3}'),
+  ('\u{d00}', '\u{d01}'), ('\u{d3b}', '\u{d3c}'), ('\u{d41}', '\u{d44}'),
+  ('\u{d4d}', '\u{d4d}'), ('\u{d62}', '\u{d63}'), ('\u{dca}', '\u{dca}'),
+  ('\u{dd2}', '\u{dd4}'), ('\u{dd6}', '\u{dd6}'), ('\u{e31}', '\u{e31}'),
+  ('\u{e34}', '\u{e3a}'), ('ๆ', '\u{e4e}'), ('\u{eb1}', '\u{eb1}'),
+  ('\u{eb4}', '\u{ebc}'), ('ໆ', 'ໆ'), ('\u{ec8}', '\u{ecd}'),
+  ('\u{f18}', '\u{f19}'), ('\u{f35}', '\u{f35}'), ('\u{f37}', '\u{f37}'),
+  ('\u{f39}', '\u{f39}'), ('\u{f71}', '\u{f7e}'), ('\u{f80}', '\u{f84}'),
+  ('\u{f86}', '\u{f87}'), ('\u{f8d}', '\u{f97}'), ('\u{f99}', '\u{fbc}'),
+  ('\u{fc6}', '\u{fc6}'), ('\u{102d}', '\u{1030}'), ('\u{1032}', '\u{1037}'),
+  ('\u{1039}', '\u{103a}'), ('\u{103d}', '\u{103e}'),
+  ('\u{1058}', '\u{1059}'), ('\u{105e}', '\u{1060}'),
+  ('\u{1071}', '\u{1074}'), ('\u{1082}', '\u{1082}'),
+  ('\u{1085}', '\u{1086}'), ('\u{108d}', '\u{108d}'),
+  ('\u{109d}', '\u{109d}'), ('ჼ', 'ჼ'), ('\u{135d}', '\u{135f}'),
+  ('\u{1712}', '\u{1714}'), ('\u{1732}', '\u{1734}'),
+  ('\u{1752}', '\u{1753}'), ('\u{1772}', '\u{1773}'),
+  ('\u{17b4}', '\u{17b5}'), ('\u{17b7}', '\u{17bd}'),
+  ('\u{17c6}', '\u{17c6}'), ('\u{17c9}', '\u{17d3}'), ('ៗ', 'ៗ'),
+  ('\u{17dd}', '\u{17dd}'), ('\u{180b}', '\u{180e}'), ('ᡃ', 'ᡃ'),
+  ('\u{1885}', '\u{1886}'), ('\u{18a9}', '\u{18a9}'),
+  ('\u{1920}', '\u{1922}'), ('\u{1927}', '\u{1928}'),
+  ('\u{1932}', '\u{1932}'), ('\u{1939}', '\u{193b}'),
+  ('\u{1a17}', '\u{1a18}'), ('\u{1a1b}', '\u{1a1b}'),
+  ('\u{1a56}', '\u{1a56}'), ('\u{1a58}', '\u{1a5e}'),
+  ('\u{1a60}', '\u{1a60}'), ('\u{1a62}', '\u{1a62}'),
+  ('\u{1a65}', '\u{1a6c}'), ('\u{1a73}', '\u{1a7c}'),
+  ('\u{1a7f}', '\u{1a7f}'), ('ᪧ', 'ᪧ'), ('\u{1ab0}', '\u{1abe}'),
+  ('\u{1b00}', '\u{1b03}'), ('\u{1b34}', '\u{1b34}'),
+  ('\u{1b36}', '\u{1b3a}'), ('\u{1b3c}', '\u{1b3c}'),
+  ('\u{1b42}', '\u{1b42}'), ('\u{1b6b}', '\u{1b73}'),
+  ('\u{1b80}', '\u{1b81}'), ('\u{1ba2}', '\u{1ba5}'),
+  ('\u{1ba8}', '\u{1ba9}'), ('\u{1bab}', '\u{1bad}'),
+  ('\u{1be6}', '\u{1be6}'), ('\u{1be8}', '\u{1be9}'),
+  ('\u{1bed}', '\u{1bed}'), ('\u{1bef}', '\u{1bf1}'),
+  ('\u{1c2c}', '\u{1c33}'), ('\u{1c36}', '\u{1c37}'), ('ᱸ', 'ᱽ'),
+  ('\u{1cd0}', '\u{1cd2}'), ('\u{1cd4}', '\u{1ce0}'),
+  ('\u{1ce2}', '\u{1ce8}'), ('\u{1ced}', '\u{1ced}'),
+  ('\u{1cf4}', '\u{1cf4}'), ('\u{1cf8}', '\u{1cf9}'), ('ᴬ', 'ᵪ'),
+  ('ᵸ', 'ᵸ'), ('ᶛ', '\u{1df9}'), ('\u{1dfb}', '\u{1dff}'),
+  ('᾽', '᾽'), ('᾿', '῁'), ('῍', '῏'), ('῝', '῟'),
+  ('῭', '`'), ('´', '῾'), ('\u{200b}', '\u{200f}'), ('‘', '’'),
+  ('․', '․'), ('‧', '‧'), ('\u{202a}', '\u{202e}'),
+  ('\u{2060}', '\u{2064}'), ('\u{2066}', '\u{206f}'), ('ⁱ', 'ⁱ'),
+  ('ⁿ', 'ⁿ'), ('ₐ', 'ₜ'), ('\u{20d0}', '\u{20f0}'), ('ⱼ', 'ⱽ'),
+  ('\u{2cef}', '\u{2cf1}'), ('ⵯ', 'ⵯ'), ('\u{2d7f}', '\u{2d7f}'),
+  ('\u{2de0}', '\u{2dff}'), ('ⸯ', 'ⸯ'), ('々', '々'),
+  ('\u{302a}', '\u{302d}'), ('〱', '〵'), ('〻', '〻'),
+  ('\u{3099}', 'ゞ'), ('ー', 'ヾ'), ('ꀕ', 'ꀕ'), ('ꓸ', 'ꓽ'),
+  ('ꘌ', 'ꘌ'), ('\u{a66f}', '\u{a672}'), ('\u{a674}', '\u{a67d}'),
+  ('ꙿ', 'ꙿ'), ('ꚜ', '\u{a69f}'), ('\u{a6f0}', '\u{a6f1}'),
+  ('꜀', '꜡'), ('ꝰ', 'ꝰ'), ('ꞈ', '꞊'), ('ꟸ', 'ꟹ'),
+  ('\u{a802}', '\u{a802}'), ('\u{a806}', '\u{a806}'),
+  ('\u{a80b}', '\u{a80b}'), ('\u{a825}', '\u{a826}'),
+  ('\u{a8c4}', '\u{a8c5}'), ('\u{a8e0}', '\u{a8f1}'),
+  ('\u{a8ff}', '\u{a8ff}'), ('\u{a926}', '\u{a92d}'),
+  ('\u{a947}', '\u{a951}'), ('\u{a980}', '\u{a982}'),
+  ('\u{a9b3}', '\u{a9b3}'), ('\u{a9b6}', '\u{a9b9}'), ('\u{a9bc}', 'ꦽ'),
+  ('ꧏ', 'ꧏ'), ('\u{a9e5}', 'ꧦ'), ('\u{aa29}', '\u{aa2e}'),
+  ('\u{aa31}', '\u{aa32}'), ('\u{aa35}', '\u{aa36}'),
+  ('\u{aa43}', '\u{aa43}'), ('\u{aa4c}', '\u{aa4c}'), ('ꩰ', 'ꩰ'),
+  ('\u{aa7c}', '\u{aa7c}'), ('\u{aab0}', '\u{aab0}'),
+  ('\u{aab2}', '\u{aab4}'), ('\u{aab7}', '\u{aab8}'),
+  ('\u{aabe}', '\u{aabf}'), ('\u{aac1}', '\u{aac1}'), ('ꫝ', 'ꫝ'),
+  ('\u{aaec}', '\u{aaed}'), ('ꫳ', 'ꫴ'), ('\u{aaf6}', '\u{aaf6}'),
+  ('꭛', 'ꭟ'), ('\u{abe5}', '\u{abe5}'), ('\u{abe8}', '\u{abe8}'),
+  ('\u{abed}', '\u{abed}'), ('\u{fb1e}', '\u{fb1e}'), ('﮲', '﯁'),
+  ('\u{fe00}', '\u{fe0f}'), ('︓', '︓'), ('\u{fe20}', '\u{fe2f}'),
+  ('﹒', '﹒'), ('﹕', '﹕'), ('\u{feff}', '\u{feff}'), (''', '''),
+  ('.', '.'), (':', ':'), ('^', '^'), ('`', '`'),
+  ('ー', 'ー'), ('\u{ff9e}', '\u{ff9f}'), (' ̄', ' ̄'),
+  ('\u{fff9}', '\u{fffb}'), ('\u{101fd}', '\u{101fd}'),
+  ('\u{102e0}', '\u{102e0}'), ('\u{10376}', '\u{1037a}'),
+  ('\u{10a01}', '\u{10a03}'), ('\u{10a05}', '\u{10a06}'),
+  ('\u{10a0c}', '\u{10a0f}'), ('\u{10a38}', '\u{10a3a}'),
+  ('\u{10a3f}', '\u{10a3f}'), ('\u{10ae5}', '\u{10ae6}'),
+  ('\u{10d24}', '\u{10d27}'), ('\u{10f46}', '\u{10f50}'),
+  ('\u{11001}', '\u{11001}'), ('\u{11038}', '\u{11046}'),
+  ('\u{1107f}', '\u{11081}'), ('\u{110b3}', '\u{110b6}'),
+  ('\u{110b9}', '\u{110ba}'), ('\u{110bd}', '\u{110bd}'),
+  ('\u{110cd}', '\u{110cd}'), ('\u{11100}', '\u{11102}'),
+  ('\u{11127}', '\u{1112b}'), ('\u{1112d}', '\u{11134}'),
+  ('\u{11173}', '\u{11173}'), ('\u{11180}', '\u{11181}'),
+  ('\u{111b6}', '\u{111be}'), ('\u{111c9}', '\u{111cc}'),
+  ('\u{1122f}', '\u{11231}'), ('\u{11234}', '\u{11234}'),
+  ('\u{11236}', '\u{11237}'), ('\u{1123e}', '\u{1123e}'),
+  ('\u{112df}', '\u{112df}'), ('\u{112e3}', '\u{112ea}'),
+  ('\u{11300}', '\u{11301}'), ('\u{1133b}', '\u{1133c}'),
+  ('\u{11340}', '\u{11340}'), ('\u{11366}', '\u{1136c}'),
+  ('\u{11370}', '\u{11374}'), ('\u{11438}', '\u{1143f}'),
+  ('\u{11442}', '\u{11444}'), ('\u{11446}', '\u{11446}'),
+  ('\u{1145e}', '\u{1145e}'), ('\u{114b3}', '\u{114b8}'),
+  ('\u{114ba}', '\u{114ba}'), ('\u{114bf}', '\u{114c0}'),
+  ('\u{114c2}', '\u{114c3}'), ('\u{115b2}', '\u{115b5}'),
+  ('\u{115bc}', '\u{115bd}'), ('\u{115bf}', '\u{115c0}'),
+  ('\u{115dc}', '\u{115dd}'), ('\u{11633}', '\u{1163a}'),
+  ('\u{1163d}', '\u{1163d}'), ('\u{1163f}', '\u{11640}'),
+  ('\u{116ab}', '\u{116ab}'), ('\u{116ad}', '\u{116ad}'),
+  ('\u{116b0}', '\u{116b5}'), ('\u{116b7}', '\u{116b7}'),
+  ('\u{1171d}', '\u{1171f}'), ('\u{11722}', '\u{11725}'),
+  ('\u{11727}', '\u{1172b}'), ('\u{1182f}', '\u{11837}'),
+  ('\u{11839}', '\u{1183a}'), ('\u{119d4}', '\u{119d7}'),
+  ('\u{119da}', '\u{119db}'), ('\u{119e0}', '\u{119e0}'),
+  ('\u{11a01}', '\u{11a0a}'), ('\u{11a33}', '\u{11a38}'),
+  ('\u{11a3b}', '\u{11a3e}'), ('\u{11a47}', '\u{11a47}'),
+  ('\u{11a51}', '\u{11a56}'), ('\u{11a59}', '\u{11a5b}'),
+  ('\u{11a8a}', '\u{11a96}'), ('\u{11a98}', '\u{11a99}'),
+  ('\u{11c30}', '\u{11c36}'), ('\u{11c38}', '\u{11c3d}'),
+  ('\u{11c3f}', '\u{11c3f}'), ('\u{11c92}', '\u{11ca7}'),
+  ('\u{11caa}', '\u{11cb0}'), ('\u{11cb2}', '\u{11cb3}'),
+  ('\u{11cb5}', '\u{11cb6}'), ('\u{11d31}', '\u{11d36}'),
+  ('\u{11d3a}', '\u{11d3a}'), ('\u{11d3c}', '\u{11d3d}'),
+  ('\u{11d3f}', '\u{11d45}'), ('\u{11d47}', '\u{11d47}'),
+  ('\u{11d90}', '\u{11d91}'), ('\u{11d95}', '\u{11d95}'),
+  ('\u{11d97}', '\u{11d97}'), ('\u{11ef3}', '\u{11ef4}'),
+  ('\u{13430}', '\u{13438}'), ('\u{16af0}', '\u{16af4}'),
+  ('\u{16b30}', '\u{16b36}'), ('𖭀', '𖭃'), ('\u{16f4f}', '\u{16f4f}'),
+  ('\u{16f8f}', '𖾟'), ('𖿠', '𖿡'), ('\u{16fe3}', '\u{16fe3}'),
+  ('\u{1bc9d}', '\u{1bc9e}'), ('\u{1bca0}', '\u{1bca3}'),
+  ('\u{1d167}', '\u{1d169}'), ('\u{1d173}', '\u{1d182}'),
+  ('\u{1d185}', '\u{1d18b}'), ('\u{1d1aa}', '\u{1d1ad}'),
+  ('\u{1d242}', '\u{1d244}'), ('\u{1da00}', '\u{1da36}'),
+  ('\u{1da3b}', '\u{1da6c}'), ('\u{1da75}', '\u{1da75}'),
+  ('\u{1da84}', '\u{1da84}'), ('\u{1da9b}', '\u{1da9f}'),
+  ('\u{1daa1}', '\u{1daaf}'), ('\u{1e000}', '\u{1e006}'),
+  ('\u{1e008}', '\u{1e018}'), ('\u{1e01b}', '\u{1e021}'),
+  ('\u{1e023}', '\u{1e024}'), ('\u{1e026}', '\u{1e02a}'),
+  ('\u{1e130}', '\u{1e13d}'), ('\u{1e2ec}', '\u{1e2ef}'),
+  ('\u{1e8d0}', '\u{1e8d6}'), ('\u{1e944}', '\u{1e94b}'), ('🏻', '🏿'),
+  ('\u{e0001}', '\u{e0001}'), ('\u{e0020}', '\u{e007f}'),
+  ('\u{e0100}', '\u{e01ef}'),
+];
+
+pub const CASED: &'static [(char, char)] = &[
+  ('A', 'Z'), ('a', 'z'), ('ª', 'ª'), ('µ', 'µ'), ('º', 'º'),
+  ('À', 'Ö'), ('Ø', 'ö'), ('ø', 'ƺ'), ('Ƽ', 'ƿ'), ('DŽ', 'ʓ'),
+  ('ʕ', 'ʸ'), ('ˀ', 'ˁ'), ('ˠ', 'ˤ'), ('\u{345}', '\u{345}'),
+  ('Ͱ', 'ͳ'), ('Ͷ', 'ͷ'), ('ͺ', 'ͽ'), ('Ϳ', 'Ϳ'), ('Ά', 'Ά'),
+  ('Έ', 'Ί'), ('Ό', 'Ό'), ('Ύ', 'Ρ'), ('Σ', 'ϵ'), ('Ϸ', 'ҁ'),
+  ('Ҋ', 'ԯ'), ('Ա', 'Ֆ'), ('ՠ', 'ֈ'), ('Ⴀ', 'Ⴥ'), ('Ⴧ', 'Ⴧ'),
+  ('Ⴭ', 'Ⴭ'), ('ა', 'ჺ'), ('ჽ', 'ჿ'), ('Ꭰ', 'Ᏽ'),
+  ('ᏸ', 'ᏽ'), ('ᲀ', 'ᲈ'), ('Ა', 'Ჺ'), ('Ჽ', 'Ჿ'),
+  ('ᴀ', 'ᶿ'), ('Ḁ', 'ἕ'), ('Ἐ', 'Ἕ'), ('ἠ', 'ὅ'),
+  ('Ὀ', 'Ὅ'), ('ὐ', 'ὗ'), ('Ὑ', 'Ὑ'), ('Ὓ', 'Ὓ'),
+  ('Ὕ', 'Ὕ'), ('Ὗ', 'ώ'), ('ᾀ', 'ᾴ'), ('ᾶ', 'ᾼ'),
+  ('ι', 'ι'), ('ῂ', 'ῄ'), ('ῆ', 'ῌ'), ('ῐ', 'ΐ'),
+  ('ῖ', 'Ί'), ('ῠ', 'Ῥ'), ('ῲ', 'ῴ'), ('ῶ', 'ῼ'),
+  ('ⁱ', 'ⁱ'), ('ⁿ', 'ⁿ'), ('ₐ', 'ₜ'), ('ℂ', 'ℂ'),
+  ('ℇ', 'ℇ'), ('ℊ', 'ℓ'), ('ℕ', 'ℕ'), ('ℙ', 'ℝ'),
+  ('ℤ', 'ℤ'), ('Ω', 'Ω'), ('ℨ', 'ℨ'), ('K', 'ℭ'),
+  ('ℯ', 'ℴ'), ('ℹ', 'ℹ'), ('ℼ', 'ℿ'), ('ⅅ', 'ⅉ'),
+  ('ⅎ', 'ⅎ'), ('Ⅰ', 'ⅿ'), ('Ↄ', 'ↄ'), ('Ⓐ', 'ⓩ'),
+  ('Ⰰ', 'Ⱞ'), ('ⰰ', 'ⱞ'), ('Ⱡ', 'ⳤ'), ('Ⳬ', 'ⳮ'),
+  ('Ⳳ', 'ⳳ'), ('ⴀ', 'ⴥ'), ('ⴧ', 'ⴧ'), ('ⴭ', 'ⴭ'),
+  ('Ꙁ', 'ꙭ'), ('Ꚁ', 'ꚝ'), ('Ꜣ', 'ꞇ'), ('Ꞌ', 'ꞎ'),
+  ('Ꞑ', '\u{a7bf}'), ('\u{a7c2}', '\u{a7c6}'), ('ꟸ', 'ꟺ'),
+  ('ꬰ', 'ꭚ'), ('ꭜ', '\u{ab67}'), ('ꭰ', 'ꮿ'), ('ff', 'st'),
+  ('ﬓ', 'ﬗ'), ('A', 'Z'), ('a', 'z'), ('𐐀', '𐑏'),
+  ('𐒰', '𐓓'), ('𐓘', '𐓻'), ('𐲀', '𐲲'), ('𐳀', '𐳲'),
+  ('𑢠', '𑣟'), ('𖹀', '𖹿'), ('𝐀', '𝑔'), ('𝑖', '𝒜'),
+  ('𝒞', '𝒟'), ('𝒢', '𝒢'), ('𝒥', '𝒦'), ('𝒩', '𝒬'),
+  ('𝒮', '𝒹'), ('𝒻', '𝒻'), ('𝒽', '𝓃'), ('𝓅', '𝔅'),
+  ('𝔇', '𝔊'), ('𝔍', '𝔔'), ('𝔖', '𝔜'), ('𝔞', '𝔹'),
+  ('𝔻', '𝔾'), ('𝕀', '𝕄'), ('𝕆', '𝕆'), ('𝕊', '𝕐'),
+  ('𝕒', '𝚥'), ('𝚨', '𝛀'), ('𝛂', '𝛚'), ('𝛜', '𝛺'),
+  ('𝛼', '𝜔'), ('𝜖', '𝜴'), ('𝜶', '𝝎'), ('𝝐', '𝝮'),
+  ('𝝰', '𝞈'), ('𝞊', '𝞨'), ('𝞪', '𝟂'), ('𝟄', '𝟋'),
+  ('𞤀', '𞥃'), ('🄰', '🅉'), ('🅐', '🅩'), ('🅰', '🆉'),
+];
+
+pub const CHANGES_WHEN_CASEFOLDED: &'static [(char, char)] = &[
+  ('A', 'Z'), ('µ', 'µ'), ('À', 'Ö'), ('Ø', 'ß'), ('Ā', 'Ā'),
+  ('Ă', 'Ă'), ('Ą', 'Ą'), ('Ć', 'Ć'), ('Ĉ', 'Ĉ'), ('Ċ', 'Ċ'),
+  ('Č', 'Č'), ('Ď', 'Ď'), ('Đ', 'Đ'), ('Ē', 'Ē'), ('Ĕ', 'Ĕ'),
+  ('Ė', 'Ė'), ('Ę', 'Ę'), ('Ě', 'Ě'), ('Ĝ', 'Ĝ'), ('Ğ', 'Ğ'),
+  ('Ġ', 'Ġ'), ('Ģ', 'Ģ'), ('Ĥ', 'Ĥ'), ('Ħ', 'Ħ'), ('Ĩ', 'Ĩ'),
+  ('Ī', 'Ī'), ('Ĭ', 'Ĭ'), ('Į', 'Į'), ('İ', 'İ'), ('IJ', 'IJ'),
+  ('Ĵ', 'Ĵ'), ('Ķ', 'Ķ'), ('Ĺ', 'Ĺ'), ('Ļ', 'Ļ'), ('Ľ', 'Ľ'),
+  ('Ŀ', 'Ŀ'), ('Ł', 'Ł'), ('Ń', 'Ń'), ('Ņ', 'Ņ'), ('Ň', 'Ň'),
+  ('ʼn', 'Ŋ'), ('Ō', 'Ō'), ('Ŏ', 'Ŏ'), ('Ő', 'Ő'), ('Œ', 'Œ'),
+  ('Ŕ', 'Ŕ'), ('Ŗ', 'Ŗ'), ('Ř', 'Ř'), ('Ś', 'Ś'), ('Ŝ', 'Ŝ'),
+  ('Ş', 'Ş'), ('Š', 'Š'), ('Ţ', 'Ţ'), ('Ť', 'Ť'), ('Ŧ', 'Ŧ'),
+  ('Ũ', 'Ũ'), ('Ū', 'Ū'), ('Ŭ', 'Ŭ'), ('Ů', 'Ů'), ('Ű', 'Ű'),
+  ('Ų', 'Ų'), ('Ŵ', 'Ŵ'), ('Ŷ', 'Ŷ'), ('Ÿ', 'Ź'), ('Ż', 'Ż'),
+  ('Ž', 'Ž'), ('ſ', 'ſ'), ('Ɓ', 'Ƃ'), ('Ƅ', 'Ƅ'), ('Ɔ', 'Ƈ'),
+  ('Ɖ', 'Ƌ'), ('Ǝ', 'Ƒ'), ('Ɠ', 'Ɣ'), ('Ɩ', 'Ƙ'), ('Ɯ', 'Ɲ'),
+  ('Ɵ', 'Ơ'), ('Ƣ', 'Ƣ'), ('Ƥ', 'Ƥ'), ('Ʀ', 'Ƨ'), ('Ʃ', 'Ʃ'),
+  ('Ƭ', 'Ƭ'), ('Ʈ', 'Ư'), ('Ʊ', 'Ƴ'), ('Ƶ', 'Ƶ'), ('Ʒ', 'Ƹ'),
+  ('Ƽ', 'Ƽ'), ('DŽ', 'Dž'), ('LJ', 'Lj'), ('NJ', 'Nj'), ('Ǎ', 'Ǎ'),
+  ('Ǐ', 'Ǐ'), ('Ǒ', 'Ǒ'), ('Ǔ', 'Ǔ'), ('Ǖ', 'Ǖ'), ('Ǘ', 'Ǘ'),
+  ('Ǚ', 'Ǚ'), ('Ǜ', 'Ǜ'), ('Ǟ', 'Ǟ'), ('Ǡ', 'Ǡ'), ('Ǣ', 'Ǣ'),
+  ('Ǥ', 'Ǥ'), ('Ǧ', 'Ǧ'), ('Ǩ', 'Ǩ'), ('Ǫ', 'Ǫ'), ('Ǭ', 'Ǭ'),
+  ('Ǯ', 'Ǯ'), ('DZ', 'Dz'), ('Ǵ', 'Ǵ'), ('Ƕ', 'Ǹ'), ('Ǻ', 'Ǻ'),
+  ('Ǽ', 'Ǽ'), ('Ǿ', 'Ǿ'), ('Ȁ', 'Ȁ'), ('Ȃ', 'Ȃ'), ('Ȅ', 'Ȅ'),
+  ('Ȇ', 'Ȇ'), ('Ȉ', 'Ȉ'), ('Ȋ', 'Ȋ'), ('Ȍ', 'Ȍ'), ('Ȏ', 'Ȏ'),
+  ('Ȑ', 'Ȑ'), ('Ȓ', 'Ȓ'), ('Ȕ', 'Ȕ'), ('Ȗ', 'Ȗ'), ('Ș', 'Ș'),
+  ('Ț', 'Ț'), ('Ȝ', 'Ȝ'), ('Ȟ', 'Ȟ'), ('Ƞ', 'Ƞ'), ('Ȣ', 'Ȣ'),
+  ('Ȥ', 'Ȥ'), ('Ȧ', 'Ȧ'), ('Ȩ', 'Ȩ'), ('Ȫ', 'Ȫ'), ('Ȭ', 'Ȭ'),
+  ('Ȯ', 'Ȯ'), ('Ȱ', 'Ȱ'), ('Ȳ', 'Ȳ'), ('Ⱥ', 'Ȼ'), ('Ƚ', 'Ⱦ'),
+  ('Ɂ', 'Ɂ'), ('Ƀ', 'Ɇ'), ('Ɉ', 'Ɉ'), ('Ɋ', 'Ɋ'), ('Ɍ', 'Ɍ'),
+  ('Ɏ', 'Ɏ'), ('\u{345}', '\u{345}'), ('Ͱ', 'Ͱ'), ('Ͳ', 'Ͳ'),
+  ('Ͷ', 'Ͷ'), ('Ϳ', 'Ϳ'), ('Ά', 'Ά'), ('Έ', 'Ί'), ('Ό', 'Ό'),
+  ('Ύ', 'Ώ'), ('Α', 'Ρ'), ('Σ', 'Ϋ'), ('ς', 'ς'), ('Ϗ', 'ϑ'),
+  ('ϕ', 'ϖ'), ('Ϙ', 'Ϙ'), ('Ϛ', 'Ϛ'), ('Ϝ', 'Ϝ'), ('Ϟ', 'Ϟ'),
+  ('Ϡ', 'Ϡ'), ('Ϣ', 'Ϣ'), ('Ϥ', 'Ϥ'), ('Ϧ', 'Ϧ'), ('Ϩ', 'Ϩ'),
+  ('Ϫ', 'Ϫ'), ('Ϭ', 'Ϭ'), ('Ϯ', 'Ϯ'), ('ϰ', 'ϱ'), ('ϴ', 'ϵ'),
+  ('Ϸ', 'Ϸ'), ('Ϲ', 'Ϻ'), ('Ͻ', 'Я'), ('Ѡ', 'Ѡ'), ('Ѣ', 'Ѣ'),
+  ('Ѥ', 'Ѥ'), ('Ѧ', 'Ѧ'), ('Ѩ', 'Ѩ'), ('Ѫ', 'Ѫ'), ('Ѭ', 'Ѭ'),
+  ('Ѯ', 'Ѯ'), ('Ѱ', 'Ѱ'), ('Ѳ', 'Ѳ'), ('Ѵ', 'Ѵ'), ('Ѷ', 'Ѷ'),
+  ('Ѹ', 'Ѹ'), ('Ѻ', 'Ѻ'), ('Ѽ', 'Ѽ'), ('Ѿ', 'Ѿ'), ('Ҁ', 'Ҁ'),
+  ('Ҋ', 'Ҋ'), ('Ҍ', 'Ҍ'), ('Ҏ', 'Ҏ'), ('Ґ', 'Ґ'), ('Ғ', 'Ғ'),
+  ('Ҕ', 'Ҕ'), ('Җ', 'Җ'), ('Ҙ', 'Ҙ'), ('Қ', 'Қ'), ('Ҝ', 'Ҝ'),
+  ('Ҟ', 'Ҟ'), ('Ҡ', 'Ҡ'), ('Ң', 'Ң'), ('Ҥ', 'Ҥ'), ('Ҧ', 'Ҧ'),
+  ('Ҩ', 'Ҩ'), ('Ҫ', 'Ҫ'), ('Ҭ', 'Ҭ'), ('Ү', 'Ү'), ('Ұ', 'Ұ'),
+  ('Ҳ', 'Ҳ'), ('Ҵ', 'Ҵ'), ('Ҷ', 'Ҷ'), ('Ҹ', 'Ҹ'), ('Һ', 'Һ'),
+  ('Ҽ', 'Ҽ'), ('Ҿ', 'Ҿ'), ('Ӏ', 'Ӂ'), ('Ӄ', 'Ӄ'), ('Ӆ', 'Ӆ'),
+  ('Ӈ', 'Ӈ'), ('Ӊ', 'Ӊ'), ('Ӌ', 'Ӌ'), ('Ӎ', 'Ӎ'), ('Ӑ', 'Ӑ'),
+  ('Ӓ', 'Ӓ'), ('Ӕ', 'Ӕ'), ('Ӗ', 'Ӗ'), ('Ә', 'Ә'), ('Ӛ', 'Ӛ'),
+  ('Ӝ', 'Ӝ'), ('Ӟ', 'Ӟ'), ('Ӡ', 'Ӡ'), ('Ӣ', 'Ӣ'), ('Ӥ', 'Ӥ'),
+  ('Ӧ', 'Ӧ'), ('Ө', 'Ө'), ('Ӫ', 'Ӫ'), ('Ӭ', 'Ӭ'), ('Ӯ', 'Ӯ'),
+  ('Ӱ', 'Ӱ'), ('Ӳ', 'Ӳ'), ('Ӵ', 'Ӵ'), ('Ӷ', 'Ӷ'), ('Ӹ', 'Ӹ'),
+  ('Ӻ', 'Ӻ'), ('Ӽ', 'Ӽ'), ('Ӿ', 'Ӿ'), ('Ԁ', 'Ԁ'), ('Ԃ', 'Ԃ'),
+  ('Ԅ', 'Ԅ'), ('Ԇ', 'Ԇ'), ('Ԉ', 'Ԉ'), ('Ԋ', 'Ԋ'), ('Ԍ', 'Ԍ'),
+  ('Ԏ', 'Ԏ'), ('Ԑ', 'Ԑ'), ('Ԓ', 'Ԓ'), ('Ԕ', 'Ԕ'), ('Ԗ', 'Ԗ'),
+  ('Ԙ', 'Ԙ'), ('Ԛ', 'Ԛ'), ('Ԝ', 'Ԝ'), ('Ԟ', 'Ԟ'), ('Ԡ', 'Ԡ'),
+  ('Ԣ', 'Ԣ'), ('Ԥ', 'Ԥ'), ('Ԧ', 'Ԧ'), ('Ԩ', 'Ԩ'), ('Ԫ', 'Ԫ'),
+  ('Ԭ', 'Ԭ'), ('Ԯ', 'Ԯ'), ('Ա', 'Ֆ'), ('և', 'և'), ('Ⴀ', 'Ⴥ'),
+  ('Ⴧ', 'Ⴧ'), ('Ⴭ', 'Ⴭ'), ('ᏸ', 'ᏽ'), ('ᲀ', 'ᲈ'),
+  ('Ა', 'Ჺ'), ('Ჽ', 'Ჿ'), ('Ḁ', 'Ḁ'), ('Ḃ', 'Ḃ'),
+  ('Ḅ', 'Ḅ'), ('Ḇ', 'Ḇ'), ('Ḉ', 'Ḉ'), ('Ḋ', 'Ḋ'),
+  ('Ḍ', 'Ḍ'), ('Ḏ', 'Ḏ'), ('Ḑ', 'Ḑ'), ('Ḓ', 'Ḓ'),
+  ('Ḕ', 'Ḕ'), ('Ḗ', 'Ḗ'), ('Ḙ', 'Ḙ'), ('Ḛ', 'Ḛ'),
+  ('Ḝ', 'Ḝ'), ('Ḟ', 'Ḟ'), ('Ḡ', 'Ḡ'), ('Ḣ', 'Ḣ'),
+  ('Ḥ', 'Ḥ'), ('Ḧ', 'Ḧ'), ('Ḩ', 'Ḩ'), ('Ḫ', 'Ḫ'),
+  ('Ḭ', 'Ḭ'), ('Ḯ', 'Ḯ'), ('Ḱ', 'Ḱ'), ('Ḳ', 'Ḳ'),
+  ('Ḵ', 'Ḵ'), ('Ḷ', 'Ḷ'), ('Ḹ', 'Ḹ'), ('Ḻ', 'Ḻ'),
+  ('Ḽ', 'Ḽ'), ('Ḿ', 'Ḿ'), ('Ṁ', 'Ṁ'), ('Ṃ', 'Ṃ'),
+  ('Ṅ', 'Ṅ'), ('Ṇ', 'Ṇ'), ('Ṉ', 'Ṉ'), ('Ṋ', 'Ṋ'),
+  ('Ṍ', 'Ṍ'), ('Ṏ', 'Ṏ'), ('Ṑ', 'Ṑ'), ('Ṓ', 'Ṓ'),
+  ('Ṕ', 'Ṕ'), ('Ṗ', 'Ṗ'), ('Ṙ', 'Ṙ'), ('Ṛ', 'Ṛ'),
+  ('Ṝ', 'Ṝ'), ('Ṟ', 'Ṟ'), ('Ṡ', 'Ṡ'), ('Ṣ', 'Ṣ'),
+  ('Ṥ', 'Ṥ'), ('Ṧ', 'Ṧ'), ('Ṩ', 'Ṩ'), ('Ṫ', 'Ṫ'),
+  ('Ṭ', 'Ṭ'), ('Ṯ', 'Ṯ'), ('Ṱ', 'Ṱ'), ('Ṳ', 'Ṳ'),
+  ('Ṵ', 'Ṵ'), ('Ṷ', 'Ṷ'), ('Ṹ', 'Ṹ'), ('Ṻ', 'Ṻ'),
+  ('Ṽ', 'Ṽ'), ('Ṿ', 'Ṿ'), ('Ẁ', 'Ẁ'), ('Ẃ', 'Ẃ'),
+  ('Ẅ', 'Ẅ'), ('Ẇ', 'Ẇ'), ('Ẉ', 'Ẉ'), ('Ẋ', 'Ẋ'),
+  ('Ẍ', 'Ẍ'), ('Ẏ', 'Ẏ'), ('Ẑ', 'Ẑ'), ('Ẓ', 'Ẓ'),
+  ('Ẕ', 'Ẕ'), ('ẚ', 'ẛ'), ('ẞ', 'ẞ'), ('Ạ', 'Ạ'),
+  ('Ả', 'Ả'), ('Ấ', 'Ấ'), ('Ầ', 'Ầ'), ('Ẩ', 'Ẩ'),
+  ('Ẫ', 'Ẫ'), ('Ậ', 'Ậ'), ('Ắ', 'Ắ'), ('Ằ', 'Ằ'),
+  ('Ẳ', 'Ẳ'), ('Ẵ', 'Ẵ'), ('Ặ', 'Ặ'), ('Ẹ', 'Ẹ'),
+  ('Ẻ', 'Ẻ'), ('Ẽ', 'Ẽ'), ('Ế', 'Ế'), ('Ề', 'Ề'),
+  ('Ể', 'Ể'), ('Ễ', 'Ễ'), ('Ệ', 'Ệ'), ('Ỉ', 'Ỉ'),
+  ('Ị', 'Ị'), ('Ọ', 'Ọ'), ('Ỏ', 'Ỏ'), ('Ố', 'Ố'),
+  ('Ồ', 'Ồ'), ('Ổ', 'Ổ'), ('Ỗ', 'Ỗ'), ('Ộ', 'Ộ'),
+  ('Ớ', 'Ớ'), ('Ờ', 'Ờ'), ('Ở', 'Ở'), ('Ỡ', 'Ỡ'),
+  ('Ợ', 'Ợ'), ('Ụ', 'Ụ'), ('Ủ', 'Ủ'), ('Ứ', 'Ứ'),
+  ('Ừ', 'Ừ'), ('Ử', 'Ử'), ('Ữ', 'Ữ'), ('Ự', 'Ự'),
+  ('Ỳ', 'Ỳ'), ('Ỵ', 'Ỵ'), ('Ỷ', 'Ỷ'), ('Ỹ', 'Ỹ'),
+  ('Ỻ', 'Ỻ'), ('Ỽ', 'Ỽ'), ('Ỿ', 'Ỿ'), ('Ἀ', 'Ἇ'),
+  ('Ἐ', 'Ἕ'), ('Ἠ', 'Ἧ'), ('Ἰ', 'Ἷ'), ('Ὀ', 'Ὅ'),
+  ('Ὑ', 'Ὑ'), ('Ὓ', 'Ὓ'), ('Ὕ', 'Ὕ'), ('Ὗ', 'Ὗ'),
+  ('Ὠ', 'Ὧ'), ('ᾀ', 'ᾯ'), ('ᾲ', 'ᾴ'), ('ᾷ', 'ᾼ'),
+  ('ῂ', 'ῄ'), ('ῇ', 'ῌ'), ('Ῐ', 'Ί'), ('Ῠ', 'Ῥ'),
+  ('ῲ', 'ῴ'), ('ῷ', 'ῼ'), ('Ω', 'Ω'), ('K', 'Å'),
+  ('Ⅎ', 'Ⅎ'), ('Ⅰ', 'Ⅿ'), ('Ↄ', 'Ↄ'), ('Ⓐ', 'Ⓩ'),
+  ('Ⰰ', 'Ⱞ'), ('Ⱡ', 'Ⱡ'), ('Ɫ', 'Ɽ'), ('Ⱨ', 'Ⱨ'),
+  ('Ⱪ', 'Ⱪ'), ('Ⱬ', 'Ⱬ'), ('Ɑ', 'Ɒ'), ('Ⱳ', 'Ⱳ'),
+  ('Ⱶ', 'Ⱶ'), ('Ȿ', 'Ⲁ'), ('Ⲃ', 'Ⲃ'), ('Ⲅ', 'Ⲅ'),
+  ('Ⲇ', 'Ⲇ'), ('Ⲉ', 'Ⲉ'), ('Ⲋ', 'Ⲋ'), ('Ⲍ', 'Ⲍ'),
+  ('Ⲏ', 'Ⲏ'), ('Ⲑ', 'Ⲑ'), ('Ⲓ', 'Ⲓ'), ('Ⲕ', 'Ⲕ'),
+  ('Ⲗ', 'Ⲗ'), ('Ⲙ', 'Ⲙ'), ('Ⲛ', 'Ⲛ'), ('Ⲝ', 'Ⲝ'),
+  ('Ⲟ', 'Ⲟ'), ('Ⲡ', 'Ⲡ'), ('Ⲣ', 'Ⲣ'), ('Ⲥ', 'Ⲥ'),
+  ('Ⲧ', 'Ⲧ'), ('Ⲩ', 'Ⲩ'), ('Ⲫ', 'Ⲫ'), ('Ⲭ', 'Ⲭ'),
+  ('Ⲯ', 'Ⲯ'), ('Ⲱ', 'Ⲱ'), ('Ⲳ', 'Ⲳ'), ('Ⲵ', 'Ⲵ'),
+  ('Ⲷ', 'Ⲷ'), ('Ⲹ', 'Ⲹ'), ('Ⲻ', 'Ⲻ'), ('Ⲽ', 'Ⲽ'),
+  ('Ⲿ', 'Ⲿ'), ('Ⳁ', 'Ⳁ'), ('Ⳃ', 'Ⳃ'), ('Ⳅ', 'Ⳅ'),
+  ('Ⳇ', 'Ⳇ'), ('Ⳉ', 'Ⳉ'), ('Ⳋ', 'Ⳋ'), ('Ⳍ', 'Ⳍ'),
+  ('Ⳏ', 'Ⳏ'), ('Ⳑ', 'Ⳑ'), ('Ⳓ', 'Ⳓ'), ('Ⳕ', 'Ⳕ'),
+  ('Ⳗ', 'Ⳗ'), ('Ⳙ', 'Ⳙ'), ('Ⳛ', 'Ⳛ'), ('Ⳝ', 'Ⳝ'),
+  ('Ⳟ', 'Ⳟ'), ('Ⳡ', 'Ⳡ'), ('Ⳣ', 'Ⳣ'), ('Ⳬ', 'Ⳬ'),
+  ('Ⳮ', 'Ⳮ'), ('Ⳳ', 'Ⳳ'), ('Ꙁ', 'Ꙁ'), ('Ꙃ', 'Ꙃ'),
+  ('Ꙅ', 'Ꙅ'), ('Ꙇ', 'Ꙇ'), ('Ꙉ', 'Ꙉ'), ('Ꙋ', 'Ꙋ'),
+  ('Ꙍ', 'Ꙍ'), ('Ꙏ', 'Ꙏ'), ('Ꙑ', 'Ꙑ'), ('Ꙓ', 'Ꙓ'),
+  ('Ꙕ', 'Ꙕ'), ('Ꙗ', 'Ꙗ'), ('Ꙙ', 'Ꙙ'), ('Ꙛ', 'Ꙛ'),
+  ('Ꙝ', 'Ꙝ'), ('Ꙟ', 'Ꙟ'), ('Ꙡ', 'Ꙡ'), ('Ꙣ', 'Ꙣ'),
+  ('Ꙥ', 'Ꙥ'), ('Ꙧ', 'Ꙧ'), ('Ꙩ', 'Ꙩ'), ('Ꙫ', 'Ꙫ'),
+  ('Ꙭ', 'Ꙭ'), ('Ꚁ', 'Ꚁ'), ('Ꚃ', 'Ꚃ'), ('Ꚅ', 'Ꚅ'),
+  ('Ꚇ', 'Ꚇ'), ('Ꚉ', 'Ꚉ'), ('Ꚋ', 'Ꚋ'), ('Ꚍ', 'Ꚍ'),
+  ('Ꚏ', 'Ꚏ'), ('Ꚑ', 'Ꚑ'), ('Ꚓ', 'Ꚓ'), ('Ꚕ', 'Ꚕ'),
+  ('Ꚗ', 'Ꚗ'), ('Ꚙ', 'Ꚙ'), ('Ꚛ', 'Ꚛ'), ('Ꜣ', 'Ꜣ'),
+  ('Ꜥ', 'Ꜥ'), ('Ꜧ', 'Ꜧ'), ('Ꜩ', 'Ꜩ'), ('Ꜫ', 'Ꜫ'),
+  ('Ꜭ', 'Ꜭ'), ('Ꜯ', 'Ꜯ'), ('Ꜳ', 'Ꜳ'), ('Ꜵ', 'Ꜵ'),
+  ('Ꜷ', 'Ꜷ'), ('Ꜹ', 'Ꜹ'), ('Ꜻ', 'Ꜻ'), ('Ꜽ', 'Ꜽ'),
+  ('Ꜿ', 'Ꜿ'), ('Ꝁ', 'Ꝁ'), ('Ꝃ', 'Ꝃ'), ('Ꝅ', 'Ꝅ'),
+  ('Ꝇ', 'Ꝇ'), ('Ꝉ', 'Ꝉ'), ('Ꝋ', 'Ꝋ'), ('Ꝍ', 'Ꝍ'),
+  ('Ꝏ', 'Ꝏ'), ('Ꝑ', 'Ꝑ'), ('Ꝓ', 'Ꝓ'), ('Ꝕ', 'Ꝕ'),
+  ('Ꝗ', 'Ꝗ'), ('Ꝙ', 'Ꝙ'), ('Ꝛ', 'Ꝛ'), ('Ꝝ', 'Ꝝ'),
+  ('Ꝟ', 'Ꝟ'), ('Ꝡ', 'Ꝡ'), ('Ꝣ', 'Ꝣ'), ('Ꝥ', 'Ꝥ'),
+  ('Ꝧ', 'Ꝧ'), ('Ꝩ', 'Ꝩ'), ('Ꝫ', 'Ꝫ'), ('Ꝭ', 'Ꝭ'),
+  ('Ꝯ', 'Ꝯ'), ('Ꝺ', 'Ꝺ'), ('Ꝼ', 'Ꝼ'), ('Ᵹ', 'Ꝿ'),
+  ('Ꞁ', 'Ꞁ'), ('Ꞃ', 'Ꞃ'), ('Ꞅ', 'Ꞅ'), ('Ꞇ', 'Ꞇ'),
+  ('Ꞌ', 'Ꞌ'), ('Ɥ', 'Ɥ'), ('Ꞑ', 'Ꞑ'), ('Ꞓ', 'Ꞓ'),
+  ('Ꞗ', 'Ꞗ'), ('Ꞙ', 'Ꞙ'), ('Ꞛ', 'Ꞛ'), ('Ꞝ', 'Ꞝ'),
+  ('Ꞟ', 'Ꞟ'), ('Ꞡ', 'Ꞡ'), ('Ꞣ', 'Ꞣ'), ('Ꞥ', 'Ꞥ'),
+  ('Ꞧ', 'Ꞧ'), ('Ꞩ', 'Ꞩ'), ('Ɦ', 'Ɪ'), ('Ʞ', 'Ꞵ'),
+  ('Ꞷ', 'Ꞷ'), ('Ꞹ', 'Ꞹ'), ('\u{a7ba}', '\u{a7ba}'),
+  ('\u{a7bc}', '\u{a7bc}'), ('\u{a7be}', '\u{a7be}'),
+  ('\u{a7c2}', '\u{a7c2}'), ('\u{a7c4}', '\u{a7c6}'), ('ꭰ', 'ꮿ'),
+  ('ff', 'st'), ('ﬓ', 'ﬗ'), ('A', 'Z'), ('𐐀', '𐐧'),
+  ('𐒰', '𐓓'), ('𐲀', '𐲲'), ('𑢠', '𑢿'), ('𖹀', '𖹟'),
+  ('𞤀', '𞤡'),
+];
+
+pub const CHANGES_WHEN_CASEMAPPED: &'static [(char, char)] = &[
+  ('A', 'Z'), ('a', 'z'), ('µ', 'µ'), ('À', 'Ö'), ('Ø', 'ö'),
+  ('ø', 'ķ'), ('Ĺ', 'ƌ'), ('Ǝ', 'ƚ'), ('Ɯ', 'Ʃ'), ('Ƭ', 'ƹ'),
+  ('Ƽ', 'ƽ'), ('ƿ', 'ƿ'), ('DŽ', 'Ƞ'), ('Ȣ', 'ȳ'), ('Ⱥ', 'ɔ'),
+  ('ɖ', 'ɗ'), ('ə', 'ə'), ('ɛ', 'ɜ'), ('ɠ', 'ɡ'), ('ɣ', 'ɣ'),
+  ('ɥ', 'ɦ'), ('ɨ', 'ɬ'), ('ɯ', 'ɯ'), ('ɱ', 'ɲ'), ('ɵ', 'ɵ'),
+  ('ɽ', 'ɽ'), ('ʀ', 'ʀ'), ('ʂ', 'ʃ'), ('ʇ', 'ʌ'), ('ʒ', 'ʒ'),
+  ('ʝ', 'ʞ'), ('\u{345}', '\u{345}'), ('Ͱ', 'ͳ'), ('Ͷ', 'ͷ'),
+  ('ͻ', 'ͽ'), ('Ϳ', 'Ϳ'), ('Ά', 'Ά'), ('Έ', 'Ί'), ('Ό', 'Ό'),
+  ('Ύ', 'Ρ'), ('Σ', 'ϑ'), ('ϕ', 'ϵ'), ('Ϸ', 'ϻ'), ('Ͻ', 'ҁ'),
+  ('Ҋ', 'ԯ'), ('Ա', 'Ֆ'), ('ա', 'և'), ('Ⴀ', 'Ⴥ'), ('Ⴧ', 'Ⴧ'),
+  ('Ⴭ', 'Ⴭ'), ('ა', 'ჺ'), ('ჽ', 'ჿ'), ('Ꭰ', 'Ᏽ'),
+  ('ᏸ', 'ᏽ'), ('ᲀ', 'ᲈ'), ('Ა', 'Ჺ'), ('Ჽ', 'Ჿ'),
+  ('ᵹ', 'ᵹ'), ('ᵽ', 'ᵽ'), ('ᶎ', 'ᶎ'), ('Ḁ', 'ẛ'),
+  ('ẞ', 'ẞ'), ('Ạ', 'ἕ'), ('Ἐ', 'Ἕ'), ('ἠ', 'ὅ'),
+  ('Ὀ', 'Ὅ'), ('ὐ', 'ὗ'), ('Ὑ', 'Ὑ'), ('Ὓ', 'Ὓ'),
+  ('Ὕ', 'Ὕ'), ('Ὗ', 'ώ'), ('ᾀ', 'ᾴ'), ('ᾶ', 'ᾼ'),
+  ('ι', 'ι'), ('ῂ', 'ῄ'), ('ῆ', 'ῌ'), ('ῐ', 'ΐ'),
+  ('ῖ', 'Ί'), ('ῠ', 'Ῥ'), ('ῲ', 'ῴ'), ('ῶ', 'ῼ'),
+  ('Ω', 'Ω'), ('K', 'Å'), ('Ⅎ', 'Ⅎ'), ('ⅎ', 'ⅎ'),
+  ('Ⅰ', 'ⅿ'), ('Ↄ', 'ↄ'), ('Ⓐ', 'ⓩ'), ('Ⰰ', 'Ⱞ'),
+  ('ⰰ', 'ⱞ'), ('Ⱡ', 'Ɒ'), ('Ⱳ', 'ⱳ'), ('Ⱶ', 'ⱶ'),
+  ('Ȿ', 'ⳣ'), ('Ⳬ', 'ⳮ'), ('Ⳳ', 'ⳳ'), ('ⴀ', 'ⴥ'),
+  ('ⴧ', 'ⴧ'), ('ⴭ', 'ⴭ'), ('Ꙁ', 'ꙭ'), ('Ꚁ', 'ꚛ'),
+  ('Ꜣ', 'ꜯ'), ('Ꜳ', 'ꝯ'), ('Ꝺ', 'ꞇ'), ('Ꞌ', 'Ɥ'),
+  ('Ꞑ', 'ꞔ'), ('Ꞗ', 'Ɪ'), ('Ʞ', '\u{a7bf}'),
+  ('\u{a7c2}', '\u{a7c6}'), ('ꭓ', 'ꭓ'), ('ꭰ', 'ꮿ'), ('ff', 'st'),
+  ('ﬓ', 'ﬗ'), ('A', 'Z'), ('a', 'z'), ('𐐀', '𐑏'),
+  ('𐒰', '𐓓'), ('𐓘', '𐓻'), ('𐲀', '𐲲'), ('𐳀', '𐳲'),
+  ('𑢠', '𑣟'), ('𖹀', '𖹿'), ('𞤀', '𞥃'),
+];
+
+pub const CHANGES_WHEN_LOWERCASED: &'static [(char, char)] = &[
+  ('A', 'Z'), ('À', 'Ö'), ('Ø', 'Þ'), ('Ā', 'Ā'), ('Ă', 'Ă'),
+  ('Ą', 'Ą'), ('Ć', 'Ć'), ('Ĉ', 'Ĉ'), ('Ċ', 'Ċ'), ('Č', 'Č'),
+  ('Ď', 'Ď'), ('Đ', 'Đ'), ('Ē', 'Ē'), ('Ĕ', 'Ĕ'), ('Ė', 'Ė'),
+  ('Ę', 'Ę'), ('Ě', 'Ě'), ('Ĝ', 'Ĝ'), ('Ğ', 'Ğ'), ('Ġ', 'Ġ'),
+  ('Ģ', 'Ģ'), ('Ĥ', 'Ĥ'), ('Ħ', 'Ħ'), ('Ĩ', 'Ĩ'), ('Ī', 'Ī'),
+  ('Ĭ', 'Ĭ'), ('Į', 'Į'), ('İ', 'İ'), ('IJ', 'IJ'), ('Ĵ', 'Ĵ'),
+  ('Ķ', 'Ķ'), ('Ĺ', 'Ĺ'), ('Ļ', 'Ļ'), ('Ľ', 'Ľ'), ('Ŀ', 'Ŀ'),
+  ('Ł', 'Ł'), ('Ń', 'Ń'), ('Ņ', 'Ņ'), ('Ň', 'Ň'), ('Ŋ', 'Ŋ'),
+  ('Ō', 'Ō'), ('Ŏ', 'Ŏ'), ('Ő', 'Ő'), ('Œ', 'Œ'), ('Ŕ', 'Ŕ'),
+  ('Ŗ', 'Ŗ'), ('Ř', 'Ř'), ('Ś', 'Ś'), ('Ŝ', 'Ŝ'), ('Ş', 'Ş'),
+  ('Š', 'Š'), ('Ţ', 'Ţ'), ('Ť', 'Ť'), ('Ŧ', 'Ŧ'), ('Ũ', 'Ũ'),
+  ('Ū', 'Ū'), ('Ŭ', 'Ŭ'), ('Ů', 'Ů'), ('Ű', 'Ű'), ('Ų', 'Ų'),
+  ('Ŵ', 'Ŵ'), ('Ŷ', 'Ŷ'), ('Ÿ', 'Ź'), ('Ż', 'Ż'), ('Ž', 'Ž'),
+  ('Ɓ', 'Ƃ'), ('Ƅ', 'Ƅ'), ('Ɔ', 'Ƈ'), ('Ɖ', 'Ƌ'), ('Ǝ', 'Ƒ'),
+  ('Ɠ', 'Ɣ'), ('Ɩ', 'Ƙ'), ('Ɯ', 'Ɲ'), ('Ɵ', 'Ơ'), ('Ƣ', 'Ƣ'),
+  ('Ƥ', 'Ƥ'), ('Ʀ', 'Ƨ'), ('Ʃ', 'Ʃ'), ('Ƭ', 'Ƭ'), ('Ʈ', 'Ư'),
+  ('Ʊ', 'Ƴ'), ('Ƶ', 'Ƶ'), ('Ʒ', 'Ƹ'), ('Ƽ', 'Ƽ'), ('DŽ', 'Dž'),
+  ('LJ', 'Lj'), ('NJ', 'Nj'), ('Ǎ', 'Ǎ'), ('Ǐ', 'Ǐ'), ('Ǒ', 'Ǒ'),
+  ('Ǔ', 'Ǔ'), ('Ǖ', 'Ǖ'), ('Ǘ', 'Ǘ'), ('Ǚ', 'Ǚ'), ('Ǜ', 'Ǜ'),
+  ('Ǟ', 'Ǟ'), ('Ǡ', 'Ǡ'), ('Ǣ', 'Ǣ'), ('Ǥ', 'Ǥ'), ('Ǧ', 'Ǧ'),
+  ('Ǩ', 'Ǩ'), ('Ǫ', 'Ǫ'), ('Ǭ', 'Ǭ'), ('Ǯ', 'Ǯ'), ('DZ', 'Dz'),
+  ('Ǵ', 'Ǵ'), ('Ƕ', 'Ǹ'), ('Ǻ', 'Ǻ'), ('Ǽ', 'Ǽ'), ('Ǿ', 'Ǿ'),
+  ('Ȁ', 'Ȁ'), ('Ȃ', 'Ȃ'), ('Ȅ', 'Ȅ'), ('Ȇ', 'Ȇ'), ('Ȉ', 'Ȉ'),
+  ('Ȋ', 'Ȋ'), ('Ȍ', 'Ȍ'), ('Ȏ', 'Ȏ'), ('Ȑ', 'Ȑ'), ('Ȓ', 'Ȓ'),
+  ('Ȕ', 'Ȕ'), ('Ȗ', 'Ȗ'), ('Ș', 'Ș'), ('Ț', 'Ț'), ('Ȝ', 'Ȝ'),
+  ('Ȟ', 'Ȟ'), ('Ƞ', 'Ƞ'), ('Ȣ', 'Ȣ'), ('Ȥ', 'Ȥ'), ('Ȧ', 'Ȧ'),
+  ('Ȩ', 'Ȩ'), ('Ȫ', 'Ȫ'), ('Ȭ', 'Ȭ'), ('Ȯ', 'Ȯ'), ('Ȱ', 'Ȱ'),
+  ('Ȳ', 'Ȳ'), ('Ⱥ', 'Ȼ'), ('Ƚ', 'Ⱦ'), ('Ɂ', 'Ɂ'), ('Ƀ', 'Ɇ'),
+  ('Ɉ', 'Ɉ'), ('Ɋ', 'Ɋ'), ('Ɍ', 'Ɍ'), ('Ɏ', 'Ɏ'), ('Ͱ', 'Ͱ'),
+  ('Ͳ', 'Ͳ'), ('Ͷ', 'Ͷ'), ('Ϳ', 'Ϳ'), ('Ά', 'Ά'), ('Έ', 'Ί'),
+  ('Ό', 'Ό'), ('Ύ', 'Ώ'), ('Α', 'Ρ'), ('Σ', 'Ϋ'), ('Ϗ', 'Ϗ'),
+  ('Ϙ', 'Ϙ'), ('Ϛ', 'Ϛ'), ('Ϝ', 'Ϝ'), ('Ϟ', 'Ϟ'), ('Ϡ', 'Ϡ'),
+  ('Ϣ', 'Ϣ'), ('Ϥ', 'Ϥ'), ('Ϧ', 'Ϧ'), ('Ϩ', 'Ϩ'), ('Ϫ', 'Ϫ'),
+  ('Ϭ', 'Ϭ'), ('Ϯ', 'Ϯ'), ('ϴ', 'ϴ'), ('Ϸ', 'Ϸ'), ('Ϲ', 'Ϻ'),
+  ('Ͻ', 'Я'), ('Ѡ', 'Ѡ'), ('Ѣ', 'Ѣ'), ('Ѥ', 'Ѥ'), ('Ѧ', 'Ѧ'),
+  ('Ѩ', 'Ѩ'), ('Ѫ', 'Ѫ'), ('Ѭ', 'Ѭ'), ('Ѯ', 'Ѯ'), ('Ѱ', 'Ѱ'),
+  ('Ѳ', 'Ѳ'), ('Ѵ', 'Ѵ'), ('Ѷ', 'Ѷ'), ('Ѹ', 'Ѹ'), ('Ѻ', 'Ѻ'),
+  ('Ѽ', 'Ѽ'), ('Ѿ', 'Ѿ'), ('Ҁ', 'Ҁ'), ('Ҋ', 'Ҋ'), ('Ҍ', 'Ҍ'),
+  ('Ҏ', 'Ҏ'), ('Ґ', 'Ґ'), ('Ғ', 'Ғ'), ('Ҕ', 'Ҕ'), ('Җ', 'Җ'),
+  ('Ҙ', 'Ҙ'), ('Қ', 'Қ'), ('Ҝ', 'Ҝ'), ('Ҟ', 'Ҟ'), ('Ҡ', 'Ҡ'),
+  ('Ң', 'Ң'), ('Ҥ', 'Ҥ'), ('Ҧ', 'Ҧ'), ('Ҩ', 'Ҩ'), ('Ҫ', 'Ҫ'),
+  ('Ҭ', 'Ҭ'), ('Ү', 'Ү'), ('Ұ', 'Ұ'), ('Ҳ', 'Ҳ'), ('Ҵ', 'Ҵ'),
+  ('Ҷ', 'Ҷ'), ('Ҹ', 'Ҹ'), ('Һ', 'Һ'), ('Ҽ', 'Ҽ'), ('Ҿ', 'Ҿ'),
+  ('Ӏ', 'Ӂ'), ('Ӄ', 'Ӄ'), ('Ӆ', 'Ӆ'), ('Ӈ', 'Ӈ'), ('Ӊ', 'Ӊ'),
+  ('Ӌ', 'Ӌ'), ('Ӎ', 'Ӎ'), ('Ӑ', 'Ӑ'), ('Ӓ', 'Ӓ'), ('Ӕ', 'Ӕ'),
+  ('Ӗ', 'Ӗ'), ('Ә', 'Ә'), ('Ӛ', 'Ӛ'), ('Ӝ', 'Ӝ'), ('Ӟ', 'Ӟ'),
+  ('Ӡ', 'Ӡ'), ('Ӣ', 'Ӣ'), ('Ӥ', 'Ӥ'), ('Ӧ', 'Ӧ'), ('Ө', 'Ө'),
+  ('Ӫ', 'Ӫ'), ('Ӭ', 'Ӭ'), ('Ӯ', 'Ӯ'), ('Ӱ', 'Ӱ'), ('Ӳ', 'Ӳ'),
+  ('Ӵ', 'Ӵ'), ('Ӷ', 'Ӷ'), ('Ӹ', 'Ӹ'), ('Ӻ', 'Ӻ'), ('Ӽ', 'Ӽ'),
+  ('Ӿ', 'Ӿ'), ('Ԁ', 'Ԁ'), ('Ԃ', 'Ԃ'), ('Ԅ', 'Ԅ'), ('Ԇ', 'Ԇ'),
+  ('Ԉ', 'Ԉ'), ('Ԋ', 'Ԋ'), ('Ԍ', 'Ԍ'), ('Ԏ', 'Ԏ'), ('Ԑ', 'Ԑ'),
+  ('Ԓ', 'Ԓ'), ('Ԕ', 'Ԕ'), ('Ԗ', 'Ԗ'), ('Ԙ', 'Ԙ'), ('Ԛ', 'Ԛ'),
+  ('Ԝ', 'Ԝ'), ('Ԟ', 'Ԟ'), ('Ԡ', 'Ԡ'), ('Ԣ', 'Ԣ'), ('Ԥ', 'Ԥ'),
+  ('Ԧ', 'Ԧ'), ('Ԩ', 'Ԩ'), ('Ԫ', 'Ԫ'), ('Ԭ', 'Ԭ'), ('Ԯ', 'Ԯ'),
+  ('Ա', 'Ֆ'), ('Ⴀ', 'Ⴥ'), ('Ⴧ', 'Ⴧ'), ('Ⴭ', 'Ⴭ'),
+  ('Ꭰ', 'Ᏽ'), ('Ა', 'Ჺ'), ('Ჽ', 'Ჿ'), ('Ḁ', 'Ḁ'),
+  ('Ḃ', 'Ḃ'), ('Ḅ', 'Ḅ'), ('Ḇ', 'Ḇ'), ('Ḉ', 'Ḉ'),
+  ('Ḋ', 'Ḋ'), ('Ḍ', 'Ḍ'), ('Ḏ', 'Ḏ'), ('Ḑ', 'Ḑ'),
+  ('Ḓ', 'Ḓ'), ('Ḕ', 'Ḕ'), ('Ḗ', 'Ḗ'), ('Ḙ', 'Ḙ'),
+  ('Ḛ', 'Ḛ'), ('Ḝ', 'Ḝ'), ('Ḟ', 'Ḟ'), ('Ḡ', 'Ḡ'),
+  ('Ḣ', 'Ḣ'), ('Ḥ', 'Ḥ'), ('Ḧ', 'Ḧ'), ('Ḩ', 'Ḩ'),
+  ('Ḫ', 'Ḫ'), ('Ḭ', 'Ḭ'), ('Ḯ', 'Ḯ'), ('Ḱ', 'Ḱ'),
+  ('Ḳ', 'Ḳ'), ('Ḵ', 'Ḵ'), ('Ḷ', 'Ḷ'), ('Ḹ', 'Ḹ'),
+  ('Ḻ', 'Ḻ'), ('Ḽ', 'Ḽ'), ('Ḿ', 'Ḿ'), ('Ṁ', 'Ṁ'),
+  ('Ṃ', 'Ṃ'), ('Ṅ', 'Ṅ'), ('Ṇ', 'Ṇ'), ('Ṉ', 'Ṉ'),
+  ('Ṋ', 'Ṋ'), ('Ṍ', 'Ṍ'), ('Ṏ', 'Ṏ'), ('Ṑ', 'Ṑ'),
+  ('Ṓ', 'Ṓ'), ('Ṕ', 'Ṕ'), ('Ṗ', 'Ṗ'), ('Ṙ', 'Ṙ'),
+  ('Ṛ', 'Ṛ'), ('Ṝ', 'Ṝ'), ('Ṟ', 'Ṟ'), ('Ṡ', 'Ṡ'),
+  ('Ṣ', 'Ṣ'), ('Ṥ', 'Ṥ'), ('Ṧ', 'Ṧ'), ('Ṩ', 'Ṩ'),
+  ('Ṫ', 'Ṫ'), ('Ṭ', 'Ṭ'), ('Ṯ', 'Ṯ'), ('Ṱ', 'Ṱ'),
+  ('Ṳ', 'Ṳ'), ('Ṵ', 'Ṵ'), ('Ṷ', 'Ṷ'), ('Ṹ', 'Ṹ'),
+  ('Ṻ', 'Ṻ'), ('Ṽ', 'Ṽ'), ('Ṿ', 'Ṿ'), ('Ẁ', 'Ẁ'),
+  ('Ẃ', 'Ẃ'), ('Ẅ', 'Ẅ'), ('Ẇ', 'Ẇ'), ('Ẉ', 'Ẉ'),
+  ('Ẋ', 'Ẋ'), ('Ẍ', 'Ẍ'), ('Ẏ', 'Ẏ'), ('Ẑ', 'Ẑ'),
+  ('Ẓ', 'Ẓ'), ('Ẕ', 'Ẕ'), ('ẞ', 'ẞ'), ('Ạ', 'Ạ'),
+  ('Ả', 'Ả'), ('Ấ', 'Ấ'), ('Ầ', 'Ầ'), ('Ẩ', 'Ẩ'),
+  ('Ẫ', 'Ẫ'), ('Ậ', 'Ậ'), ('Ắ', 'Ắ'), ('Ằ', 'Ằ'),
+  ('Ẳ', 'Ẳ'), ('Ẵ', 'Ẵ'), ('Ặ', 'Ặ'), ('Ẹ', 'Ẹ'),
+  ('Ẻ', 'Ẻ'), ('Ẽ', 'Ẽ'), ('Ế', 'Ế'), ('Ề', 'Ề'),
+  ('Ể', 'Ể'), ('Ễ', 'Ễ'), ('Ệ', 'Ệ'), ('Ỉ', 'Ỉ'),
+  ('Ị', 'Ị'), ('Ọ', 'Ọ'), ('Ỏ', 'Ỏ'), ('Ố', 'Ố'),
+  ('Ồ', 'Ồ'), ('Ổ', 'Ổ'), ('Ỗ', 'Ỗ'), ('Ộ', 'Ộ'),
+  ('Ớ', 'Ớ'), ('Ờ', 'Ờ'), ('Ở', 'Ở'), ('Ỡ', 'Ỡ'),
+  ('Ợ', 'Ợ'), ('Ụ', 'Ụ'), ('Ủ', 'Ủ'), ('Ứ', 'Ứ'),
+  ('Ừ', 'Ừ'), ('Ử', 'Ử'), ('Ữ', 'Ữ'), ('Ự', 'Ự'),
+  ('Ỳ', 'Ỳ'), ('Ỵ', 'Ỵ'), ('Ỷ', 'Ỷ'), ('Ỹ', 'Ỹ'),
+  ('Ỻ', 'Ỻ'), ('Ỽ', 'Ỽ'), ('Ỿ', 'Ỿ'), ('Ἀ', 'Ἇ'),
+  ('Ἐ', 'Ἕ'), ('Ἠ', 'Ἧ'), ('Ἰ', 'Ἷ'), ('Ὀ', 'Ὅ'),
+  ('Ὑ', 'Ὑ'), ('Ὓ', 'Ὓ'), ('Ὕ', 'Ὕ'), ('Ὗ', 'Ὗ'),
+  ('Ὠ', 'Ὧ'), ('ᾈ', 'ᾏ'), ('ᾘ', 'ᾟ'), ('ᾨ', 'ᾯ'),
+  ('Ᾰ', 'ᾼ'), ('Ὲ', 'ῌ'), ('Ῐ', 'Ί'), ('Ῠ', 'Ῥ'),
+  ('Ὸ', 'ῼ'), ('Ω', 'Ω'), ('K', 'Å'), ('Ⅎ', 'Ⅎ'),
+  ('Ⅰ', 'Ⅿ'), ('Ↄ', 'Ↄ'), ('Ⓐ', 'Ⓩ'), ('Ⰰ', 'Ⱞ'),
+  ('Ⱡ', 'Ⱡ'), ('Ɫ', 'Ɽ'), ('Ⱨ', 'Ⱨ'), ('Ⱪ', 'Ⱪ'),
+  ('Ⱬ', 'Ⱬ'), ('Ɑ', 'Ɒ'), ('Ⱳ', 'Ⱳ'), ('Ⱶ', 'Ⱶ'),
+  ('Ȿ', 'Ⲁ'), ('Ⲃ', 'Ⲃ'), ('Ⲅ', 'Ⲅ'), ('Ⲇ', 'Ⲇ'),
+  ('Ⲉ', 'Ⲉ'), ('Ⲋ', 'Ⲋ'), ('Ⲍ', 'Ⲍ'), ('Ⲏ', 'Ⲏ'),
+  ('Ⲑ', 'Ⲑ'), ('Ⲓ', 'Ⲓ'), ('Ⲕ', 'Ⲕ'), ('Ⲗ', 'Ⲗ'),
+  ('Ⲙ', 'Ⲙ'), ('Ⲛ', 'Ⲛ'), ('Ⲝ', 'Ⲝ'), ('Ⲟ', 'Ⲟ'),
+  ('Ⲡ', 'Ⲡ'), ('Ⲣ', 'Ⲣ'), ('Ⲥ', 'Ⲥ'), ('Ⲧ', 'Ⲧ'),
+  ('Ⲩ', 'Ⲩ'), ('Ⲫ', 'Ⲫ'), ('Ⲭ', 'Ⲭ'), ('Ⲯ', 'Ⲯ'),
+  ('Ⲱ', 'Ⲱ'), ('Ⲳ', 'Ⲳ'), ('Ⲵ', 'Ⲵ'), ('Ⲷ', 'Ⲷ'),
+  ('Ⲹ', 'Ⲹ'), ('Ⲻ', 'Ⲻ'), ('Ⲽ', 'Ⲽ'), ('Ⲿ', 'Ⲿ'),
+  ('Ⳁ', 'Ⳁ'), ('Ⳃ', 'Ⳃ'), ('Ⳅ', 'Ⳅ'), ('Ⳇ', 'Ⳇ'),
+  ('Ⳉ', 'Ⳉ'), ('Ⳋ', 'Ⳋ'), ('Ⳍ', 'Ⳍ'), ('Ⳏ', 'Ⳏ'),
+  ('Ⳑ', 'Ⳑ'), ('Ⳓ', 'Ⳓ'), ('Ⳕ', 'Ⳕ'), ('Ⳗ', 'Ⳗ'),
+  ('Ⳙ', 'Ⳙ'), ('Ⳛ', 'Ⳛ'), ('Ⳝ', 'Ⳝ'), ('Ⳟ', 'Ⳟ'),
+  ('Ⳡ', 'Ⳡ'), ('Ⳣ', 'Ⳣ'), ('Ⳬ', 'Ⳬ'), ('Ⳮ', 'Ⳮ'),
+  ('Ⳳ', 'Ⳳ'), ('Ꙁ', 'Ꙁ'), ('Ꙃ', 'Ꙃ'), ('Ꙅ', 'Ꙅ'),
+  ('Ꙇ', 'Ꙇ'), ('Ꙉ', 'Ꙉ'), ('Ꙋ', 'Ꙋ'), ('Ꙍ', 'Ꙍ'),
+  ('Ꙏ', 'Ꙏ'), ('Ꙑ', 'Ꙑ'), ('Ꙓ', 'Ꙓ'), ('Ꙕ', 'Ꙕ'),
+  ('Ꙗ', 'Ꙗ'), ('Ꙙ', 'Ꙙ'), ('Ꙛ', 'Ꙛ'), ('Ꙝ', 'Ꙝ'),
+  ('Ꙟ', 'Ꙟ'), ('Ꙡ', 'Ꙡ'), ('Ꙣ', 'Ꙣ'), ('Ꙥ', 'Ꙥ'),
+  ('Ꙧ', 'Ꙧ'), ('Ꙩ', 'Ꙩ'), ('Ꙫ', 'Ꙫ'), ('Ꙭ', 'Ꙭ'),
+  ('Ꚁ', 'Ꚁ'), ('Ꚃ', 'Ꚃ'), ('Ꚅ', 'Ꚅ'), ('Ꚇ', 'Ꚇ'),
+  ('Ꚉ', 'Ꚉ'), ('Ꚋ', 'Ꚋ'), ('Ꚍ', 'Ꚍ'), ('Ꚏ', 'Ꚏ'),
+  ('Ꚑ', 'Ꚑ'), ('Ꚓ', 'Ꚓ'), ('Ꚕ', 'Ꚕ'), ('Ꚗ', 'Ꚗ'),
+  ('Ꚙ', 'Ꚙ'), ('Ꚛ', 'Ꚛ'), ('Ꜣ', 'Ꜣ'), ('Ꜥ', 'Ꜥ'),
+  ('Ꜧ', 'Ꜧ'), ('Ꜩ', 'Ꜩ'), ('Ꜫ', 'Ꜫ'), ('Ꜭ', 'Ꜭ'),
+  ('Ꜯ', 'Ꜯ'), ('Ꜳ', 'Ꜳ'), ('Ꜵ', 'Ꜵ'), ('Ꜷ', 'Ꜷ'),
+  ('Ꜹ', 'Ꜹ'), ('Ꜻ', 'Ꜻ'), ('Ꜽ', 'Ꜽ'), ('Ꜿ', 'Ꜿ'),
+  ('Ꝁ', 'Ꝁ'), ('Ꝃ', 'Ꝃ'), ('Ꝅ', 'Ꝅ'), ('Ꝇ', 'Ꝇ'),
+  ('Ꝉ', 'Ꝉ'), ('Ꝋ', 'Ꝋ'), ('Ꝍ', 'Ꝍ'), ('Ꝏ', 'Ꝏ'),
+  ('Ꝑ', 'Ꝑ'), ('Ꝓ', 'Ꝓ'), ('Ꝕ', 'Ꝕ'), ('Ꝗ', 'Ꝗ'),
+  ('Ꝙ', 'Ꝙ'), ('Ꝛ', 'Ꝛ'), ('Ꝝ', 'Ꝝ'), ('Ꝟ', 'Ꝟ'),
+  ('Ꝡ', 'Ꝡ'), ('Ꝣ', 'Ꝣ'), ('Ꝥ', 'Ꝥ'), ('Ꝧ', 'Ꝧ'),
+  ('Ꝩ', 'Ꝩ'), ('Ꝫ', 'Ꝫ'), ('Ꝭ', 'Ꝭ'), ('Ꝯ', 'Ꝯ'),
+  ('Ꝺ', 'Ꝺ'), ('Ꝼ', 'Ꝼ'), ('Ᵹ', 'Ꝿ'), ('Ꞁ', 'Ꞁ'),
+  ('Ꞃ', 'Ꞃ'), ('Ꞅ', 'Ꞅ'), ('Ꞇ', 'Ꞇ'), ('Ꞌ', 'Ꞌ'),
+  ('Ɥ', 'Ɥ'), ('Ꞑ', 'Ꞑ'), ('Ꞓ', 'Ꞓ'), ('Ꞗ', 'Ꞗ'),
+  ('Ꞙ', 'Ꞙ'), ('Ꞛ', 'Ꞛ'), ('Ꞝ', 'Ꞝ'), ('Ꞟ', 'Ꞟ'),
+  ('Ꞡ', 'Ꞡ'), ('Ꞣ', 'Ꞣ'), ('Ꞥ', 'Ꞥ'), ('Ꞧ', 'Ꞧ'),
+  ('Ꞩ', 'Ꞩ'), ('Ɦ', 'Ɪ'), ('Ʞ', 'Ꞵ'), ('Ꞷ', 'Ꞷ'),
+  ('Ꞹ', 'Ꞹ'), ('\u{a7ba}', '\u{a7ba}'), ('\u{a7bc}', '\u{a7bc}'),
+  ('\u{a7be}', '\u{a7be}'), ('\u{a7c2}', '\u{a7c2}'),
+  ('\u{a7c4}', '\u{a7c6}'), ('A', 'Z'), ('𐐀', '𐐧'),
+  ('𐒰', '𐓓'), ('𐲀', '𐲲'), ('𑢠', '𑢿'), ('𖹀', '𖹟'),
+  ('𞤀', '𞤡'),
+];
+
+pub const CHANGES_WHEN_TITLECASED: &'static [(char, char)] = &[
+  ('a', 'z'), ('µ', 'µ'), ('ß', 'ö'), ('ø', 'ÿ'), ('ā', 'ā'),
+  ('ă', 'ă'), ('ą', 'ą'), ('ć', 'ć'), ('ĉ', 'ĉ'), ('ċ', 'ċ'),
+  ('č', 'č'), ('ď', 'ď'), ('đ', 'đ'), ('ē', 'ē'), ('ĕ', 'ĕ'),
+  ('ė', 'ė'), ('ę', 'ę'), ('ě', 'ě'), ('ĝ', 'ĝ'), ('ğ', 'ğ'),
+  ('ġ', 'ġ'), ('ģ', 'ģ'), ('ĥ', 'ĥ'), ('ħ', 'ħ'), ('ĩ', 'ĩ'),
+  ('ī', 'ī'), ('ĭ', 'ĭ'), ('į', 'į'), ('ı', 'ı'), ('ij', 'ij'),
+  ('ĵ', 'ĵ'), ('ķ', 'ķ'), ('ĺ', 'ĺ'), ('ļ', 'ļ'), ('ľ', 'ľ'),
+  ('ŀ', 'ŀ'), ('ł', 'ł'), ('ń', 'ń'), ('ņ', 'ņ'), ('ň', 'ʼn'),
+  ('ŋ', 'ŋ'), ('ō', 'ō'), ('ŏ', 'ŏ'), ('ő', 'ő'), ('œ', 'œ'),
+  ('ŕ', 'ŕ'), ('ŗ', 'ŗ'), ('ř', 'ř'), ('ś', 'ś'), ('ŝ', 'ŝ'),
+  ('ş', 'ş'), ('š', 'š'), ('ţ', 'ţ'), ('ť', 'ť'), ('ŧ', 'ŧ'),
+  ('ũ', 'ũ'), ('ū', 'ū'), ('ŭ', 'ŭ'), ('ů', 'ů'), ('ű', 'ű'),
+  ('ų', 'ų'), ('ŵ', 'ŵ'), ('ŷ', 'ŷ'), ('ź', 'ź'), ('ż', 'ż'),
+  ('ž', 'ƀ'), ('ƃ', 'ƃ'), ('ƅ', 'ƅ'), ('ƈ', 'ƈ'), ('ƌ', 'ƌ'),
+  ('ƒ', 'ƒ'), ('ƕ', 'ƕ'), ('ƙ', 'ƚ'), ('ƞ', 'ƞ'), ('ơ', 'ơ'),
+  ('ƣ', 'ƣ'), ('ƥ', 'ƥ'), ('ƨ', 'ƨ'), ('ƭ', 'ƭ'), ('ư', 'ư'),
+  ('ƴ', 'ƴ'), ('ƶ', 'ƶ'), ('ƹ', 'ƹ'), ('ƽ', 'ƽ'), ('ƿ', 'ƿ'),
+  ('DŽ', 'DŽ'), ('dž', 'LJ'), ('lj', 'NJ'), ('nj', 'nj'), ('ǎ', 'ǎ'),
+  ('ǐ', 'ǐ'), ('ǒ', 'ǒ'), ('ǔ', 'ǔ'), ('ǖ', 'ǖ'), ('ǘ', 'ǘ'),
+  ('ǚ', 'ǚ'), ('ǜ', 'ǝ'), ('ǟ', 'ǟ'), ('ǡ', 'ǡ'), ('ǣ', 'ǣ'),
+  ('ǥ', 'ǥ'), ('ǧ', 'ǧ'), ('ǩ', 'ǩ'), ('ǫ', 'ǫ'), ('ǭ', 'ǭ'),
+  ('ǯ', 'DZ'), ('dz', 'dz'), ('ǵ', 'ǵ'), ('ǹ', 'ǹ'), ('ǻ', 'ǻ'),
+  ('ǽ', 'ǽ'), ('ǿ', 'ǿ'), ('ȁ', 'ȁ'), ('ȃ', 'ȃ'), ('ȅ', 'ȅ'),
+  ('ȇ', 'ȇ'), ('ȉ', 'ȉ'), ('ȋ', 'ȋ'), ('ȍ', 'ȍ'), ('ȏ', 'ȏ'),
+  ('ȑ', 'ȑ'), ('ȓ', 'ȓ'), ('ȕ', 'ȕ'), ('ȗ', 'ȗ'), ('ș', 'ș'),
+  ('ț', 'ț'), ('ȝ', 'ȝ'), ('ȟ', 'ȟ'), ('ȣ', 'ȣ'), ('ȥ', 'ȥ'),
+  ('ȧ', 'ȧ'), ('ȩ', 'ȩ'), ('ȫ', 'ȫ'), ('ȭ', 'ȭ'), ('ȯ', 'ȯ'),
+  ('ȱ', 'ȱ'), ('ȳ', 'ȳ'), ('ȼ', 'ȼ'), ('ȿ', 'ɀ'), ('ɂ', 'ɂ'),
+  ('ɇ', 'ɇ'), ('ɉ', 'ɉ'), ('ɋ', 'ɋ'), ('ɍ', 'ɍ'), ('ɏ', 'ɔ'),
+  ('ɖ', 'ɗ'), ('ə', 'ə'), ('ɛ', 'ɜ'), ('ɠ', 'ɡ'), ('ɣ', 'ɣ'),
+  ('ɥ', 'ɦ'), ('ɨ', 'ɬ'), ('ɯ', 'ɯ'), ('ɱ', 'ɲ'), ('ɵ', 'ɵ'),
+  ('ɽ', 'ɽ'), ('ʀ', 'ʀ'), ('ʂ', 'ʃ'), ('ʇ', 'ʌ'), ('ʒ', 'ʒ'),
+  ('ʝ', 'ʞ'), ('\u{345}', '\u{345}'), ('ͱ', 'ͱ'), ('ͳ', 'ͳ'),
+  ('ͷ', 'ͷ'), ('ͻ', 'ͽ'), ('ΐ', 'ΐ'), ('ά', 'ώ'), ('ϐ', 'ϑ'),
+  ('ϕ', 'ϗ'), ('ϙ', 'ϙ'), ('ϛ', 'ϛ'), ('ϝ', 'ϝ'), ('ϟ', 'ϟ'),
+  ('ϡ', 'ϡ'), ('ϣ', 'ϣ'), ('ϥ', 'ϥ'), ('ϧ', 'ϧ'), ('ϩ', 'ϩ'),
+  ('ϫ', 'ϫ'), ('ϭ', 'ϭ'), ('ϯ', 'ϳ'), ('ϵ', 'ϵ'), ('ϸ', 'ϸ'),
+  ('ϻ', 'ϻ'), ('а', 'џ'), ('ѡ', 'ѡ'), ('ѣ', 'ѣ'), ('ѥ', 'ѥ'),
+  ('ѧ', 'ѧ'), ('ѩ', 'ѩ'), ('ѫ', 'ѫ'), ('ѭ', 'ѭ'), ('ѯ', 'ѯ'),
+  ('ѱ', 'ѱ'), ('ѳ', 'ѳ'), ('ѵ', 'ѵ'), ('ѷ', 'ѷ'), ('ѹ', 'ѹ'),
+  ('ѻ', 'ѻ'), ('ѽ', 'ѽ'), ('ѿ', 'ѿ'), ('ҁ', 'ҁ'), ('ҋ', 'ҋ'),
+  ('ҍ', 'ҍ'), ('ҏ', 'ҏ'), ('ґ', 'ґ'), ('ғ', 'ғ'), ('ҕ', 'ҕ'),
+  ('җ', 'җ'), ('ҙ', 'ҙ'), ('қ', 'қ'), ('ҝ', 'ҝ'), ('ҟ', 'ҟ'),
+  ('ҡ', 'ҡ'), ('ң', 'ң'), ('ҥ', 'ҥ'), ('ҧ', 'ҧ'), ('ҩ', 'ҩ'),
+  ('ҫ', 'ҫ'), ('ҭ', 'ҭ'), ('ү', 'ү'), ('ұ', 'ұ'), ('ҳ', 'ҳ'),
+  ('ҵ', 'ҵ'), ('ҷ', 'ҷ'), ('ҹ', 'ҹ'), ('һ', 'һ'), ('ҽ', 'ҽ'),
+  ('ҿ', 'ҿ'), ('ӂ', 'ӂ'), ('ӄ', 'ӄ'), ('ӆ', 'ӆ'), ('ӈ', 'ӈ'),
+  ('ӊ', 'ӊ'), ('ӌ', 'ӌ'), ('ӎ', 'ӏ'), ('ӑ', 'ӑ'), ('ӓ', 'ӓ'),
+  ('ӕ', 'ӕ'), ('ӗ', 'ӗ'), ('ә', 'ә'), ('ӛ', 'ӛ'), ('ӝ', 'ӝ'),
+  ('ӟ', 'ӟ'), ('ӡ', 'ӡ'), ('ӣ', 'ӣ'), ('ӥ', 'ӥ'), ('ӧ', 'ӧ'),
+  ('ө', 'ө'), ('ӫ', 'ӫ'), ('ӭ', 'ӭ'), ('ӯ', 'ӯ'), ('ӱ', 'ӱ'),
+  ('ӳ', 'ӳ'), ('ӵ', 'ӵ'), ('ӷ', 'ӷ'), ('ӹ', 'ӹ'), ('ӻ', 'ӻ'),
+  ('ӽ', 'ӽ'), ('ӿ', 'ӿ'), ('ԁ', 'ԁ'), ('ԃ', 'ԃ'), ('ԅ', 'ԅ'),
+  ('ԇ', 'ԇ'), ('ԉ', 'ԉ'), ('ԋ', 'ԋ'), ('ԍ', 'ԍ'), ('ԏ', 'ԏ'),
+  ('ԑ', 'ԑ'), ('ԓ', 'ԓ'), ('ԕ', 'ԕ'), ('ԗ', 'ԗ'), ('ԙ', 'ԙ'),
+  ('ԛ', 'ԛ'), ('ԝ', 'ԝ'), ('ԟ', 'ԟ'), ('ԡ', 'ԡ'), ('ԣ', 'ԣ'),
+  ('ԥ', 'ԥ'), ('ԧ', 'ԧ'), ('ԩ', 'ԩ'), ('ԫ', 'ԫ'), ('ԭ', 'ԭ'),
+  ('ԯ', 'ԯ'), ('ա', 'և'), ('ᏸ', 'ᏽ'), ('ᲀ', 'ᲈ'), ('ᵹ', 'ᵹ'),
+  ('ᵽ', 'ᵽ'), ('ᶎ', 'ᶎ'), ('ḁ', 'ḁ'), ('ḃ', 'ḃ'),
+  ('ḅ', 'ḅ'), ('ḇ', 'ḇ'), ('ḉ', 'ḉ'), ('ḋ', 'ḋ'),
+  ('ḍ', 'ḍ'), ('ḏ', 'ḏ'), ('ḑ', 'ḑ'), ('ḓ', 'ḓ'),
+  ('ḕ', 'ḕ'), ('ḗ', 'ḗ'), ('ḙ', 'ḙ'), ('ḛ', 'ḛ'),
+  ('ḝ', 'ḝ'), ('ḟ', 'ḟ'), ('ḡ', 'ḡ'), ('ḣ', 'ḣ'),
+  ('ḥ', 'ḥ'), ('ḧ', 'ḧ'), ('ḩ', 'ḩ'), ('ḫ', 'ḫ'),
+  ('ḭ', 'ḭ'), ('ḯ', 'ḯ'), ('ḱ', 'ḱ'), ('ḳ', 'ḳ'),
+  ('ḵ', 'ḵ'), ('ḷ', 'ḷ'), ('ḹ', 'ḹ'), ('ḻ', 'ḻ'),
+  ('ḽ', 'ḽ'), ('ḿ', 'ḿ'), ('ṁ', 'ṁ'), ('ṃ', 'ṃ'),
+  ('ṅ', 'ṅ'), ('ṇ', 'ṇ'), ('ṉ', 'ṉ'), ('ṋ', 'ṋ'),
+  ('ṍ', 'ṍ'), ('ṏ', 'ṏ'), ('ṑ', 'ṑ'), ('ṓ', 'ṓ'),
+  ('ṕ', 'ṕ'), ('ṗ', 'ṗ'), ('ṙ', 'ṙ'), ('ṛ', 'ṛ'),
+  ('ṝ', 'ṝ'), ('ṟ', 'ṟ'), ('ṡ', 'ṡ'), ('ṣ', 'ṣ'),
+  ('ṥ', 'ṥ'), ('ṧ', 'ṧ'), ('ṩ', 'ṩ'), ('ṫ', 'ṫ'),
+  ('ṭ', 'ṭ'), ('ṯ', 'ṯ'), ('ṱ', 'ṱ'), ('ṳ', 'ṳ'),
+  ('ṵ', 'ṵ'), ('ṷ', 'ṷ'), ('ṹ', 'ṹ'), ('ṻ', 'ṻ'),
+  ('ṽ', 'ṽ'), ('ṿ', 'ṿ'), ('ẁ', 'ẁ'), ('ẃ', 'ẃ'),
+  ('ẅ', 'ẅ'), ('ẇ', 'ẇ'), ('ẉ', 'ẉ'), ('ẋ', 'ẋ'),
+  ('ẍ', 'ẍ'), ('ẏ', 'ẏ'), ('ẑ', 'ẑ'), ('ẓ', 'ẓ'),
+  ('ẕ', 'ẛ'), ('ạ', 'ạ'), ('ả', 'ả'), ('ấ', 'ấ'),
+  ('ầ', 'ầ'), ('ẩ', 'ẩ'), ('ẫ', 'ẫ'), ('ậ', 'ậ'),
+  ('ắ', 'ắ'), ('ằ', 'ằ'), ('ẳ', 'ẳ'), ('ẵ', 'ẵ'),
+  ('ặ', 'ặ'), ('ẹ', 'ẹ'), ('ẻ', 'ẻ'), ('ẽ', 'ẽ'),
+  ('ế', 'ế'), ('ề', 'ề'), ('ể', 'ể'), ('ễ', 'ễ'),
+  ('ệ', 'ệ'), ('ỉ', 'ỉ'), ('ị', 'ị'), ('ọ', 'ọ'),
+  ('ỏ', 'ỏ'), ('ố', 'ố'), ('ồ', 'ồ'), ('ổ', 'ổ'),
+  ('ỗ', 'ỗ'), ('ộ', 'ộ'), ('ớ', 'ớ'), ('ờ', 'ờ'),
+  ('ở', 'ở'), ('ỡ', 'ỡ'), ('ợ', 'ợ'), ('ụ', 'ụ'),
+  ('ủ', 'ủ'), ('ứ', 'ứ'), ('ừ', 'ừ'), ('ử', 'ử'),
+  ('ữ', 'ữ'), ('ự', 'ự'), ('ỳ', 'ỳ'), ('ỵ', 'ỵ'),
+  ('ỷ', 'ỷ'), ('ỹ', 'ỹ'), ('ỻ', 'ỻ'), ('ỽ', 'ỽ'),
+  ('ỿ', 'ἇ'), ('ἐ', 'ἕ'), ('ἠ', 'ἧ'), ('ἰ', 'ἷ'),
+  ('ὀ', 'ὅ'), ('ὐ', 'ὗ'), ('ὠ', 'ὧ'), ('ὰ', 'ώ'),
+  ('ᾀ', 'ᾇ'), ('ᾐ', 'ᾗ'), ('ᾠ', 'ᾧ'), ('ᾰ', 'ᾴ'),
+  ('ᾶ', 'ᾷ'), ('ι', 'ι'), ('ῂ', 'ῄ'), ('ῆ', 'ῇ'),
+  ('ῐ', 'ΐ'), ('ῖ', 'ῗ'), ('ῠ', 'ῧ'), ('ῲ', 'ῴ'),
+  ('ῶ', 'ῷ'), ('ⅎ', 'ⅎ'), ('ⅰ', 'ⅿ'), ('ↄ', 'ↄ'),
+  ('ⓐ', 'ⓩ'), ('ⰰ', 'ⱞ'), ('ⱡ', 'ⱡ'), ('ⱥ', 'ⱦ'),
+  ('ⱨ', 'ⱨ'), ('ⱪ', 'ⱪ'), ('ⱬ', 'ⱬ'), ('ⱳ', 'ⱳ'),
+  ('ⱶ', 'ⱶ'), ('ⲁ', 'ⲁ'), ('ⲃ', 'ⲃ'), ('ⲅ', 'ⲅ'),
+  ('ⲇ', 'ⲇ'), ('ⲉ', 'ⲉ'), ('ⲋ', 'ⲋ'), ('ⲍ', 'ⲍ'),
+  ('ⲏ', 'ⲏ'), ('ⲑ', 'ⲑ'), ('ⲓ', 'ⲓ'), ('ⲕ', 'ⲕ'),
+  ('ⲗ', 'ⲗ'), ('ⲙ', 'ⲙ'), ('ⲛ', 'ⲛ'), ('ⲝ', 'ⲝ'),
+  ('ⲟ', 'ⲟ'), ('ⲡ', 'ⲡ'), ('ⲣ', 'ⲣ'), ('ⲥ', 'ⲥ'),
+  ('ⲧ', 'ⲧ'), ('ⲩ', 'ⲩ'), ('ⲫ', 'ⲫ'), ('ⲭ', 'ⲭ'),
+  ('ⲯ', 'ⲯ'), ('ⲱ', 'ⲱ'), ('ⲳ', 'ⲳ'), ('ⲵ', 'ⲵ'),
+  ('ⲷ', 'ⲷ'), ('ⲹ', 'ⲹ'), ('ⲻ', 'ⲻ'), ('ⲽ', 'ⲽ'),
+  ('ⲿ', 'ⲿ'), ('ⳁ', 'ⳁ'), ('ⳃ', 'ⳃ'), ('ⳅ', 'ⳅ'),
+  ('ⳇ', 'ⳇ'), ('ⳉ', 'ⳉ'), ('ⳋ', 'ⳋ'), ('ⳍ', 'ⳍ'),
+  ('ⳏ', 'ⳏ'), ('ⳑ', 'ⳑ'), ('ⳓ', 'ⳓ'), ('ⳕ', 'ⳕ'),
+  ('ⳗ', 'ⳗ'), ('ⳙ', 'ⳙ'), ('ⳛ', 'ⳛ'), ('ⳝ', 'ⳝ'),
+  ('ⳟ', 'ⳟ'), ('ⳡ', 'ⳡ'), ('ⳣ', 'ⳣ'), ('ⳬ', 'ⳬ'),
+  ('ⳮ', 'ⳮ'), ('ⳳ', 'ⳳ'), ('ⴀ', 'ⴥ'), ('ⴧ', 'ⴧ'),
+  ('ⴭ', 'ⴭ'), ('ꙁ', 'ꙁ'), ('ꙃ', 'ꙃ'), ('ꙅ', 'ꙅ'),
+  ('ꙇ', 'ꙇ'), ('ꙉ', 'ꙉ'), ('ꙋ', 'ꙋ'), ('ꙍ', 'ꙍ'),
+  ('ꙏ', 'ꙏ'), ('ꙑ', 'ꙑ'), ('ꙓ', 'ꙓ'), ('ꙕ', 'ꙕ'),
+  ('ꙗ', 'ꙗ'), ('ꙙ', 'ꙙ'), ('ꙛ', 'ꙛ'), ('ꙝ', 'ꙝ'),
+  ('ꙟ', 'ꙟ'), ('ꙡ', 'ꙡ'), ('ꙣ', 'ꙣ'), ('ꙥ', 'ꙥ'),
+  ('ꙧ', 'ꙧ'), ('ꙩ', 'ꙩ'), ('ꙫ', 'ꙫ'), ('ꙭ', 'ꙭ'),
+  ('ꚁ', 'ꚁ'), ('ꚃ', 'ꚃ'), ('ꚅ', 'ꚅ'), ('ꚇ', 'ꚇ'),
+  ('ꚉ', 'ꚉ'), ('ꚋ', 'ꚋ'), ('ꚍ', 'ꚍ'), ('ꚏ', 'ꚏ'),
+  ('ꚑ', 'ꚑ'), ('ꚓ', 'ꚓ'), ('ꚕ', 'ꚕ'), ('ꚗ', 'ꚗ'),
+  ('ꚙ', 'ꚙ'), ('ꚛ', 'ꚛ'), ('ꜣ', 'ꜣ'), ('ꜥ', 'ꜥ'),
+  ('ꜧ', 'ꜧ'), ('ꜩ', 'ꜩ'), ('ꜫ', 'ꜫ'), ('ꜭ', 'ꜭ'),
+  ('ꜯ', 'ꜯ'), ('ꜳ', 'ꜳ'), ('ꜵ', 'ꜵ'), ('ꜷ', 'ꜷ'),
+  ('ꜹ', 'ꜹ'), ('ꜻ', 'ꜻ'), ('ꜽ', 'ꜽ'), ('ꜿ', 'ꜿ'),
+  ('ꝁ', 'ꝁ'), ('ꝃ', 'ꝃ'), ('ꝅ', 'ꝅ'), ('ꝇ', 'ꝇ'),
+  ('ꝉ', 'ꝉ'), ('ꝋ', 'ꝋ'), ('ꝍ', 'ꝍ'), ('ꝏ', 'ꝏ'),
+  ('ꝑ', 'ꝑ'), ('ꝓ', 'ꝓ'), ('ꝕ', 'ꝕ'), ('ꝗ', 'ꝗ'),
+  ('ꝙ', 'ꝙ'), ('ꝛ', 'ꝛ'), ('ꝝ', 'ꝝ'), ('ꝟ', 'ꝟ'),
+  ('ꝡ', 'ꝡ'), ('ꝣ', 'ꝣ'), ('ꝥ', 'ꝥ'), ('ꝧ', 'ꝧ'),
+  ('ꝩ', 'ꝩ'), ('ꝫ', 'ꝫ'), ('ꝭ', 'ꝭ'), ('ꝯ', 'ꝯ'),
+  ('ꝺ', 'ꝺ'), ('ꝼ', 'ꝼ'), ('ꝿ', 'ꝿ'), ('ꞁ', 'ꞁ'),
+  ('ꞃ', 'ꞃ'), ('ꞅ', 'ꞅ'), ('ꞇ', 'ꞇ'), ('ꞌ', 'ꞌ'),
+  ('ꞑ', 'ꞑ'), ('ꞓ', 'ꞔ'), ('ꞗ', 'ꞗ'), ('ꞙ', 'ꞙ'),
+  ('ꞛ', 'ꞛ'), ('ꞝ', 'ꞝ'), ('ꞟ', 'ꞟ'), ('ꞡ', 'ꞡ'),
+  ('ꞣ', 'ꞣ'), ('ꞥ', 'ꞥ'), ('ꞧ', 'ꞧ'), ('ꞩ', 'ꞩ'),
+  ('ꞵ', 'ꞵ'), ('ꞷ', 'ꞷ'), ('ꞹ', 'ꞹ'), ('\u{a7bb}', '\u{a7bb}'),
+  ('\u{a7bd}', '\u{a7bd}'), ('\u{a7bf}', '\u{a7bf}'),
+  ('\u{a7c3}', '\u{a7c3}'), ('ꭓ', 'ꭓ'), ('ꭰ', 'ꮿ'), ('ff', 'st'),
+  ('ﬓ', 'ﬗ'), ('a', 'z'), ('𐐨', '𐑏'), ('𐓘', '𐓻'),
+  ('𐳀', '𐳲'), ('𑣀', '𑣟'), ('𖹠', '𖹿'), ('𞤢', '𞥃'),
+];
+
+pub const CHANGES_WHEN_UPPERCASED: &'static [(char, char)] = &[
+  ('a', 'z'), ('µ', 'µ'), ('ß', 'ö'), ('ø', 'ÿ'), ('ā', 'ā'),
+  ('ă', 'ă'), ('ą', 'ą'), ('ć', 'ć'), ('ĉ', 'ĉ'), ('ċ', 'ċ'),
+  ('č', 'č'), ('ď', 'ď'), ('đ', 'đ'), ('ē', 'ē'), ('ĕ', 'ĕ'),
+  ('ė', 'ė'), ('ę', 'ę'), ('ě', 'ě'), ('ĝ', 'ĝ'), ('ğ', 'ğ'),
+  ('ġ', 'ġ'), ('ģ', 'ģ'), ('ĥ', 'ĥ'), ('ħ', 'ħ'), ('ĩ', 'ĩ'),
+  ('ī', 'ī'), ('ĭ', 'ĭ'), ('į', 'į'), ('ı', 'ı'), ('ij', 'ij'),
+  ('ĵ', 'ĵ'), ('ķ', 'ķ'), ('ĺ', 'ĺ'), ('ļ', 'ļ'), ('ľ', 'ľ'),
+  ('ŀ', 'ŀ'), ('ł', 'ł'), ('ń', 'ń'), ('ņ', 'ņ'), ('ň', 'ʼn'),
+  ('ŋ', 'ŋ'), ('ō', 'ō'), ('ŏ', 'ŏ'), ('ő', 'ő'), ('œ', 'œ'),
+  ('ŕ', 'ŕ'), ('ŗ', 'ŗ'), ('ř', 'ř'), ('ś', 'ś'), ('ŝ', 'ŝ'),
+  ('ş', 'ş'), ('š', 'š'), ('ţ', 'ţ'), ('ť', 'ť'), ('ŧ', 'ŧ'),
+  ('ũ', 'ũ'), ('ū', 'ū'), ('ŭ', 'ŭ'), ('ů', 'ů'), ('ű', 'ű'),
+  ('ų', 'ų'), ('ŵ', 'ŵ'), ('ŷ', 'ŷ'), ('ź', 'ź'), ('ż', 'ż'),
+  ('ž', 'ƀ'), ('ƃ', 'ƃ'), ('ƅ', 'ƅ'), ('ƈ', 'ƈ'), ('ƌ', 'ƌ'),
+  ('ƒ', 'ƒ'), ('ƕ', 'ƕ'), ('ƙ', 'ƚ'), ('ƞ', 'ƞ'), ('ơ', 'ơ'),
+  ('ƣ', 'ƣ'), ('ƥ', 'ƥ'), ('ƨ', 'ƨ'), ('ƭ', 'ƭ'), ('ư', 'ư'),
+  ('ƴ', 'ƴ'), ('ƶ', 'ƶ'), ('ƹ', 'ƹ'), ('ƽ', 'ƽ'), ('ƿ', 'ƿ'),
+  ('Dž', 'dž'), ('Lj', 'lj'), ('Nj', 'nj'), ('ǎ', 'ǎ'), ('ǐ', 'ǐ'),
+  ('ǒ', 'ǒ'), ('ǔ', 'ǔ'), ('ǖ', 'ǖ'), ('ǘ', 'ǘ'), ('ǚ', 'ǚ'),
+  ('ǜ', 'ǝ'), ('ǟ', 'ǟ'), ('ǡ', 'ǡ'), ('ǣ', 'ǣ'), ('ǥ', 'ǥ'),
+  ('ǧ', 'ǧ'), ('ǩ', 'ǩ'), ('ǫ', 'ǫ'), ('ǭ', 'ǭ'), ('ǯ', 'ǰ'),
+  ('Dz', 'dz'), ('ǵ', 'ǵ'), ('ǹ', 'ǹ'), ('ǻ', 'ǻ'), ('ǽ', 'ǽ'),
+  ('ǿ', 'ǿ'), ('ȁ', 'ȁ'), ('ȃ', 'ȃ'), ('ȅ', 'ȅ'), ('ȇ', 'ȇ'),
+  ('ȉ', 'ȉ'), ('ȋ', 'ȋ'), ('ȍ', 'ȍ'), ('ȏ', 'ȏ'), ('ȑ', 'ȑ'),
+  ('ȓ', 'ȓ'), ('ȕ', 'ȕ'), ('ȗ', 'ȗ'), ('ș', 'ș'), ('ț', 'ț'),
+  ('ȝ', 'ȝ'), ('ȟ', 'ȟ'), ('ȣ', 'ȣ'), ('ȥ', 'ȥ'), ('ȧ', 'ȧ'),
+  ('ȩ', 'ȩ'), ('ȫ', 'ȫ'), ('ȭ', 'ȭ'), ('ȯ', 'ȯ'), ('ȱ', 'ȱ'),
+  ('ȳ', 'ȳ'), ('ȼ', 'ȼ'), ('ȿ', 'ɀ'), ('ɂ', 'ɂ'), ('ɇ', 'ɇ'),
+  ('ɉ', 'ɉ'), ('ɋ', 'ɋ'), ('ɍ', 'ɍ'), ('ɏ', 'ɔ'), ('ɖ', 'ɗ'),
+  ('ə', 'ə'), ('ɛ', 'ɜ'), ('ɠ', 'ɡ'), ('ɣ', 'ɣ'), ('ɥ', 'ɦ'),
+  ('ɨ', 'ɬ'), ('ɯ', 'ɯ'), ('ɱ', 'ɲ'), ('ɵ', 'ɵ'), ('ɽ', 'ɽ'),
+  ('ʀ', 'ʀ'), ('ʂ', 'ʃ'), ('ʇ', 'ʌ'), ('ʒ', 'ʒ'), ('ʝ', 'ʞ'),
+  ('\u{345}', '\u{345}'), ('ͱ', 'ͱ'), ('ͳ', 'ͳ'), ('ͷ', 'ͷ'),
+  ('ͻ', 'ͽ'), ('ΐ', 'ΐ'), ('ά', 'ώ'), ('ϐ', 'ϑ'), ('ϕ', 'ϗ'),
+  ('ϙ', 'ϙ'), ('ϛ', 'ϛ'), ('ϝ', 'ϝ'), ('ϟ', 'ϟ'), ('ϡ', 'ϡ'),
+  ('ϣ', 'ϣ'), ('ϥ', 'ϥ'), ('ϧ', 'ϧ'), ('ϩ', 'ϩ'), ('ϫ', 'ϫ'),
+  ('ϭ', 'ϭ'), ('ϯ', 'ϳ'), ('ϵ', 'ϵ'), ('ϸ', 'ϸ'), ('ϻ', 'ϻ'),
+  ('а', 'џ'), ('ѡ', 'ѡ'), ('ѣ', 'ѣ'), ('ѥ', 'ѥ'), ('ѧ', 'ѧ'),
+  ('ѩ', 'ѩ'), ('ѫ', 'ѫ'), ('ѭ', 'ѭ'), ('ѯ', 'ѯ'), ('ѱ', 'ѱ'),
+  ('ѳ', 'ѳ'), ('ѵ', 'ѵ'), ('ѷ', 'ѷ'), ('ѹ', 'ѹ'), ('ѻ', 'ѻ'),
+  ('ѽ', 'ѽ'), ('ѿ', 'ѿ'), ('ҁ', 'ҁ'), ('ҋ', 'ҋ'), ('ҍ', 'ҍ'),
+  ('ҏ', 'ҏ'), ('ґ', 'ґ'), ('ғ', 'ғ'), ('ҕ', 'ҕ'), ('җ', 'җ'),
+  ('ҙ', 'ҙ'), ('қ', 'қ'), ('ҝ', 'ҝ'), ('ҟ', 'ҟ'), ('ҡ', 'ҡ'),
+  ('ң', 'ң'), ('ҥ', 'ҥ'), ('ҧ', 'ҧ'), ('ҩ', 'ҩ'), ('ҫ', 'ҫ'),
+  ('ҭ', 'ҭ'), ('ү', 'ү'), ('ұ', 'ұ'), ('ҳ', 'ҳ'), ('ҵ', 'ҵ'),
+  ('ҷ', 'ҷ'), ('ҹ', 'ҹ'), ('һ', 'һ'), ('ҽ', 'ҽ'), ('ҿ', 'ҿ'),
+  ('ӂ', 'ӂ'), ('ӄ', 'ӄ'), ('ӆ', 'ӆ'), ('ӈ', 'ӈ'), ('ӊ', 'ӊ'),
+  ('ӌ', 'ӌ'), ('ӎ', 'ӏ'), ('ӑ', 'ӑ'), ('ӓ', 'ӓ'), ('ӕ', 'ӕ'),
+  ('ӗ', 'ӗ'), ('ә', 'ә'), ('ӛ', 'ӛ'), ('ӝ', 'ӝ'), ('ӟ', 'ӟ'),
+  ('ӡ', 'ӡ'), ('ӣ', 'ӣ'), ('ӥ', 'ӥ'), ('ӧ', 'ӧ'), ('ө', 'ө'),
+  ('ӫ', 'ӫ'), ('ӭ', 'ӭ'), ('ӯ', 'ӯ'), ('ӱ', 'ӱ'), ('ӳ', 'ӳ'),
+  ('ӵ', 'ӵ'), ('ӷ', 'ӷ'), ('ӹ', 'ӹ'), ('ӻ', 'ӻ'), ('ӽ', 'ӽ'),
+  ('ӿ', 'ӿ'), ('ԁ', 'ԁ'), ('ԃ', 'ԃ'), ('ԅ', 'ԅ'), ('ԇ', 'ԇ'),
+  ('ԉ', 'ԉ'), ('ԋ', 'ԋ'), ('ԍ', 'ԍ'), ('ԏ', 'ԏ'), ('ԑ', 'ԑ'),
+  ('ԓ', 'ԓ'), ('ԕ', 'ԕ'), ('ԗ', 'ԗ'), ('ԙ', 'ԙ'), ('ԛ', 'ԛ'),
+  ('ԝ', 'ԝ'), ('ԟ', 'ԟ'), ('ԡ', 'ԡ'), ('ԣ', 'ԣ'), ('ԥ', 'ԥ'),
+  ('ԧ', 'ԧ'), ('ԩ', 'ԩ'), ('ԫ', 'ԫ'), ('ԭ', 'ԭ'), ('ԯ', 'ԯ'),
+  ('ա', 'և'), ('ა', 'ჺ'), ('ჽ', 'ჿ'), ('ᏸ', 'ᏽ'),
+  ('ᲀ', 'ᲈ'), ('ᵹ', 'ᵹ'), ('ᵽ', 'ᵽ'), ('ᶎ', 'ᶎ'),
+  ('ḁ', 'ḁ'), ('ḃ', 'ḃ'), ('ḅ', 'ḅ'), ('ḇ', 'ḇ'),
+  ('ḉ', 'ḉ'), ('ḋ', 'ḋ'), ('ḍ', 'ḍ'), ('ḏ', 'ḏ'),
+  ('ḑ', 'ḑ'), ('ḓ', 'ḓ'), ('ḕ', 'ḕ'), ('ḗ', 'ḗ'),
+  ('ḙ', 'ḙ'), ('ḛ', 'ḛ'), ('ḝ', 'ḝ'), ('ḟ', 'ḟ'),
+  ('ḡ', 'ḡ'), ('ḣ', 'ḣ'), ('ḥ', 'ḥ'), ('ḧ', 'ḧ'),
+  ('ḩ', 'ḩ'), ('ḫ', 'ḫ'), ('ḭ', 'ḭ'), ('ḯ', 'ḯ'),
+  ('ḱ', 'ḱ'), ('ḳ', 'ḳ'), ('ḵ', 'ḵ'), ('ḷ', 'ḷ'),
+  ('ḹ', 'ḹ'), ('ḻ', 'ḻ'), ('ḽ', 'ḽ'), ('ḿ', 'ḿ'),
+  ('ṁ', 'ṁ'), ('ṃ', 'ṃ'), ('ṅ', 'ṅ'), ('ṇ', 'ṇ'),
+  ('ṉ', 'ṉ'), ('ṋ', 'ṋ'), ('ṍ', 'ṍ'), ('ṏ', 'ṏ'),
+  ('ṑ', 'ṑ'), ('ṓ', 'ṓ'), ('ṕ', 'ṕ'), ('ṗ', 'ṗ'),
+  ('ṙ', 'ṙ'), ('ṛ', 'ṛ'), ('ṝ', 'ṝ'), ('ṟ', 'ṟ'),
+  ('ṡ', 'ṡ'), ('ṣ', 'ṣ'), ('ṥ', 'ṥ'), ('ṧ', 'ṧ'),
+  ('ṩ', 'ṩ'), ('ṫ', 'ṫ'), ('ṭ', 'ṭ'), ('ṯ', 'ṯ'),
+  ('ṱ', 'ṱ'), ('ṳ', 'ṳ'), ('ṵ', 'ṵ'), ('ṷ', 'ṷ'),
+  ('ṹ', 'ṹ'), ('ṻ', 'ṻ'), ('ṽ', 'ṽ'), ('ṿ', 'ṿ'),
+  ('ẁ', 'ẁ'), ('ẃ', 'ẃ'), ('ẅ', 'ẅ'), ('ẇ', 'ẇ'),
+  ('ẉ', 'ẉ'), ('ẋ', 'ẋ'), ('ẍ', 'ẍ'), ('ẏ', 'ẏ'),
+  ('ẑ', 'ẑ'), ('ẓ', 'ẓ'), ('ẕ', 'ẛ'), ('ạ', 'ạ'),
+  ('ả', 'ả'), ('ấ', 'ấ'), ('ầ', 'ầ'), ('ẩ', 'ẩ'),
+  ('ẫ', 'ẫ'), ('ậ', 'ậ'), ('ắ', 'ắ'), ('ằ', 'ằ'),
+  ('ẳ', 'ẳ'), ('ẵ', 'ẵ'), ('ặ', 'ặ'), ('ẹ', 'ẹ'),
+  ('ẻ', 'ẻ'), ('ẽ', 'ẽ'), ('ế', 'ế'), ('ề', 'ề'),
+  ('ể', 'ể'), ('ễ', 'ễ'), ('ệ', 'ệ'), ('ỉ', 'ỉ'),
+  ('ị', 'ị'), ('ọ', 'ọ'), ('ỏ', 'ỏ'), ('ố', 'ố'),
+  ('ồ', 'ồ'), ('ổ', 'ổ'), ('ỗ', 'ỗ'), ('ộ', 'ộ'),
+  ('ớ', 'ớ'), ('ờ', 'ờ'), ('ở', 'ở'), ('ỡ', 'ỡ'),
+  ('ợ', 'ợ'), ('ụ', 'ụ'), ('ủ', 'ủ'), ('ứ', 'ứ'),
+  ('ừ', 'ừ'), ('ử', 'ử'), ('ữ', 'ữ'), ('ự', 'ự'),
+  ('ỳ', 'ỳ'), ('ỵ', 'ỵ'), ('ỷ', 'ỷ'), ('ỹ', 'ỹ'),
+  ('ỻ', 'ỻ'), ('ỽ', 'ỽ'), ('ỿ', 'ἇ'), ('ἐ', 'ἕ'),
+  ('ἠ', 'ἧ'), ('ἰ', 'ἷ'), ('ὀ', 'ὅ'), ('ὐ', 'ὗ'),
+  ('ὠ', 'ὧ'), ('ὰ', 'ώ'), ('ᾀ', 'ᾴ'), ('ᾶ', 'ᾷ'),
+  ('ᾼ', 'ᾼ'), ('ι', 'ι'), ('ῂ', 'ῄ'), ('ῆ', 'ῇ'),
+  ('ῌ', 'ῌ'), ('ῐ', 'ΐ'), ('ῖ', 'ῗ'), ('ῠ', 'ῧ'),
+  ('ῲ', 'ῴ'), ('ῶ', 'ῷ'), ('ῼ', 'ῼ'), ('ⅎ', 'ⅎ'),
+  ('ⅰ', 'ⅿ'), ('ↄ', 'ↄ'), ('ⓐ', 'ⓩ'), ('ⰰ', 'ⱞ'),
+  ('ⱡ', 'ⱡ'), ('ⱥ', 'ⱦ'), ('ⱨ', 'ⱨ'), ('ⱪ', 'ⱪ'),
+  ('ⱬ', 'ⱬ'), ('ⱳ', 'ⱳ'), ('ⱶ', 'ⱶ'), ('ⲁ', 'ⲁ'),
+  ('ⲃ', 'ⲃ'), ('ⲅ', 'ⲅ'), ('ⲇ', 'ⲇ'), ('ⲉ', 'ⲉ'),
+  ('ⲋ', 'ⲋ'), ('ⲍ', 'ⲍ'), ('ⲏ', 'ⲏ'), ('ⲑ', 'ⲑ'),
+  ('ⲓ', 'ⲓ'), ('ⲕ', 'ⲕ'), ('ⲗ', 'ⲗ'), ('ⲙ', 'ⲙ'),
+  ('ⲛ', 'ⲛ'), ('ⲝ', 'ⲝ'), ('ⲟ', 'ⲟ'), ('ⲡ', 'ⲡ'),
+  ('ⲣ', 'ⲣ'), ('ⲥ', 'ⲥ'), ('ⲧ', 'ⲧ'), ('ⲩ', 'ⲩ'),
+  ('ⲫ', 'ⲫ'), ('ⲭ', 'ⲭ'), ('ⲯ', 'ⲯ'), ('ⲱ', 'ⲱ'),
+  ('ⲳ', 'ⲳ'), ('ⲵ', 'ⲵ'), ('ⲷ', 'ⲷ'), ('ⲹ', 'ⲹ'),
+  ('ⲻ', 'ⲻ'), ('ⲽ', 'ⲽ'), ('ⲿ', 'ⲿ'), ('ⳁ', 'ⳁ'),
+  ('ⳃ', 'ⳃ'), ('ⳅ', 'ⳅ'), ('ⳇ', 'ⳇ'), ('ⳉ', 'ⳉ'),
+  ('ⳋ', 'ⳋ'), ('ⳍ', 'ⳍ'), ('ⳏ', 'ⳏ'), ('ⳑ', 'ⳑ'),
+  ('ⳓ', 'ⳓ'), ('ⳕ', 'ⳕ'), ('ⳗ', 'ⳗ'), ('ⳙ', 'ⳙ'),
+  ('ⳛ', 'ⳛ'), ('ⳝ', 'ⳝ'), ('ⳟ', 'ⳟ'), ('ⳡ', 'ⳡ'),
+  ('ⳣ', 'ⳣ'), ('ⳬ', 'ⳬ'), ('ⳮ', 'ⳮ'), ('ⳳ', 'ⳳ'),
+  ('ⴀ', 'ⴥ'), ('ⴧ', 'ⴧ'), ('ⴭ', 'ⴭ'), ('ꙁ', 'ꙁ'),
+  ('ꙃ', 'ꙃ'), ('ꙅ', 'ꙅ'), ('ꙇ', 'ꙇ'), ('ꙉ', 'ꙉ'),
+  ('ꙋ', 'ꙋ'), ('ꙍ', 'ꙍ'), ('ꙏ', 'ꙏ'), ('ꙑ', 'ꙑ'),
+  ('ꙓ', 'ꙓ'), ('ꙕ', 'ꙕ'), ('ꙗ', 'ꙗ'), ('ꙙ', 'ꙙ'),
+  ('ꙛ', 'ꙛ'), ('ꙝ', 'ꙝ'), ('ꙟ', 'ꙟ'), ('ꙡ', 'ꙡ'),
+  ('ꙣ', 'ꙣ'), ('ꙥ', 'ꙥ'), ('ꙧ', 'ꙧ'), ('ꙩ', 'ꙩ'),
+  ('ꙫ', 'ꙫ'), ('ꙭ', 'ꙭ'), ('ꚁ', 'ꚁ'), ('ꚃ', 'ꚃ'),
+  ('ꚅ', 'ꚅ'), ('ꚇ', 'ꚇ'), ('ꚉ', 'ꚉ'), ('ꚋ', 'ꚋ'),
+  ('ꚍ', 'ꚍ'), ('ꚏ', 'ꚏ'), ('ꚑ', 'ꚑ'), ('ꚓ', 'ꚓ'),
+  ('ꚕ', 'ꚕ'), ('ꚗ', 'ꚗ'), ('ꚙ', 'ꚙ'), ('ꚛ', 'ꚛ'),
+  ('ꜣ', 'ꜣ'), ('ꜥ', 'ꜥ'), ('ꜧ', 'ꜧ'), ('ꜩ', 'ꜩ'),
+  ('ꜫ', 'ꜫ'), ('ꜭ', 'ꜭ'), ('ꜯ', 'ꜯ'), ('ꜳ', 'ꜳ'),
+  ('ꜵ', 'ꜵ'), ('ꜷ', 'ꜷ'), ('ꜹ', 'ꜹ'), ('ꜻ', 'ꜻ'),
+  ('ꜽ', 'ꜽ'), ('ꜿ', 'ꜿ'), ('ꝁ', 'ꝁ'), ('ꝃ', 'ꝃ'),
+  ('ꝅ', 'ꝅ'), ('ꝇ', 'ꝇ'), ('ꝉ', 'ꝉ'), ('ꝋ', 'ꝋ'),
+  ('ꝍ', 'ꝍ'), ('ꝏ', 'ꝏ'), ('ꝑ', 'ꝑ'), ('ꝓ', 'ꝓ'),
+  ('ꝕ', 'ꝕ'), ('ꝗ', 'ꝗ'), ('ꝙ', 'ꝙ'), ('ꝛ', 'ꝛ'),
+  ('ꝝ', 'ꝝ'), ('ꝟ', 'ꝟ'), ('ꝡ', 'ꝡ'), ('ꝣ', 'ꝣ'),
+  ('ꝥ', 'ꝥ'), ('ꝧ', 'ꝧ'), ('ꝩ', 'ꝩ'), ('ꝫ', 'ꝫ'),
+  ('ꝭ', 'ꝭ'), ('ꝯ', 'ꝯ'), ('ꝺ', 'ꝺ'), ('ꝼ', 'ꝼ'),
+  ('ꝿ', 'ꝿ'), ('ꞁ', 'ꞁ'), ('ꞃ', 'ꞃ'), ('ꞅ', 'ꞅ'),
+  ('ꞇ', 'ꞇ'), ('ꞌ', 'ꞌ'), ('ꞑ', 'ꞑ'), ('ꞓ', 'ꞔ'),
+  ('ꞗ', 'ꞗ'), ('ꞙ', 'ꞙ'), ('ꞛ', 'ꞛ'), ('ꞝ', 'ꞝ'),
+  ('ꞟ', 'ꞟ'), ('ꞡ', 'ꞡ'), ('ꞣ', 'ꞣ'), ('ꞥ', 'ꞥ'),
+  ('ꞧ', 'ꞧ'), ('ꞩ', 'ꞩ'), ('ꞵ', 'ꞵ'), ('ꞷ', 'ꞷ'),
+  ('ꞹ', 'ꞹ'), ('\u{a7bb}', '\u{a7bb}'), ('\u{a7bd}', '\u{a7bd}'),
+  ('\u{a7bf}', '\u{a7bf}'), ('\u{a7c3}', '\u{a7c3}'), ('ꭓ', 'ꭓ'),
+  ('ꭰ', 'ꮿ'), ('ff', 'st'), ('ﬓ', 'ﬗ'), ('a', 'z'),
+  ('𐐨', '𐑏'), ('𐓘', '𐓻'), ('𐳀', '𐳲'), ('𑣀', '𑣟'),
+  ('𖹠', '𖹿'), ('𞤢', '𞥃'),
+];
+
+pub const DASH: &'static [(char, char)] = &[
+  ('-', '-'), ('֊', '֊'), ('־', '־'), ('᐀', '᐀'), ('᠆', '᠆'),
+  ('‐', '―'), ('⁓', '⁓'), ('⁻', '⁻'), ('₋', '₋'),
+  ('−', '−'), ('⸗', '⸗'), ('⸚', '⸚'), ('⸺', '⸻'),
+  ('⹀', '⹀'), ('〜', '〜'), ('〰', '〰'), ('゠', '゠'),
+  ('︱', '︲'), ('﹘', '﹘'), ('﹣', '﹣'), ('-', '-'),
+];
+
+pub const DEFAULT_IGNORABLE_CODE_POINT: &'static [(char, char)] = &[
+  ('\u{ad}', '\u{ad}'), ('\u{34f}', '\u{34f}'), ('\u{61c}', '\u{61c}'),
+  ('ᅟ', 'ᅠ'), ('\u{17b4}', '\u{17b5}'), ('\u{180b}', '\u{180e}'),
+  ('\u{200b}', '\u{200f}'), ('\u{202a}', '\u{202e}'),
+  ('\u{2060}', '\u{206f}'), ('ㅤ', 'ㅤ'), ('\u{fe00}', '\u{fe0f}'),
+  ('\u{feff}', '\u{feff}'), ('ᅠ', 'ᅠ'), ('\u{fff0}', '\u{fff8}'),
+  ('\u{1bca0}', '\u{1bca3}'), ('\u{1d173}', '\u{1d17a}'),
+  ('\u{e0000}', '\u{e0fff}'),
+];
+
+pub const DEPRECATED: &'static [(char, char)] = &[
+  ('ʼn', 'ʼn'), ('ٳ', 'ٳ'), ('\u{f77}', '\u{f77}'), ('\u{f79}', '\u{f79}'),
+  ('ឣ', 'ឤ'), ('\u{206a}', '\u{206f}'), ('〈', '〉'),
+  ('\u{e0001}', '\u{e0001}'),
+];
+
+pub const DIACRITIC: &'static [(char, char)] = &[
+  ('^', '^'), ('`', '`'), ('¨', '¨'), ('¯', '¯'), ('´', '´'),
+  ('·', '¸'), ('ʰ', '\u{34e}'), ('\u{350}', '\u{357}'),
+  ('\u{35d}', '\u{362}'), ('ʹ', '͵'), ('ͺ', 'ͺ'), ('΄', '΅'),
+  ('\u{483}', '\u{487}'), ('ՙ', 'ՙ'), ('\u{591}', '\u{5a1}'),
+  ('\u{5a3}', '\u{5bd}'), ('\u{5bf}', '\u{5bf}'), ('\u{5c1}', '\u{5c2}'),
+  ('\u{5c4}', '\u{5c4}'), ('\u{64b}', '\u{652}'), ('\u{657}', '\u{658}'),
+  ('\u{6df}', '\u{6e0}'), ('ۥ', 'ۦ'), ('\u{6ea}', '\u{6ec}'),
+  ('\u{730}', '\u{74a}'), ('\u{7a6}', '\u{7b0}'), ('\u{7eb}', 'ߵ'),
+  ('\u{818}', '\u{819}'), ('\u{8e3}', '\u{8fe}'), ('\u{93c}', '\u{93c}'),
+  ('\u{94d}', '\u{94d}'), ('\u{951}', '\u{954}'), ('ॱ', 'ॱ'),
+  ('\u{9bc}', '\u{9bc}'), ('\u{9cd}', '\u{9cd}'), ('\u{a3c}', '\u{a3c}'),
+  ('\u{a4d}', '\u{a4d}'), ('\u{abc}', '\u{abc}'), ('\u{acd}', '\u{acd}'),
+  ('\u{afd}', '\u{aff}'), ('\u{b3c}', '\u{b3c}'), ('\u{b4d}', '\u{b4d}'),
+  ('\u{bcd}', '\u{bcd}'), ('\u{c4d}', '\u{c4d}'), ('\u{cbc}', '\u{cbc}'),
+  ('\u{ccd}', '\u{ccd}'), ('\u{d3b}', '\u{d3c}'), ('\u{d4d}', '\u{d4d}'),
+  ('\u{dca}', '\u{dca}'), ('\u{e47}', '\u{e4c}'), ('\u{e4e}', '\u{e4e}'),
+  ('\u{eba}', '\u{eba}'), ('\u{ec8}', '\u{ecc}'), ('\u{f18}', '\u{f19}'),
+  ('\u{f35}', '\u{f35}'), ('\u{f37}', '\u{f37}'), ('\u{f39}', '\u{f39}'),
+  ('༾', '༿'), ('\u{f82}', '\u{f84}'), ('\u{f86}', '\u{f87}'),
+  ('\u{fc6}', '\u{fc6}'), ('\u{1037}', '\u{1037}'), ('\u{1039}', '\u{103a}'),
+  ('ၣ', 'ၤ'), ('ၩ', 'ၭ'), ('ႇ', '\u{108d}'), ('ႏ', 'ႏ'),
+  ('ႚ', 'ႛ'), ('\u{135d}', '\u{135f}'), ('\u{17c9}', '\u{17d3}'),
+  ('\u{17dd}', '\u{17dd}'), ('\u{1939}', '\u{193b}'),
+  ('\u{1a75}', '\u{1a7c}'), ('\u{1a7f}', '\u{1a7f}'),
+  ('\u{1ab0}', '\u{1abd}'), ('\u{1b34}', '\u{1b34}'), ('᭄', '᭄'),
+  ('\u{1b6b}', '\u{1b73}'), ('᮪', '\u{1bab}'), ('\u{1c36}', '\u{1c37}'),
+  ('ᱸ', 'ᱽ'), ('\u{1cd0}', '\u{1ce8}'), ('\u{1ced}', '\u{1ced}'),
+  ('\u{1cf4}', '\u{1cf4}'), ('᳷', '\u{1cf9}'), ('ᴬ', 'ᵪ'),
+  ('\u{1dc4}', '\u{1dcf}'), ('\u{1df5}', '\u{1df9}'),
+  ('\u{1dfd}', '\u{1dff}'), ('᾽', '᾽'), ('᾿', '῁'), ('῍', '῏'),
+  ('῝', '῟'), ('῭', '`'), ('´', '῾'), ('\u{2cef}', '\u{2cf1}'),
+  ('ⸯ', 'ⸯ'), ('\u{302a}', '\u{302f}'), ('\u{3099}', '゜'),
+  ('ー', 'ー'), ('\u{a66f}', '\u{a66f}'), ('\u{a67c}', '\u{a67d}'),
+  ('ꙿ', 'ꙿ'), ('ꚜ', 'ꚝ'), ('\u{a6f0}', '\u{a6f1}'), ('꜀', '꜡'),
+  ('ꞈ', '꞊'), ('ꟸ', 'ꟹ'), ('\u{a8c4}', '\u{a8c4}'),
+  ('\u{a8e0}', '\u{a8f1}'), ('\u{a92b}', '꤮'), ('꥓', '꥓'),
+  ('\u{a9b3}', '\u{a9b3}'), ('꧀', '꧀'), ('\u{a9e5}', '\u{a9e5}'),
+  ('ꩻ', 'ꩽ'), ('\u{aabf}', 'ꫂ'), ('\u{aaf6}', '\u{aaf6}'),
+  ('꭛', 'ꭟ'), ('꯬', '\u{abed}'), ('\u{fb1e}', '\u{fb1e}'),
+  ('\u{fe20}', '\u{fe2f}'), ('^', '^'), ('`', '`'), ('ー', 'ー'),
+  ('\u{ff9e}', '\u{ff9f}'), (' ̄', ' ̄'), ('\u{102e0}', '\u{102e0}'),
+  ('\u{10ae5}', '\u{10ae6}'), ('𐴢', '\u{10d27}'),
+  ('\u{10f46}', '\u{10f50}'), ('\u{110b9}', '\u{110ba}'),
+  ('\u{11133}', '\u{11134}'), ('\u{11173}', '\u{11173}'), ('𑇀', '𑇀'),
+  ('\u{111ca}', '\u{111cc}'), ('𑈵', '\u{11236}'),
+  ('\u{112e9}', '\u{112ea}'), ('\u{1133c}', '\u{1133c}'), ('𑍍', '𑍍'),
+  ('\u{11366}', '\u{1136c}'), ('\u{11370}', '\u{11374}'),
+  ('\u{11442}', '\u{11442}'), ('\u{11446}', '\u{11446}'),
+  ('\u{114c2}', '\u{114c3}'), ('\u{115bf}', '\u{115c0}'),
+  ('\u{1163f}', '\u{1163f}'), ('𑚶', '\u{116b7}'),
+  ('\u{1172b}', '\u{1172b}'), ('\u{11839}', '\u{1183a}'),
+  ('\u{119e0}', '\u{119e0}'), ('\u{11a34}', '\u{11a34}'),
+  ('\u{11a47}', '\u{11a47}'), ('\u{11a99}', '\u{11a99}'),
+  ('\u{11c3f}', '\u{11c3f}'), ('\u{11d42}', '\u{11d42}'),
+  ('\u{11d44}', '\u{11d45}'), ('\u{11d97}', '\u{11d97}'),
+  ('\u{16af0}', '\u{16af4}'), ('\u{16b30}', '\u{16b36}'),
+  ('\u{16f8f}', '𖾟'), ('\u{1d167}', '\u{1d169}'), ('𝅭', '\u{1d172}'),
+  ('\u{1d17b}', '\u{1d182}'), ('\u{1d185}', '\u{1d18b}'),
+  ('\u{1d1aa}', '\u{1d1ad}'), ('\u{1e130}', '\u{1e136}'),
+  ('\u{1e2ec}', '\u{1e2ef}'), ('\u{1e8d0}', '\u{1e8d6}'),
+  ('\u{1e944}', '\u{1e946}'), ('\u{1e948}', '\u{1e94a}'),
+];
+
+pub const EMOJI: &'static [(char, char)] = &[
+  ('#', '#'), ('*', '*'), ('0', '9'), ('©', '©'), ('®', '®'),
+  ('‼', '‼'), ('⁉', '⁉'), ('™', '™'), ('ℹ', 'ℹ'),
+  ('↔', '↙'), ('↩', '↪'), ('⌚', '⌛'), ('⌨', '⌨'),
+  ('⏏', '⏏'), ('⏩', '⏳'), ('⏸', '⏺'), ('Ⓜ', 'Ⓜ'),
+  ('▪', '▫'), ('▶', '▶'), ('◀', '◀'), ('◻', '◾'),
+  ('☀', '☄'), ('☎', '☎'), ('☑', '☑'), ('☔', '☕'),
+  ('☘', '☘'), ('☝', '☝'), ('☠', '☠'), ('☢', '☣'),
+  ('☦', '☦'), ('☪', '☪'), ('☮', '☯'), ('☸', '☺'),
+  ('♀', '♀'), ('♂', '♂'), ('♈', '♓'), ('♟', '♠'),
+  ('♣', '♣'), ('♥', '♦'), ('♨', '♨'), ('♻', '♻'),
+  ('♾', '♿'), ('⚒', '⚗'), ('⚙', '⚙'), ('⚛', '⚜'),
+  ('⚠', '⚡'), ('⚪', '⚫'), ('⚰', '⚱'), ('⚽', '⚾'),
+  ('⛄', '⛅'), ('⛈', '⛈'), ('⛎', '⛏'), ('⛑', '⛑'),
+  ('⛓', '⛔'), ('⛩', '⛪'), ('⛰', '⛵'), ('⛷', '⛺'),
+  ('⛽', '⛽'), ('✂', '✂'), ('✅', '✅'), ('✈', '✍'),
+  ('✏', '✏'), ('✒', '✒'), ('✔', '✔'), ('✖', '✖'),
+  ('✝', '✝'), ('✡', '✡'), ('✨', '✨'), ('✳', '✴'),
+  ('❄', '❄'), ('❇', '❇'), ('❌', '❌'), ('❎', '❎'),
+  ('❓', '❕'), ('❗', '❗'), ('❣', '❤'), ('➕', '➗'),
+  ('➡', '➡'), ('➰', '➰'), ('➿', '➿'), ('⤴', '⤵'),
+  ('⬅', '⬇'), ('⬛', '⬜'), ('⭐', '⭐'), ('⭕', '⭕'),
+  ('〰', '〰'), ('〽', '〽'), ('㊗', '㊗'), ('㊙', '㊙'),
+  ('🀄', '🀄'), ('🃏', '🃏'), ('🅰', '🅱'), ('🅾', '🅿'),
+  ('🆎', '🆎'), ('🆑', '🆚'), ('🇦', '🇿'), ('🈁', '🈂'),
+  ('🈚', '🈚'), ('🈯', '🈯'), ('🈲', '🈺'), ('🉐', '🉑'),
+  ('🌀', '🌡'), ('🌤', '🎓'), ('🎖', '🎗'), ('🎙', '🎛'),
+  ('🎞', '🏰'), ('🏳', '🏵'), ('🏷', '📽'), ('📿', '🔽'),
+  ('🕉', '🕎'), ('🕐', '🕧'), ('🕯', '🕰'), ('🕳', '🕺'),
+  ('🖇', '🖇'), ('🖊', '🖍'), ('🖐', '🖐'), ('🖕', '🖖'),
+  ('🖤', '🖥'), ('🖨', '🖨'), ('🖱', '🖲'), ('🖼', '🖼'),
+  ('🗂', '🗄'), ('🗑', '🗓'), ('🗜', '🗞'), ('🗡', '🗡'),
+  ('🗣', '🗣'), ('🗨', '🗨'), ('🗯', '🗯'), ('🗳', '🗳'),
+  ('🗺', '🙏'), ('🚀', '🛅'), ('🛋', '🛒'),
+  ('\u{1f6d5}', '\u{1f6d5}'), ('🛠', '🛥'), ('🛩', '🛩'),
+  ('🛫', '🛬'), ('🛰', '🛰'), ('🛳', '\u{1f6fa}'),
+  ('\u{1f7e0}', '\u{1f7eb}'), ('\u{1f90d}', '🤺'), ('🤼', '🥅'),
+  ('🥇', '\u{1f971}'), ('🥳', '🥶'), ('🥺', '🦢'),
+  ('\u{1f9a5}', '\u{1f9aa}'), ('\u{1f9ae}', '\u{1f9ca}'),
+  ('\u{1f9cd}', '🧿'), ('\u{1fa70}', '\u{1fa73}'),
+  ('\u{1fa78}', '\u{1fa7a}'), ('\u{1fa80}', '\u{1fa82}'),
+  ('\u{1fa90}', '\u{1fa95}'),
+];
+
+pub const EMOJI_COMPONENT: &'static [(char, char)] = &[
+  ('#', '#'), ('*', '*'), ('0', '9'), ('\u{200d}', '\u{200d}'),
+  ('\u{20e3}', '\u{20e3}'), ('\u{fe0f}', '\u{fe0f}'), ('🇦', '🇿'),
+  ('🏻', '🏿'), ('🦰', '🦳'), ('\u{e0020}', '\u{e007f}'),
+];
+
+pub const EMOJI_MODIFIER: &'static [(char, char)] = &[
+  ('🏻', '🏿'),
+];
+
+pub const EMOJI_MODIFIER_BASE: &'static [(char, char)] = &[
+  ('☝', '☝'), ('⛹', '⛹'), ('✊', '✍'), ('🎅', '🎅'),
+  ('🏂', '🏄'), ('🏇', '🏇'), ('🏊', '🏌'), ('👂', '👃'),
+  ('👆', '👐'), ('👦', '👸'), ('👼', '👼'), ('💁', '💃'),
+  ('💅', '💇'), ('💏', '💏'), ('💑', '💑'), ('💪', '💪'),
+  ('🕴', '🕵'), ('🕺', '🕺'), ('🖐', '🖐'), ('🖕', '🖖'),
+  ('🙅', '🙇'), ('🙋', '🙏'), ('🚣', '🚣'), ('🚴', '🚶'),
+  ('🛀', '🛀'), ('🛌', '🛌'), ('\u{1f90f}', '\u{1f90f}'),
+  ('🤘', '🤟'), ('🤦', '🤦'), ('🤰', '🤹'), ('🤼', '🤾'),
+  ('🦵', '🦶'), ('🦸', '🦹'), ('\u{1f9bb}', '\u{1f9bb}'),
+  ('\u{1f9cd}', '\u{1f9cf}'), ('🧑', '🧝'),
+];
+
+pub const EMOJI_PRESENTATION: &'static [(char, char)] = &[
+  ('⌚', '⌛'), ('⏩', '⏬'), ('⏰', '⏰'), ('⏳', '⏳'),
+  ('◽', '◾'), ('☔', '☕'), ('♈', '♓'), ('♿', '♿'),
+  ('⚓', '⚓'), ('⚡', '⚡'), ('⚪', '⚫'), ('⚽', '⚾'),
+  ('⛄', '⛅'), ('⛎', '⛎'), ('⛔', '⛔'), ('⛪', '⛪'),
+  ('⛲', '⛳'), ('⛵', '⛵'), ('⛺', '⛺'), ('⛽', '⛽'),
+  ('✅', '✅'), ('✊', '✋'), ('✨', '✨'), ('❌', '❌'),
+  ('❎', '❎'), ('❓', '❕'), ('❗', '❗'), ('➕', '➗'),
+  ('➰', '➰'), ('➿', '➿'), ('⬛', '⬜'), ('⭐', '⭐'),
+  ('⭕', '⭕'), ('🀄', '🀄'), ('🃏', '🃏'), ('🆎', '🆎'),
+  ('🆑', '🆚'), ('🇦', '🇿'), ('🈁', '🈁'), ('🈚', '🈚'),
+  ('🈯', '🈯'), ('🈲', '🈶'), ('🈸', '🈺'), ('🉐', '🉑'),
+  ('🌀', '🌠'), ('🌭', '🌵'), ('🌷', '🍼'), ('🍾', '🎓'),
+  ('🎠', '🏊'), ('🏏', '🏓'), ('🏠', '🏰'), ('🏴', '🏴'),
+  ('🏸', '🐾'), ('👀', '👀'), ('👂', '📼'), ('📿', '🔽'),
+  ('🕋', '🕎'), ('🕐', '🕧'), ('🕺', '🕺'), ('🖕', '🖖'),
+  ('🖤', '🖤'), ('🗻', '🙏'), ('🚀', '🛅'), ('🛌', '🛌'),
+  ('🛐', '🛒'), ('\u{1f6d5}', '\u{1f6d5}'), ('🛫', '🛬'),
+  ('🛴', '\u{1f6fa}'), ('\u{1f7e0}', '\u{1f7eb}'), ('\u{1f90d}', '🤺'),
+  ('🤼', '🥅'), ('🥇', '\u{1f971}'), ('🥳', '🥶'), ('🥺', '🦢'),
+  ('\u{1f9a5}', '\u{1f9aa}'), ('\u{1f9ae}', '\u{1f9ca}'),
+  ('\u{1f9cd}', '🧿'), ('\u{1fa70}', '\u{1fa73}'),
+  ('\u{1fa78}', '\u{1fa7a}'), ('\u{1fa80}', '\u{1fa82}'),
+  ('\u{1fa90}', '\u{1fa95}'),
+];
+
+pub const EXTENDED_PICTOGRAPHIC: &'static [(char, char)] = &[
+  ('©', '©'), ('®', '®'), ('‼', '‼'), ('⁉', '⁉'), ('™', '™'),
+  ('ℹ', 'ℹ'), ('↔', '↙'), ('↩', '↪'), ('⌚', '⌛'),
+  ('⌨', '⌨'), ('⎈', '⎈'), ('⏏', '⏏'), ('⏩', '⏳'),
+  ('⏸', '⏺'), ('Ⓜ', 'Ⓜ'), ('▪', '▫'), ('▶', '▶'),
+  ('◀', '◀'), ('◻', '◾'), ('☀', '★'), ('☇', '☒'),
+  ('☔', '⚅'), ('⚐', '✅'), ('✈', '✒'), ('✔', '✔'),
+  ('✖', '✖'), ('✝', '✝'), ('✡', '✡'), ('✨', '✨'),
+  ('✳', '✴'), ('❄', '❄'), ('❇', '❇'), ('❌', '❌'),
+  ('❎', '❎'), ('❓', '❕'), ('❗', '❗'), ('❣', '❧'),
+  ('➕', '➗'), ('➡', '➡'), ('➰', '➰'), ('➿', '➿'),
+  ('⤴', '⤵'), ('⬅', '⬇'), ('⬛', '⬜'), ('⭐', '⭐'),
+  ('⭕', '⭕'), ('〰', '〰'), ('〽', '〽'), ('㊗', '㊗'),
+  ('㊙', '㊙'), ('🀀', '\u{1f0ff}'), ('\u{1f10d}', '\u{1f10f}'),
+  ('🄯', '🄯'), ('\u{1f16c}', '🅱'), ('🅾', '🅿'), ('🆎', '🆎'),
+  ('🆑', '🆚'), ('\u{1f1ad}', '\u{1f1e5}'), ('🈁', '\u{1f20f}'),
+  ('🈚', '🈚'), ('🈯', '🈯'), ('🈲', '🈺'),
+  ('\u{1f23c}', '\u{1f23f}'), ('\u{1f249}', '🏺'), ('🐀', '🔽'),
+  ('🕆', '🙏'), ('🚀', '\u{1f6ff}'), ('\u{1f774}', '\u{1f77f}'),
+  ('🟕', '\u{1f7ff}'), ('\u{1f80c}', '\u{1f80f}'),
+  ('\u{1f848}', '\u{1f84f}'), ('\u{1f85a}', '\u{1f85f}'),
+  ('\u{1f888}', '\u{1f88f}'), ('\u{1f8ae}', '\u{1f8ff}'),
+  ('\u{1f90c}', '🤺'), ('🤼', '🥅'), ('🥇', '\u{1fffd}'),
+];
+
+pub const EXTENDER: &'static [(char, char)] = &[
+  ('·', '·'), ('ː', 'ˑ'), ('ـ', 'ـ'), ('ߺ', 'ߺ'), ('ๆ', 'ๆ'),
+  ('ໆ', 'ໆ'), ('᠊', '᠊'), ('ᡃ', 'ᡃ'), ('ᪧ', 'ᪧ'),
+  ('\u{1c36}', '\u{1c36}'), ('ᱻ', 'ᱻ'), ('々', '々'), ('〱', '〵'),
+  ('ゝ', 'ゞ'), ('ー', 'ヾ'), ('ꀕ', 'ꀕ'), ('ꘌ', 'ꘌ'),
+  ('ꧏ', 'ꧏ'), ('ꧦ', 'ꧦ'), ('ꩰ', 'ꩰ'), ('ꫝ', 'ꫝ'),
+  ('ꫳ', 'ꫴ'), ('ー', 'ー'), ('𑍝', '𑍝'), ('𑗆', '𑗈'),
+  ('\u{11a98}', '\u{11a98}'), ('𖭂', '𖭃'), ('𖿠', '𖿡'),
+  ('\u{16fe3}', '\u{16fe3}'), ('\u{1e13c}', '\u{1e13d}'),
+  ('\u{1e944}', '\u{1e946}'),
+];
+
+pub const GRAPHEME_BASE: &'static [(char, char)] = &[
+  (' ', '~'), ('\u{a0}', '¬'), ('®', '˿'), ('Ͱ', 'ͷ'), ('ͺ', 'Ϳ'),
+  ('΄', 'Ί'), ('Ό', 'Ό'), ('Ύ', 'Ρ'), ('Σ', '҂'), ('Ҋ', 'ԯ'),
+  ('Ա', 'Ֆ'), ('ՙ', '֊'), ('֍', '֏'), ('־', '־'), ('׀', '׀'),
+  ('׃', '׃'), ('׆', '׆'), ('א', 'ת'), ('ׯ', '״'), ('؆', '؏'),
+  ('؛', '؛'), ('؞', 'ي'), ('٠', 'ٯ'), ('ٱ', 'ە'), ('۞', '۞'),
+  ('ۥ', 'ۦ'), ('۩', '۩'), ('ۮ', '܍'), ('ܐ', 'ܐ'), ('ܒ', 'ܯ'),
+  ('ݍ', 'ޥ'), ('ޱ', 'ޱ'), ('߀', 'ߪ'), ('ߴ', 'ߺ'), ('߾', 'ࠕ'),
+  ('ࠚ', 'ࠚ'), ('ࠤ', 'ࠤ'), ('ࠨ', 'ࠨ'), ('࠰', '࠾'),
+  ('ࡀ', 'ࡘ'), ('࡞', '࡞'), ('ࡠ', 'ࡪ'), ('ࢠ', 'ࢴ'),
+  ('ࢶ', 'ࢽ'), ('ः', 'ह'), ('ऻ', 'ऻ'), ('ऽ', 'ी'),
+  ('ॉ', 'ौ'), ('ॎ', 'ॐ'), ('क़', 'ॡ'), ('।', 'ঀ'),
+  ('ং', 'ঃ'), ('অ', 'ঌ'), ('এ', 'ঐ'), ('ও', 'ন'),
+  ('প', 'র'), ('ল', 'ল'), ('শ', 'হ'), ('ঽ', 'ঽ'),
+  ('ি', 'ী'), ('ে', 'ৈ'), ('ো', 'ৌ'), ('ৎ', 'ৎ'),
+  ('ড়', 'ঢ়'), ('য়', 'ৡ'), ('০', '৽'), ('ਃ', 'ਃ'),
+  ('ਅ', 'ਊ'), ('ਏ', 'ਐ'), ('ਓ', 'ਨ'), ('ਪ', 'ਰ'),
+  ('ਲ', 'ਲ਼'), ('ਵ', 'ਸ਼'), ('ਸ', 'ਹ'), ('ਾ', 'ੀ'),
+  ('ਖ਼', 'ੜ'), ('ਫ਼', 'ਫ਼'), ('੦', '੯'), ('ੲ', 'ੴ'),
+  ('੶', '੶'), ('ઃ', 'ઃ'), ('અ', 'ઍ'), ('એ', 'ઑ'),
+  ('ઓ', 'ન'), ('પ', 'ર'), ('લ', 'ળ'), ('વ', 'હ'),
+  ('ઽ', 'ી'), ('ૉ', 'ૉ'), ('ો', 'ૌ'), ('ૐ', 'ૐ'),
+  ('ૠ', 'ૡ'), ('૦', '૱'), ('ૹ', 'ૹ'), ('ଂ', 'ଃ'),
+  ('ଅ', 'ଌ'), ('ଏ', 'ଐ'), ('ଓ', 'ନ'), ('ପ', 'ର'),
+  ('ଲ', 'ଳ'), ('ଵ', 'ହ'), ('ଽ', 'ଽ'), ('ୀ', 'ୀ'),
+  ('େ', 'ୈ'), ('ୋ', 'ୌ'), ('ଡ଼', 'ଢ଼'), ('ୟ', 'ୡ'),
+  ('୦', '୷'), ('ஃ', 'ஃ'), ('அ', 'ஊ'), ('எ', 'ஐ'),
+  ('ஒ', 'க'), ('ங', 'ச'), ('ஜ', 'ஜ'), ('ஞ', 'ட'),
+  ('ண', 'த'), ('ந', 'ப'), ('ம', 'ஹ'), ('ி', 'ி'),
+  ('ு', 'ூ'), ('ெ', 'ை'), ('ொ', 'ௌ'), ('ௐ', 'ௐ'),
+  ('௦', '௺'), ('ఁ', 'ః'), ('అ', 'ఌ'), ('ఎ', 'ఐ'),
+  ('ఒ', 'న'), ('ప', 'హ'), ('ఽ', 'ఽ'), ('ు', 'ౄ'),
+  ('ౘ', 'ౚ'), ('ౠ', 'ౡ'), ('౦', '౯'), ('\u{c77}', 'ಀ'),
+  ('ಂ', 'ಌ'), ('ಎ', 'ಐ'), ('ಒ', 'ನ'), ('ಪ', 'ಳ'),
+  ('ವ', 'ಹ'), ('ಽ', 'ಾ'), ('ೀ', 'ು'), ('ೃ', 'ೄ'),
+  ('ೇ', 'ೈ'), ('ೊ', 'ೋ'), ('ೞ', 'ೞ'), ('ೠ', 'ೡ'),
+  ('೦', '೯'), ('ೱ', 'ೲ'), ('ം', 'ഃ'), ('അ', 'ഌ'),
+  ('എ', 'ഐ'), ('ഒ', 'ഺ'), ('ഽ', 'ഽ'), ('ി', 'ീ'),
+  ('െ', 'ൈ'), ('ൊ', 'ൌ'), ('ൎ', '൏'), ('ൔ', 'ൖ'),
+  ('൘', 'ൡ'), ('൦', 'ൿ'), ('ං', 'ඃ'), ('අ', 'ඖ'),
+  ('ක', 'න'), ('ඳ', 'ර'), ('ල', 'ල'), ('ව', 'ෆ'),
+  ('ැ', 'ෑ'), ('ෘ', 'ෞ'), ('෦', '෯'), ('ෲ', '෴'),
+  ('ก', 'ะ'), ('า', 'ำ'), ('฿', 'ๆ'), ('๏', '๛'),
+  ('ກ', 'ຂ'), ('ຄ', 'ຄ'), ('\u{e86}', 'ຊ'), ('\u{e8c}', 'ຣ'),
+  ('ລ', 'ລ'), ('ວ', 'ະ'), ('າ', 'ຳ'), ('ຽ', 'ຽ'),
+  ('ເ', 'ໄ'), ('ໆ', 'ໆ'), ('໐', '໙'), ('ໜ', 'ໟ'),
+  ('ༀ', '༗'), ('༚', '༴'), ('༶', '༶'), ('༸', '༸'),
+  ('༺', 'ཇ'), ('ཉ', 'ཬ'), ('ཿ', 'ཿ'), ('྅', '྅'),
+  ('ྈ', 'ྌ'), ('྾', '࿅'), ('࿇', '࿌'), ('࿎', '࿚'),
+  ('က', 'ာ'), ('ေ', 'ေ'), ('း', 'း'), ('ျ', 'ြ'),
+  ('ဿ', 'ၗ'), ('ၚ', 'ၝ'), ('ၡ', 'ၰ'), ('ၵ', 'ႁ'),
+  ('ႃ', 'ႄ'), ('ႇ', 'ႌ'), ('ႎ', 'ႜ'), ('႞', 'Ⴥ'),
+  ('Ⴧ', 'Ⴧ'), ('Ⴭ', 'Ⴭ'), ('ა', 'ቈ'), ('ቊ', 'ቍ'),
+  ('ቐ', 'ቖ'), ('ቘ', 'ቘ'), ('ቚ', 'ቝ'), ('በ', 'ኈ'),
+  ('ኊ', 'ኍ'), ('ነ', 'ኰ'), ('ኲ', 'ኵ'), ('ኸ', 'ኾ'),
+  ('ዀ', 'ዀ'), ('ዂ', 'ዅ'), ('ወ', 'ዖ'), ('ዘ', 'ጐ'),
+  ('ጒ', 'ጕ'), ('ጘ', 'ፚ'), ('፠', '፼'), ('ᎀ', '᎙'),
+  ('Ꭰ', 'Ᏽ'), ('ᏸ', 'ᏽ'), ('᐀', '᚜'), ('ᚠ', 'ᛸ'),
+  ('ᜀ', 'ᜌ'), ('ᜎ', 'ᜑ'), ('ᜠ', 'ᜱ'), ('᜵', '᜶'),
+  ('ᝀ', 'ᝑ'), ('ᝠ', 'ᝬ'), ('ᝮ', 'ᝰ'), ('ក', 'ឳ'),
+  ('ា', 'ា'), ('ើ', 'ៅ'), ('ះ', 'ៈ'), ('។', 'ៜ'),
+  ('០', '៩'), ('៰', '៹'), ('᠀', '᠊'), ('᠐', '᠙'),
+  ('ᠠ', 'ᡸ'), ('ᢀ', 'ᢄ'), ('ᢇ', 'ᢨ'), ('ᢪ', 'ᢪ'),
+  ('ᢰ', 'ᣵ'), ('ᤀ', 'ᤞ'), ('ᤣ', 'ᤦ'), ('ᤩ', 'ᤫ'),
+  ('ᤰ', 'ᤱ'), ('ᤳ', 'ᤸ'), ('᥀', '᥀'), ('᥄', 'ᥭ'),
+  ('ᥰ', 'ᥴ'), ('ᦀ', 'ᦫ'), ('ᦰ', 'ᧉ'), ('᧐', '᧚'),
+  ('᧞', 'ᨖ'), ('ᨙ', 'ᨚ'), ('᨞', 'ᩕ'), ('ᩗ', 'ᩗ'),
+  ('ᩡ', 'ᩡ'), ('ᩣ', 'ᩤ'), ('ᩭ', 'ᩲ'), ('᪀', '᪉'),
+  ('᪐', '᪙'), ('᪠', '᪭'), ('ᬄ', 'ᬳ'), ('ᬻ', 'ᬻ'),
+  ('ᬽ', 'ᭁ'), ('ᭃ', 'ᭋ'), ('᭐', '᭪'), ('᭴', '᭼'),
+  ('ᮂ', 'ᮡ'), ('ᮦ', 'ᮧ'), ('᮪', '᮪'), ('ᮮ', 'ᯥ'),
+  ('ᯧ', 'ᯧ'), ('ᯪ', 'ᯬ'), ('ᯮ', 'ᯮ'), ('᯲', '᯳'),
+  ('᯼', 'ᰫ'), ('ᰴ', 'ᰵ'), ('᰻', '᱉'), ('ᱍ', 'ᲈ'),
+  ('Ა', 'Ჺ'), ('Ჽ', '᳇'), ('᳓', '᳓'), ('᳡', '᳡'),
+  ('ᳩ', 'ᳬ'), ('ᳮ', 'ᳳ'), ('ᳵ', '᳷'), ('\u{1cfa}', '\u{1cfa}'),
+  ('ᴀ', 'ᶿ'), ('Ḁ', 'ἕ'), ('Ἐ', 'Ἕ'), ('ἠ', 'ὅ'),
+  ('Ὀ', 'Ὅ'), ('ὐ', 'ὗ'), ('Ὑ', 'Ὑ'), ('Ὓ', 'Ὓ'),
+  ('Ὕ', 'Ὕ'), ('Ὗ', 'ώ'), ('ᾀ', 'ᾴ'), ('ᾶ', 'ῄ'),
+  ('ῆ', 'ΐ'), ('ῖ', 'Ί'), ('῝', '`'), ('ῲ', 'ῴ'),
+  ('ῶ', '῾'), ('\u{2000}', '\u{200a}'), ('‐', '‧'),
+  ('\u{202f}', '\u{205f}'), ('⁰', 'ⁱ'), ('⁴', '₎'), ('ₐ', 'ₜ'),
+  ('₠', '₿'), ('℀', '↋'), ('←', '␦'), ('⑀', '⑊'),
+  ('①', '⭳'), ('⭶', '⮕'), ('⮘', 'Ⱞ'), ('ⰰ', 'ⱞ'),
+  ('Ⱡ', 'ⳮ'), ('Ⳳ', 'ⳳ'), ('⳹', 'ⴥ'), ('ⴧ', 'ⴧ'),
+  ('ⴭ', 'ⴭ'), ('ⴰ', 'ⵧ'), ('ⵯ', '⵰'), ('ⶀ', 'ⶖ'),
+  ('ⶠ', 'ⶦ'), ('ⶨ', 'ⶮ'), ('ⶰ', 'ⶶ'), ('ⶸ', 'ⶾ'),
+  ('ⷀ', 'ⷆ'), ('ⷈ', 'ⷎ'), ('ⷐ', 'ⷖ'), ('ⷘ', 'ⷞ'),
+  ('⸀', '\u{2e4f}'), ('⺀', '⺙'), ('⺛', '⻳'), ('⼀', '⿕'),
+  ('⿰', '⿻'), ('\u{3000}', '〩'), ('〰', '〿'), ('ぁ', 'ゖ'),
+  ('゛', 'ヿ'), ('ㄅ', 'ㄯ'), ('ㄱ', 'ㆎ'), ('㆐', 'ㆺ'),
+  ('㇀', '㇣'), ('ㇰ', '㈞'), ('㈠', '䶵'), ('䷀', '鿯'),
+  ('ꀀ', 'ꒌ'), ('꒐', '꓆'), ('ꓐ', 'ꘫ'), ('Ꙁ', 'ꙮ'),
+  ('꙳', '꙳'), ('꙾', 'ꚝ'), ('ꚠ', 'ꛯ'), ('꛲', '꛷'),
+  ('꜀', '\u{a7bf}'), ('\u{a7c2}', '\u{a7c6}'), ('ꟷ', 'ꠁ'),
+  ('ꠃ', 'ꠅ'), ('ꠇ', 'ꠊ'), ('ꠌ', 'ꠤ'), ('ꠧ', '꠫'),
+  ('꠰', '꠹'), ('ꡀ', '꡷'), ('ꢀ', 'ꣃ'), ('꣎', '꣙'),
+  ('ꣲ', 'ꣾ'), ('꤀', 'ꤥ'), ('꤮', 'ꥆ'), ('ꥒ', '꥓'),
+  ('꥟', 'ꥼ'), ('ꦃ', 'ꦲ'), ('ꦴ', 'ꦵ'), ('ꦺ', 'ꦻ'),
+  ('ꦾ', '꧍'), ('ꧏ', '꧙'), ('꧞', 'ꧤ'), ('ꧦ', 'ꧾ'),
+  ('ꨀ', 'ꨨ'), ('ꨯ', 'ꨰ'), ('ꨳ', 'ꨴ'), ('ꩀ', 'ꩂ'),
+  ('ꩄ', 'ꩋ'), ('ꩍ', 'ꩍ'), ('꩐', '꩙'), ('꩜', 'ꩻ'),
+  ('ꩽ', 'ꪯ'), ('ꪱ', 'ꪱ'), ('ꪵ', 'ꪶ'), ('ꪹ', 'ꪽ'),
+  ('ꫀ', 'ꫀ'), ('ꫂ', 'ꫂ'), ('ꫛ', 'ꫫ'), ('ꫮ', 'ꫵ'),
+  ('ꬁ', 'ꬆ'), ('ꬉ', 'ꬎ'), ('ꬑ', 'ꬖ'), ('ꬠ', 'ꬦ'),
+  ('ꬨ', 'ꬮ'), ('ꬰ', '\u{ab67}'), ('ꭰ', 'ꯤ'), ('ꯦ', 'ꯧ'),
+  ('ꯩ', '꯬'), ('꯰', '꯹'), ('가', '힣'), ('ힰ', 'ퟆ'),
+  ('ퟋ', 'ퟻ'), ('豈', '舘'), ('並', '龎'), ('ff', 'st'),
+  ('ﬓ', 'ﬗ'), ('יִ', 'יִ'), ('ײַ', 'זּ'), ('טּ', 'לּ'),
+  ('מּ', 'מּ'), ('נּ', 'סּ'), ('ףּ', 'פּ'), ('צּ', '﯁'),
+  ('ﯓ', '﴿'), ('ﵐ', 'ﶏ'), ('ﶒ', 'ﷇ'), ('ﷰ', '﷽'),
+  ('︐', '︙'), ('︰', '﹒'), ('﹔', '﹦'), ('﹨', '﹫'),
+  ('ﹰ', 'ﹴ'), ('ﹶ', 'ﻼ'), ('!', 'ン'), ('ᅠ', 'ᄒ'),
+  ('ᅡ', 'ᅦ'), ('ᅧ', 'ᅬ'), ('ᅭ', 'ᅲ'), ('ᅳ', 'ᅵ'),
+  ('¢', '₩'), ('│', '○'), ('', '�'), ('𐀀', '𐀋'),
+  ('𐀍', '𐀦'), ('𐀨', '𐀺'), ('𐀼', '𐀽'), ('𐀿', '𐁍'),
+  ('𐁐', '𐁝'), ('𐂀', '𐃺'), ('𐄀', '𐄂'), ('𐄇', '𐄳'),
+  ('𐄷', '𐆎'), ('𐆐', '𐆛'), ('𐆠', '𐆠'), ('𐇐', '𐇼'),
+  ('𐊀', '𐊜'), ('𐊠', '𐋐'), ('𐋡', '𐋻'), ('𐌀', '𐌣'),
+  ('𐌭', '𐍊'), ('𐍐', '𐍵'), ('𐎀', '𐎝'), ('𐎟', '𐏃'),
+  ('𐏈', '𐏕'), ('𐐀', '𐒝'), ('𐒠', '𐒩'), ('𐒰', '𐓓'),
+  ('𐓘', '𐓻'), ('𐔀', '𐔧'), ('𐔰', '𐕣'), ('𐕯', '𐕯'),
+  ('𐘀', '𐜶'), ('𐝀', '𐝕'), ('𐝠', '𐝧'), ('𐠀', '𐠅'),
+  ('𐠈', '𐠈'), ('𐠊', '𐠵'), ('𐠷', '𐠸'), ('𐠼', '𐠼'),
+  ('𐠿', '𐡕'), ('𐡗', '𐢞'), ('𐢧', '𐢯'), ('𐣠', '𐣲'),
+  ('𐣴', '𐣵'), ('𐣻', '𐤛'), ('𐤟', '𐤹'), ('𐤿', '𐤿'),
+  ('𐦀', '𐦷'), ('𐦼', '𐧏'), ('𐧒', '𐨀'), ('𐨐', '𐨓'),
+  ('𐨕', '𐨗'), ('𐨙', '𐨵'), ('𐩀', '𐩈'), ('𐩐', '𐩘'),
+  ('𐩠', '𐪟'), ('𐫀', '𐫤'), ('𐫫', '𐫶'), ('𐬀', '𐬵'),
+  ('𐬹', '𐭕'), ('𐭘', '𐭲'), ('𐭸', '𐮑'), ('𐮙', '𐮜'),
+  ('𐮩', '𐮯'), ('𐰀', '𐱈'), ('𐲀', '𐲲'), ('𐳀', '𐳲'),
+  ('𐳺', '𐴣'), ('𐴰', '𐴹'), ('𐹠', '𐹾'), ('𐼀', '𐼧'),
+  ('𐼰', '𐽅'), ('𐽑', '𐽙'), ('\u{10fe0}', '\u{10ff6}'),
+  ('𑀀', '𑀀'), ('𑀂', '𑀷'), ('𑁇', '𑁍'), ('𑁒', '𑁯'),
+  ('𑂂', '𑂲'), ('𑂷', '𑂸'), ('𑂻', '𑂼'), ('𑂾', '𑃁'),
+  ('𑃐', '𑃨'), ('𑃰', '𑃹'), ('𑄃', '𑄦'), ('𑄬', '𑄬'),
+  ('𑄶', '𑅆'), ('𑅐', '𑅲'), ('𑅴', '𑅶'), ('𑆂', '𑆵'),
+  ('𑆿', '𑇈'), ('𑇍', '𑇍'), ('𑇐', '𑇟'), ('𑇡', '𑇴'),
+  ('𑈀', '𑈑'), ('𑈓', '𑈮'), ('𑈲', '𑈳'), ('𑈵', '𑈵'),
+  ('𑈸', '𑈽'), ('𑊀', '𑊆'), ('𑊈', '𑊈'), ('𑊊', '𑊍'),
+  ('𑊏', '𑊝'), ('𑊟', '𑊩'), ('𑊰', '𑋞'), ('𑋠', '𑋢'),
+  ('𑋰', '𑋹'), ('𑌂', '𑌃'), ('𑌅', '𑌌'), ('𑌏', '𑌐'),
+  ('𑌓', '𑌨'), ('𑌪', '𑌰'), ('𑌲', '𑌳'), ('𑌵', '𑌹'),
+  ('𑌽', '𑌽'), ('𑌿', '𑌿'), ('𑍁', '𑍄'), ('𑍇', '𑍈'),
+  ('𑍋', '𑍍'), ('𑍐', '𑍐'), ('𑍝', '𑍣'), ('𑐀', '𑐷'),
+  ('𑑀', '𑑁'), ('𑑅', '𑑅'), ('𑑇', '𑑙'), ('𑑛', '𑑛'),
+  ('𑑝', '𑑝'), ('\u{1145f}', '\u{1145f}'), ('𑒀', '𑒯'),
+  ('𑒱', '𑒲'), ('𑒹', '𑒹'), ('𑒻', '𑒼'), ('𑒾', '𑒾'),
+  ('𑓁', '𑓁'), ('𑓄', '𑓇'), ('𑓐', '𑓙'), ('𑖀', '𑖮'),
+  ('𑖰', '𑖱'), ('𑖸', '𑖻'), ('𑖾', '𑖾'), ('𑗁', '𑗛'),
+  ('𑘀', '𑘲'), ('𑘻', '𑘼'), ('𑘾', '𑘾'), ('𑙁', '𑙄'),
+  ('𑙐', '𑙙'), ('𑙠', '𑙬'), ('𑚀', '𑚪'), ('𑚬', '𑚬'),
+  ('𑚮', '𑚯'), ('𑚶', '𑚶'), ('\u{116b8}', '\u{116b8}'),
+  ('𑛀', '𑛉'), ('𑜀', '𑜚'), ('𑜠', '𑜡'), ('𑜦', '𑜦'),
+  ('𑜰', '𑜿'), ('𑠀', '𑠮'), ('𑠸', '𑠸'), ('𑠻', '𑠻'),
+  ('𑢠', '𑣲'), ('𑣿', '𑣿'), ('\u{119a0}', '\u{119a7}'),
+  ('\u{119aa}', '\u{119d3}'), ('\u{119dc}', '\u{119df}'),
+  ('\u{119e1}', '\u{119e4}'), ('𑨀', '𑨀'), ('𑨋', '𑨲'),
+  ('𑨹', '𑨺'), ('𑨿', '𑩆'), ('𑩐', '𑩐'), ('𑩗', '𑩘'),
+  ('𑩜', '𑪉'), ('𑪗', '𑪗'), ('𑪚', '𑪢'), ('𑫀', '𑫸'),
+  ('𑰀', '𑰈'), ('𑰊', '𑰯'), ('𑰾', '𑰾'), ('𑱀', '𑱅'),
+  ('𑱐', '𑱬'), ('𑱰', '𑲏'), ('𑲩', '𑲩'), ('𑲱', '𑲱'),
+  ('𑲴', '𑲴'), ('𑴀', '𑴆'), ('𑴈', '𑴉'), ('𑴋', '𑴰'),
+  ('𑵆', '𑵆'), ('𑵐', '𑵙'), ('𑵠', '𑵥'), ('𑵧', '𑵨'),
+  ('𑵪', '𑶎'), ('𑶓', '𑶔'), ('𑶖', '𑶖'), ('𑶘', '𑶘'),
+  ('𑶠', '𑶩'), ('𑻠', '𑻲'), ('𑻵', '𑻸'),
+  ('\u{11fc0}', '\u{11ff1}'), ('\u{11fff}', '𒎙'), ('𒐀', '𒑮'),
+  ('𒑰', '𒑴'), ('𒒀', '𒕃'), ('𓀀', '𓐮'), ('𔐀', '𔙆'),
+  ('𖠀', '𖨸'), ('𖩀', '𖩞'), ('𖩠', '𖩩'), ('𖩮', '𖩯'),
+  ('𖫐', '𖫭'), ('𖫵', '𖫵'), ('𖬀', '𖬯'), ('𖬷', '𖭅'),
+  ('𖭐', '𖭙'), ('𖭛', '𖭡'), ('𖭣', '𖭷'), ('𖭽', '𖮏'),
+  ('𖹀', '𖺚'), ('𖼀', '\u{16f4a}'), ('𖽐', '\u{16f87}'),
+  ('𖾓', '𖾟'), ('𖿠', '\u{16fe3}'), ('𗀀', '\u{187f7}'),
+  ('𘠀', '𘫲'), ('𛀀', '𛄞'), ('\u{1b150}', '\u{1b152}'),
+  ('\u{1b164}', '\u{1b167}'), ('𛅰', '𛋻'), ('𛰀', '𛱪'),
+  ('𛱰', '𛱼'), ('𛲀', '𛲈'), ('𛲐', '𛲙'), ('𛲜', '𛲜'),
+  ('𛲟', '𛲟'), ('𝀀', '𝃵'), ('𝄀', '𝄦'), ('𝄩', '𝅘𝅥𝅲'),
+  ('𝅦', '𝅦'), ('𝅪', '𝅭'), ('𝆃', '𝆄'), ('𝆌', '𝆩'),
+  ('𝆮', '𝇨'), ('𝈀', '𝉁'), ('𝉅', '𝉅'), ('𝋠', '𝋳'),
+  ('𝌀', '𝍖'), ('𝍠', '𝍸'), ('𝐀', '𝑔'), ('𝑖', '𝒜'),
+  ('𝒞', '𝒟'), ('𝒢', '𝒢'), ('𝒥', '𝒦'), ('𝒩', '𝒬'),
+  ('𝒮', '𝒹'), ('𝒻', '𝒻'), ('𝒽', '𝓃'), ('𝓅', '𝔅'),
+  ('𝔇', '𝔊'), ('𝔍', '𝔔'), ('𝔖', '𝔜'), ('𝔞', '𝔹'),
+  ('𝔻', '𝔾'), ('𝕀', '𝕄'), ('𝕆', '𝕆'), ('𝕊', '𝕐'),
+  ('𝕒', '𝚥'), ('𝚨', '𝟋'), ('𝟎', '𝧿'), ('𝨷', '𝨺'),
+  ('𝩭', '𝩴'), ('𝩶', '𝪃'), ('𝪅', '𝪋'),
+  ('\u{1e100}', '\u{1e12c}'), ('\u{1e137}', '\u{1e13d}'),
+  ('\u{1e140}', '\u{1e149}'), ('\u{1e14e}', '\u{1e14f}'),
+  ('\u{1e2c0}', '\u{1e2eb}'), ('\u{1e2f0}', '\u{1e2f9}'),
+  ('\u{1e2ff}', '\u{1e2ff}'), ('𞠀', '𞣄'), ('𞣇', '𞣏'),
+  ('𞤀', '𞥃'), ('\u{1e94b}', '\u{1e94b}'), ('𞥐', '𞥙'),
+  ('𞥞', '𞥟'), ('𞱱', '𞲴'), ('\u{1ed01}', '\u{1ed3d}'),
+  ('𞸀', '𞸃'), ('𞸅', '𞸟'), ('𞸡', '𞸢'), ('𞸤', '𞸤'),
+  ('𞸧', '𞸧'), ('𞸩', '𞸲'), ('𞸴', '𞸷'), ('𞸹', '𞸹'),
+  ('𞸻', '𞸻'), ('𞹂', '𞹂'), ('𞹇', '𞹇'), ('𞹉', '𞹉'),
+  ('𞹋', '𞹋'), ('𞹍', '𞹏'), ('𞹑', '𞹒'), ('𞹔', '𞹔'),
+  ('𞹗', '𞹗'), ('𞹙', '𞹙'), ('𞹛', '𞹛'), ('𞹝', '𞹝'),
+  ('𞹟', '𞹟'), ('𞹡', '𞹢'), ('𞹤', '𞹤'), ('𞹧', '𞹪'),
+  ('𞹬', '𞹲'), ('𞹴', '𞹷'), ('𞹹', '𞹼'), ('𞹾', '𞹾'),
+  ('𞺀', '𞺉'), ('𞺋', '𞺛'), ('𞺡', '𞺣'), ('𞺥', '𞺩'),
+  ('𞺫', '𞺻'), ('𞻰', '𞻱'), ('🀀', '🀫'), ('🀰', '🂓'),
+  ('🂠', '🂮'), ('🂱', '🂿'), ('🃁', '🃏'), ('🃑', '🃵'),
+  ('🄀', '🄌'), ('🄐', '\u{1f16c}'), ('🅰', '🆬'), ('🇦', '🈂'),
+  ('🈐', '🈻'), ('🉀', '🉈'), ('🉐', '🉑'), ('🉠', '🉥'),
+  ('🌀', '\u{1f6d5}'), ('🛠', '🛬'), ('🛰', '\u{1f6fa}'),
+  ('🜀', '🝳'), ('🞀', '🟘'), ('\u{1f7e0}', '\u{1f7eb}'),
+  ('🠀', '🠋'), ('🠐', '🡇'), ('🡐', '🡙'), ('🡠', '🢇'),
+  ('🢐', '🢭'), ('🤀', '🤋'), ('\u{1f90d}', '\u{1f971}'),
+  ('🥳', '🥶'), ('🥺', '🦢'), ('\u{1f9a5}', '\u{1f9aa}'),
+  ('\u{1f9ae}', '\u{1f9ca}'), ('\u{1f9cd}', '\u{1fa53}'), ('🩠', '🩭'),
+  ('\u{1fa70}', '\u{1fa73}'), ('\u{1fa78}', '\u{1fa7a}'),
+  ('\u{1fa80}', '\u{1fa82}'), ('\u{1fa90}', '\u{1fa95}'), ('𠀀', '𪛖'),
+  ('𪜀', '𫜴'), ('𫝀', '𫠝'), ('𫠠', '𬺡'), ('𬺰', '𮯠'),
+  ('丽', '𪘀'),
+];
+
+pub const GRAPHEME_EXTEND: &'static [(char, char)] = &[
+  ('\u{300}', '\u{36f}'), ('\u{483}', '\u{489}'), ('\u{591}', '\u{5bd}'),
+  ('\u{5bf}', '\u{5bf}'), ('\u{5c1}', '\u{5c2}'), ('\u{5c4}', '\u{5c5}'),
+  ('\u{5c7}', '\u{5c7}'), ('\u{610}', '\u{61a}'), ('\u{64b}', '\u{65f}'),
+  ('\u{670}', '\u{670}'), ('\u{6d6}', '\u{6dc}'), ('\u{6df}', '\u{6e4}'),
+  ('\u{6e7}', '\u{6e8}'), ('\u{6ea}', '\u{6ed}'), ('\u{711}', '\u{711}'),
+  ('\u{730}', '\u{74a}'), ('\u{7a6}', '\u{7b0}'), ('\u{7eb}', '\u{7f3}'),
+  ('\u{7fd}', '\u{7fd}'), ('\u{816}', '\u{819}'), ('\u{81b}', '\u{823}'),
+  ('\u{825}', '\u{827}'), ('\u{829}', '\u{82d}'), ('\u{859}', '\u{85b}'),
+  ('\u{8d3}', '\u{8e1}'), ('\u{8e3}', '\u{902}'), ('\u{93a}', '\u{93a}'),
+  ('\u{93c}', '\u{93c}'), ('\u{941}', '\u{948}'), ('\u{94d}', '\u{94d}'),
+  ('\u{951}', '\u{957}'), ('\u{962}', '\u{963}'), ('\u{981}', '\u{981}'),
+  ('\u{9bc}', '\u{9bc}'), ('\u{9be}', '\u{9be}'), ('\u{9c1}', '\u{9c4}'),
+  ('\u{9cd}', '\u{9cd}'), ('\u{9d7}', '\u{9d7}'), ('\u{9e2}', '\u{9e3}'),
+  ('\u{9fe}', '\u{9fe}'), ('\u{a01}', '\u{a02}'), ('\u{a3c}', '\u{a3c}'),
+  ('\u{a41}', '\u{a42}'), ('\u{a47}', '\u{a48}'), ('\u{a4b}', '\u{a4d}'),
+  ('\u{a51}', '\u{a51}'), ('\u{a70}', '\u{a71}'), ('\u{a75}', '\u{a75}'),
+  ('\u{a81}', '\u{a82}'), ('\u{abc}', '\u{abc}'), ('\u{ac1}', '\u{ac5}'),
+  ('\u{ac7}', '\u{ac8}'), ('\u{acd}', '\u{acd}'), ('\u{ae2}', '\u{ae3}'),
+  ('\u{afa}', '\u{aff}'), ('\u{b01}', '\u{b01}'), ('\u{b3c}', '\u{b3c}'),
+  ('\u{b3e}', '\u{b3f}'), ('\u{b41}', '\u{b44}'), ('\u{b4d}', '\u{b4d}'),
+  ('\u{b56}', '\u{b57}'), ('\u{b62}', '\u{b63}'), ('\u{b82}', '\u{b82}'),
+  ('\u{bbe}', '\u{bbe}'), ('\u{bc0}', '\u{bc0}'), ('\u{bcd}', '\u{bcd}'),
+  ('\u{bd7}', '\u{bd7}'), ('\u{c00}', '\u{c00}'), ('\u{c04}', '\u{c04}'),
+  ('\u{c3e}', '\u{c40}'), ('\u{c46}', '\u{c48}'), ('\u{c4a}', '\u{c4d}'),
+  ('\u{c55}', '\u{c56}'), ('\u{c62}', '\u{c63}'), ('\u{c81}', '\u{c81}'),
+  ('\u{cbc}', '\u{cbc}'), ('\u{cbf}', '\u{cbf}'), ('\u{cc2}', '\u{cc2}'),
+  ('\u{cc6}', '\u{cc6}'), ('\u{ccc}', '\u{ccd}'), ('\u{cd5}', '\u{cd6}'),
+  ('\u{ce2}', '\u{ce3}'), ('\u{d00}', '\u{d01}'), ('\u{d3b}', '\u{d3c}'),
+  ('\u{d3e}', '\u{d3e}'), ('\u{d41}', '\u{d44}'), ('\u{d4d}', '\u{d4d}'),
+  ('\u{d57}', '\u{d57}'), ('\u{d62}', '\u{d63}'), ('\u{dca}', '\u{dca}'),
+  ('\u{dcf}', '\u{dcf}'), ('\u{dd2}', '\u{dd4}'), ('\u{dd6}', '\u{dd6}'),
+  ('\u{ddf}', '\u{ddf}'), ('\u{e31}', '\u{e31}'), ('\u{e34}', '\u{e3a}'),
+  ('\u{e47}', '\u{e4e}'), ('\u{eb1}', '\u{eb1}'), ('\u{eb4}', '\u{ebc}'),
+  ('\u{ec8}', '\u{ecd}'), ('\u{f18}', '\u{f19}'), ('\u{f35}', '\u{f35}'),
+  ('\u{f37}', '\u{f37}'), ('\u{f39}', '\u{f39}'), ('\u{f71}', '\u{f7e}'),
+  ('\u{f80}', '\u{f84}'), ('\u{f86}', '\u{f87}'), ('\u{f8d}', '\u{f97}'),
+  ('\u{f99}', '\u{fbc}'), ('\u{fc6}', '\u{fc6}'), ('\u{102d}', '\u{1030}'),
+  ('\u{1032}', '\u{1037}'), ('\u{1039}', '\u{103a}'),
+  ('\u{103d}', '\u{103e}'), ('\u{1058}', '\u{1059}'),
+  ('\u{105e}', '\u{1060}'), ('\u{1071}', '\u{1074}'),
+  ('\u{1082}', '\u{1082}'), ('\u{1085}', '\u{1086}'),
+  ('\u{108d}', '\u{108d}'), ('\u{109d}', '\u{109d}'),
+  ('\u{135d}', '\u{135f}'), ('\u{1712}', '\u{1714}'),
+  ('\u{1732}', '\u{1734}'), ('\u{1752}', '\u{1753}'),
+  ('\u{1772}', '\u{1773}'), ('\u{17b4}', '\u{17b5}'),
+  ('\u{17b7}', '\u{17bd}'), ('\u{17c6}', '\u{17c6}'),
+  ('\u{17c9}', '\u{17d3}'), ('\u{17dd}', '\u{17dd}'),
+  ('\u{180b}', '\u{180d}'), ('\u{1885}', '\u{1886}'),
+  ('\u{18a9}', '\u{18a9}'), ('\u{1920}', '\u{1922}'),
+  ('\u{1927}', '\u{1928}'), ('\u{1932}', '\u{1932}'),
+  ('\u{1939}', '\u{193b}'), ('\u{1a17}', '\u{1a18}'),
+  ('\u{1a1b}', '\u{1a1b}'), ('\u{1a56}', '\u{1a56}'),
+  ('\u{1a58}', '\u{1a5e}'), ('\u{1a60}', '\u{1a60}'),
+  ('\u{1a62}', '\u{1a62}'), ('\u{1a65}', '\u{1a6c}'),
+  ('\u{1a73}', '\u{1a7c}'), ('\u{1a7f}', '\u{1a7f}'),
+  ('\u{1ab0}', '\u{1abe}'), ('\u{1b00}', '\u{1b03}'),
+  ('\u{1b34}', '\u{1b3a}'), ('\u{1b3c}', '\u{1b3c}'),
+  ('\u{1b42}', '\u{1b42}'), ('\u{1b6b}', '\u{1b73}'),
+  ('\u{1b80}', '\u{1b81}'), ('\u{1ba2}', '\u{1ba5}'),
+  ('\u{1ba8}', '\u{1ba9}'), ('\u{1bab}', '\u{1bad}'),
+  ('\u{1be6}', '\u{1be6}'), ('\u{1be8}', '\u{1be9}'),
+  ('\u{1bed}', '\u{1bed}'), ('\u{1bef}', '\u{1bf1}'),
+  ('\u{1c2c}', '\u{1c33}'), ('\u{1c36}', '\u{1c37}'),
+  ('\u{1cd0}', '\u{1cd2}'), ('\u{1cd4}', '\u{1ce0}'),
+  ('\u{1ce2}', '\u{1ce8}'), ('\u{1ced}', '\u{1ced}'),
+  ('\u{1cf4}', '\u{1cf4}'), ('\u{1cf8}', '\u{1cf9}'),
+  ('\u{1dc0}', '\u{1df9}'), ('\u{1dfb}', '\u{1dff}'),
+  ('\u{200c}', '\u{200c}'), ('\u{20d0}', '\u{20f0}'),
+  ('\u{2cef}', '\u{2cf1}'), ('\u{2d7f}', '\u{2d7f}'),
+  ('\u{2de0}', '\u{2dff}'), ('\u{302a}', '\u{302f}'),
+  ('\u{3099}', '\u{309a}'), ('\u{a66f}', '\u{a672}'),
+  ('\u{a674}', '\u{a67d}'), ('\u{a69e}', '\u{a69f}'),
+  ('\u{a6f0}', '\u{a6f1}'), ('\u{a802}', '\u{a802}'),
+  ('\u{a806}', '\u{a806}'), ('\u{a80b}', '\u{a80b}'),
+  ('\u{a825}', '\u{a826}'), ('\u{a8c4}', '\u{a8c5}'),
+  ('\u{a8e0}', '\u{a8f1}'), ('\u{a8ff}', '\u{a8ff}'),
+  ('\u{a926}', '\u{a92d}'), ('\u{a947}', '\u{a951}'),
+  ('\u{a980}', '\u{a982}'), ('\u{a9b3}', '\u{a9b3}'),
+  ('\u{a9b6}', '\u{a9b9}'), ('\u{a9bc}', 'ꦽ'), ('\u{a9e5}', '\u{a9e5}'),
+  ('\u{aa29}', '\u{aa2e}'), ('\u{aa31}', '\u{aa32}'),
+  ('\u{aa35}', '\u{aa36}'), ('\u{aa43}', '\u{aa43}'),
+  ('\u{aa4c}', '\u{aa4c}'), ('\u{aa7c}', '\u{aa7c}'),
+  ('\u{aab0}', '\u{aab0}'), ('\u{aab2}', '\u{aab4}'),
+  ('\u{aab7}', '\u{aab8}'), ('\u{aabe}', '\u{aabf}'),
+  ('\u{aac1}', '\u{aac1}'), ('\u{aaec}', '\u{aaed}'),
+  ('\u{aaf6}', '\u{aaf6}'), ('\u{abe5}', '\u{abe5}'),
+  ('\u{abe8}', '\u{abe8}'), ('\u{abed}', '\u{abed}'),
+  ('\u{fb1e}', '\u{fb1e}'), ('\u{fe00}', '\u{fe0f}'),
+  ('\u{fe20}', '\u{fe2f}'), ('\u{ff9e}', '\u{ff9f}'),
+  ('\u{101fd}', '\u{101fd}'), ('\u{102e0}', '\u{102e0}'),
+  ('\u{10376}', '\u{1037a}'), ('\u{10a01}', '\u{10a03}'),
+  ('\u{10a05}', '\u{10a06}'), ('\u{10a0c}', '\u{10a0f}'),
+  ('\u{10a38}', '\u{10a3a}'), ('\u{10a3f}', '\u{10a3f}'),
+  ('\u{10ae5}', '\u{10ae6}'), ('\u{10d24}', '\u{10d27}'),
+  ('\u{10f46}', '\u{10f50}'), ('\u{11001}', '\u{11001}'),
+  ('\u{11038}', '\u{11046}'), ('\u{1107f}', '\u{11081}'),
+  ('\u{110b3}', '\u{110b6}'), ('\u{110b9}', '\u{110ba}'),
+  ('\u{11100}', '\u{11102}'), ('\u{11127}', '\u{1112b}'),
+  ('\u{1112d}', '\u{11134}'), ('\u{11173}', '\u{11173}'),
+  ('\u{11180}', '\u{11181}'), ('\u{111b6}', '\u{111be}'),
+  ('\u{111c9}', '\u{111cc}'), ('\u{1122f}', '\u{11231}'),
+  ('\u{11234}', '\u{11234}'), ('\u{11236}', '\u{11237}'),
+  ('\u{1123e}', '\u{1123e}'), ('\u{112df}', '\u{112df}'),
+  ('\u{112e3}', '\u{112ea}'), ('\u{11300}', '\u{11301}'),
+  ('\u{1133b}', '\u{1133c}'), ('\u{1133e}', '\u{1133e}'),
+  ('\u{11340}', '\u{11340}'), ('\u{11357}', '\u{11357}'),
+  ('\u{11366}', '\u{1136c}'), ('\u{11370}', '\u{11374}'),
+  ('\u{11438}', '\u{1143f}'), ('\u{11442}', '\u{11444}'),
+  ('\u{11446}', '\u{11446}'), ('\u{1145e}', '\u{1145e}'),
+  ('\u{114b0}', '\u{114b0}'), ('\u{114b3}', '\u{114b8}'),
+  ('\u{114ba}', '\u{114ba}'), ('\u{114bd}', '\u{114bd}'),
+  ('\u{114bf}', '\u{114c0}'), ('\u{114c2}', '\u{114c3}'),
+  ('\u{115af}', '\u{115af}'), ('\u{115b2}', '\u{115b5}'),
+  ('\u{115bc}', '\u{115bd}'), ('\u{115bf}', '\u{115c0}'),
+  ('\u{115dc}', '\u{115dd}'), ('\u{11633}', '\u{1163a}'),
+  ('\u{1163d}', '\u{1163d}'), ('\u{1163f}', '\u{11640}'),
+  ('\u{116ab}', '\u{116ab}'), ('\u{116ad}', '\u{116ad}'),
+  ('\u{116b0}', '\u{116b5}'), ('\u{116b7}', '\u{116b7}'),
+  ('\u{1171d}', '\u{1171f}'), ('\u{11722}', '\u{11725}'),
+  ('\u{11727}', '\u{1172b}'), ('\u{1182f}', '\u{11837}'),
+  ('\u{11839}', '\u{1183a}'), ('\u{119d4}', '\u{119d7}'),
+  ('\u{119da}', '\u{119db}'), ('\u{119e0}', '\u{119e0}'),
+  ('\u{11a01}', '\u{11a0a}'), ('\u{11a33}', '\u{11a38}'),
+  ('\u{11a3b}', '\u{11a3e}'), ('\u{11a47}', '\u{11a47}'),
+  ('\u{11a51}', '\u{11a56}'), ('\u{11a59}', '\u{11a5b}'),
+  ('\u{11a8a}', '\u{11a96}'), ('\u{11a98}', '\u{11a99}'),
+  ('\u{11c30}', '\u{11c36}'), ('\u{11c38}', '\u{11c3d}'),
+  ('\u{11c3f}', '\u{11c3f}'), ('\u{11c92}', '\u{11ca7}'),
+  ('\u{11caa}', '\u{11cb0}'), ('\u{11cb2}', '\u{11cb3}'),
+  ('\u{11cb5}', '\u{11cb6}'), ('\u{11d31}', '\u{11d36}'),
+  ('\u{11d3a}', '\u{11d3a}'), ('\u{11d3c}', '\u{11d3d}'),
+  ('\u{11d3f}', '\u{11d45}'), ('\u{11d47}', '\u{11d47}'),
+  ('\u{11d90}', '\u{11d91}'), ('\u{11d95}', '\u{11d95}'),
+  ('\u{11d97}', '\u{11d97}'), ('\u{11ef3}', '\u{11ef4}'),
+  ('\u{16af0}', '\u{16af4}'), ('\u{16b30}', '\u{16b36}'),
+  ('\u{16f4f}', '\u{16f4f}'), ('\u{16f8f}', '\u{16f92}'),
+  ('\u{1bc9d}', '\u{1bc9e}'), ('\u{1d165}', '\u{1d165}'),
+  ('\u{1d167}', '\u{1d169}'), ('\u{1d16e}', '\u{1d172}'),
+  ('\u{1d17b}', '\u{1d182}'), ('\u{1d185}', '\u{1d18b}'),
+  ('\u{1d1aa}', '\u{1d1ad}'), ('\u{1d242}', '\u{1d244}'),
+  ('\u{1da00}', '\u{1da36}'), ('\u{1da3b}', '\u{1da6c}'),
+  ('\u{1da75}', '\u{1da75}'), ('\u{1da84}', '\u{1da84}'),
+  ('\u{1da9b}', '\u{1da9f}'), ('\u{1daa1}', '\u{1daaf}'),
+  ('\u{1e000}', '\u{1e006}'), ('\u{1e008}', '\u{1e018}'),
+  ('\u{1e01b}', '\u{1e021}'), ('\u{1e023}', '\u{1e024}'),
+  ('\u{1e026}', '\u{1e02a}'), ('\u{1e130}', '\u{1e136}'),
+  ('\u{1e2ec}', '\u{1e2ef}'), ('\u{1e8d0}', '\u{1e8d6}'),
+  ('\u{1e944}', '\u{1e94a}'), ('\u{e0020}', '\u{e007f}'),
+  ('\u{e0100}', '\u{e01ef}'),
+];
+
+pub const GRAPHEME_LINK: &'static [(char, char)] = &[
+  ('\u{94d}', '\u{94d}'), ('\u{9cd}', '\u{9cd}'), ('\u{a4d}', '\u{a4d}'),
+  ('\u{acd}', '\u{acd}'), ('\u{b4d}', '\u{b4d}'), ('\u{bcd}', '\u{bcd}'),
+  ('\u{c4d}', '\u{c4d}'), ('\u{ccd}', '\u{ccd}'), ('\u{d3b}', '\u{d3c}'),
+  ('\u{d4d}', '\u{d4d}'), ('\u{dca}', '\u{dca}'), ('\u{e3a}', '\u{e3a}'),
+  ('\u{eba}', '\u{eba}'), ('\u{f84}', '\u{f84}'), ('\u{1039}', '\u{103a}'),
+  ('\u{1714}', '\u{1714}'), ('\u{1734}', '\u{1734}'),
+  ('\u{17d2}', '\u{17d2}'), ('\u{1a60}', '\u{1a60}'), ('᭄', '᭄'),
+  ('᮪', '\u{1bab}'), ('᯲', '᯳'), ('\u{2d7f}', '\u{2d7f}'),
+  ('\u{a806}', '\u{a806}'), ('\u{a8c4}', '\u{a8c4}'), ('꥓', '꥓'),
+  ('꧀', '꧀'), ('\u{aaf6}', '\u{aaf6}'), ('\u{abed}', '\u{abed}'),
+  ('\u{10a3f}', '\u{10a3f}'), ('\u{11046}', '\u{11046}'),
+  ('\u{1107f}', '\u{1107f}'), ('\u{110b9}', '\u{110b9}'),
+  ('\u{11133}', '\u{11134}'), ('𑇀', '𑇀'), ('𑈵', '𑈵'),
+  ('\u{112ea}', '\u{112ea}'), ('𑍍', '𑍍'), ('\u{11442}', '\u{11442}'),
+  ('\u{114c2}', '\u{114c2}'), ('\u{115bf}', '\u{115bf}'),
+  ('\u{1163f}', '\u{1163f}'), ('𑚶', '𑚶'), ('\u{1172b}', '\u{1172b}'),
+  ('\u{11839}', '\u{11839}'), ('\u{119e0}', '\u{119e0}'),
+  ('\u{11a34}', '\u{11a34}'), ('\u{11a47}', '\u{11a47}'),
+  ('\u{11a99}', '\u{11a99}'), ('\u{11c3f}', '\u{11c3f}'),
+  ('\u{11d44}', '\u{11d45}'), ('\u{11d97}', '\u{11d97}'),
+];
+
+pub const HEX_DIGIT: &'static [(char, char)] = &[
+  ('0', '9'), ('A', 'F'), ('a', 'f'), ('0', '9'), ('A', 'F'),
+  ('a', 'f'),
+];
+
+pub const HYPHEN: &'static [(char, char)] = &[
+  ('-', '-'), ('\u{ad}', '\u{ad}'), ('֊', '֊'), ('᠆', '᠆'),
+  ('‐', '‑'), ('⸗', '⸗'), ('・', '・'), ('﹣', '﹣'),
+  ('-', '-'), ('・', '・'),
+];
+
+pub const IDS_BINARY_OPERATOR: &'static [(char, char)] = &[
+  ('⿰', '⿱'), ('⿴', '⿻'),
+];
+
+pub const IDS_TRINARY_OPERATOR: &'static [(char, char)] = &[
+  ('⿲', '⿳'),
+];
+
+pub const ID_CONTINUE: &'static [(char, char)] = &[
+  ('0', '9'), ('A', 'Z'), ('_', '_'), ('a', 'z'), ('ª', 'ª'), ('µ', 'µ'),
+  ('·', '·'), ('º', 'º'), ('À', 'Ö'), ('Ø', 'ö'), ('ø', 'ˁ'),
+  ('ˆ', 'ˑ'), ('ˠ', 'ˤ'), ('ˬ', 'ˬ'), ('ˮ', 'ˮ'), ('\u{300}', 'ʹ'),
+  ('Ͷ', 'ͷ'), ('ͺ', 'ͽ'), ('Ϳ', 'Ϳ'), ('Ά', 'Ί'), ('Ό', 'Ό'),
+  ('Ύ', 'Ρ'), ('Σ', 'ϵ'), ('Ϸ', 'ҁ'), ('\u{483}', '\u{487}'),
+  ('Ҋ', 'ԯ'), ('Ա', 'Ֆ'), ('ՙ', 'ՙ'), ('ՠ', 'ֈ'),
+  ('\u{591}', '\u{5bd}'), ('\u{5bf}', '\u{5bf}'), ('\u{5c1}', '\u{5c2}'),
+  ('\u{5c4}', '\u{5c5}'), ('\u{5c7}', '\u{5c7}'), ('א', 'ת'), ('ׯ', 'ײ'),
+  ('\u{610}', '\u{61a}'), ('ؠ', '٩'), ('ٮ', 'ۓ'), ('ە', '\u{6dc}'),
+  ('\u{6df}', '\u{6e8}'), ('\u{6ea}', 'ۼ'), ('ۿ', 'ۿ'), ('ܐ', '\u{74a}'),
+  ('ݍ', 'ޱ'), ('߀', 'ߵ'), ('ߺ', 'ߺ'), ('\u{7fd}', '\u{7fd}'),
+  ('ࠀ', '\u{82d}'), ('ࡀ', '\u{85b}'), ('ࡠ', 'ࡪ'), ('ࢠ', 'ࢴ'),
+  ('ࢶ', 'ࢽ'), ('\u{8d3}', '\u{8e1}'), ('\u{8e3}', '\u{963}'),
+  ('०', '९'), ('ॱ', 'ঃ'), ('অ', 'ঌ'), ('এ', 'ঐ'),
+  ('ও', 'ন'), ('প', 'র'), ('ল', 'ল'), ('শ', 'হ'),
+  ('\u{9bc}', '\u{9c4}'), ('ে', 'ৈ'), ('ো', 'ৎ'),
+  ('\u{9d7}', '\u{9d7}'), ('ড়', 'ঢ়'), ('য়', '\u{9e3}'), ('০', 'ৱ'),
+  ('ৼ', 'ৼ'), ('\u{9fe}', '\u{9fe}'), ('\u{a01}', 'ਃ'), ('ਅ', 'ਊ'),
+  ('ਏ', 'ਐ'), ('ਓ', 'ਨ'), ('ਪ', 'ਰ'), ('ਲ', 'ਲ਼'),
+  ('ਵ', 'ਸ਼'), ('ਸ', 'ਹ'), ('\u{a3c}', '\u{a3c}'), ('ਾ', '\u{a42}'),
+  ('\u{a47}', '\u{a48}'), ('\u{a4b}', '\u{a4d}'), ('\u{a51}', '\u{a51}'),
+  ('ਖ਼', 'ੜ'), ('ਫ਼', 'ਫ਼'), ('੦', '\u{a75}'), ('\u{a81}', 'ઃ'),
+  ('અ', 'ઍ'), ('એ', 'ઑ'), ('ઓ', 'ન'), ('પ', 'ર'),
+  ('લ', 'ળ'), ('વ', 'હ'), ('\u{abc}', '\u{ac5}'), ('\u{ac7}', 'ૉ'),
+  ('ો', '\u{acd}'), ('ૐ', 'ૐ'), ('ૠ', '\u{ae3}'), ('૦', '૯'),
+  ('ૹ', '\u{aff}'), ('\u{b01}', 'ଃ'), ('ଅ', 'ଌ'), ('ଏ', 'ଐ'),
+  ('ଓ', 'ନ'), ('ପ', 'ର'), ('ଲ', 'ଳ'), ('ଵ', 'ହ'),
+  ('\u{b3c}', '\u{b44}'), ('େ', 'ୈ'), ('ୋ', '\u{b4d}'),
+  ('\u{b56}', '\u{b57}'), ('ଡ଼', 'ଢ଼'), ('ୟ', '\u{b63}'), ('୦', '୯'),
+  ('ୱ', 'ୱ'), ('\u{b82}', 'ஃ'), ('அ', 'ஊ'), ('எ', 'ஐ'),
+  ('ஒ', 'க'), ('ங', 'ச'), ('ஜ', 'ஜ'), ('ஞ', 'ட'),
+  ('ண', 'த'), ('ந', 'ப'), ('ம', 'ஹ'), ('\u{bbe}', 'ூ'),
+  ('ெ', 'ை'), ('ொ', '\u{bcd}'), ('ௐ', 'ௐ'), ('\u{bd7}', '\u{bd7}'),
+  ('௦', '௯'), ('\u{c00}', 'ఌ'), ('ఎ', 'ఐ'), ('ఒ', 'న'),
+  ('ప', 'హ'), ('ఽ', 'ౄ'), ('\u{c46}', '\u{c48}'),
+  ('\u{c4a}', '\u{c4d}'), ('\u{c55}', '\u{c56}'), ('ౘ', 'ౚ'),
+  ('ౠ', '\u{c63}'), ('౦', '౯'), ('ಀ', 'ಃ'), ('ಅ', 'ಌ'),
+  ('ಎ', 'ಐ'), ('ಒ', 'ನ'), ('ಪ', 'ಳ'), ('ವ', 'ಹ'),
+  ('\u{cbc}', 'ೄ'), ('\u{cc6}', 'ೈ'), ('ೊ', '\u{ccd}'),
+  ('\u{cd5}', '\u{cd6}'), ('ೞ', 'ೞ'), ('ೠ', '\u{ce3}'), ('೦', '೯'),
+  ('ೱ', 'ೲ'), ('\u{d00}', 'ഃ'), ('അ', 'ഌ'), ('എ', 'ഐ'),
+  ('ഒ', '\u{d44}'), ('െ', 'ൈ'), ('ൊ', 'ൎ'), ('ൔ', '\u{d57}'),
+  ('ൟ', '\u{d63}'), ('൦', '൯'), ('ൺ', 'ൿ'), ('ං', 'ඃ'),
+  ('අ', 'ඖ'), ('ක', 'න'), ('ඳ', 'ර'), ('ල', 'ල'),
+  ('ව', 'ෆ'), ('\u{dca}', '\u{dca}'), ('\u{dcf}', '\u{dd4}'),
+  ('\u{dd6}', '\u{dd6}'), ('ෘ', '\u{ddf}'), ('෦', '෯'), ('ෲ', 'ෳ'),
+  ('ก', '\u{e3a}'), ('เ', '\u{e4e}'), ('๐', '๙'), ('ກ', 'ຂ'),
+  ('ຄ', 'ຄ'), ('\u{e86}', 'ຊ'), ('\u{e8c}', 'ຣ'), ('ລ', 'ລ'),
+  ('ວ', 'ຽ'), ('ເ', 'ໄ'), ('ໆ', 'ໆ'), ('\u{ec8}', '\u{ecd}'),
+  ('໐', '໙'), ('ໜ', 'ໟ'), ('ༀ', 'ༀ'), ('\u{f18}', '\u{f19}'),
+  ('༠', '༩'), ('\u{f35}', '\u{f35}'), ('\u{f37}', '\u{f37}'),
+  ('\u{f39}', '\u{f39}'), ('༾', 'ཇ'), ('ཉ', 'ཬ'),
+  ('\u{f71}', '\u{f84}'), ('\u{f86}', '\u{f97}'), ('\u{f99}', '\u{fbc}'),
+  ('\u{fc6}', '\u{fc6}'), ('က', '၉'), ('ၐ', '\u{109d}'), ('Ⴀ', 'Ⴥ'),
+  ('Ⴧ', 'Ⴧ'), ('Ⴭ', 'Ⴭ'), ('ა', 'ჺ'), ('ჼ', 'ቈ'),
+  ('ቊ', 'ቍ'), ('ቐ', 'ቖ'), ('ቘ', 'ቘ'), ('ቚ', 'ቝ'),
+  ('በ', 'ኈ'), ('ኊ', 'ኍ'), ('ነ', 'ኰ'), ('ኲ', 'ኵ'),
+  ('ኸ', 'ኾ'), ('ዀ', 'ዀ'), ('ዂ', 'ዅ'), ('ወ', 'ዖ'),
+  ('ዘ', 'ጐ'), ('ጒ', 'ጕ'), ('ጘ', 'ፚ'), ('\u{135d}', '\u{135f}'),
+  ('፩', '፱'), ('ᎀ', 'ᎏ'), ('Ꭰ', 'Ᏽ'), ('ᏸ', 'ᏽ'),
+  ('ᐁ', 'ᙬ'), ('ᙯ', 'ᙿ'), ('ᚁ', 'ᚚ'), ('ᚠ', 'ᛪ'),
+  ('ᛮ', 'ᛸ'), ('ᜀ', 'ᜌ'), ('ᜎ', '\u{1714}'), ('ᜠ', '\u{1734}'),
+  ('ᝀ', '\u{1753}'), ('ᝠ', 'ᝬ'), ('ᝮ', 'ᝰ'),
+  ('\u{1772}', '\u{1773}'), ('ក', '\u{17d3}'), ('ៗ', 'ៗ'),
+  ('ៜ', '\u{17dd}'), ('០', '៩'), ('\u{180b}', '\u{180d}'),
+  ('᠐', '᠙'), ('ᠠ', 'ᡸ'), ('ᢀ', 'ᢪ'), ('ᢰ', 'ᣵ'),
+  ('ᤀ', 'ᤞ'), ('\u{1920}', 'ᤫ'), ('ᤰ', '\u{193b}'), ('᥆', 'ᥭ'),
+  ('ᥰ', 'ᥴ'), ('ᦀ', 'ᦫ'), ('ᦰ', 'ᧉ'), ('᧐', '᧚'),
+  ('ᨀ', '\u{1a1b}'), ('ᨠ', '\u{1a5e}'), ('\u{1a60}', '\u{1a7c}'),
+  ('\u{1a7f}', '᪉'), ('᪐', '᪙'), ('ᪧ', 'ᪧ'),
+  ('\u{1ab0}', '\u{1abd}'), ('\u{1b00}', 'ᭋ'), ('᭐', '᭙'),
+  ('\u{1b6b}', '\u{1b73}'), ('\u{1b80}', '᯳'), ('ᰀ', '\u{1c37}'),
+  ('᱀', '᱉'), ('ᱍ', 'ᱽ'), ('ᲀ', 'ᲈ'), ('Ა', 'Ჺ'),
+  ('Ჽ', 'Ჿ'), ('\u{1cd0}', '\u{1cd2}'), ('\u{1cd4}', '\u{1cfa}'),
+  ('ᴀ', '\u{1df9}'), ('\u{1dfb}', 'ἕ'), ('Ἐ', 'Ἕ'), ('ἠ', 'ὅ'),
+  ('Ὀ', 'Ὅ'), ('ὐ', 'ὗ'), ('Ὑ', 'Ὑ'), ('Ὓ', 'Ὓ'),
+  ('Ὕ', 'Ὕ'), ('Ὗ', 'ώ'), ('ᾀ', 'ᾴ'), ('ᾶ', 'ᾼ'),
+  ('ι', 'ι'), ('ῂ', 'ῄ'), ('ῆ', 'ῌ'), ('ῐ', 'ΐ'),
+  ('ῖ', 'Ί'), ('ῠ', 'Ῥ'), ('ῲ', 'ῴ'), ('ῶ', 'ῼ'),
+  ('‿', '⁀'), ('⁔', '⁔'), ('ⁱ', 'ⁱ'), ('ⁿ', 'ⁿ'),
+  ('ₐ', 'ₜ'), ('\u{20d0}', '\u{20dc}'), ('\u{20e1}', '\u{20e1}'),
+  ('\u{20e5}', '\u{20f0}'), ('ℂ', 'ℂ'), ('ℇ', 'ℇ'), ('ℊ', 'ℓ'),
+  ('ℕ', 'ℕ'), ('℘', 'ℝ'), ('ℤ', 'ℤ'), ('Ω', 'Ω'),
+  ('ℨ', 'ℨ'), ('K', 'ℹ'), ('ℼ', 'ℿ'), ('ⅅ', 'ⅉ'),
+  ('ⅎ', 'ⅎ'), ('Ⅰ', 'ↈ'), ('Ⰰ', 'Ⱞ'), ('ⰰ', 'ⱞ'),
+  ('Ⱡ', 'ⳤ'), ('Ⳬ', 'ⳳ'), ('ⴀ', 'ⴥ'), ('ⴧ', 'ⴧ'),
+  ('ⴭ', 'ⴭ'), ('ⴰ', 'ⵧ'), ('ⵯ', 'ⵯ'), ('\u{2d7f}', 'ⶖ'),
+  ('ⶠ', 'ⶦ'), ('ⶨ', 'ⶮ'), ('ⶰ', 'ⶶ'), ('ⶸ', 'ⶾ'),
+  ('ⷀ', 'ⷆ'), ('ⷈ', 'ⷎ'), ('ⷐ', 'ⷖ'), ('ⷘ', 'ⷞ'),
+  ('\u{2de0}', '\u{2dff}'), ('々', '〇'), ('〡', '\u{302f}'),
+  ('〱', '〵'), ('〸', '〼'), ('ぁ', 'ゖ'), ('\u{3099}', 'ゟ'),
+  ('ァ', 'ヺ'), ('ー', 'ヿ'), ('ㄅ', 'ㄯ'), ('ㄱ', 'ㆎ'),
+  ('ㆠ', 'ㆺ'), ('ㇰ', 'ㇿ'), ('㐀', '䶵'), ('一', '鿯'),
+  ('ꀀ', 'ꒌ'), ('ꓐ', 'ꓽ'), ('ꔀ', 'ꘌ'), ('ꘐ', 'ꘫ'),
+  ('Ꙁ', '\u{a66f}'), ('\u{a674}', '\u{a67d}'), ('ꙿ', '\u{a6f1}'),
+  ('ꜗ', 'ꜟ'), ('Ꜣ', 'ꞈ'), ('Ꞌ', '\u{a7bf}'),
+  ('\u{a7c2}', '\u{a7c6}'), ('ꟷ', 'ꠧ'), ('ꡀ', 'ꡳ'),
+  ('ꢀ', '\u{a8c5}'), ('꣐', '꣙'), ('\u{a8e0}', 'ꣷ'), ('ꣻ', 'ꣻ'),
+  ('ꣽ', '\u{a92d}'), ('ꤰ', '꥓'), ('ꥠ', 'ꥼ'), ('\u{a980}', '꧀'),
+  ('ꧏ', '꧙'), ('ꧠ', 'ꧾ'), ('ꨀ', '\u{aa36}'), ('ꩀ', 'ꩍ'),
+  ('꩐', '꩙'), ('ꩠ', 'ꩶ'), ('ꩺ', 'ꫂ'), ('ꫛ', 'ꫝ'),
+  ('ꫠ', 'ꫯ'), ('ꫲ', '\u{aaf6}'), ('ꬁ', 'ꬆ'), ('ꬉ', 'ꬎ'),
+  ('ꬑ', 'ꬖ'), ('ꬠ', 'ꬦ'), ('ꬨ', 'ꬮ'), ('ꬰ', 'ꭚ'),
+  ('ꭜ', '\u{ab67}'), ('ꭰ', 'ꯪ'), ('꯬', '\u{abed}'), ('꯰', '꯹'),
+  ('가', '힣'), ('ힰ', 'ퟆ'), ('ퟋ', 'ퟻ'), ('豈', '舘'),
+  ('並', '龎'), ('ff', 'st'), ('ﬓ', 'ﬗ'), ('יִ', 'ﬨ'),
+  ('שׁ', 'זּ'), ('טּ', 'לּ'), ('מּ', 'מּ'), ('נּ', 'סּ'),
+  ('ףּ', 'פּ'), ('צּ', 'ﮱ'), ('ﯓ', 'ﴽ'), ('ﵐ', 'ﶏ'),
+  ('ﶒ', 'ﷇ'), ('ﷰ', 'ﷻ'), ('\u{fe00}', '\u{fe0f}'),
+  ('\u{fe20}', '\u{fe2f}'), ('︳', '︴'), ('﹍', '﹏'), ('ﹰ', 'ﹴ'),
+  ('ﹶ', 'ﻼ'), ('0', '9'), ('A', 'Z'), ('_', '_'),
+  ('a', 'z'), ('ヲ', 'ᄒ'), ('ᅡ', 'ᅦ'), ('ᅧ', 'ᅬ'),
+  ('ᅭ', 'ᅲ'), ('ᅳ', 'ᅵ'), ('𐀀', '𐀋'), ('𐀍', '𐀦'),
+  ('𐀨', '𐀺'), ('𐀼', '𐀽'), ('𐀿', '𐁍'), ('𐁐', '𐁝'),
+  ('𐂀', '𐃺'), ('𐅀', '𐅴'), ('\u{101fd}', '\u{101fd}'),
+  ('𐊀', '𐊜'), ('𐊠', '𐋐'), ('\u{102e0}', '\u{102e0}'),
+  ('𐌀', '𐌟'), ('𐌭', '𐍊'), ('𐍐', '\u{1037a}'), ('𐎀', '𐎝'),
+  ('𐎠', '𐏃'), ('𐏈', '𐏏'), ('𐏑', '𐏕'), ('𐐀', '𐒝'),
+  ('𐒠', '𐒩'), ('𐒰', '𐓓'), ('𐓘', '𐓻'), ('𐔀', '𐔧'),
+  ('𐔰', '𐕣'), ('𐘀', '𐜶'), ('𐝀', '𐝕'), ('𐝠', '𐝧'),
+  ('𐠀', '𐠅'), ('𐠈', '𐠈'), ('𐠊', '𐠵'), ('𐠷', '𐠸'),
+  ('𐠼', '𐠼'), ('𐠿', '𐡕'), ('𐡠', '𐡶'), ('𐢀', '𐢞'),
+  ('𐣠', '𐣲'), ('𐣴', '𐣵'), ('𐤀', '𐤕'), ('𐤠', '𐤹'),
+  ('𐦀', '𐦷'), ('𐦾', '𐦿'), ('𐨀', '\u{10a03}'),
+  ('\u{10a05}', '\u{10a06}'), ('\u{10a0c}', '𐨓'), ('𐨕', '𐨗'),
+  ('𐨙', '𐨵'), ('\u{10a38}', '\u{10a3a}'), ('\u{10a3f}', '\u{10a3f}'),
+  ('𐩠', '𐩼'), ('𐪀', '𐪜'), ('𐫀', '𐫇'), ('𐫉', '\u{10ae6}'),
+  ('𐬀', '𐬵'), ('𐭀', '𐭕'), ('𐭠', '𐭲'), ('𐮀', '𐮑'),
+  ('𐰀', '𐱈'), ('𐲀', '𐲲'), ('𐳀', '𐳲'), ('𐴀', '\u{10d27}'),
+  ('𐴰', '𐴹'), ('𐼀', '𐼜'), ('𐼧', '𐼧'), ('𐼰', '\u{10f50}'),
+  ('\u{10fe0}', '\u{10ff6}'), ('𑀀', '\u{11046}'), ('𑁦', '𑁯'),
+  ('\u{1107f}', '\u{110ba}'), ('𑃐', '𑃨'), ('𑃰', '𑃹'),
+  ('\u{11100}', '\u{11134}'), ('𑄶', '𑄿'), ('𑅄', '𑅆'),
+  ('𑅐', '\u{11173}'), ('𑅶', '𑅶'), ('\u{11180}', '𑇄'),
+  ('\u{111c9}', '\u{111cc}'), ('𑇐', '𑇚'), ('𑇜', '𑇜'),
+  ('𑈀', '𑈑'), ('𑈓', '\u{11237}'), ('\u{1123e}', '\u{1123e}'),
+  ('𑊀', '𑊆'), ('𑊈', '𑊈'), ('𑊊', '𑊍'), ('𑊏', '𑊝'),
+  ('𑊟', '𑊨'), ('𑊰', '\u{112ea}'), ('𑋰', '𑋹'),
+  ('\u{11300}', '𑌃'), ('𑌅', '𑌌'), ('𑌏', '𑌐'), ('𑌓', '𑌨'),
+  ('𑌪', '𑌰'), ('𑌲', '𑌳'), ('𑌵', '𑌹'), ('\u{1133b}', '𑍄'),
+  ('𑍇', '𑍈'), ('𑍋', '𑍍'), ('𑍐', '𑍐'),
+  ('\u{11357}', '\u{11357}'), ('𑍝', '𑍣'), ('\u{11366}', '\u{1136c}'),
+  ('\u{11370}', '\u{11374}'), ('𑐀', '𑑊'), ('𑑐', '𑑙'),
+  ('\u{1145e}', '\u{1145f}'), ('𑒀', '𑓅'), ('𑓇', '𑓇'),
+  ('𑓐', '𑓙'), ('𑖀', '\u{115b5}'), ('𑖸', '\u{115c0}'),
+  ('𑗘', '\u{115dd}'), ('𑘀', '\u{11640}'), ('𑙄', '𑙄'),
+  ('𑙐', '𑙙'), ('𑚀', '\u{116b8}'), ('𑛀', '𑛉'), ('𑜀', '𑜚'),
+  ('\u{1171d}', '\u{1172b}'), ('𑜰', '𑜹'), ('𑠀', '\u{1183a}'),
+  ('𑢠', '𑣩'), ('𑣿', '𑣿'), ('\u{119a0}', '\u{119a7}'),
+  ('\u{119aa}', '\u{119d7}'), ('\u{119da}', '\u{119e1}'),
+  ('\u{119e3}', '\u{119e4}'), ('𑨀', '\u{11a3e}'),
+  ('\u{11a47}', '\u{11a47}'), ('𑩐', '\u{11a99}'), ('𑪝', '𑪝'),
+  ('𑫀', '𑫸'), ('𑰀', '𑰈'), ('𑰊', '\u{11c36}'),
+  ('\u{11c38}', '𑱀'), ('𑱐', '𑱙'), ('𑱲', '𑲏'),
+  ('\u{11c92}', '\u{11ca7}'), ('𑲩', '\u{11cb6}'), ('𑴀', '𑴆'),
+  ('𑴈', '𑴉'), ('𑴋', '\u{11d36}'), ('\u{11d3a}', '\u{11d3a}'),
+  ('\u{11d3c}', '\u{11d3d}'), ('\u{11d3f}', '\u{11d47}'), ('𑵐', '𑵙'),
+  ('𑵠', '𑵥'), ('𑵧', '𑵨'), ('𑵪', '𑶎'),
+  ('\u{11d90}', '\u{11d91}'), ('𑶓', '𑶘'), ('𑶠', '𑶩'),
+  ('𑻠', '𑻶'), ('𒀀', '𒎙'), ('𒐀', '𒑮'), ('𒒀', '𒕃'),
+  ('𓀀', '𓐮'), ('𔐀', '𔙆'), ('𖠀', '𖨸'), ('𖩀', '𖩞'),
+  ('𖩠', '𖩩'), ('𖫐', '𖫭'), ('\u{16af0}', '\u{16af4}'),
+  ('𖬀', '\u{16b36}'), ('𖭀', '𖭃'), ('𖭐', '𖭙'), ('𖭣', '𖭷'),
+  ('𖭽', '𖮏'), ('𖹀', '𖹿'), ('𖼀', '\u{16f4a}'),
+  ('\u{16f4f}', '\u{16f87}'), ('\u{16f8f}', '𖾟'), ('𖿠', '𖿡'),
+  ('\u{16fe3}', '\u{16fe3}'), ('𗀀', '\u{187f7}'), ('𘠀', '𘫲'),
+  ('𛀀', '𛄞'), ('\u{1b150}', '\u{1b152}'), ('\u{1b164}', '\u{1b167}'),
+  ('𛅰', '𛋻'), ('𛰀', '𛱪'), ('𛱰', '𛱼'), ('𛲀', '𛲈'),
+  ('𛲐', '𛲙'), ('\u{1bc9d}', '\u{1bc9e}'), ('\u{1d165}', '\u{1d169}'),
+  ('𝅭', '\u{1d172}'), ('\u{1d17b}', '\u{1d182}'),
+  ('\u{1d185}', '\u{1d18b}'), ('\u{1d1aa}', '\u{1d1ad}'),
+  ('\u{1d242}', '\u{1d244}'), ('𝐀', '𝑔'), ('𝑖', '𝒜'),
+  ('𝒞', '𝒟'), ('𝒢', '𝒢'), ('𝒥', '𝒦'), ('𝒩', '𝒬'),
+  ('𝒮', '𝒹'), ('𝒻', '𝒻'), ('𝒽', '𝓃'), ('𝓅', '𝔅'),
+  ('𝔇', '𝔊'), ('𝔍', '𝔔'), ('𝔖', '𝔜'), ('𝔞', '𝔹'),
+  ('𝔻', '𝔾'), ('𝕀', '𝕄'), ('𝕆', '𝕆'), ('𝕊', '𝕐'),
+  ('𝕒', '𝚥'), ('𝚨', '𝛀'), ('𝛂', '𝛚'), ('𝛜', '𝛺'),
+  ('𝛼', '𝜔'), ('𝜖', '𝜴'), ('𝜶', '𝝎'), ('𝝐', '𝝮'),
+  ('𝝰', '𝞈'), ('𝞊', '𝞨'), ('𝞪', '𝟂'), ('𝟄', '𝟋'),
+  ('𝟎', '𝟿'), ('\u{1da00}', '\u{1da36}'), ('\u{1da3b}', '\u{1da6c}'),
+  ('\u{1da75}', '\u{1da75}'), ('\u{1da84}', '\u{1da84}'),
+  ('\u{1da9b}', '\u{1da9f}'), ('\u{1daa1}', '\u{1daaf}'),
+  ('\u{1e000}', '\u{1e006}'), ('\u{1e008}', '\u{1e018}'),
+  ('\u{1e01b}', '\u{1e021}'), ('\u{1e023}', '\u{1e024}'),
+  ('\u{1e026}', '\u{1e02a}'), ('\u{1e100}', '\u{1e12c}'),
+  ('\u{1e130}', '\u{1e13d}'), ('\u{1e140}', '\u{1e149}'),
+  ('\u{1e14e}', '\u{1e14e}'), ('\u{1e2c0}', '\u{1e2f9}'), ('𞠀', '𞣄'),
+  ('\u{1e8d0}', '\u{1e8d6}'), ('𞤀', '\u{1e94b}'), ('𞥐', '𞥙'),
+  ('𞸀', '𞸃'), ('𞸅', '𞸟'), ('𞸡', '𞸢'), ('𞸤', '𞸤'),
+  ('𞸧', '𞸧'), ('𞸩', '𞸲'), ('𞸴', '𞸷'), ('𞸹', '𞸹'),
+  ('𞸻', '𞸻'), ('𞹂', '𞹂'), ('𞹇', '𞹇'), ('𞹉', '𞹉'),
+  ('𞹋', '𞹋'), ('𞹍', '𞹏'), ('𞹑', '𞹒'), ('𞹔', '𞹔'),
+  ('𞹗', '𞹗'), ('𞹙', '𞹙'), ('𞹛', '𞹛'), ('𞹝', '𞹝'),
+  ('𞹟', '𞹟'), ('𞹡', '𞹢'), ('𞹤', '𞹤'), ('𞹧', '𞹪'),
+  ('𞹬', '𞹲'), ('𞹴', '𞹷'), ('𞹹', '𞹼'), ('𞹾', '𞹾'),
+  ('𞺀', '𞺉'), ('𞺋', '𞺛'), ('𞺡', '𞺣'), ('𞺥', '𞺩'),
+  ('𞺫', '𞺻'), ('𠀀', '𪛖'), ('𪜀', '𫜴'), ('𫝀', '𫠝'),
+  ('𫠠', '𬺡'), ('𬺰', '𮯠'), ('丽', '𪘀'),
+  ('\u{e0100}', '\u{e01ef}'),
+];
+
+pub const ID_START: &'static [(char, char)] = &[
+  ('A', 'Z'), ('a', 'z'), ('ª', 'ª'), ('µ', 'µ'), ('º', 'º'),
+  ('À', 'Ö'), ('Ø', 'ö'), ('ø', 'ˁ'), ('ˆ', 'ˑ'), ('ˠ', 'ˤ'),
+  ('ˬ', 'ˬ'), ('ˮ', 'ˮ'), ('Ͱ', 'ʹ'), ('Ͷ', 'ͷ'), ('ͺ', 'ͽ'),
+  ('Ϳ', 'Ϳ'), ('Ά', 'Ά'), ('Έ', 'Ί'), ('Ό', 'Ό'), ('Ύ', 'Ρ'),
+  ('Σ', 'ϵ'), ('Ϸ', 'ҁ'), ('Ҋ', 'ԯ'), ('Ա', 'Ֆ'), ('ՙ', 'ՙ'),
+  ('ՠ', 'ֈ'), ('א', 'ת'), ('ׯ', 'ײ'), ('ؠ', 'ي'), ('ٮ', 'ٯ'),
+  ('ٱ', 'ۓ'), ('ە', 'ە'), ('ۥ', 'ۦ'), ('ۮ', 'ۯ'), ('ۺ', 'ۼ'),
+  ('ۿ', 'ۿ'), ('ܐ', 'ܐ'), ('ܒ', 'ܯ'), ('ݍ', 'ޥ'), ('ޱ', 'ޱ'),
+  ('ߊ', 'ߪ'), ('ߴ', 'ߵ'), ('ߺ', 'ߺ'), ('ࠀ', 'ࠕ'), ('ࠚ', 'ࠚ'),
+  ('ࠤ', 'ࠤ'), ('ࠨ', 'ࠨ'), ('ࡀ', 'ࡘ'), ('ࡠ', 'ࡪ'),
+  ('ࢠ', 'ࢴ'), ('ࢶ', 'ࢽ'), ('ऄ', 'ह'), ('ऽ', 'ऽ'),
+  ('ॐ', 'ॐ'), ('क़', 'ॡ'), ('ॱ', 'ঀ'), ('অ', 'ঌ'),
+  ('এ', 'ঐ'), ('ও', 'ন'), ('প', 'র'), ('ল', 'ল'),
+  ('শ', 'হ'), ('ঽ', 'ঽ'), ('ৎ', 'ৎ'), ('ড়', 'ঢ়'),
+  ('য়', 'ৡ'), ('ৰ', 'ৱ'), ('ৼ', 'ৼ'), ('ਅ', 'ਊ'),
+  ('ਏ', 'ਐ'), ('ਓ', 'ਨ'), ('ਪ', 'ਰ'), ('ਲ', 'ਲ਼'),
+  ('ਵ', 'ਸ਼'), ('ਸ', 'ਹ'), ('ਖ਼', 'ੜ'), ('ਫ਼', 'ਫ਼'),
+  ('ੲ', 'ੴ'), ('અ', 'ઍ'), ('એ', 'ઑ'), ('ઓ', 'ન'),
+  ('પ', 'ર'), ('લ', 'ળ'), ('વ', 'હ'), ('ઽ', 'ઽ'),
+  ('ૐ', 'ૐ'), ('ૠ', 'ૡ'), ('ૹ', 'ૹ'), ('ଅ', 'ଌ'),
+  ('ଏ', 'ଐ'), ('ଓ', 'ନ'), ('ପ', 'ର'), ('ଲ', 'ଳ'),
+  ('ଵ', 'ହ'), ('ଽ', 'ଽ'), ('ଡ଼', 'ଢ଼'), ('ୟ', 'ୡ'),
+  ('ୱ', 'ୱ'), ('ஃ', 'ஃ'), ('அ', 'ஊ'), ('எ', 'ஐ'),
+  ('ஒ', 'க'), ('ங', 'ச'), ('ஜ', 'ஜ'), ('ஞ', 'ட'),
+  ('ண', 'த'), ('ந', 'ப'), ('ம', 'ஹ'), ('ௐ', 'ௐ'),
+  ('అ', 'ఌ'), ('ఎ', 'ఐ'), ('ఒ', 'న'), ('ప', 'హ'),
+  ('ఽ', 'ఽ'), ('ౘ', 'ౚ'), ('ౠ', 'ౡ'), ('ಀ', 'ಀ'),
+  ('ಅ', 'ಌ'), ('ಎ', 'ಐ'), ('ಒ', 'ನ'), ('ಪ', 'ಳ'),
+  ('ವ', 'ಹ'), ('ಽ', 'ಽ'), ('ೞ', 'ೞ'), ('ೠ', 'ೡ'),
+  ('ೱ', 'ೲ'), ('അ', 'ഌ'), ('എ', 'ഐ'), ('ഒ', 'ഺ'),
+  ('ഽ', 'ഽ'), ('ൎ', 'ൎ'), ('ൔ', 'ൖ'), ('ൟ', 'ൡ'),
+  ('ൺ', 'ൿ'), ('අ', 'ඖ'), ('ක', 'න'), ('ඳ', 'ර'),
+  ('ල', 'ල'), ('ව', 'ෆ'), ('ก', 'ะ'), ('า', 'ำ'),
+  ('เ', 'ๆ'), ('ກ', 'ຂ'), ('ຄ', 'ຄ'), ('\u{e86}', 'ຊ'),
+  ('\u{e8c}', 'ຣ'), ('ລ', 'ລ'), ('ວ', 'ະ'), ('າ', 'ຳ'),
+  ('ຽ', 'ຽ'), ('ເ', 'ໄ'), ('ໆ', 'ໆ'), ('ໜ', 'ໟ'),
+  ('ༀ', 'ༀ'), ('ཀ', 'ཇ'), ('ཉ', 'ཬ'), ('ྈ', 'ྌ'),
+  ('က', 'ဪ'), ('ဿ', 'ဿ'), ('ၐ', 'ၕ'), ('ၚ', 'ၝ'),
+  ('ၡ', 'ၡ'), ('ၥ', 'ၦ'), ('ၮ', 'ၰ'), ('ၵ', 'ႁ'),
+  ('ႎ', 'ႎ'), ('Ⴀ', 'Ⴥ'), ('Ⴧ', 'Ⴧ'), ('Ⴭ', 'Ⴭ'),
+  ('ა', 'ჺ'), ('ჼ', 'ቈ'), ('ቊ', 'ቍ'), ('ቐ', 'ቖ'),
+  ('ቘ', 'ቘ'), ('ቚ', 'ቝ'), ('በ', 'ኈ'), ('ኊ', 'ኍ'),
+  ('ነ', 'ኰ'), ('ኲ', 'ኵ'), ('ኸ', 'ኾ'), ('ዀ', 'ዀ'),
+  ('ዂ', 'ዅ'), ('ወ', 'ዖ'), ('ዘ', 'ጐ'), ('ጒ', 'ጕ'),
+  ('ጘ', 'ፚ'), ('ᎀ', 'ᎏ'), ('Ꭰ', 'Ᏽ'), ('ᏸ', 'ᏽ'),
+  ('ᐁ', 'ᙬ'), ('ᙯ', 'ᙿ'), ('ᚁ', 'ᚚ'), ('ᚠ', 'ᛪ'),
+  ('ᛮ', 'ᛸ'), ('ᜀ', 'ᜌ'), ('ᜎ', 'ᜑ'), ('ᜠ', 'ᜱ'),
+  ('ᝀ', 'ᝑ'), ('ᝠ', 'ᝬ'), ('ᝮ', 'ᝰ'), ('ក', 'ឳ'),
+  ('ៗ', 'ៗ'), ('ៜ', 'ៜ'), ('ᠠ', 'ᡸ'), ('ᢀ', 'ᢨ'),
+  ('ᢪ', 'ᢪ'), ('ᢰ', 'ᣵ'), ('ᤀ', 'ᤞ'), ('ᥐ', 'ᥭ'),
+  ('ᥰ', 'ᥴ'), ('ᦀ', 'ᦫ'), ('ᦰ', 'ᧉ'), ('ᨀ', 'ᨖ'),
+  ('ᨠ', 'ᩔ'), ('ᪧ', 'ᪧ'), ('ᬅ', 'ᬳ'), ('ᭅ', 'ᭋ'),
+  ('ᮃ', 'ᮠ'), ('ᮮ', 'ᮯ'), ('ᮺ', 'ᯥ'), ('ᰀ', 'ᰣ'),
+  ('ᱍ', 'ᱏ'), ('ᱚ', 'ᱽ'), ('ᲀ', 'ᲈ'), ('Ა', 'Ჺ'),
+  ('Ჽ', 'Ჿ'), ('ᳩ', 'ᳬ'), ('ᳮ', 'ᳳ'), ('ᳵ', 'ᳶ'),
+  ('\u{1cfa}', '\u{1cfa}'), ('ᴀ', 'ᶿ'), ('Ḁ', 'ἕ'), ('Ἐ', 'Ἕ'),
+  ('ἠ', 'ὅ'), ('Ὀ', 'Ὅ'), ('ὐ', 'ὗ'), ('Ὑ', 'Ὑ'),
+  ('Ὓ', 'Ὓ'), ('Ὕ', 'Ὕ'), ('Ὗ', 'ώ'), ('ᾀ', 'ᾴ'),
+  ('ᾶ', 'ᾼ'), ('ι', 'ι'), ('ῂ', 'ῄ'), ('ῆ', 'ῌ'),
+  ('ῐ', 'ΐ'), ('ῖ', 'Ί'), ('ῠ', 'Ῥ'), ('ῲ', 'ῴ'),
+  ('ῶ', 'ῼ'), ('ⁱ', 'ⁱ'), ('ⁿ', 'ⁿ'), ('ₐ', 'ₜ'),
+  ('ℂ', 'ℂ'), ('ℇ', 'ℇ'), ('ℊ', 'ℓ'), ('ℕ', 'ℕ'),
+  ('℘', 'ℝ'), ('ℤ', 'ℤ'), ('Ω', 'Ω'), ('ℨ', 'ℨ'),
+  ('K', 'ℹ'), ('ℼ', 'ℿ'), ('ⅅ', 'ⅉ'), ('ⅎ', 'ⅎ'),
+  ('Ⅰ', 'ↈ'), ('Ⰰ', 'Ⱞ'), ('ⰰ', 'ⱞ'), ('Ⱡ', 'ⳤ'),
+  ('Ⳬ', 'ⳮ'), ('Ⳳ', 'ⳳ'), ('ⴀ', 'ⴥ'), ('ⴧ', 'ⴧ'),
+  ('ⴭ', 'ⴭ'), ('ⴰ', 'ⵧ'), ('ⵯ', 'ⵯ'), ('ⶀ', 'ⶖ'),
+  ('ⶠ', 'ⶦ'), ('ⶨ', 'ⶮ'), ('ⶰ', 'ⶶ'), ('ⶸ', 'ⶾ'),
+  ('ⷀ', 'ⷆ'), ('ⷈ', 'ⷎ'), ('ⷐ', 'ⷖ'), ('ⷘ', 'ⷞ'),
+  ('々', '〇'), ('〡', '〩'), ('〱', '〵'), ('〸', '〼'),
+  ('ぁ', 'ゖ'), ('゛', 'ゟ'), ('ァ', 'ヺ'), ('ー', 'ヿ'),
+  ('ㄅ', 'ㄯ'), ('ㄱ', 'ㆎ'), ('ㆠ', 'ㆺ'), ('ㇰ', 'ㇿ'),
+  ('㐀', '䶵'), ('一', '鿯'), ('ꀀ', 'ꒌ'), ('ꓐ', 'ꓽ'),
+  ('ꔀ', 'ꘌ'), ('ꘐ', 'ꘟ'), ('ꘪ', 'ꘫ'), ('Ꙁ', 'ꙮ'),
+  ('ꙿ', 'ꚝ'), ('ꚠ', 'ꛯ'), ('ꜗ', 'ꜟ'), ('Ꜣ', 'ꞈ'),
+  ('Ꞌ', '\u{a7bf}'), ('\u{a7c2}', '\u{a7c6}'), ('ꟷ', 'ꠁ'),
+  ('ꠃ', 'ꠅ'), ('ꠇ', 'ꠊ'), ('ꠌ', 'ꠢ'), ('ꡀ', 'ꡳ'),
+  ('ꢂ', 'ꢳ'), ('ꣲ', 'ꣷ'), ('ꣻ', 'ꣻ'), ('ꣽ', 'ꣾ'),
+  ('ꤊ', 'ꤥ'), ('ꤰ', 'ꥆ'), ('ꥠ', 'ꥼ'), ('ꦄ', 'ꦲ'),
+  ('ꧏ', 'ꧏ'), ('ꧠ', 'ꧤ'), ('ꧦ', 'ꧯ'), ('ꧺ', 'ꧾ'),
+  ('ꨀ', 'ꨨ'), ('ꩀ', 'ꩂ'), ('ꩄ', 'ꩋ'), ('ꩠ', 'ꩶ'),
+  ('ꩺ', 'ꩺ'), ('ꩾ', 'ꪯ'), ('ꪱ', 'ꪱ'), ('ꪵ', 'ꪶ'),
+  ('ꪹ', 'ꪽ'), ('ꫀ', 'ꫀ'), ('ꫂ', 'ꫂ'), ('ꫛ', 'ꫝ'),
+  ('ꫠ', 'ꫪ'), ('ꫲ', 'ꫴ'), ('ꬁ', 'ꬆ'), ('ꬉ', 'ꬎ'),
+  ('ꬑ', 'ꬖ'), ('ꬠ', 'ꬦ'), ('ꬨ', 'ꬮ'), ('ꬰ', 'ꭚ'),
+  ('ꭜ', '\u{ab67}'), ('ꭰ', 'ꯢ'), ('가', '힣'), ('ힰ', 'ퟆ'),
+  ('ퟋ', 'ퟻ'), ('豈', '舘'), ('並', '龎'), ('ff', 'st'),
+  ('ﬓ', 'ﬗ'), ('יִ', 'יִ'), ('ײַ', 'ﬨ'), ('שׁ', 'זּ'),
+  ('טּ', 'לּ'), ('מּ', 'מּ'), ('נּ', 'סּ'), ('ףּ', 'פּ'),
+  ('צּ', 'ﮱ'), ('ﯓ', 'ﴽ'), ('ﵐ', 'ﶏ'), ('ﶒ', 'ﷇ'),
+  ('ﷰ', 'ﷻ'), ('ﹰ', 'ﹴ'), ('ﹶ', 'ﻼ'), ('A', 'Z'),
+  ('a', 'z'), ('ヲ', 'ᄒ'), ('ᅡ', 'ᅦ'), ('ᅧ', 'ᅬ'),
+  ('ᅭ', 'ᅲ'), ('ᅳ', 'ᅵ'), ('𐀀', '𐀋'), ('𐀍', '𐀦'),
+  ('𐀨', '𐀺'), ('𐀼', '𐀽'), ('𐀿', '𐁍'), ('𐁐', '𐁝'),
+  ('𐂀', '𐃺'), ('𐅀', '𐅴'), ('𐊀', '𐊜'), ('𐊠', '𐋐'),
+  ('𐌀', '𐌟'), ('𐌭', '𐍊'), ('𐍐', '𐍵'), ('𐎀', '𐎝'),
+  ('𐎠', '𐏃'), ('𐏈', '𐏏'), ('𐏑', '𐏕'), ('𐐀', '𐒝'),
+  ('𐒰', '𐓓'), ('𐓘', '𐓻'), ('𐔀', '𐔧'), ('𐔰', '𐕣'),
+  ('𐘀', '𐜶'), ('𐝀', '𐝕'), ('𐝠', '𐝧'), ('𐠀', '𐠅'),
+  ('𐠈', '𐠈'), ('𐠊', '𐠵'), ('𐠷', '𐠸'), ('𐠼', '𐠼'),
+  ('𐠿', '𐡕'), ('𐡠', '𐡶'), ('𐢀', '𐢞'), ('𐣠', '𐣲'),
+  ('𐣴', '𐣵'), ('𐤀', '𐤕'), ('𐤠', '𐤹'), ('𐦀', '𐦷'),
+  ('𐦾', '𐦿'), ('𐨀', '𐨀'), ('𐨐', '𐨓'), ('𐨕', '𐨗'),
+  ('𐨙', '𐨵'), ('𐩠', '𐩼'), ('𐪀', '𐪜'), ('𐫀', '𐫇'),
+  ('𐫉', '𐫤'), ('𐬀', '𐬵'), ('𐭀', '𐭕'), ('𐭠', '𐭲'),
+  ('𐮀', '𐮑'), ('𐰀', '𐱈'), ('𐲀', '𐲲'), ('𐳀', '𐳲'),
+  ('𐴀', '𐴣'), ('𐼀', '𐼜'), ('𐼧', '𐼧'), ('𐼰', '𐽅'),
+  ('\u{10fe0}', '\u{10ff6}'), ('𑀃', '𑀷'), ('𑂃', '𑂯'),
+  ('𑃐', '𑃨'), ('𑄃', '𑄦'), ('𑅄', '𑅄'), ('𑅐', '𑅲'),
+  ('𑅶', '𑅶'), ('𑆃', '𑆲'), ('𑇁', '𑇄'), ('𑇚', '𑇚'),
+  ('𑇜', '𑇜'), ('𑈀', '𑈑'), ('𑈓', '𑈫'), ('𑊀', '𑊆'),
+  ('𑊈', '𑊈'), ('𑊊', '𑊍'), ('𑊏', '𑊝'), ('𑊟', '𑊨'),
+  ('𑊰', '𑋞'), ('𑌅', '𑌌'), ('𑌏', '𑌐'), ('𑌓', '𑌨'),
+  ('𑌪', '𑌰'), ('𑌲', '𑌳'), ('𑌵', '𑌹'), ('𑌽', '𑌽'),
+  ('𑍐', '𑍐'), ('𑍝', '𑍡'), ('𑐀', '𑐴'), ('𑑇', '𑑊'),
+  ('\u{1145f}', '\u{1145f}'), ('𑒀', '𑒯'), ('𑓄', '𑓅'),
+  ('𑓇', '𑓇'), ('𑖀', '𑖮'), ('𑗘', '𑗛'), ('𑘀', '𑘯'),
+  ('𑙄', '𑙄'), ('𑚀', '𑚪'), ('\u{116b8}', '\u{116b8}'),
+  ('𑜀', '𑜚'), ('𑠀', '𑠫'), ('𑢠', '𑣟'), ('𑣿', '𑣿'),
+  ('\u{119a0}', '\u{119a7}'), ('\u{119aa}', '\u{119d0}'),
+  ('\u{119e1}', '\u{119e1}'), ('\u{119e3}', '\u{119e3}'), ('𑨀', '𑨀'),
+  ('𑨋', '𑨲'), ('𑨺', '𑨺'), ('𑩐', '𑩐'), ('𑩜', '𑪉'),
+  ('𑪝', '𑪝'), ('𑫀', '𑫸'), ('𑰀', '𑰈'), ('𑰊', '𑰮'),
+  ('𑱀', '𑱀'), ('𑱲', '𑲏'), ('𑴀', '𑴆'), ('𑴈', '𑴉'),
+  ('𑴋', '𑴰'), ('𑵆', '𑵆'), ('𑵠', '𑵥'), ('𑵧', '𑵨'),
+  ('𑵪', '𑶉'), ('𑶘', '𑶘'), ('𑻠', '𑻲'), ('𒀀', '𒎙'),
+  ('𒐀', '𒑮'), ('𒒀', '𒕃'), ('𓀀', '𓐮'), ('𔐀', '𔙆'),
+  ('𖠀', '𖨸'), ('𖩀', '𖩞'), ('𖫐', '𖫭'), ('𖬀', '𖬯'),
+  ('𖭀', '𖭃'), ('𖭣', '𖭷'), ('𖭽', '𖮏'), ('𖹀', '𖹿'),
+  ('𖼀', '\u{16f4a}'), ('𖽐', '𖽐'), ('𖾓', '𖾟'), ('𖿠', '𖿡'),
+  ('\u{16fe3}', '\u{16fe3}'), ('𗀀', '\u{187f7}'), ('𘠀', '𘫲'),
+  ('𛀀', '𛄞'), ('\u{1b150}', '\u{1b152}'), ('\u{1b164}', '\u{1b167}'),
+  ('𛅰', '𛋻'), ('𛰀', '𛱪'), ('𛱰', '𛱼'), ('𛲀', '𛲈'),
+  ('𛲐', '𛲙'), ('𝐀', '𝑔'), ('𝑖', '𝒜'), ('𝒞', '𝒟'),
+  ('𝒢', '𝒢'), ('𝒥', '𝒦'), ('𝒩', '𝒬'), ('𝒮', '𝒹'),
+  ('𝒻', '𝒻'), ('𝒽', '𝓃'), ('𝓅', '𝔅'), ('𝔇', '𝔊'),
+  ('𝔍', '𝔔'), ('𝔖', '𝔜'), ('𝔞', '𝔹'), ('𝔻', '𝔾'),
+  ('𝕀', '𝕄'), ('𝕆', '𝕆'), ('𝕊', '𝕐'), ('𝕒', '𝚥'),
+  ('𝚨', '𝛀'), ('𝛂', '𝛚'), ('𝛜', '𝛺'), ('𝛼', '𝜔'),
+  ('𝜖', '𝜴'), ('𝜶', '𝝎'), ('𝝐', '𝝮'), ('𝝰', '𝞈'),
+  ('𝞊', '𝞨'), ('𝞪', '𝟂'), ('𝟄', '𝟋'),
+  ('\u{1e100}', '\u{1e12c}'), ('\u{1e137}', '\u{1e13d}'),
+  ('\u{1e14e}', '\u{1e14e}'), ('\u{1e2c0}', '\u{1e2eb}'), ('𞠀', '𞣄'),
+  ('𞤀', '𞥃'), ('\u{1e94b}', '\u{1e94b}'), ('𞸀', '𞸃'),
+  ('𞸅', '𞸟'), ('𞸡', '𞸢'), ('𞸤', '𞸤'), ('𞸧', '𞸧'),
+  ('𞸩', '𞸲'), ('𞸴', '𞸷'), ('𞸹', '𞸹'), ('𞸻', '𞸻'),
+  ('𞹂', '𞹂'), ('𞹇', '𞹇'), ('𞹉', '𞹉'), ('𞹋', '𞹋'),
+  ('𞹍', '𞹏'), ('𞹑', '𞹒'), ('𞹔', '𞹔'), ('𞹗', '𞹗'),
+  ('𞹙', '𞹙'), ('𞹛', '𞹛'), ('𞹝', '𞹝'), ('𞹟', '𞹟'),
+  ('𞹡', '𞹢'), ('𞹤', '𞹤'), ('𞹧', '𞹪'), ('𞹬', '𞹲'),
+  ('𞹴', '𞹷'), ('𞹹', '𞹼'), ('𞹾', '𞹾'), ('𞺀', '𞺉'),
+  ('𞺋', '𞺛'), ('𞺡', '𞺣'), ('𞺥', '𞺩'), ('𞺫', '𞺻'),
+  ('𠀀', '𪛖'), ('𪜀', '𫜴'), ('𫝀', '𫠝'), ('𫠠', '𬺡'),
+  ('𬺰', '𮯠'), ('丽', '𪘀'),
+];
+
+pub const IDEOGRAPHIC: &'static [(char, char)] = &[
+  ('〆', '〇'), ('〡', '〩'), ('〸', '〺'), ('㐀', '䶵'),
+  ('一', '鿯'), ('豈', '舘'), ('並', '龎'), ('𗀀', '\u{187f7}'),
+  ('𘠀', '𘫲'), ('𛅰', '𛋻'), ('𠀀', '𪛖'), ('𪜀', '𫜴'),
+  ('𫝀', '𫠝'), ('𫠠', '𬺡'), ('𬺰', '𮯠'), ('丽', '𪘀'),
+];
+
+pub const JOIN_CONTROL: &'static [(char, char)] = &[
+  ('\u{200c}', '\u{200d}'),
+];
+
+pub const LOGICAL_ORDER_EXCEPTION: &'static [(char, char)] = &[
+  ('เ', 'ไ'), ('ເ', 'ໄ'), ('ᦵ', 'ᦷ'), ('ᦺ', 'ᦺ'),
+  ('ꪵ', 'ꪶ'), ('ꪹ', 'ꪹ'), ('ꪻ', 'ꪼ'),
+];
+
+pub const LOWERCASE: &'static [(char, char)] = &[
+  ('a', 'z'), ('ª', 'ª'), ('µ', 'µ'), ('º', 'º'), ('ß', 'ö'),
+  ('ø', 'ÿ'), ('ā', 'ā'), ('ă', 'ă'), ('ą', 'ą'), ('ć', 'ć'),
+  ('ĉ', 'ĉ'), ('ċ', 'ċ'), ('č', 'č'), ('ď', 'ď'), ('đ', 'đ'),
+  ('ē', 'ē'), ('ĕ', 'ĕ'), ('ė', 'ė'), ('ę', 'ę'), ('ě', 'ě'),
+  ('ĝ', 'ĝ'), ('ğ', 'ğ'), ('ġ', 'ġ'), ('ģ', 'ģ'), ('ĥ', 'ĥ'),
+  ('ħ', 'ħ'), ('ĩ', 'ĩ'), ('ī', 'ī'), ('ĭ', 'ĭ'), ('į', 'į'),
+  ('ı', 'ı'), ('ij', 'ij'), ('ĵ', 'ĵ'), ('ķ', 'ĸ'), ('ĺ', 'ĺ'),
+  ('ļ', 'ļ'), ('ľ', 'ľ'), ('ŀ', 'ŀ'), ('ł', 'ł'), ('ń', 'ń'),
+  ('ņ', 'ņ'), ('ň', 'ʼn'), ('ŋ', 'ŋ'), ('ō', 'ō'), ('ŏ', 'ŏ'),
+  ('ő', 'ő'), ('œ', 'œ'), ('ŕ', 'ŕ'), ('ŗ', 'ŗ'), ('ř', 'ř'),
+  ('ś', 'ś'), ('ŝ', 'ŝ'), ('ş', 'ş'), ('š', 'š'), ('ţ', 'ţ'),
+  ('ť', 'ť'), ('ŧ', 'ŧ'), ('ũ', 'ũ'), ('ū', 'ū'), ('ŭ', 'ŭ'),
+  ('ů', 'ů'), ('ű', 'ű'), ('ų', 'ų'), ('ŵ', 'ŵ'), ('ŷ', 'ŷ'),
+  ('ź', 'ź'), ('ż', 'ż'), ('ž', 'ƀ'), ('ƃ', 'ƃ'), ('ƅ', 'ƅ'),
+  ('ƈ', 'ƈ'), ('ƌ', 'ƍ'), ('ƒ', 'ƒ'), ('ƕ', 'ƕ'), ('ƙ', 'ƛ'),
+  ('ƞ', 'ƞ'), ('ơ', 'ơ'), ('ƣ', 'ƣ'), ('ƥ', 'ƥ'), ('ƨ', 'ƨ'),
+  ('ƪ', 'ƫ'), ('ƭ', 'ƭ'), ('ư', 'ư'), ('ƴ', 'ƴ'), ('ƶ', 'ƶ'),
+  ('ƹ', 'ƺ'), ('ƽ', 'ƿ'), ('dž', 'dž'), ('lj', 'lj'), ('nj', 'nj'),
+  ('ǎ', 'ǎ'), ('ǐ', 'ǐ'), ('ǒ', 'ǒ'), ('ǔ', 'ǔ'), ('ǖ', 'ǖ'),
+  ('ǘ', 'ǘ'), ('ǚ', 'ǚ'), ('ǜ', 'ǝ'), ('ǟ', 'ǟ'), ('ǡ', 'ǡ'),
+  ('ǣ', 'ǣ'), ('ǥ', 'ǥ'), ('ǧ', 'ǧ'), ('ǩ', 'ǩ'), ('ǫ', 'ǫ'),
+  ('ǭ', 'ǭ'), ('ǯ', 'ǰ'), ('dz', 'dz'), ('ǵ', 'ǵ'), ('ǹ', 'ǹ'),
+  ('ǻ', 'ǻ'), ('ǽ', 'ǽ'), ('ǿ', 'ǿ'), ('ȁ', 'ȁ'), ('ȃ', 'ȃ'),
+  ('ȅ', 'ȅ'), ('ȇ', 'ȇ'), ('ȉ', 'ȉ'), ('ȋ', 'ȋ'), ('ȍ', 'ȍ'),
+  ('ȏ', 'ȏ'), ('ȑ', 'ȑ'), ('ȓ', 'ȓ'), ('ȕ', 'ȕ'), ('ȗ', 'ȗ'),
+  ('ș', 'ș'), ('ț', 'ț'), ('ȝ', 'ȝ'), ('ȟ', 'ȟ'), ('ȡ', 'ȡ'),
+  ('ȣ', 'ȣ'), ('ȥ', 'ȥ'), ('ȧ', 'ȧ'), ('ȩ', 'ȩ'), ('ȫ', 'ȫ'),
+  ('ȭ', 'ȭ'), ('ȯ', 'ȯ'), ('ȱ', 'ȱ'), ('ȳ', 'ȹ'), ('ȼ', 'ȼ'),
+  ('ȿ', 'ɀ'), ('ɂ', 'ɂ'), ('ɇ', 'ɇ'), ('ɉ', 'ɉ'), ('ɋ', 'ɋ'),
+  ('ɍ', 'ɍ'), ('ɏ', 'ʓ'), ('ʕ', 'ʸ'), ('ˀ', 'ˁ'), ('ˠ', 'ˤ'),
+  ('\u{345}', '\u{345}'), ('ͱ', 'ͱ'), ('ͳ', 'ͳ'), ('ͷ', 'ͷ'),
+  ('ͺ', 'ͽ'), ('ΐ', 'ΐ'), ('ά', 'ώ'), ('ϐ', 'ϑ'), ('ϕ', 'ϗ'),
+  ('ϙ', 'ϙ'), ('ϛ', 'ϛ'), ('ϝ', 'ϝ'), ('ϟ', 'ϟ'), ('ϡ', 'ϡ'),
+  ('ϣ', 'ϣ'), ('ϥ', 'ϥ'), ('ϧ', 'ϧ'), ('ϩ', 'ϩ'), ('ϫ', 'ϫ'),
+  ('ϭ', 'ϭ'), ('ϯ', 'ϳ'), ('ϵ', 'ϵ'), ('ϸ', 'ϸ'), ('ϻ', 'ϼ'),
+  ('а', 'џ'), ('ѡ', 'ѡ'), ('ѣ', 'ѣ'), ('ѥ', 'ѥ'), ('ѧ', 'ѧ'),
+  ('ѩ', 'ѩ'), ('ѫ', 'ѫ'), ('ѭ', 'ѭ'), ('ѯ', 'ѯ'), ('ѱ', 'ѱ'),
+  ('ѳ', 'ѳ'), ('ѵ', 'ѵ'), ('ѷ', 'ѷ'), ('ѹ', 'ѹ'), ('ѻ', 'ѻ'),
+  ('ѽ', 'ѽ'), ('ѿ', 'ѿ'), ('ҁ', 'ҁ'), ('ҋ', 'ҋ'), ('ҍ', 'ҍ'),
+  ('ҏ', 'ҏ'), ('ґ', 'ґ'), ('ғ', 'ғ'), ('ҕ', 'ҕ'), ('җ', 'җ'),
+  ('ҙ', 'ҙ'), ('қ', 'қ'), ('ҝ', 'ҝ'), ('ҟ', 'ҟ'), ('ҡ', 'ҡ'),
+  ('ң', 'ң'), ('ҥ', 'ҥ'), ('ҧ', 'ҧ'), ('ҩ', 'ҩ'), ('ҫ', 'ҫ'),
+  ('ҭ', 'ҭ'), ('ү', 'ү'), ('ұ', 'ұ'), ('ҳ', 'ҳ'), ('ҵ', 'ҵ'),
+  ('ҷ', 'ҷ'), ('ҹ', 'ҹ'), ('һ', 'һ'), ('ҽ', 'ҽ'), ('ҿ', 'ҿ'),
+  ('ӂ', 'ӂ'), ('ӄ', 'ӄ'), ('ӆ', 'ӆ'), ('ӈ', 'ӈ'), ('ӊ', 'ӊ'),
+  ('ӌ', 'ӌ'), ('ӎ', 'ӏ'), ('ӑ', 'ӑ'), ('ӓ', 'ӓ'), ('ӕ', 'ӕ'),
+  ('ӗ', 'ӗ'), ('ә', 'ә'), ('ӛ', 'ӛ'), ('ӝ', 'ӝ'), ('ӟ', 'ӟ'),
+  ('ӡ', 'ӡ'), ('ӣ', 'ӣ'), ('ӥ', 'ӥ'), ('ӧ', 'ӧ'), ('ө', 'ө'),
+  ('ӫ', 'ӫ'), ('ӭ', 'ӭ'), ('ӯ', 'ӯ'), ('ӱ', 'ӱ'), ('ӳ', 'ӳ'),
+  ('ӵ', 'ӵ'), ('ӷ', 'ӷ'), ('ӹ', 'ӹ'), ('ӻ', 'ӻ'), ('ӽ', 'ӽ'),
+  ('ӿ', 'ӿ'), ('ԁ', 'ԁ'), ('ԃ', 'ԃ'), ('ԅ', 'ԅ'), ('ԇ', 'ԇ'),
+  ('ԉ', 'ԉ'), ('ԋ', 'ԋ'), ('ԍ', 'ԍ'), ('ԏ', 'ԏ'), ('ԑ', 'ԑ'),
+  ('ԓ', 'ԓ'), ('ԕ', 'ԕ'), ('ԗ', 'ԗ'), ('ԙ', 'ԙ'), ('ԛ', 'ԛ'),
+  ('ԝ', 'ԝ'), ('ԟ', 'ԟ'), ('ԡ', 'ԡ'), ('ԣ', 'ԣ'), ('ԥ', 'ԥ'),
+  ('ԧ', 'ԧ'), ('ԩ', 'ԩ'), ('ԫ', 'ԫ'), ('ԭ', 'ԭ'), ('ԯ', 'ԯ'),
+  ('ՠ', 'ֈ'), ('ა', 'ჺ'), ('ჽ', 'ჿ'), ('ᏸ', 'ᏽ'),
+  ('ᲀ', 'ᲈ'), ('ᴀ', 'ᶿ'), ('ḁ', 'ḁ'), ('ḃ', 'ḃ'),
+  ('ḅ', 'ḅ'), ('ḇ', 'ḇ'), ('ḉ', 'ḉ'), ('ḋ', 'ḋ'),
+  ('ḍ', 'ḍ'), ('ḏ', 'ḏ'), ('ḑ', 'ḑ'), ('ḓ', 'ḓ'),
+  ('ḕ', 'ḕ'), ('ḗ', 'ḗ'), ('ḙ', 'ḙ'), ('ḛ', 'ḛ'),
+  ('ḝ', 'ḝ'), ('ḟ', 'ḟ'), ('ḡ', 'ḡ'), ('ḣ', 'ḣ'),
+  ('ḥ', 'ḥ'), ('ḧ', 'ḧ'), ('ḩ', 'ḩ'), ('ḫ', 'ḫ'),
+  ('ḭ', 'ḭ'), ('ḯ', 'ḯ'), ('ḱ', 'ḱ'), ('ḳ', 'ḳ'),
+  ('ḵ', 'ḵ'), ('ḷ', 'ḷ'), ('ḹ', 'ḹ'), ('ḻ', 'ḻ'),
+  ('ḽ', 'ḽ'), ('ḿ', 'ḿ'), ('ṁ', 'ṁ'), ('ṃ', 'ṃ'),
+  ('ṅ', 'ṅ'), ('ṇ', 'ṇ'), ('ṉ', 'ṉ'), ('ṋ', 'ṋ'),
+  ('ṍ', 'ṍ'), ('ṏ', 'ṏ'), ('ṑ', 'ṑ'), ('ṓ', 'ṓ'),
+  ('ṕ', 'ṕ'), ('ṗ', 'ṗ'), ('ṙ', 'ṙ'), ('ṛ', 'ṛ'),
+  ('ṝ', 'ṝ'), ('ṟ', 'ṟ'), ('ṡ', 'ṡ'), ('ṣ', 'ṣ'),
+  ('ṥ', 'ṥ'), ('ṧ', 'ṧ'), ('ṩ', 'ṩ'), ('ṫ', 'ṫ'),
+  ('ṭ', 'ṭ'), ('ṯ', 'ṯ'), ('ṱ', 'ṱ'), ('ṳ', 'ṳ'),
+  ('ṵ', 'ṵ'), ('ṷ', 'ṷ'), ('ṹ', 'ṹ'), ('ṻ', 'ṻ'),
+  ('ṽ', 'ṽ'), ('ṿ', 'ṿ'), ('ẁ', 'ẁ'), ('ẃ', 'ẃ'),
+  ('ẅ', 'ẅ'), ('ẇ', 'ẇ'), ('ẉ', 'ẉ'), ('ẋ', 'ẋ'),
+  ('ẍ', 'ẍ'), ('ẏ', 'ẏ'), ('ẑ', 'ẑ'), ('ẓ', 'ẓ'),
+  ('ẕ', 'ẝ'), ('ẟ', 'ẟ'), ('ạ', 'ạ'), ('ả', 'ả'),
+  ('ấ', 'ấ'), ('ầ', 'ầ'), ('ẩ', 'ẩ'), ('ẫ', 'ẫ'),
+  ('ậ', 'ậ'), ('ắ', 'ắ'), ('ằ', 'ằ'), ('ẳ', 'ẳ'),
+  ('ẵ', 'ẵ'), ('ặ', 'ặ'), ('ẹ', 'ẹ'), ('ẻ', 'ẻ'),
+  ('ẽ', 'ẽ'), ('ế', 'ế'), ('ề', 'ề'), ('ể', 'ể'),
+  ('ễ', 'ễ'), ('ệ', 'ệ'), ('ỉ', 'ỉ'), ('ị', 'ị'),
+  ('ọ', 'ọ'), ('ỏ', 'ỏ'), ('ố', 'ố'), ('ồ', 'ồ'),
+  ('ổ', 'ổ'), ('ỗ', 'ỗ'), ('ộ', 'ộ'), ('ớ', 'ớ'),
+  ('ờ', 'ờ'), ('ở', 'ở'), ('ỡ', 'ỡ'), ('ợ', 'ợ'),
+  ('ụ', 'ụ'), ('ủ', 'ủ'), ('ứ', 'ứ'), ('ừ', 'ừ'),
+  ('ử', 'ử'), ('ữ', 'ữ'), ('ự', 'ự'), ('ỳ', 'ỳ'),
+  ('ỵ', 'ỵ'), ('ỷ', 'ỷ'), ('ỹ', 'ỹ'), ('ỻ', 'ỻ'),
+  ('ỽ', 'ỽ'), ('ỿ', 'ἇ'), ('ἐ', 'ἕ'), ('ἠ', 'ἧ'),
+  ('ἰ', 'ἷ'), ('ὀ', 'ὅ'), ('ὐ', 'ὗ'), ('ὠ', 'ὧ'),
+  ('ὰ', 'ώ'), ('ᾀ', 'ᾇ'), ('ᾐ', 'ᾗ'), ('ᾠ', 'ᾧ'),
+  ('ᾰ', 'ᾴ'), ('ᾶ', 'ᾷ'), ('ι', 'ι'), ('ῂ', 'ῄ'),
+  ('ῆ', 'ῇ'), ('ῐ', 'ΐ'), ('ῖ', 'ῗ'), ('ῠ', 'ῧ'),
+  ('ῲ', 'ῴ'), ('ῶ', 'ῷ'), ('ⁱ', 'ⁱ'), ('ⁿ', 'ⁿ'),
+  ('ₐ', 'ₜ'), ('ℊ', 'ℊ'), ('ℎ', 'ℏ'), ('ℓ', 'ℓ'),
+  ('ℯ', 'ℯ'), ('ℴ', 'ℴ'), ('ℹ', 'ℹ'), ('ℼ', 'ℽ'),
+  ('ⅆ', 'ⅉ'), ('ⅎ', 'ⅎ'), ('ⅰ', 'ⅿ'), ('ↄ', 'ↄ'),
+  ('ⓐ', 'ⓩ'), ('ⰰ', 'ⱞ'), ('ⱡ', 'ⱡ'), ('ⱥ', 'ⱦ'),
+  ('ⱨ', 'ⱨ'), ('ⱪ', 'ⱪ'), ('ⱬ', 'ⱬ'), ('ⱱ', 'ⱱ'),
+  ('ⱳ', 'ⱴ'), ('ⱶ', 'ⱽ'), ('ⲁ', 'ⲁ'), ('ⲃ', 'ⲃ'),
+  ('ⲅ', 'ⲅ'), ('ⲇ', 'ⲇ'), ('ⲉ', 'ⲉ'), ('ⲋ', 'ⲋ'),
+  ('ⲍ', 'ⲍ'), ('ⲏ', 'ⲏ'), ('ⲑ', 'ⲑ'), ('ⲓ', 'ⲓ'),
+  ('ⲕ', 'ⲕ'), ('ⲗ', 'ⲗ'), ('ⲙ', 'ⲙ'), ('ⲛ', 'ⲛ'),
+  ('ⲝ', 'ⲝ'), ('ⲟ', 'ⲟ'), ('ⲡ', 'ⲡ'), ('ⲣ', 'ⲣ'),
+  ('ⲥ', 'ⲥ'), ('ⲧ', 'ⲧ'), ('ⲩ', 'ⲩ'), ('ⲫ', 'ⲫ'),
+  ('ⲭ', 'ⲭ'), ('ⲯ', 'ⲯ'), ('ⲱ', 'ⲱ'), ('ⲳ', 'ⲳ'),
+  ('ⲵ', 'ⲵ'), ('ⲷ', 'ⲷ'), ('ⲹ', 'ⲹ'), ('ⲻ', 'ⲻ'),
+  ('ⲽ', 'ⲽ'), ('ⲿ', 'ⲿ'), ('ⳁ', 'ⳁ'), ('ⳃ', 'ⳃ'),
+  ('ⳅ', 'ⳅ'), ('ⳇ', 'ⳇ'), ('ⳉ', 'ⳉ'), ('ⳋ', 'ⳋ'),
+  ('ⳍ', 'ⳍ'), ('ⳏ', 'ⳏ'), ('ⳑ', 'ⳑ'), ('ⳓ', 'ⳓ'),
+  ('ⳕ', 'ⳕ'), ('ⳗ', 'ⳗ'), ('ⳙ', 'ⳙ'), ('ⳛ', 'ⳛ'),
+  ('ⳝ', 'ⳝ'), ('ⳟ', 'ⳟ'), ('ⳡ', 'ⳡ'), ('ⳣ', 'ⳤ'),
+  ('ⳬ', 'ⳬ'), ('ⳮ', 'ⳮ'), ('ⳳ', 'ⳳ'), ('ⴀ', 'ⴥ'),
+  ('ⴧ', 'ⴧ'), ('ⴭ', 'ⴭ'), ('ꙁ', 'ꙁ'), ('ꙃ', 'ꙃ'),
+  ('ꙅ', 'ꙅ'), ('ꙇ', 'ꙇ'), ('ꙉ', 'ꙉ'), ('ꙋ', 'ꙋ'),
+  ('ꙍ', 'ꙍ'), ('ꙏ', 'ꙏ'), ('ꙑ', 'ꙑ'), ('ꙓ', 'ꙓ'),
+  ('ꙕ', 'ꙕ'), ('ꙗ', 'ꙗ'), ('ꙙ', 'ꙙ'), ('ꙛ', 'ꙛ'),
+  ('ꙝ', 'ꙝ'), ('ꙟ', 'ꙟ'), ('ꙡ', 'ꙡ'), ('ꙣ', 'ꙣ'),
+  ('ꙥ', 'ꙥ'), ('ꙧ', 'ꙧ'), ('ꙩ', 'ꙩ'), ('ꙫ', 'ꙫ'),
+  ('ꙭ', 'ꙭ'), ('ꚁ', 'ꚁ'), ('ꚃ', 'ꚃ'), ('ꚅ', 'ꚅ'),
+  ('ꚇ', 'ꚇ'), ('ꚉ', 'ꚉ'), ('ꚋ', 'ꚋ'), ('ꚍ', 'ꚍ'),
+  ('ꚏ', 'ꚏ'), ('ꚑ', 'ꚑ'), ('ꚓ', 'ꚓ'), ('ꚕ', 'ꚕ'),
+  ('ꚗ', 'ꚗ'), ('ꚙ', 'ꚙ'), ('ꚛ', 'ꚝ'), ('ꜣ', 'ꜣ'),
+  ('ꜥ', 'ꜥ'), ('ꜧ', 'ꜧ'), ('ꜩ', 'ꜩ'), ('ꜫ', 'ꜫ'),
+  ('ꜭ', 'ꜭ'), ('ꜯ', 'ꜱ'), ('ꜳ', 'ꜳ'), ('ꜵ', 'ꜵ'),
+  ('ꜷ', 'ꜷ'), ('ꜹ', 'ꜹ'), ('ꜻ', 'ꜻ'), ('ꜽ', 'ꜽ'),
+  ('ꜿ', 'ꜿ'), ('ꝁ', 'ꝁ'), ('ꝃ', 'ꝃ'), ('ꝅ', 'ꝅ'),
+  ('ꝇ', 'ꝇ'), ('ꝉ', 'ꝉ'), ('ꝋ', 'ꝋ'), ('ꝍ', 'ꝍ'),
+  ('ꝏ', 'ꝏ'), ('ꝑ', 'ꝑ'), ('ꝓ', 'ꝓ'), ('ꝕ', 'ꝕ'),
+  ('ꝗ', 'ꝗ'), ('ꝙ', 'ꝙ'), ('ꝛ', 'ꝛ'), ('ꝝ', 'ꝝ'),
+  ('ꝟ', 'ꝟ'), ('ꝡ', 'ꝡ'), ('ꝣ', 'ꝣ'), ('ꝥ', 'ꝥ'),
+  ('ꝧ', 'ꝧ'), ('ꝩ', 'ꝩ'), ('ꝫ', 'ꝫ'), ('ꝭ', 'ꝭ'),
+  ('ꝯ', 'ꝸ'), ('ꝺ', 'ꝺ'), ('ꝼ', 'ꝼ'), ('ꝿ', 'ꝿ'),
+  ('ꞁ', 'ꞁ'), ('ꞃ', 'ꞃ'), ('ꞅ', 'ꞅ'), ('ꞇ', 'ꞇ'),
+  ('ꞌ', 'ꞌ'), ('ꞎ', 'ꞎ'), ('ꞑ', 'ꞑ'), ('ꞓ', 'ꞕ'),
+  ('ꞗ', 'ꞗ'), ('ꞙ', 'ꞙ'), ('ꞛ', 'ꞛ'), ('ꞝ', 'ꞝ'),
+  ('ꞟ', 'ꞟ'), ('ꞡ', 'ꞡ'), ('ꞣ', 'ꞣ'), ('ꞥ', 'ꞥ'),
+  ('ꞧ', 'ꞧ'), ('ꞩ', 'ꞩ'), ('ꞯ', 'ꞯ'), ('ꞵ', 'ꞵ'),
+  ('ꞷ', 'ꞷ'), ('ꞹ', 'ꞹ'), ('\u{a7bb}', '\u{a7bb}'),
+  ('\u{a7bd}', '\u{a7bd}'), ('\u{a7bf}', '\u{a7bf}'),
+  ('\u{a7c3}', '\u{a7c3}'), ('ꟸ', 'ꟺ'), ('ꬰ', 'ꭚ'),
+  ('ꭜ', '\u{ab67}'), ('ꭰ', 'ꮿ'), ('ff', 'st'), ('ﬓ', 'ﬗ'),
+  ('a', 'z'), ('𐐨', '𐑏'), ('𐓘', '𐓻'), ('𐳀', '𐳲'),
+  ('𑣀', '𑣟'), ('𖹠', '𖹿'), ('𝐚', '𝐳'), ('𝑎', '𝑔'),
+  ('𝑖', '𝑧'), ('𝒂', '𝒛'), ('𝒶', '𝒹'), ('𝒻', '𝒻'),
+  ('𝒽', '𝓃'), ('𝓅', '𝓏'), ('𝓪', '𝔃'), ('𝔞', '𝔷'),
+  ('𝕒', '𝕫'), ('𝖆', '𝖟'), ('𝖺', '𝗓'), ('𝗮', '𝘇'),
+  ('𝘢', '𝘻'), ('𝙖', '𝙯'), ('𝚊', '𝚥'), ('𝛂', '𝛚'),
+  ('𝛜', '𝛡'), ('𝛼', '𝜔'), ('𝜖', '𝜛'), ('𝜶', '𝝎'),
+  ('𝝐', '𝝕'), ('𝝰', '𝞈'), ('𝞊', '𝞏'), ('𝞪', '𝟂'),
+  ('𝟄', '𝟉'), ('𝟋', '𝟋'), ('𞤢', '𞥃'),
+];
+
+pub const MATH: &'static [(char, char)] = &[
+  ('+', '+'), ('<', '>'), ('^', '^'), ('|', '|'), ('~', '~'), ('¬', '¬'),
+  ('±', '±'), ('×', '×'), ('÷', '÷'), ('ϐ', 'ϒ'), ('ϕ', 'ϕ'),
+  ('ϰ', 'ϱ'), ('ϴ', '϶'), ('؆', '؈'), ('‖', '‖'), ('′', '‴'),
+  ('⁀', '⁀'), ('⁄', '⁄'), ('⁒', '⁒'), ('\u{2061}', '\u{2064}'),
+  ('⁺', '⁾'), ('₊', '₎'), ('\u{20d0}', '\u{20dc}'),
+  ('\u{20e1}', '\u{20e1}'), ('\u{20e5}', '\u{20e6}'),
+  ('\u{20eb}', '\u{20ef}'), ('ℂ', 'ℂ'), ('ℇ', 'ℇ'), ('ℊ', 'ℓ'),
+  ('ℕ', 'ℕ'), ('℘', 'ℝ'), ('ℤ', 'ℤ'), ('ℨ', '℩'),
+  ('ℬ', 'ℭ'), ('ℯ', 'ℱ'), ('ℳ', 'ℸ'), ('ℼ', 'ⅉ'),
+  ('⅋', '⅋'), ('←', '↧'), ('↩', '↮'), ('↰', '↱'),
+  ('↶', '↷'), ('↼', '⇛'), ('⇝', '⇝'), ('⇤', '⇥'),
+  ('⇴', '⋿'), ('⌈', '⌋'), ('⌠', '⌡'), ('⍼', '⍼'),
+  ('⎛', '⎵'), ('⎷', '⎷'), ('⏐', '⏐'), ('⏜', '⏢'),
+  ('■', '□'), ('▮', '▷'), ('▼', '◁'), ('◆', '◇'),
+  ('◊', '○'), ('●', '◓'), ('◢', '◢'), ('◤', '◤'),
+  ('◧', '◬'), ('◸', '◿'), ('★', '☆'), ('♀', '♀'),
+  ('♂', '♂'), ('♠', '♣'), ('♭', '♯'), ('⟀', '⟿'),
+  ('⤀', '⫿'), ('⬰', '⭄'), ('⭇', '⭌'), ('﬩', '﬩'),
+  ('﹡', '﹦'), ('﹨', '﹨'), ('+', '+'), ('<', '>'),
+  ('\', '\'), ('^', '^'), ('|', '|'), ('~', '~'),
+  ('¬', '¬'), ('←', '↓'), ('𝐀', '𝑔'), ('𝑖', '𝒜'),
+  ('𝒞', '𝒟'), ('𝒢', '𝒢'), ('𝒥', '𝒦'), ('𝒩', '𝒬'),
+  ('𝒮', '𝒹'), ('𝒻', '𝒻'), ('𝒽', '𝓃'), ('𝓅', '𝔅'),
+  ('𝔇', '𝔊'), ('𝔍', '𝔔'), ('𝔖', '𝔜'), ('𝔞', '𝔹'),
+  ('𝔻', '𝔾'), ('𝕀', '𝕄'), ('𝕆', '𝕆'), ('𝕊', '𝕐'),
+  ('𝕒', '𝚥'), ('𝚨', '𝟋'), ('𝟎', '𝟿'), ('𞸀', '𞸃'),
+  ('𞸅', '𞸟'), ('𞸡', '𞸢'), ('𞸤', '𞸤'), ('𞸧', '𞸧'),
+  ('𞸩', '𞸲'), ('𞸴', '𞸷'), ('𞸹', '𞸹'), ('𞸻', '𞸻'),
+  ('𞹂', '𞹂'), ('𞹇', '𞹇'), ('𞹉', '𞹉'), ('𞹋', '𞹋'),
+  ('𞹍', '𞹏'), ('𞹑', '𞹒'), ('𞹔', '𞹔'), ('𞹗', '𞹗'),
+  ('𞹙', '𞹙'), ('𞹛', '𞹛'), ('𞹝', '𞹝'), ('𞹟', '𞹟'),
+  ('𞹡', '𞹢'), ('𞹤', '𞹤'), ('𞹧', '𞹪'), ('𞹬', '𞹲'),
+  ('𞹴', '𞹷'), ('𞹹', '𞹼'), ('𞹾', '𞹾'), ('𞺀', '𞺉'),
+  ('𞺋', '𞺛'), ('𞺡', '𞺣'), ('𞺥', '𞺩'), ('𞺫', '𞺻'),
+  ('𞻰', '𞻱'),
+];
+
+pub const NONCHARACTER_CODE_POINT: &'static [(char, char)] = &[
+  ('\u{fdd0}', '\u{fdef}'), ('\u{fffe}', '\u{ffff}'),
+  ('\u{1fffe}', '\u{1ffff}'), ('\u{2fffe}', '\u{2ffff}'),
+  ('\u{3fffe}', '\u{3ffff}'), ('\u{4fffe}', '\u{4ffff}'),
+  ('\u{5fffe}', '\u{5ffff}'), ('\u{6fffe}', '\u{6ffff}'),
+  ('\u{7fffe}', '\u{7ffff}'), ('\u{8fffe}', '\u{8ffff}'),
+  ('\u{9fffe}', '\u{9ffff}'), ('\u{afffe}', '\u{affff}'),
+  ('\u{bfffe}', '\u{bffff}'), ('\u{cfffe}', '\u{cffff}'),
+  ('\u{dfffe}', '\u{dffff}'), ('\u{efffe}', '\u{effff}'),
+  ('\u{ffffe}', '\u{fffff}'), ('\u{10fffe}', '\u{10ffff}'),
+];
+
+pub const OTHER_ALPHABETIC: &'static [(char, char)] = &[
+  ('\u{345}', '\u{345}'), ('\u{5b0}', '\u{5bd}'), ('\u{5bf}', '\u{5bf}'),
+  ('\u{5c1}', '\u{5c2}'), ('\u{5c4}', '\u{5c5}'), ('\u{5c7}', '\u{5c7}'),
+  ('\u{610}', '\u{61a}'), ('\u{64b}', '\u{657}'), ('\u{659}', '\u{65f}'),
+  ('\u{670}', '\u{670}'), ('\u{6d6}', '\u{6dc}'), ('\u{6e1}', '\u{6e4}'),
+  ('\u{6e7}', '\u{6e8}'), ('\u{6ed}', '\u{6ed}'), ('\u{711}', '\u{711}'),
+  ('\u{730}', '\u{73f}'), ('\u{7a6}', '\u{7b0}'), ('\u{816}', '\u{817}'),
+  ('\u{81b}', '\u{823}'), ('\u{825}', '\u{827}'), ('\u{829}', '\u{82c}'),
+  ('\u{8d4}', '\u{8df}'), ('\u{8e3}', '\u{8e9}'), ('\u{8f0}', 'ः'),
+  ('\u{93a}', 'ऻ'), ('ा', 'ौ'), ('ॎ', 'ॏ'), ('\u{955}', '\u{957}'),
+  ('\u{962}', '\u{963}'), ('\u{981}', 'ঃ'), ('\u{9be}', '\u{9c4}'),
+  ('ে', 'ৈ'), ('ো', 'ৌ'), ('\u{9d7}', '\u{9d7}'),
+  ('\u{9e2}', '\u{9e3}'), ('\u{a01}', 'ਃ'), ('ਾ', '\u{a42}'),
+  ('\u{a47}', '\u{a48}'), ('\u{a4b}', '\u{a4c}'), ('\u{a51}', '\u{a51}'),
+  ('\u{a70}', '\u{a71}'), ('\u{a75}', '\u{a75}'), ('\u{a81}', 'ઃ'),
+  ('ા', '\u{ac5}'), ('\u{ac7}', 'ૉ'), ('ો', 'ૌ'),
+  ('\u{ae2}', '\u{ae3}'), ('\u{afa}', '\u{afc}'), ('\u{b01}', 'ଃ'),
+  ('\u{b3e}', '\u{b44}'), ('େ', 'ୈ'), ('ୋ', 'ୌ'),
+  ('\u{b56}', '\u{b57}'), ('\u{b62}', '\u{b63}'), ('\u{b82}', '\u{b82}'),
+  ('\u{bbe}', 'ூ'), ('ெ', 'ை'), ('ொ', 'ௌ'), ('\u{bd7}', '\u{bd7}'),
+  ('\u{c00}', 'ః'), ('\u{c3e}', 'ౄ'), ('\u{c46}', '\u{c48}'),
+  ('\u{c4a}', '\u{c4c}'), ('\u{c55}', '\u{c56}'), ('\u{c62}', '\u{c63}'),
+  ('\u{c81}', 'ಃ'), ('ಾ', 'ೄ'), ('\u{cc6}', 'ೈ'), ('ೊ', '\u{ccc}'),
+  ('\u{cd5}', '\u{cd6}'), ('\u{ce2}', '\u{ce3}'), ('\u{d00}', 'ഃ'),
+  ('\u{d3e}', '\u{d44}'), ('െ', 'ൈ'), ('ൊ', 'ൌ'),
+  ('\u{d57}', '\u{d57}'), ('\u{d62}', '\u{d63}'), ('ං', 'ඃ'),
+  ('\u{dcf}', '\u{dd4}'), ('\u{dd6}', '\u{dd6}'), ('ෘ', '\u{ddf}'),
+  ('ෲ', 'ෳ'), ('\u{e31}', '\u{e31}'), ('\u{e34}', '\u{e3a}'),
+  ('\u{e4d}', '\u{e4d}'), ('\u{eb1}', '\u{eb1}'), ('\u{eb4}', '\u{eb9}'),
+  ('\u{ebb}', '\u{ebc}'), ('\u{ecd}', '\u{ecd}'), ('\u{f71}', '\u{f81}'),
+  ('\u{f8d}', '\u{f97}'), ('\u{f99}', '\u{fbc}'), ('ါ', '\u{1036}'),
+  ('း', 'း'), ('ျ', '\u{103e}'), ('ၖ', '\u{1059}'),
+  ('\u{105e}', '\u{1060}'), ('ၢ', 'ၤ'), ('ၧ', 'ၭ'),
+  ('\u{1071}', '\u{1074}'), ('\u{1082}', '\u{108d}'), ('ႏ', 'ႏ'),
+  ('ႚ', '\u{109d}'), ('\u{1712}', '\u{1713}'), ('\u{1732}', '\u{1733}'),
+  ('\u{1752}', '\u{1753}'), ('\u{1772}', '\u{1773}'), ('ា', 'ៈ'),
+  ('\u{1885}', '\u{1886}'), ('\u{18a9}', '\u{18a9}'), ('\u{1920}', 'ᤫ'),
+  ('ᤰ', 'ᤸ'), ('\u{1a17}', '\u{1a1b}'), ('ᩕ', '\u{1a5e}'),
+  ('ᩡ', '\u{1a74}'), ('\u{1b00}', 'ᬄ'), ('ᬵ', 'ᭃ'),
+  ('\u{1b80}', 'ᮂ'), ('ᮡ', '\u{1ba9}'), ('\u{1bac}', '\u{1bad}'),
+  ('ᯧ', '\u{1bf1}'), ('ᰤ', '\u{1c36}'), ('\u{1de7}', '\u{1df4}'),
+  ('Ⓐ', 'ⓩ'), ('\u{2de0}', '\u{2dff}'), ('\u{a674}', '\u{a67b}'),
+  ('\u{a69e}', '\u{a69f}'), ('\u{a802}', '\u{a802}'),
+  ('\u{a80b}', '\u{a80b}'), ('ꠣ', 'ꠧ'), ('ꢀ', 'ꢁ'), ('ꢴ', 'ꣃ'),
+  ('\u{a8c5}', '\u{a8c5}'), ('\u{a8ff}', '\u{a8ff}'),
+  ('\u{a926}', '\u{a92a}'), ('\u{a947}', 'ꥒ'), ('\u{a980}', 'ꦃ'),
+  ('ꦴ', 'ꦿ'), ('\u{a9e5}', '\u{a9e5}'), ('\u{aa29}', '\u{aa36}'),
+  ('\u{aa43}', '\u{aa43}'), ('\u{aa4c}', 'ꩍ'), ('ꩻ', 'ꩽ'),
+  ('\u{aab0}', '\u{aab0}'), ('\u{aab2}', '\u{aab4}'),
+  ('\u{aab7}', '\u{aab8}'), ('\u{aabe}', '\u{aabe}'), ('ꫫ', 'ꫯ'),
+  ('ꫵ', 'ꫵ'), ('ꯣ', 'ꯪ'), ('\u{fb1e}', '\u{fb1e}'),
+  ('\u{10376}', '\u{1037a}'), ('\u{10a01}', '\u{10a03}'),
+  ('\u{10a05}', '\u{10a06}'), ('\u{10a0c}', '\u{10a0f}'),
+  ('\u{10d24}', '\u{10d27}'), ('𑀀', '𑀂'), ('\u{11038}', '\u{11045}'),
+  ('𑂂', '𑂂'), ('𑂰', '𑂸'), ('\u{11100}', '\u{11102}'),
+  ('\u{11127}', '\u{11132}'), ('𑅅', '𑅆'), ('\u{11180}', '𑆂'),
+  ('𑆳', '𑆿'), ('𑈬', '\u{11234}'), ('\u{11237}', '\u{11237}'),
+  ('\u{1123e}', '\u{1123e}'), ('\u{112df}', '\u{112e8}'),
+  ('\u{11300}', '𑌃'), ('\u{1133e}', '𑍄'), ('𑍇', '𑍈'),
+  ('𑍋', '𑍌'), ('\u{11357}', '\u{11357}'), ('𑍢', '𑍣'),
+  ('𑐵', '𑑁'), ('\u{11443}', '𑑅'), ('\u{114b0}', '𑓁'),
+  ('\u{115af}', '\u{115b5}'), ('𑖸', '𑖾'), ('\u{115dc}', '\u{115dd}'),
+  ('𑘰', '𑘾'), ('\u{11640}', '\u{11640}'), ('\u{116ab}', '\u{116b5}'),
+  ('\u{1171d}', '\u{1172a}'), ('𑠬', '𑠸'), ('\u{119d1}', '\u{119d7}'),
+  ('\u{119da}', '\u{119df}'), ('\u{119e4}', '\u{119e4}'),
+  ('\u{11a01}', '\u{11a0a}'), ('\u{11a35}', '𑨹'),
+  ('\u{11a3b}', '\u{11a3e}'), ('\u{11a51}', '\u{11a5b}'),
+  ('\u{11a8a}', '𑪗'), ('𑰯', '\u{11c36}'), ('\u{11c38}', '𑰾'),
+  ('\u{11c92}', '\u{11ca7}'), ('𑲩', '\u{11cb6}'),
+  ('\u{11d31}', '\u{11d36}'), ('\u{11d3a}', '\u{11d3a}'),
+  ('\u{11d3c}', '\u{11d3d}'), ('\u{11d3f}', '\u{11d41}'),
+  ('\u{11d43}', '\u{11d43}'), ('\u{11d47}', '\u{11d47}'), ('𑶊', '𑶎'),
+  ('\u{11d90}', '\u{11d91}'), ('𑶓', '𑶖'), ('\u{11ef3}', '𑻶'),
+  ('\u{16f4f}', '\u{16f4f}'), ('𖽑', '\u{16f87}'),
+  ('\u{16f8f}', '\u{16f92}'), ('\u{1bc9e}', '\u{1bc9e}'),
+  ('\u{1e000}', '\u{1e006}'), ('\u{1e008}', '\u{1e018}'),
+  ('\u{1e01b}', '\u{1e021}'), ('\u{1e023}', '\u{1e024}'),
+  ('\u{1e026}', '\u{1e02a}'), ('\u{1e947}', '\u{1e947}'), ('🄰', '🅉'),
+  ('🅐', '🅩'), ('🅰', '🆉'),
+];
+
+pub const OTHER_DEFAULT_IGNORABLE_CODE_POINT: &'static [(char, char)] = &[
+  ('\u{34f}', '\u{34f}'), ('ᅟ', 'ᅠ'), ('\u{17b4}', '\u{17b5}'),
+  ('\u{2065}', '\u{2065}'), ('ㅤ', 'ㅤ'), ('ᅠ', 'ᅠ'),
+  ('\u{fff0}', '\u{fff8}'), ('\u{e0000}', '\u{e0000}'),
+  ('\u{e0002}', '\u{e001f}'), ('\u{e0080}', '\u{e00ff}'),
+  ('\u{e01f0}', '\u{e0fff}'),
+];
+
+pub const OTHER_GRAPHEME_EXTEND: &'static [(char, char)] = &[
+  ('\u{9be}', '\u{9be}'), ('\u{9d7}', '\u{9d7}'), ('\u{b3e}', '\u{b3e}'),
+  ('\u{b57}', '\u{b57}'), ('\u{bbe}', '\u{bbe}'), ('\u{bd7}', '\u{bd7}'),
+  ('\u{cc2}', '\u{cc2}'), ('\u{cd5}', '\u{cd6}'), ('\u{d3e}', '\u{d3e}'),
+  ('\u{d57}', '\u{d57}'), ('\u{dcf}', '\u{dcf}'), ('\u{ddf}', '\u{ddf}'),
+  ('ᬵ', 'ᬵ'), ('\u{200c}', '\u{200c}'), ('\u{302e}', '\u{302f}'),
+  ('\u{ff9e}', '\u{ff9f}'), ('\u{1133e}', '\u{1133e}'),
+  ('\u{11357}', '\u{11357}'), ('\u{114b0}', '\u{114b0}'),
+  ('\u{114bd}', '\u{114bd}'), ('\u{115af}', '\u{115af}'),
+  ('\u{1d165}', '\u{1d165}'), ('\u{1d16e}', '\u{1d172}'),
+  ('\u{e0020}', '\u{e007f}'),
+];
+
+pub const OTHER_ID_CONTINUE: &'static [(char, char)] = &[
+  ('·', '·'), ('·', '·'), ('፩', '፱'), ('᧚', '᧚'),
+];
+
+pub const OTHER_ID_START: &'static [(char, char)] = &[
+  ('\u{1885}', '\u{1886}'), ('℘', '℘'), ('℮', '℮'), ('゛', '゜'),
+];
+
+pub const OTHER_LOWERCASE: &'static [(char, char)] = &[
+  ('ª', 'ª'), ('º', 'º'), ('ʰ', 'ʸ'), ('ˀ', 'ˁ'), ('ˠ', 'ˤ'),
+  ('\u{345}', '\u{345}'), ('ͺ', 'ͺ'), ('ᴬ', 'ᵪ'), ('ᵸ', 'ᵸ'),
+  ('ᶛ', 'ᶿ'), ('ⁱ', 'ⁱ'), ('ⁿ', 'ⁿ'), ('ₐ', 'ₜ'),
+  ('ⅰ', 'ⅿ'), ('ⓐ', 'ⓩ'), ('ⱼ', 'ⱽ'), ('ꚜ', 'ꚝ'),
+  ('ꝰ', 'ꝰ'), ('ꟸ', 'ꟹ'), ('ꭜ', 'ꭟ'),
+];
+
+pub const OTHER_MATH: &'static [(char, char)] = &[
+  ('^', '^'), ('ϐ', 'ϒ'), ('ϕ', 'ϕ'), ('ϰ', 'ϱ'), ('ϴ', 'ϵ'),
+  ('‖', '‖'), ('′', '‴'), ('⁀', '⁀'), ('\u{2061}', '\u{2064}'),
+  ('⁽', '⁾'), ('₍', '₎'), ('\u{20d0}', '\u{20dc}'),
+  ('\u{20e1}', '\u{20e1}'), ('\u{20e5}', '\u{20e6}'),
+  ('\u{20eb}', '\u{20ef}'), ('ℂ', 'ℂ'), ('ℇ', 'ℇ'), ('ℊ', 'ℓ'),
+  ('ℕ', 'ℕ'), ('ℙ', 'ℝ'), ('ℤ', 'ℤ'), ('ℨ', '℩'),
+  ('ℬ', 'ℭ'), ('ℯ', 'ℱ'), ('ℳ', 'ℸ'), ('ℼ', 'ℿ'),
+  ('ⅅ', 'ⅉ'), ('↕', '↙'), ('↜', '↟'), ('↡', '↢'),
+  ('↤', '↥'), ('↧', '↧'), ('↩', '↭'), ('↰', '↱'),
+  ('↶', '↷'), ('↼', '⇍'), ('⇐', '⇑'), ('⇓', '⇓'),
+  ('⇕', '⇛'), ('⇝', '⇝'), ('⇤', '⇥'), ('⌈', '⌋'),
+  ('⎴', '⎵'), ('⎷', '⎷'), ('⏐', '⏐'), ('⏢', '⏢'),
+  ('■', '□'), ('▮', '▶'), ('▼', '◀'), ('◆', '◇'),
+  ('◊', '○'), ('●', '◓'), ('◢', '◢'), ('◤', '◤'),
+  ('◧', '◬'), ('★', '☆'), ('♀', '♀'), ('♂', '♂'),
+  ('♠', '♣'), ('♭', '♮'), ('⟅', '⟆'), ('⟦', '⟯'),
+  ('⦃', '⦘'), ('⧘', '⧛'), ('⧼', '⧽'), ('﹡', '﹡'),
+  ('﹣', '﹣'), ('﹨', '﹨'), ('\', '\'), ('^', '^'),
+  ('𝐀', '𝑔'), ('𝑖', '𝒜'), ('𝒞', '𝒟'), ('𝒢', '𝒢'),
+  ('𝒥', '𝒦'), ('𝒩', '𝒬'), ('𝒮', '𝒹'), ('𝒻', '𝒻'),
+  ('𝒽', '𝓃'), ('𝓅', '𝔅'), ('𝔇', '𝔊'), ('𝔍', '𝔔'),
+  ('𝔖', '𝔜'), ('𝔞', '𝔹'), ('𝔻', '𝔾'), ('𝕀', '𝕄'),
+  ('𝕆', '𝕆'), ('𝕊', '𝕐'), ('𝕒', '𝚥'), ('𝚨', '𝛀'),
+  ('𝛂', '𝛚'), ('𝛜', '𝛺'), ('𝛼', '𝜔'), ('𝜖', '𝜴'),
+  ('𝜶', '𝝎'), ('𝝐', '𝝮'), ('𝝰', '𝞈'), ('𝞊', '𝞨'),
+  ('𝞪', '𝟂'), ('𝟄', '𝟋'), ('𝟎', '𝟿'), ('𞸀', '𞸃'),
+  ('𞸅', '𞸟'), ('𞸡', '𞸢'), ('𞸤', '𞸤'), ('𞸧', '𞸧'),
+  ('𞸩', '𞸲'), ('𞸴', '𞸷'), ('𞸹', '𞸹'), ('𞸻', '𞸻'),
+  ('𞹂', '𞹂'), ('𞹇', '𞹇'), ('𞹉', '𞹉'), ('𞹋', '𞹋'),
+  ('𞹍', '𞹏'), ('𞹑', '𞹒'), ('𞹔', '𞹔'), ('𞹗', '𞹗'),
+  ('𞹙', '𞹙'), ('𞹛', '𞹛'), ('𞹝', '𞹝'), ('𞹟', '𞹟'),
+  ('𞹡', '𞹢'), ('𞹤', '𞹤'), ('𞹧', '𞹪'), ('𞹬', '𞹲'),
+  ('𞹴', '𞹷'), ('𞹹', '𞹼'), ('𞹾', '𞹾'), ('𞺀', '𞺉'),
+  ('𞺋', '𞺛'), ('𞺡', '𞺣'), ('𞺥', '𞺩'), ('𞺫', '𞺻'),
+];
+
+pub const OTHER_UPPERCASE: &'static [(char, char)] = &[
+  ('Ⅰ', 'Ⅿ'), ('Ⓐ', 'Ⓩ'), ('🄰', '🅉'), ('🅐', '🅩'),
+  ('🅰', '🆉'),
+];
+
+pub const PATTERN_SYNTAX: &'static [(char, char)] = &[
+  ('!', '/'), (':', '@'), ('[', '^'), ('`', '`'), ('{', '~'), ('¡', '§'),
+  ('©', '©'), ('«', '¬'), ('®', '®'), ('°', '±'), ('¶', '¶'),
+  ('»', '»'), ('¿', '¿'), ('×', '×'), ('÷', '÷'), ('‐', '‧'),
+  ('‰', '‾'), ('⁁', '⁓'), ('⁕', '⁞'), ('←', '\u{245f}'),
+  ('─', '❵'), ('➔', '\u{2bff}'), ('⸀', '\u{2e7f}'), ('、', '〃'),
+  ('〈', '〠'), ('〰', '〰'), ('﴾', '﴿'), ('﹅', '﹆'),
+];
+
+pub const PATTERN_WHITE_SPACE: &'static [(char, char)] = &[
+  ('\t', '\r'), (' ', ' '), ('\u{85}', '\u{85}'), ('\u{200e}', '\u{200f}'),
+  ('\u{2028}', '\u{2029}'),
+];
+
+pub const PREPENDED_CONCATENATION_MARK: &'static [(char, char)] = &[
+  ('\u{600}', '\u{605}'), ('\u{6dd}', '\u{6dd}'), ('\u{70f}', '\u{70f}'),
+  ('\u{8e2}', '\u{8e2}'), ('\u{110bd}', '\u{110bd}'),
+  ('\u{110cd}', '\u{110cd}'),
+];
+
+pub const QUOTATION_MARK: &'static [(char, char)] = &[
+  ('\"', '\"'), ('\'', '\''), ('«', '«'), ('»', '»'), ('‘', '‟'),
+  ('‹', '›'), ('⹂', '⹂'), ('「', '』'), ('〝', '〟'),
+  ('﹁', '﹄'), ('"', '"'), (''', '''), ('「', '」'),
+];
+
+pub const RADICAL: &'static [(char, char)] = &[
+  ('⺀', '⺙'), ('⺛', '⻳'), ('⼀', '⿕'),
+];
+
+pub const REGIONAL_INDICATOR: &'static [(char, char)] = &[
+  ('🇦', '🇿'),
+];
+
+pub const SENTENCE_TERMINAL: &'static [(char, char)] = &[
+  ('!', '!'), ('.', '.'), ('?', '?'), ('։', '։'), ('؞', '؟'),
+  ('۔', '۔'), ('܀', '܂'), ('߹', '߹'), ('࠷', '࠷'), ('࠹', '࠹'),
+  ('࠽', '࠾'), ('।', '॥'), ('၊', '။'), ('።', '።'),
+  ('፧', '፨'), ('᙮', '᙮'), ('᜵', '᜶'), ('᠃', '᠃'),
+  ('᠉', '᠉'), ('᥄', '᥅'), ('᪨', '᪫'), ('᭚', '᭛'),
+  ('᭞', '᭟'), ('᰻', '᰼'), ('᱾', '᱿'), ('‼', '‽'),
+  ('⁇', '⁉'), ('⸮', '⸮'), ('⸼', '⸼'), ('。', '。'),
+  ('꓿', '꓿'), ('꘎', '꘏'), ('꛳', '꛳'), ('꛷', '꛷'),
+  ('꡶', '꡷'), ('꣎', '꣏'), ('꤯', '꤯'), ('꧈', '꧉'),
+  ('꩝', '꩟'), ('꫰', '꫱'), ('꯫', '꯫'), ('﹒', '﹒'),
+  ('﹖', '﹗'), ('!', '!'), ('.', '.'), ('?', '?'),
+  ('。', '。'), ('𐩖', '𐩗'), ('𐽕', '𐽙'), ('𑁇', '𑁈'),
+  ('𑂾', '𑃁'), ('𑅁', '𑅃'), ('𑇅', '𑇆'), ('𑇍', '𑇍'),
+  ('𑇞', '𑇟'), ('𑈸', '𑈹'), ('𑈻', '𑈼'), ('𑊩', '𑊩'),
+  ('𑑋', '𑑌'), ('𑗂', '𑗃'), ('𑗉', '𑗗'), ('𑙁', '𑙂'),
+  ('𑜼', '𑜾'), ('𑩂', '𑩃'), ('𑪛', '𑪜'), ('𑱁', '𑱂'),
+  ('𑻷', '𑻸'), ('𖩮', '𖩯'), ('𖫵', '𖫵'), ('𖬷', '𖬸'),
+  ('𖭄', '𖭄'), ('𖺘', '𖺘'), ('𛲟', '𛲟'), ('𝪈', '𝪈'),
+];
+
+pub const SOFT_DOTTED: &'static [(char, char)] = &[
+  ('i', 'j'), ('į', 'į'), ('ɉ', 'ɉ'), ('ɨ', 'ɨ'), ('ʝ', 'ʝ'),
+  ('ʲ', 'ʲ'), ('ϳ', 'ϳ'), ('і', 'і'), ('ј', 'ј'), ('ᵢ', 'ᵢ'),
+  ('ᶖ', 'ᶖ'), ('ᶤ', 'ᶤ'), ('ᶨ', 'ᶨ'), ('ḭ', 'ḭ'),
+  ('ị', 'ị'), ('ⁱ', 'ⁱ'), ('ⅈ', 'ⅉ'), ('ⱼ', 'ⱼ'),
+  ('𝐢', '𝐣'), ('𝑖', '𝑗'), ('𝒊', '𝒋'), ('𝒾', '𝒿'),
+  ('𝓲', '𝓳'), ('𝔦', '𝔧'), ('𝕚', '𝕛'), ('𝖎', '𝖏'),
+  ('𝗂', '𝗃'), ('𝗶', '𝗷'), ('𝘪', '𝘫'), ('𝙞', '𝙟'),
+  ('𝚒', '𝚓'),
+];
+
+pub const TERMINAL_PUNCTUATION: &'static [(char, char)] = &[
+  ('!', '!'), (',', ','), ('.', '.'), (':', ';'), ('?', '?'), (';', ';'),
+  ('·', '·'), ('։', '։'), ('׃', '׃'), ('،', '،'), ('؛', '؛'),
+  ('؞', '؟'), ('۔', '۔'), ('܀', '܊'), ('܌', '܌'), ('߸', '߹'),
+  ('࠰', '࠾'), ('࡞', '࡞'), ('।', '॥'), ('๚', '๛'),
+  ('༈', '༈'), ('།', '༒'), ('၊', '။'), ('፡', '፨'),
+  ('᙮', '᙮'), ('᛫', '᛭'), ('᜵', '᜶'), ('។', '៖'),
+  ('៚', '៚'), ('᠂', '᠅'), ('᠈', '᠉'), ('᥄', '᥅'),
+  ('᪨', '᪫'), ('᭚', '᭛'), ('᭝', '᭟'), ('᰻', '᰿'),
+  ('᱾', '᱿'), ('‼', '‽'), ('⁇', '⁉'), ('⸮', '⸮'),
+  ('⸼', '⸼'), ('⹁', '⹁'), ('⹌', '⹌'), ('⹎', '\u{2e4f}'),
+  ('、', '。'), ('꓾', '꓿'), ('꘍', '꘏'), ('꛳', '꛷'),
+  ('꡶', '꡷'), ('꣎', '꣏'), ('꤯', '꤯'), ('꧇', '꧉'),
+  ('꩝', '꩟'), ('꫟', '꫟'), ('꫰', '꫱'), ('꯫', '꯫'),
+  ('﹐', '﹒'), ('﹔', '﹗'), ('!', '!'), (',', ','),
+  ('.', '.'), (':', ';'), ('?', '?'), ('。', '。'),
+  ('、', '、'), ('𐎟', '𐎟'), ('𐏐', '𐏐'), ('𐡗', '𐡗'),
+  ('𐤟', '𐤟'), ('𐩖', '𐩗'), ('𐫰', '𐫵'), ('𐬺', '𐬿'),
+  ('𐮙', '𐮜'), ('𐽕', '𐽙'), ('𑁇', '𑁍'), ('𑂾', '𑃁'),
+  ('𑅁', '𑅃'), ('𑇅', '𑇆'), ('𑇍', '𑇍'), ('𑇞', '𑇟'),
+  ('𑈸', '𑈼'), ('𑊩', '𑊩'), ('𑑋', '𑑍'), ('𑑛', '𑑛'),
+  ('𑗂', '𑗅'), ('𑗉', '𑗗'), ('𑙁', '𑙂'), ('𑜼', '𑜾'),
+  ('𑩂', '𑩃'), ('𑪛', '𑪜'), ('𑪡', '𑪢'), ('𑱁', '𑱃'),
+  ('𑱱', '𑱱'), ('𑻷', '𑻸'), ('𒑰', '𒑴'), ('𖩮', '𖩯'),
+  ('𖫵', '𖫵'), ('𖬷', '𖬹'), ('𖭄', '𖭄'), ('𖺗', '𖺘'),
+  ('𛲟', '𛲟'), ('𝪇', '𝪊'),
+];
+
+pub const UNIFIED_IDEOGRAPH: &'static [(char, char)] = &[
+  ('㐀', '䶵'), ('一', '鿯'), ('﨎', '﨏'), ('﨑', '﨑'),
+  ('﨓', '﨔'), ('﨟', '﨟'), ('﨡', '﨡'), ('﨣', '﨤'),
+  ('﨧', '﨩'), ('𠀀', '𪛖'), ('𪜀', '𫜴'), ('𫝀', '𫠝'),
+  ('𫠠', '𬺡'), ('𬺰', '𮯠'),
+];
+
+pub const UPPERCASE: &'static [(char, char)] = &[
+  ('A', 'Z'), ('À', 'Ö'), ('Ø', 'Þ'), ('Ā', 'Ā'), ('Ă', 'Ă'),
+  ('Ą', 'Ą'), ('Ć', 'Ć'), ('Ĉ', 'Ĉ'), ('Ċ', 'Ċ'), ('Č', 'Č'),
+  ('Ď', 'Ď'), ('Đ', 'Đ'), ('Ē', 'Ē'), ('Ĕ', 'Ĕ'), ('Ė', 'Ė'),
+  ('Ę', 'Ę'), ('Ě', 'Ě'), ('Ĝ', 'Ĝ'), ('Ğ', 'Ğ'), ('Ġ', 'Ġ'),
+  ('Ģ', 'Ģ'), ('Ĥ', 'Ĥ'), ('Ħ', 'Ħ'), ('Ĩ', 'Ĩ'), ('Ī', 'Ī'),
+  ('Ĭ', 'Ĭ'), ('Į', 'Į'), ('İ', 'İ'), ('IJ', 'IJ'), ('Ĵ', 'Ĵ'),
+  ('Ķ', 'Ķ'), ('Ĺ', 'Ĺ'), ('Ļ', 'Ļ'), ('Ľ', 'Ľ'), ('Ŀ', 'Ŀ'),
+  ('Ł', 'Ł'), ('Ń', 'Ń'), ('Ņ', 'Ņ'), ('Ň', 'Ň'), ('Ŋ', 'Ŋ'),
+  ('Ō', 'Ō'), ('Ŏ', 'Ŏ'), ('Ő', 'Ő'), ('Œ', 'Œ'), ('Ŕ', 'Ŕ'),
+  ('Ŗ', 'Ŗ'), ('Ř', 'Ř'), ('Ś', 'Ś'), ('Ŝ', 'Ŝ'), ('Ş', 'Ş'),
+  ('Š', 'Š'), ('Ţ', 'Ţ'), ('Ť', 'Ť'), ('Ŧ', 'Ŧ'), ('Ũ', 'Ũ'),
+  ('Ū', 'Ū'), ('Ŭ', 'Ŭ'), ('Ů', 'Ů'), ('Ű', 'Ű'), ('Ų', 'Ų'),
+  ('Ŵ', 'Ŵ'), ('Ŷ', 'Ŷ'), ('Ÿ', 'Ź'), ('Ż', 'Ż'), ('Ž', 'Ž'),
+  ('Ɓ', 'Ƃ'), ('Ƅ', 'Ƅ'), ('Ɔ', 'Ƈ'), ('Ɖ', 'Ƌ'), ('Ǝ', 'Ƒ'),
+  ('Ɠ', 'Ɣ'), ('Ɩ', 'Ƙ'), ('Ɯ', 'Ɲ'), ('Ɵ', 'Ơ'), ('Ƣ', 'Ƣ'),
+  ('Ƥ', 'Ƥ'), ('Ʀ', 'Ƨ'), ('Ʃ', 'Ʃ'), ('Ƭ', 'Ƭ'), ('Ʈ', 'Ư'),
+  ('Ʊ', 'Ƴ'), ('Ƶ', 'Ƶ'), ('Ʒ', 'Ƹ'), ('Ƽ', 'Ƽ'), ('DŽ', 'DŽ'),
+  ('LJ', 'LJ'), ('NJ', 'NJ'), ('Ǎ', 'Ǎ'), ('Ǐ', 'Ǐ'), ('Ǒ', 'Ǒ'),
+  ('Ǔ', 'Ǔ'), ('Ǖ', 'Ǖ'), ('Ǘ', 'Ǘ'), ('Ǚ', 'Ǚ'), ('Ǜ', 'Ǜ'),
+  ('Ǟ', 'Ǟ'), ('Ǡ', 'Ǡ'), ('Ǣ', 'Ǣ'), ('Ǥ', 'Ǥ'), ('Ǧ', 'Ǧ'),
+  ('Ǩ', 'Ǩ'), ('Ǫ', 'Ǫ'), ('Ǭ', 'Ǭ'), ('Ǯ', 'Ǯ'), ('DZ', 'DZ'),
+  ('Ǵ', 'Ǵ'), ('Ƕ', 'Ǹ'), ('Ǻ', 'Ǻ'), ('Ǽ', 'Ǽ'), ('Ǿ', 'Ǿ'),
+  ('Ȁ', 'Ȁ'), ('Ȃ', 'Ȃ'), ('Ȅ', 'Ȅ'), ('Ȇ', 'Ȇ'), ('Ȉ', 'Ȉ'),
+  ('Ȋ', 'Ȋ'), ('Ȍ', 'Ȍ'), ('Ȏ', 'Ȏ'), ('Ȑ', 'Ȑ'), ('Ȓ', 'Ȓ'),
+  ('Ȕ', 'Ȕ'), ('Ȗ', 'Ȗ'), ('Ș', 'Ș'), ('Ț', 'Ț'), ('Ȝ', 'Ȝ'),
+  ('Ȟ', 'Ȟ'), ('Ƞ', 'Ƞ'), ('Ȣ', 'Ȣ'), ('Ȥ', 'Ȥ'), ('Ȧ', 'Ȧ'),
+  ('Ȩ', 'Ȩ'), ('Ȫ', 'Ȫ'), ('Ȭ', 'Ȭ'), ('Ȯ', 'Ȯ'), ('Ȱ', 'Ȱ'),
+  ('Ȳ', 'Ȳ'), ('Ⱥ', 'Ȼ'), ('Ƚ', 'Ⱦ'), ('Ɂ', 'Ɂ'), ('Ƀ', 'Ɇ'),
+  ('Ɉ', 'Ɉ'), ('Ɋ', 'Ɋ'), ('Ɍ', 'Ɍ'), ('Ɏ', 'Ɏ'), ('Ͱ', 'Ͱ'),
+  ('Ͳ', 'Ͳ'), ('Ͷ', 'Ͷ'), ('Ϳ', 'Ϳ'), ('Ά', 'Ά'), ('Έ', 'Ί'),
+  ('Ό', 'Ό'), ('Ύ', 'Ώ'), ('Α', 'Ρ'), ('Σ', 'Ϋ'), ('Ϗ', 'Ϗ'),
+  ('ϒ', 'ϔ'), ('Ϙ', 'Ϙ'), ('Ϛ', 'Ϛ'), ('Ϝ', 'Ϝ'), ('Ϟ', 'Ϟ'),
+  ('Ϡ', 'Ϡ'), ('Ϣ', 'Ϣ'), ('Ϥ', 'Ϥ'), ('Ϧ', 'Ϧ'), ('Ϩ', 'Ϩ'),
+  ('Ϫ', 'Ϫ'), ('Ϭ', 'Ϭ'), ('Ϯ', 'Ϯ'), ('ϴ', 'ϴ'), ('Ϸ', 'Ϸ'),
+  ('Ϲ', 'Ϻ'), ('Ͻ', 'Я'), ('Ѡ', 'Ѡ'), ('Ѣ', 'Ѣ'), ('Ѥ', 'Ѥ'),
+  ('Ѧ', 'Ѧ'), ('Ѩ', 'Ѩ'), ('Ѫ', 'Ѫ'), ('Ѭ', 'Ѭ'), ('Ѯ', 'Ѯ'),
+  ('Ѱ', 'Ѱ'), ('Ѳ', 'Ѳ'), ('Ѵ', 'Ѵ'), ('Ѷ', 'Ѷ'), ('Ѹ', 'Ѹ'),
+  ('Ѻ', 'Ѻ'), ('Ѽ', 'Ѽ'), ('Ѿ', 'Ѿ'), ('Ҁ', 'Ҁ'), ('Ҋ', 'Ҋ'),
+  ('Ҍ', 'Ҍ'), ('Ҏ', 'Ҏ'), ('Ґ', 'Ґ'), ('Ғ', 'Ғ'), ('Ҕ', 'Ҕ'),
+  ('Җ', 'Җ'), ('Ҙ', 'Ҙ'), ('Қ', 'Қ'), ('Ҝ', 'Ҝ'), ('Ҟ', 'Ҟ'),
+  ('Ҡ', 'Ҡ'), ('Ң', 'Ң'), ('Ҥ', 'Ҥ'), ('Ҧ', 'Ҧ'), ('Ҩ', 'Ҩ'),
+  ('Ҫ', 'Ҫ'), ('Ҭ', 'Ҭ'), ('Ү', 'Ү'), ('Ұ', 'Ұ'), ('Ҳ', 'Ҳ'),
+  ('Ҵ', 'Ҵ'), ('Ҷ', 'Ҷ'), ('Ҹ', 'Ҹ'), ('Һ', 'Һ'), ('Ҽ', 'Ҽ'),
+  ('Ҿ', 'Ҿ'), ('Ӏ', 'Ӂ'), ('Ӄ', 'Ӄ'), ('Ӆ', 'Ӆ'), ('Ӈ', 'Ӈ'),
+  ('Ӊ', 'Ӊ'), ('Ӌ', 'Ӌ'), ('Ӎ', 'Ӎ'), ('Ӑ', 'Ӑ'), ('Ӓ', 'Ӓ'),
+  ('Ӕ', 'Ӕ'), ('Ӗ', 'Ӗ'), ('Ә', 'Ә'), ('Ӛ', 'Ӛ'), ('Ӝ', 'Ӝ'),
+  ('Ӟ', 'Ӟ'), ('Ӡ', 'Ӡ'), ('Ӣ', 'Ӣ'), ('Ӥ', 'Ӥ'), ('Ӧ', 'Ӧ'),
+  ('Ө', 'Ө'), ('Ӫ', 'Ӫ'), ('Ӭ', 'Ӭ'), ('Ӯ', 'Ӯ'), ('Ӱ', 'Ӱ'),
+  ('Ӳ', 'Ӳ'), ('Ӵ', 'Ӵ'), ('Ӷ', 'Ӷ'), ('Ӹ', 'Ӹ'), ('Ӻ', 'Ӻ'),
+  ('Ӽ', 'Ӽ'), ('Ӿ', 'Ӿ'), ('Ԁ', 'Ԁ'), ('Ԃ', 'Ԃ'), ('Ԅ', 'Ԅ'),
+  ('Ԇ', 'Ԇ'), ('Ԉ', 'Ԉ'), ('Ԋ', 'Ԋ'), ('Ԍ', 'Ԍ'), ('Ԏ', 'Ԏ'),
+  ('Ԑ', 'Ԑ'), ('Ԓ', 'Ԓ'), ('Ԕ', 'Ԕ'), ('Ԗ', 'Ԗ'), ('Ԙ', 'Ԙ'),
+  ('Ԛ', 'Ԛ'), ('Ԝ', 'Ԝ'), ('Ԟ', 'Ԟ'), ('Ԡ', 'Ԡ'), ('Ԣ', 'Ԣ'),
+  ('Ԥ', 'Ԥ'), ('Ԧ', 'Ԧ'), ('Ԩ', 'Ԩ'), ('Ԫ', 'Ԫ'), ('Ԭ', 'Ԭ'),
+  ('Ԯ', 'Ԯ'), ('Ա', 'Ֆ'), ('Ⴀ', 'Ⴥ'), ('Ⴧ', 'Ⴧ'), ('Ⴭ', 'Ⴭ'),
+  ('Ꭰ', 'Ᏽ'), ('Ა', 'Ჺ'), ('Ჽ', 'Ჿ'), ('Ḁ', 'Ḁ'),
+  ('Ḃ', 'Ḃ'), ('Ḅ', 'Ḅ'), ('Ḇ', 'Ḇ'), ('Ḉ', 'Ḉ'),
+  ('Ḋ', 'Ḋ'), ('Ḍ', 'Ḍ'), ('Ḏ', 'Ḏ'), ('Ḑ', 'Ḑ'),
+  ('Ḓ', 'Ḓ'), ('Ḕ', 'Ḕ'), ('Ḗ', 'Ḗ'), ('Ḙ', 'Ḙ'),
+  ('Ḛ', 'Ḛ'), ('Ḝ', 'Ḝ'), ('Ḟ', 'Ḟ'), ('Ḡ', 'Ḡ'),
+  ('Ḣ', 'Ḣ'), ('Ḥ', 'Ḥ'), ('Ḧ', 'Ḧ'), ('Ḩ', 'Ḩ'),
+  ('Ḫ', 'Ḫ'), ('Ḭ', 'Ḭ'), ('Ḯ', 'Ḯ'), ('Ḱ', 'Ḱ'),
+  ('Ḳ', 'Ḳ'), ('Ḵ', 'Ḵ'), ('Ḷ', 'Ḷ'), ('Ḹ', 'Ḹ'),
+  ('Ḻ', 'Ḻ'), ('Ḽ', 'Ḽ'), ('Ḿ', 'Ḿ'), ('Ṁ', 'Ṁ'),
+  ('Ṃ', 'Ṃ'), ('Ṅ', 'Ṅ'), ('Ṇ', 'Ṇ'), ('Ṉ', 'Ṉ'),
+  ('Ṋ', 'Ṋ'), ('Ṍ', 'Ṍ'), ('Ṏ', 'Ṏ'), ('Ṑ', 'Ṑ'),
+  ('Ṓ', 'Ṓ'), ('Ṕ', 'Ṕ'), ('Ṗ', 'Ṗ'), ('Ṙ', 'Ṙ'),
+  ('Ṛ', 'Ṛ'), ('Ṝ', 'Ṝ'), ('Ṟ', 'Ṟ'), ('Ṡ', 'Ṡ'),
+  ('Ṣ', 'Ṣ'), ('Ṥ', 'Ṥ'), ('Ṧ', 'Ṧ'), ('Ṩ', 'Ṩ'),
+  ('Ṫ', 'Ṫ'), ('Ṭ', 'Ṭ'), ('Ṯ', 'Ṯ'), ('Ṱ', 'Ṱ'),
+  ('Ṳ', 'Ṳ'), ('Ṵ', 'Ṵ'), ('Ṷ', 'Ṷ'), ('Ṹ', 'Ṹ'),
+  ('Ṻ', 'Ṻ'), ('Ṽ', 'Ṽ'), ('Ṿ', 'Ṿ'), ('Ẁ', 'Ẁ'),
+  ('Ẃ', 'Ẃ'), ('Ẅ', 'Ẅ'), ('Ẇ', 'Ẇ'), ('Ẉ', 'Ẉ'),
+  ('Ẋ', 'Ẋ'), ('Ẍ', 'Ẍ'), ('Ẏ', 'Ẏ'), ('Ẑ', 'Ẑ'),
+  ('Ẓ', 'Ẓ'), ('Ẕ', 'Ẕ'), ('ẞ', 'ẞ'), ('Ạ', 'Ạ'),
+  ('Ả', 'Ả'), ('Ấ', 'Ấ'), ('Ầ', 'Ầ'), ('Ẩ', 'Ẩ'),
+  ('Ẫ', 'Ẫ'), ('Ậ', 'Ậ'), ('Ắ', 'Ắ'), ('Ằ', 'Ằ'),
+  ('Ẳ', 'Ẳ'), ('Ẵ', 'Ẵ'), ('Ặ', 'Ặ'), ('Ẹ', 'Ẹ'),
+  ('Ẻ', 'Ẻ'), ('Ẽ', 'Ẽ'), ('Ế', 'Ế'), ('Ề', 'Ề'),
+  ('Ể', 'Ể'), ('Ễ', 'Ễ'), ('Ệ', 'Ệ'), ('Ỉ', 'Ỉ'),
+  ('Ị', 'Ị'), ('Ọ', 'Ọ'), ('Ỏ', 'Ỏ'), ('Ố', 'Ố'),
+  ('Ồ', 'Ồ'), ('Ổ', 'Ổ'), ('Ỗ', 'Ỗ'), ('Ộ', 'Ộ'),
+  ('Ớ', 'Ớ'), ('Ờ', 'Ờ'), ('Ở', 'Ở'), ('Ỡ', 'Ỡ'),
+  ('Ợ', 'Ợ'), ('Ụ', 'Ụ'), ('Ủ', 'Ủ'), ('Ứ', 'Ứ'),
+  ('Ừ', 'Ừ'), ('Ử', 'Ử'), ('Ữ', 'Ữ'), ('Ự', 'Ự'),
+  ('Ỳ', 'Ỳ'), ('Ỵ', 'Ỵ'), ('Ỷ', 'Ỷ'), ('Ỹ', 'Ỹ'),
+  ('Ỻ', 'Ỻ'), ('Ỽ', 'Ỽ'), ('Ỿ', 'Ỿ'), ('Ἀ', 'Ἇ'),
+  ('Ἐ', 'Ἕ'), ('Ἠ', 'Ἧ'), ('Ἰ', 'Ἷ'), ('Ὀ', 'Ὅ'),
+  ('Ὑ', 'Ὑ'), ('Ὓ', 'Ὓ'), ('Ὕ', 'Ὕ'), ('Ὗ', 'Ὗ'),
+  ('Ὠ', 'Ὧ'), ('Ᾰ', 'Ά'), ('Ὲ', 'Ή'), ('Ῐ', 'Ί'),
+  ('Ῠ', 'Ῥ'), ('Ὸ', 'Ώ'), ('ℂ', 'ℂ'), ('ℇ', 'ℇ'),
+  ('ℋ', 'ℍ'), ('ℐ', 'ℒ'), ('ℕ', 'ℕ'), ('ℙ', 'ℝ'),
+  ('ℤ', 'ℤ'), ('Ω', 'Ω'), ('ℨ', 'ℨ'), ('K', 'ℭ'),
+  ('ℰ', 'ℳ'), ('ℾ', 'ℿ'), ('ⅅ', 'ⅅ'), ('Ⅰ', 'Ⅿ'),
+  ('Ↄ', 'Ↄ'), ('Ⓐ', 'Ⓩ'), ('Ⰰ', 'Ⱞ'), ('Ⱡ', 'Ⱡ'),
+  ('Ɫ', 'Ɽ'), ('Ⱨ', 'Ⱨ'), ('Ⱪ', 'Ⱪ'), ('Ⱬ', 'Ⱬ'),
+  ('Ɑ', 'Ɒ'), ('Ⱳ', 'Ⱳ'), ('Ⱶ', 'Ⱶ'), ('Ȿ', 'Ⲁ'),
+  ('Ⲃ', 'Ⲃ'), ('Ⲅ', 'Ⲅ'), ('Ⲇ', 'Ⲇ'), ('Ⲉ', 'Ⲉ'),
+  ('Ⲋ', 'Ⲋ'), ('Ⲍ', 'Ⲍ'), ('Ⲏ', 'Ⲏ'), ('Ⲑ', 'Ⲑ'),
+  ('Ⲓ', 'Ⲓ'), ('Ⲕ', 'Ⲕ'), ('Ⲗ', 'Ⲗ'), ('Ⲙ', 'Ⲙ'),
+  ('Ⲛ', 'Ⲛ'), ('Ⲝ', 'Ⲝ'), ('Ⲟ', 'Ⲟ'), ('Ⲡ', 'Ⲡ'),
+  ('Ⲣ', 'Ⲣ'), ('Ⲥ', 'Ⲥ'), ('Ⲧ', 'Ⲧ'), ('Ⲩ', 'Ⲩ'),
+  ('Ⲫ', 'Ⲫ'), ('Ⲭ', 'Ⲭ'), ('Ⲯ', 'Ⲯ'), ('Ⲱ', 'Ⲱ'),
+  ('Ⲳ', 'Ⲳ'), ('Ⲵ', 'Ⲵ'), ('Ⲷ', 'Ⲷ'), ('Ⲹ', 'Ⲹ'),
+  ('Ⲻ', 'Ⲻ'), ('Ⲽ', 'Ⲽ'), ('Ⲿ', 'Ⲿ'), ('Ⳁ', 'Ⳁ'),
+  ('Ⳃ', 'Ⳃ'), ('Ⳅ', 'Ⳅ'), ('Ⳇ', 'Ⳇ'), ('Ⳉ', 'Ⳉ'),
+  ('Ⳋ', 'Ⳋ'), ('Ⳍ', 'Ⳍ'), ('Ⳏ', 'Ⳏ'), ('Ⳑ', 'Ⳑ'),
+  ('Ⳓ', 'Ⳓ'), ('Ⳕ', 'Ⳕ'), ('Ⳗ', 'Ⳗ'), ('Ⳙ', 'Ⳙ'),
+  ('Ⳛ', 'Ⳛ'), ('Ⳝ', 'Ⳝ'), ('Ⳟ', 'Ⳟ'), ('Ⳡ', 'Ⳡ'),
+  ('Ⳣ', 'Ⳣ'), ('Ⳬ', 'Ⳬ'), ('Ⳮ', 'Ⳮ'), ('Ⳳ', 'Ⳳ'),
+  ('Ꙁ', 'Ꙁ'), ('Ꙃ', 'Ꙃ'), ('Ꙅ', 'Ꙅ'), ('Ꙇ', 'Ꙇ'),
+  ('Ꙉ', 'Ꙉ'), ('Ꙋ', 'Ꙋ'), ('Ꙍ', 'Ꙍ'), ('Ꙏ', 'Ꙏ'),
+  ('Ꙑ', 'Ꙑ'), ('Ꙓ', 'Ꙓ'), ('Ꙕ', 'Ꙕ'), ('Ꙗ', 'Ꙗ'),
+  ('Ꙙ', 'Ꙙ'), ('Ꙛ', 'Ꙛ'), ('Ꙝ', 'Ꙝ'), ('Ꙟ', 'Ꙟ'),
+  ('Ꙡ', 'Ꙡ'), ('Ꙣ', 'Ꙣ'), ('Ꙥ', 'Ꙥ'), ('Ꙧ', 'Ꙧ'),
+  ('Ꙩ', 'Ꙩ'), ('Ꙫ', 'Ꙫ'), ('Ꙭ', 'Ꙭ'), ('Ꚁ', 'Ꚁ'),
+  ('Ꚃ', 'Ꚃ'), ('Ꚅ', 'Ꚅ'), ('Ꚇ', 'Ꚇ'), ('Ꚉ', 'Ꚉ'),
+  ('Ꚋ', 'Ꚋ'), ('Ꚍ', 'Ꚍ'), ('Ꚏ', 'Ꚏ'), ('Ꚑ', 'Ꚑ'),
+  ('Ꚓ', 'Ꚓ'), ('Ꚕ', 'Ꚕ'), ('Ꚗ', 'Ꚗ'), ('Ꚙ', 'Ꚙ'),
+  ('Ꚛ', 'Ꚛ'), ('Ꜣ', 'Ꜣ'), ('Ꜥ', 'Ꜥ'), ('Ꜧ', 'Ꜧ'),
+  ('Ꜩ', 'Ꜩ'), ('Ꜫ', 'Ꜫ'), ('Ꜭ', 'Ꜭ'), ('Ꜯ', 'Ꜯ'),
+  ('Ꜳ', 'Ꜳ'), ('Ꜵ', 'Ꜵ'), ('Ꜷ', 'Ꜷ'), ('Ꜹ', 'Ꜹ'),
+  ('Ꜻ', 'Ꜻ'), ('Ꜽ', 'Ꜽ'), ('Ꜿ', 'Ꜿ'), ('Ꝁ', 'Ꝁ'),
+  ('Ꝃ', 'Ꝃ'), ('Ꝅ', 'Ꝅ'), ('Ꝇ', 'Ꝇ'), ('Ꝉ', 'Ꝉ'),
+  ('Ꝋ', 'Ꝋ'), ('Ꝍ', 'Ꝍ'), ('Ꝏ', 'Ꝏ'), ('Ꝑ', 'Ꝑ'),
+  ('Ꝓ', 'Ꝓ'), ('Ꝕ', 'Ꝕ'), ('Ꝗ', 'Ꝗ'), ('Ꝙ', 'Ꝙ'),
+  ('Ꝛ', 'Ꝛ'), ('Ꝝ', 'Ꝝ'), ('Ꝟ', 'Ꝟ'), ('Ꝡ', 'Ꝡ'),
+  ('Ꝣ', 'Ꝣ'), ('Ꝥ', 'Ꝥ'), ('Ꝧ', 'Ꝧ'), ('Ꝩ', 'Ꝩ'),
+  ('Ꝫ', 'Ꝫ'), ('Ꝭ', 'Ꝭ'), ('Ꝯ', 'Ꝯ'), ('Ꝺ', 'Ꝺ'),
+  ('Ꝼ', 'Ꝼ'), ('Ᵹ', 'Ꝿ'), ('Ꞁ', 'Ꞁ'), ('Ꞃ', 'Ꞃ'),
+  ('Ꞅ', 'Ꞅ'), ('Ꞇ', 'Ꞇ'), ('Ꞌ', 'Ꞌ'), ('Ɥ', 'Ɥ'),
+  ('Ꞑ', 'Ꞑ'), ('Ꞓ', 'Ꞓ'), ('Ꞗ', 'Ꞗ'), ('Ꞙ', 'Ꞙ'),
+  ('Ꞛ', 'Ꞛ'), ('Ꞝ', 'Ꞝ'), ('Ꞟ', 'Ꞟ'), ('Ꞡ', 'Ꞡ'),
+  ('Ꞣ', 'Ꞣ'), ('Ꞥ', 'Ꞥ'), ('Ꞧ', 'Ꞧ'), ('Ꞩ', 'Ꞩ'),
+  ('Ɦ', 'Ɪ'), ('Ʞ', 'Ꞵ'), ('Ꞷ', 'Ꞷ'), ('Ꞹ', 'Ꞹ'),
+  ('\u{a7ba}', '\u{a7ba}'), ('\u{a7bc}', '\u{a7bc}'),
+  ('\u{a7be}', '\u{a7be}'), ('\u{a7c2}', '\u{a7c2}'),
+  ('\u{a7c4}', '\u{a7c6}'), ('A', 'Z'), ('𐐀', '𐐧'),
+  ('𐒰', '𐓓'), ('𐲀', '𐲲'), ('𑢠', '𑢿'), ('𖹀', '𖹟'),
+  ('𝐀', '𝐙'), ('𝐴', '𝑍'), ('𝑨', '𝒁'), ('𝒜', '𝒜'),
+  ('𝒞', '𝒟'), ('𝒢', '𝒢'), ('𝒥', '𝒦'), ('𝒩', '𝒬'),
+  ('𝒮', '𝒵'), ('𝓐', '𝓩'), ('𝔄', '𝔅'), ('𝔇', '𝔊'),
+  ('𝔍', '𝔔'), ('𝔖', '𝔜'), ('𝔸', '𝔹'), ('𝔻', '𝔾'),
+  ('𝕀', '𝕄'), ('𝕆', '𝕆'), ('𝕊', '𝕐'), ('𝕬', '𝖅'),
+  ('𝖠', '𝖹'), ('𝗔', '𝗭'), ('𝘈', '𝘡'), ('𝘼', '𝙕'),
+  ('𝙰', '𝚉'), ('𝚨', '𝛀'), ('𝛢', '𝛺'), ('𝜜', '𝜴'),
+  ('𝝖', '𝝮'), ('𝞐', '𝞨'), ('𝟊', '𝟊'), ('𞤀', '𞤡'),
+  ('🄰', '🅉'), ('🅐', '🅩'), ('🅰', '🆉'),
+];
+
+pub const VARIATION_SELECTOR: &'static [(char, char)] = &[
+  ('\u{180b}', '\u{180d}'), ('\u{fe00}', '\u{fe0f}'),
+  ('\u{e0100}', '\u{e01ef}'),
+];
+
+pub const WHITE_SPACE: &'static [(char, char)] = &[
+  ('\t', '\r'), (' ', ' '), ('\u{85}', '\u{85}'), ('\u{a0}', '\u{a0}'),
+  ('\u{1680}', '\u{1680}'), ('\u{2000}', '\u{200a}'),
+  ('\u{2028}', '\u{2029}'), ('\u{202f}', '\u{202f}'),
+  ('\u{205f}', '\u{205f}'), ('\u{3000}', '\u{3000}'),
+];
+
+pub const XID_CONTINUE: &'static [(char, char)] = &[
+  ('0', '9'), ('A', 'Z'), ('_', '_'), ('a', 'z'), ('ª', 'ª'), ('µ', 'µ'),
+  ('·', '·'), ('º', 'º'), ('À', 'Ö'), ('Ø', 'ö'), ('ø', 'ˁ'),
+  ('ˆ', 'ˑ'), ('ˠ', 'ˤ'), ('ˬ', 'ˬ'), ('ˮ', 'ˮ'), ('\u{300}', 'ʹ'),
+  ('Ͷ', 'ͷ'), ('ͻ', 'ͽ'), ('Ϳ', 'Ϳ'), ('Ά', 'Ί'), ('Ό', 'Ό'),
+  ('Ύ', 'Ρ'), ('Σ', 'ϵ'), ('Ϸ', 'ҁ'), ('\u{483}', '\u{487}'),
+  ('Ҋ', 'ԯ'), ('Ա', 'Ֆ'), ('ՙ', 'ՙ'), ('ՠ', 'ֈ'),
+  ('\u{591}', '\u{5bd}'), ('\u{5bf}', '\u{5bf}'), ('\u{5c1}', '\u{5c2}'),
+  ('\u{5c4}', '\u{5c5}'), ('\u{5c7}', '\u{5c7}'), ('א', 'ת'), ('ׯ', 'ײ'),
+  ('\u{610}', '\u{61a}'), ('ؠ', '٩'), ('ٮ', 'ۓ'), ('ە', '\u{6dc}'),
+  ('\u{6df}', '\u{6e8}'), ('\u{6ea}', 'ۼ'), ('ۿ', 'ۿ'), ('ܐ', '\u{74a}'),
+  ('ݍ', 'ޱ'), ('߀', 'ߵ'), ('ߺ', 'ߺ'), ('\u{7fd}', '\u{7fd}'),
+  ('ࠀ', '\u{82d}'), ('ࡀ', '\u{85b}'), ('ࡠ', 'ࡪ'), ('ࢠ', 'ࢴ'),
+  ('ࢶ', 'ࢽ'), ('\u{8d3}', '\u{8e1}'), ('\u{8e3}', '\u{963}'),
+  ('०', '९'), ('ॱ', 'ঃ'), ('অ', 'ঌ'), ('এ', 'ঐ'),
+  ('ও', 'ন'), ('প', 'র'), ('ল', 'ল'), ('শ', 'হ'),
+  ('\u{9bc}', '\u{9c4}'), ('ে', 'ৈ'), ('ো', 'ৎ'),
+  ('\u{9d7}', '\u{9d7}'), ('ড়', 'ঢ়'), ('য়', '\u{9e3}'), ('০', 'ৱ'),
+  ('ৼ', 'ৼ'), ('\u{9fe}', '\u{9fe}'), ('\u{a01}', 'ਃ'), ('ਅ', 'ਊ'),
+  ('ਏ', 'ਐ'), ('ਓ', 'ਨ'), ('ਪ', 'ਰ'), ('ਲ', 'ਲ਼'),
+  ('ਵ', 'ਸ਼'), ('ਸ', 'ਹ'), ('\u{a3c}', '\u{a3c}'), ('ਾ', '\u{a42}'),
+  ('\u{a47}', '\u{a48}'), ('\u{a4b}', '\u{a4d}'), ('\u{a51}', '\u{a51}'),
+  ('ਖ਼', 'ੜ'), ('ਫ਼', 'ਫ਼'), ('੦', '\u{a75}'), ('\u{a81}', 'ઃ'),
+  ('અ', 'ઍ'), ('એ', 'ઑ'), ('ઓ', 'ન'), ('પ', 'ર'),
+  ('લ', 'ળ'), ('વ', 'હ'), ('\u{abc}', '\u{ac5}'), ('\u{ac7}', 'ૉ'),
+  ('ો', '\u{acd}'), ('ૐ', 'ૐ'), ('ૠ', '\u{ae3}'), ('૦', '૯'),
+  ('ૹ', '\u{aff}'), ('\u{b01}', 'ଃ'), ('ଅ', 'ଌ'), ('ଏ', 'ଐ'),
+  ('ଓ', 'ନ'), ('ପ', 'ର'), ('ଲ', 'ଳ'), ('ଵ', 'ହ'),
+  ('\u{b3c}', '\u{b44}'), ('େ', 'ୈ'), ('ୋ', '\u{b4d}'),
+  ('\u{b56}', '\u{b57}'), ('ଡ଼', 'ଢ଼'), ('ୟ', '\u{b63}'), ('୦', '୯'),
+  ('ୱ', 'ୱ'), ('\u{b82}', 'ஃ'), ('அ', 'ஊ'), ('எ', 'ஐ'),
+  ('ஒ', 'க'), ('ங', 'ச'), ('ஜ', 'ஜ'), ('ஞ', 'ட'),
+  ('ண', 'த'), ('ந', 'ப'), ('ம', 'ஹ'), ('\u{bbe}', 'ூ'),
+  ('ெ', 'ை'), ('ொ', '\u{bcd}'), ('ௐ', 'ௐ'), ('\u{bd7}', '\u{bd7}'),
+  ('௦', '௯'), ('\u{c00}', 'ఌ'), ('ఎ', 'ఐ'), ('ఒ', 'న'),
+  ('ప', 'హ'), ('ఽ', 'ౄ'), ('\u{c46}', '\u{c48}'),
+  ('\u{c4a}', '\u{c4d}'), ('\u{c55}', '\u{c56}'), ('ౘ', 'ౚ'),
+  ('ౠ', '\u{c63}'), ('౦', '౯'), ('ಀ', 'ಃ'), ('ಅ', 'ಌ'),
+  ('ಎ', 'ಐ'), ('ಒ', 'ನ'), ('ಪ', 'ಳ'), ('ವ', 'ಹ'),
+  ('\u{cbc}', 'ೄ'), ('\u{cc6}', 'ೈ'), ('ೊ', '\u{ccd}'),
+  ('\u{cd5}', '\u{cd6}'), ('ೞ', 'ೞ'), ('ೠ', '\u{ce3}'), ('೦', '೯'),
+  ('ೱ', 'ೲ'), ('\u{d00}', 'ഃ'), ('അ', 'ഌ'), ('എ', 'ഐ'),
+  ('ഒ', '\u{d44}'), ('െ', 'ൈ'), ('ൊ', 'ൎ'), ('ൔ', '\u{d57}'),
+  ('ൟ', '\u{d63}'), ('൦', '൯'), ('ൺ', 'ൿ'), ('ං', 'ඃ'),
+  ('අ', 'ඖ'), ('ක', 'න'), ('ඳ', 'ර'), ('ල', 'ල'),
+  ('ව', 'ෆ'), ('\u{dca}', '\u{dca}'), ('\u{dcf}', '\u{dd4}'),
+  ('\u{dd6}', '\u{dd6}'), ('ෘ', '\u{ddf}'), ('෦', '෯'), ('ෲ', 'ෳ'),
+  ('ก', '\u{e3a}'), ('เ', '\u{e4e}'), ('๐', '๙'), ('ກ', 'ຂ'),
+  ('ຄ', 'ຄ'), ('\u{e86}', 'ຊ'), ('\u{e8c}', 'ຣ'), ('ລ', 'ລ'),
+  ('ວ', 'ຽ'), ('ເ', 'ໄ'), ('ໆ', 'ໆ'), ('\u{ec8}', '\u{ecd}'),
+  ('໐', '໙'), ('ໜ', 'ໟ'), ('ༀ', 'ༀ'), ('\u{f18}', '\u{f19}'),
+  ('༠', '༩'), ('\u{f35}', '\u{f35}'), ('\u{f37}', '\u{f37}'),
+  ('\u{f39}', '\u{f39}'), ('༾', 'ཇ'), ('ཉ', 'ཬ'),
+  ('\u{f71}', '\u{f84}'), ('\u{f86}', '\u{f97}'), ('\u{f99}', '\u{fbc}'),
+  ('\u{fc6}', '\u{fc6}'), ('က', '၉'), ('ၐ', '\u{109d}'), ('Ⴀ', 'Ⴥ'),
+  ('Ⴧ', 'Ⴧ'), ('Ⴭ', 'Ⴭ'), ('ა', 'ჺ'), ('ჼ', 'ቈ'),
+  ('ቊ', 'ቍ'), ('ቐ', 'ቖ'), ('ቘ', 'ቘ'), ('ቚ', 'ቝ'),
+  ('በ', 'ኈ'), ('ኊ', 'ኍ'), ('ነ', 'ኰ'), ('ኲ', 'ኵ'),
+  ('ኸ', 'ኾ'), ('ዀ', 'ዀ'), ('ዂ', 'ዅ'), ('ወ', 'ዖ'),
+  ('ዘ', 'ጐ'), ('ጒ', 'ጕ'), ('ጘ', 'ፚ'), ('\u{135d}', '\u{135f}'),
+  ('፩', '፱'), ('ᎀ', 'ᎏ'), ('Ꭰ', 'Ᏽ'), ('ᏸ', 'ᏽ'),
+  ('ᐁ', 'ᙬ'), ('ᙯ', 'ᙿ'), ('ᚁ', 'ᚚ'), ('ᚠ', 'ᛪ'),
+  ('ᛮ', 'ᛸ'), ('ᜀ', 'ᜌ'), ('ᜎ', '\u{1714}'), ('ᜠ', '\u{1734}'),
+  ('ᝀ', '\u{1753}'), ('ᝠ', 'ᝬ'), ('ᝮ', 'ᝰ'),
+  ('\u{1772}', '\u{1773}'), ('ក', '\u{17d3}'), ('ៗ', 'ៗ'),
+  ('ៜ', '\u{17dd}'), ('០', '៩'), ('\u{180b}', '\u{180d}'),
+  ('᠐', '᠙'), ('ᠠ', 'ᡸ'), ('ᢀ', 'ᢪ'), ('ᢰ', 'ᣵ'),
+  ('ᤀ', 'ᤞ'), ('\u{1920}', 'ᤫ'), ('ᤰ', '\u{193b}'), ('᥆', 'ᥭ'),
+  ('ᥰ', 'ᥴ'), ('ᦀ', 'ᦫ'), ('ᦰ', 'ᧉ'), ('᧐', '᧚'),
+  ('ᨀ', '\u{1a1b}'), ('ᨠ', '\u{1a5e}'), ('\u{1a60}', '\u{1a7c}'),
+  ('\u{1a7f}', '᪉'), ('᪐', '᪙'), ('ᪧ', 'ᪧ'),
+  ('\u{1ab0}', '\u{1abd}'), ('\u{1b00}', 'ᭋ'), ('᭐', '᭙'),
+  ('\u{1b6b}', '\u{1b73}'), ('\u{1b80}', '᯳'), ('ᰀ', '\u{1c37}'),
+  ('᱀', '᱉'), ('ᱍ', 'ᱽ'), ('ᲀ', 'ᲈ'), ('Ა', 'Ჺ'),
+  ('Ჽ', 'Ჿ'), ('\u{1cd0}', '\u{1cd2}'), ('\u{1cd4}', '\u{1cfa}'),
+  ('ᴀ', '\u{1df9}'), ('\u{1dfb}', 'ἕ'), ('Ἐ', 'Ἕ'), ('ἠ', 'ὅ'),
+  ('Ὀ', 'Ὅ'), ('ὐ', 'ὗ'), ('Ὑ', 'Ὑ'), ('Ὓ', 'Ὓ'),
+  ('Ὕ', 'Ὕ'), ('Ὗ', 'ώ'), ('ᾀ', 'ᾴ'), ('ᾶ', 'ᾼ'),
+  ('ι', 'ι'), ('ῂ', 'ῄ'), ('ῆ', 'ῌ'), ('ῐ', 'ΐ'),
+  ('ῖ', 'Ί'), ('ῠ', 'Ῥ'), ('ῲ', 'ῴ'), ('ῶ', 'ῼ'),
+  ('‿', '⁀'), ('⁔', '⁔'), ('ⁱ', 'ⁱ'), ('ⁿ', 'ⁿ'),
+  ('ₐ', 'ₜ'), ('\u{20d0}', '\u{20dc}'), ('\u{20e1}', '\u{20e1}'),
+  ('\u{20e5}', '\u{20f0}'), ('ℂ', 'ℂ'), ('ℇ', 'ℇ'), ('ℊ', 'ℓ'),
+  ('ℕ', 'ℕ'), ('℘', 'ℝ'), ('ℤ', 'ℤ'), ('Ω', 'Ω'),
+  ('ℨ', 'ℨ'), ('K', 'ℹ'), ('ℼ', 'ℿ'), ('ⅅ', 'ⅉ'),
+  ('ⅎ', 'ⅎ'), ('Ⅰ', 'ↈ'), ('Ⰰ', 'Ⱞ'), ('ⰰ', 'ⱞ'),
+  ('Ⱡ', 'ⳤ'), ('Ⳬ', 'ⳳ'), ('ⴀ', 'ⴥ'), ('ⴧ', 'ⴧ'),
+  ('ⴭ', 'ⴭ'), ('ⴰ', 'ⵧ'), ('ⵯ', 'ⵯ'), ('\u{2d7f}', 'ⶖ'),
+  ('ⶠ', 'ⶦ'), ('ⶨ', 'ⶮ'), ('ⶰ', 'ⶶ'), ('ⶸ', 'ⶾ'),
+  ('ⷀ', 'ⷆ'), ('ⷈ', 'ⷎ'), ('ⷐ', 'ⷖ'), ('ⷘ', 'ⷞ'),
+  ('\u{2de0}', '\u{2dff}'), ('々', '〇'), ('〡', '\u{302f}'),
+  ('〱', '〵'), ('〸', '〼'), ('ぁ', 'ゖ'), ('\u{3099}', '\u{309a}'),
+  ('ゝ', 'ゟ'), ('ァ', 'ヺ'), ('ー', 'ヿ'), ('ㄅ', 'ㄯ'),
+  ('ㄱ', 'ㆎ'), ('ㆠ', 'ㆺ'), ('ㇰ', 'ㇿ'), ('㐀', '䶵'),
+  ('一', '鿯'), ('ꀀ', 'ꒌ'), ('ꓐ', 'ꓽ'), ('ꔀ', 'ꘌ'),
+  ('ꘐ', 'ꘫ'), ('Ꙁ', '\u{a66f}'), ('\u{a674}', '\u{a67d}'),
+  ('ꙿ', '\u{a6f1}'), ('ꜗ', 'ꜟ'), ('Ꜣ', 'ꞈ'), ('Ꞌ', '\u{a7bf}'),
+  ('\u{a7c2}', '\u{a7c6}'), ('ꟷ', 'ꠧ'), ('ꡀ', 'ꡳ'),
+  ('ꢀ', '\u{a8c5}'), ('꣐', '꣙'), ('\u{a8e0}', 'ꣷ'), ('ꣻ', 'ꣻ'),
+  ('ꣽ', '\u{a92d}'), ('ꤰ', '꥓'), ('ꥠ', 'ꥼ'), ('\u{a980}', '꧀'),
+  ('ꧏ', '꧙'), ('ꧠ', 'ꧾ'), ('ꨀ', '\u{aa36}'), ('ꩀ', 'ꩍ'),
+  ('꩐', '꩙'), ('ꩠ', 'ꩶ'), ('ꩺ', 'ꫂ'), ('ꫛ', 'ꫝ'),
+  ('ꫠ', 'ꫯ'), ('ꫲ', '\u{aaf6}'), ('ꬁ', 'ꬆ'), ('ꬉ', 'ꬎ'),
+  ('ꬑ', 'ꬖ'), ('ꬠ', 'ꬦ'), ('ꬨ', 'ꬮ'), ('ꬰ', 'ꭚ'),
+  ('ꭜ', '\u{ab67}'), ('ꭰ', 'ꯪ'), ('꯬', '\u{abed}'), ('꯰', '꯹'),
+  ('가', '힣'), ('ힰ', 'ퟆ'), ('ퟋ', 'ퟻ'), ('豈', '舘'),
+  ('並', '龎'), ('ff', 'st'), ('ﬓ', 'ﬗ'), ('יִ', 'ﬨ'),
+  ('שׁ', 'זּ'), ('טּ', 'לּ'), ('מּ', 'מּ'), ('נּ', 'סּ'),
+  ('ףּ', 'פּ'), ('צּ', 'ﮱ'), ('ﯓ', 'ﱝ'), ('ﱤ', 'ﴽ'),
+  ('ﵐ', 'ﶏ'), ('ﶒ', 'ﷇ'), ('ﷰ', 'ﷹ'), ('\u{fe00}', '\u{fe0f}'),
+  ('\u{fe20}', '\u{fe2f}'), ('︳', '︴'), ('﹍', '﹏'), ('ﹱ', 'ﹱ'),
+  ('ﹳ', 'ﹳ'), ('ﹷ', 'ﹷ'), ('ﹹ', 'ﹹ'), ('ﹻ', 'ﹻ'),
+  ('ﹽ', 'ﹽ'), ('ﹿ', 'ﻼ'), ('0', '9'), ('A', 'Z'),
+  ('_', '_'), ('a', 'z'), ('ヲ', 'ᄒ'), ('ᅡ', 'ᅦ'),
+  ('ᅧ', 'ᅬ'), ('ᅭ', 'ᅲ'), ('ᅳ', 'ᅵ'), ('𐀀', '𐀋'),
+  ('𐀍', '𐀦'), ('𐀨', '𐀺'), ('𐀼', '𐀽'), ('𐀿', '𐁍'),
+  ('𐁐', '𐁝'), ('𐂀', '𐃺'), ('𐅀', '𐅴'),
+  ('\u{101fd}', '\u{101fd}'), ('𐊀', '𐊜'), ('𐊠', '𐋐'),
+  ('\u{102e0}', '\u{102e0}'), ('𐌀', '𐌟'), ('𐌭', '𐍊'),
+  ('𐍐', '\u{1037a}'), ('𐎀', '𐎝'), ('𐎠', '𐏃'), ('𐏈', '𐏏'),
+  ('𐏑', '𐏕'), ('𐐀', '𐒝'), ('𐒠', '𐒩'), ('𐒰', '𐓓'),
+  ('𐓘', '𐓻'), ('𐔀', '𐔧'), ('𐔰', '𐕣'), ('𐘀', '𐜶'),
+  ('𐝀', '𐝕'), ('𐝠', '𐝧'), ('𐠀', '𐠅'), ('𐠈', '𐠈'),
+  ('𐠊', '𐠵'), ('𐠷', '𐠸'), ('𐠼', '𐠼'), ('𐠿', '𐡕'),
+  ('𐡠', '𐡶'), ('𐢀', '𐢞'), ('𐣠', '𐣲'), ('𐣴', '𐣵'),
+  ('𐤀', '𐤕'), ('𐤠', '𐤹'), ('𐦀', '𐦷'), ('𐦾', '𐦿'),
+  ('𐨀', '\u{10a03}'), ('\u{10a05}', '\u{10a06}'), ('\u{10a0c}', '𐨓'),
+  ('𐨕', '𐨗'), ('𐨙', '𐨵'), ('\u{10a38}', '\u{10a3a}'),
+  ('\u{10a3f}', '\u{10a3f}'), ('𐩠', '𐩼'), ('𐪀', '𐪜'),
+  ('𐫀', '𐫇'), ('𐫉', '\u{10ae6}'), ('𐬀', '𐬵'), ('𐭀', '𐭕'),
+  ('𐭠', '𐭲'), ('𐮀', '𐮑'), ('𐰀', '𐱈'), ('𐲀', '𐲲'),
+  ('𐳀', '𐳲'), ('𐴀', '\u{10d27}'), ('𐴰', '𐴹'), ('𐼀', '𐼜'),
+  ('𐼧', '𐼧'), ('𐼰', '\u{10f50}'), ('\u{10fe0}', '\u{10ff6}'),
+  ('𑀀', '\u{11046}'), ('𑁦', '𑁯'), ('\u{1107f}', '\u{110ba}'),
+  ('𑃐', '𑃨'), ('𑃰', '𑃹'), ('\u{11100}', '\u{11134}'),
+  ('𑄶', '𑄿'), ('𑅄', '𑅆'), ('𑅐', '\u{11173}'), ('𑅶', '𑅶'),
+  ('\u{11180}', '𑇄'), ('\u{111c9}', '\u{111cc}'), ('𑇐', '𑇚'),
+  ('𑇜', '𑇜'), ('𑈀', '𑈑'), ('𑈓', '\u{11237}'),
+  ('\u{1123e}', '\u{1123e}'), ('𑊀', '𑊆'), ('𑊈', '𑊈'),
+  ('𑊊', '𑊍'), ('𑊏', '𑊝'), ('𑊟', '𑊨'), ('𑊰', '\u{112ea}'),
+  ('𑋰', '𑋹'), ('\u{11300}', '𑌃'), ('𑌅', '𑌌'), ('𑌏', '𑌐'),
+  ('𑌓', '𑌨'), ('𑌪', '𑌰'), ('𑌲', '𑌳'), ('𑌵', '𑌹'),
+  ('\u{1133b}', '𑍄'), ('𑍇', '𑍈'), ('𑍋', '𑍍'), ('𑍐', '𑍐'),
+  ('\u{11357}', '\u{11357}'), ('𑍝', '𑍣'), ('\u{11366}', '\u{1136c}'),
+  ('\u{11370}', '\u{11374}'), ('𑐀', '𑑊'), ('𑑐', '𑑙'),
+  ('\u{1145e}', '\u{1145f}'), ('𑒀', '𑓅'), ('𑓇', '𑓇'),
+  ('𑓐', '𑓙'), ('𑖀', '\u{115b5}'), ('𑖸', '\u{115c0}'),
+  ('𑗘', '\u{115dd}'), ('𑘀', '\u{11640}'), ('𑙄', '𑙄'),
+  ('𑙐', '𑙙'), ('𑚀', '\u{116b8}'), ('𑛀', '𑛉'), ('𑜀', '𑜚'),
+  ('\u{1171d}', '\u{1172b}'), ('𑜰', '𑜹'), ('𑠀', '\u{1183a}'),
+  ('𑢠', '𑣩'), ('𑣿', '𑣿'), ('\u{119a0}', '\u{119a7}'),
+  ('\u{119aa}', '\u{119d7}'), ('\u{119da}', '\u{119e1}'),
+  ('\u{119e3}', '\u{119e4}'), ('𑨀', '\u{11a3e}'),
+  ('\u{11a47}', '\u{11a47}'), ('𑩐', '\u{11a99}'), ('𑪝', '𑪝'),
+  ('𑫀', '𑫸'), ('𑰀', '𑰈'), ('𑰊', '\u{11c36}'),
+  ('\u{11c38}', '𑱀'), ('𑱐', '𑱙'), ('𑱲', '𑲏'),
+  ('\u{11c92}', '\u{11ca7}'), ('𑲩', '\u{11cb6}'), ('𑴀', '𑴆'),
+  ('𑴈', '𑴉'), ('𑴋', '\u{11d36}'), ('\u{11d3a}', '\u{11d3a}'),
+  ('\u{11d3c}', '\u{11d3d}'), ('\u{11d3f}', '\u{11d47}'), ('𑵐', '𑵙'),
+  ('𑵠', '𑵥'), ('𑵧', '𑵨'), ('𑵪', '𑶎'),
+  ('\u{11d90}', '\u{11d91}'), ('𑶓', '𑶘'), ('𑶠', '𑶩'),
+  ('𑻠', '𑻶'), ('𒀀', '𒎙'), ('𒐀', '𒑮'), ('𒒀', '𒕃'),
+  ('𓀀', '𓐮'), ('𔐀', '𔙆'), ('𖠀', '𖨸'), ('𖩀', '𖩞'),
+  ('𖩠', '𖩩'), ('𖫐', '𖫭'), ('\u{16af0}', '\u{16af4}'),
+  ('𖬀', '\u{16b36}'), ('𖭀', '𖭃'), ('𖭐', '𖭙'), ('𖭣', '𖭷'),
+  ('𖭽', '𖮏'), ('𖹀', '𖹿'), ('𖼀', '\u{16f4a}'),
+  ('\u{16f4f}', '\u{16f87}'), ('\u{16f8f}', '𖾟'), ('𖿠', '𖿡'),
+  ('\u{16fe3}', '\u{16fe3}'), ('𗀀', '\u{187f7}'), ('𘠀', '𘫲'),
+  ('𛀀', '𛄞'), ('\u{1b150}', '\u{1b152}'), ('\u{1b164}', '\u{1b167}'),
+  ('𛅰', '𛋻'), ('𛰀', '𛱪'), ('𛱰', '𛱼'), ('𛲀', '𛲈'),
+  ('𛲐', '𛲙'), ('\u{1bc9d}', '\u{1bc9e}'), ('\u{1d165}', '\u{1d169}'),
+  ('𝅭', '\u{1d172}'), ('\u{1d17b}', '\u{1d182}'),
+  ('\u{1d185}', '\u{1d18b}'), ('\u{1d1aa}', '\u{1d1ad}'),
+  ('\u{1d242}', '\u{1d244}'), ('𝐀', '𝑔'), ('𝑖', '𝒜'),
+  ('𝒞', '𝒟'), ('𝒢', '𝒢'), ('𝒥', '𝒦'), ('𝒩', '𝒬'),
+  ('𝒮', '𝒹'), ('𝒻', '𝒻'), ('𝒽', '𝓃'), ('𝓅', '𝔅'),
+  ('𝔇', '𝔊'), ('𝔍', '𝔔'), ('𝔖', '𝔜'), ('𝔞', '𝔹'),
+  ('𝔻', '𝔾'), ('𝕀', '𝕄'), ('𝕆', '𝕆'), ('𝕊', '𝕐'),
+  ('𝕒', '𝚥'), ('𝚨', '𝛀'), ('𝛂', '𝛚'), ('𝛜', '𝛺'),
+  ('𝛼', '𝜔'), ('𝜖', '𝜴'), ('𝜶', '𝝎'), ('𝝐', '𝝮'),
+  ('𝝰', '𝞈'), ('𝞊', '𝞨'), ('𝞪', '𝟂'), ('𝟄', '𝟋'),
+  ('𝟎', '𝟿'), ('\u{1da00}', '\u{1da36}'), ('\u{1da3b}', '\u{1da6c}'),
+  ('\u{1da75}', '\u{1da75}'), ('\u{1da84}', '\u{1da84}'),
+  ('\u{1da9b}', '\u{1da9f}'), ('\u{1daa1}', '\u{1daaf}'),
+  ('\u{1e000}', '\u{1e006}'), ('\u{1e008}', '\u{1e018}'),
+  ('\u{1e01b}', '\u{1e021}'), ('\u{1e023}', '\u{1e024}'),
+  ('\u{1e026}', '\u{1e02a}'), ('\u{1e100}', '\u{1e12c}'),
+  ('\u{1e130}', '\u{1e13d}'), ('\u{1e140}', '\u{1e149}'),
+  ('\u{1e14e}', '\u{1e14e}'), ('\u{1e2c0}', '\u{1e2f9}'), ('𞠀', '𞣄'),
+  ('\u{1e8d0}', '\u{1e8d6}'), ('𞤀', '\u{1e94b}'), ('𞥐', '𞥙'),
+  ('𞸀', '𞸃'), ('𞸅', '𞸟'), ('𞸡', '𞸢'), ('𞸤', '𞸤'),
+  ('𞸧', '𞸧'), ('𞸩', '𞸲'), ('𞸴', '𞸷'), ('𞸹', '𞸹'),
+  ('𞸻', '𞸻'), ('𞹂', '𞹂'), ('𞹇', '𞹇'), ('𞹉', '𞹉'),
+  ('𞹋', '𞹋'), ('𞹍', '𞹏'), ('𞹑', '𞹒'), ('𞹔', '𞹔'),
+  ('𞹗', '𞹗'), ('𞹙', '𞹙'), ('𞹛', '𞹛'), ('𞹝', '𞹝'),
+  ('𞹟', '𞹟'), ('𞹡', '𞹢'), ('𞹤', '𞹤'), ('𞹧', '𞹪'),
+  ('𞹬', '𞹲'), ('𞹴', '𞹷'), ('𞹹', '𞹼'), ('𞹾', '𞹾'),
+  ('𞺀', '𞺉'), ('𞺋', '𞺛'), ('𞺡', '𞺣'), ('𞺥', '𞺩'),
+  ('𞺫', '𞺻'), ('𠀀', '𪛖'), ('𪜀', '𫜴'), ('𫝀', '𫠝'),
+  ('𫠠', '𬺡'), ('𬺰', '𮯠'), ('丽', '𪘀'),
+  ('\u{e0100}', '\u{e01ef}'),
+];
+
+pub const XID_START: &'static [(char, char)] = &[
+  ('A', 'Z'), ('a', 'z'), ('ª', 'ª'), ('µ', 'µ'), ('º', 'º'),
+  ('À', 'Ö'), ('Ø', 'ö'), ('ø', 'ˁ'), ('ˆ', 'ˑ'), ('ˠ', 'ˤ'),
+  ('ˬ', 'ˬ'), ('ˮ', 'ˮ'), ('Ͱ', 'ʹ'), ('Ͷ', 'ͷ'), ('ͻ', 'ͽ'),
+  ('Ϳ', 'Ϳ'), ('Ά', 'Ά'), ('Έ', 'Ί'), ('Ό', 'Ό'), ('Ύ', 'Ρ'),
+  ('Σ', 'ϵ'), ('Ϸ', 'ҁ'), ('Ҋ', 'ԯ'), ('Ա', 'Ֆ'), ('ՙ', 'ՙ'),
+  ('ՠ', 'ֈ'), ('א', 'ת'), ('ׯ', 'ײ'), ('ؠ', 'ي'), ('ٮ', 'ٯ'),
+  ('ٱ', 'ۓ'), ('ە', 'ە'), ('ۥ', 'ۦ'), ('ۮ', 'ۯ'), ('ۺ', 'ۼ'),
+  ('ۿ', 'ۿ'), ('ܐ', 'ܐ'), ('ܒ', 'ܯ'), ('ݍ', 'ޥ'), ('ޱ', 'ޱ'),
+  ('ߊ', 'ߪ'), ('ߴ', 'ߵ'), ('ߺ', 'ߺ'), ('ࠀ', 'ࠕ'), ('ࠚ', 'ࠚ'),
+  ('ࠤ', 'ࠤ'), ('ࠨ', 'ࠨ'), ('ࡀ', 'ࡘ'), ('ࡠ', 'ࡪ'),
+  ('ࢠ', 'ࢴ'), ('ࢶ', 'ࢽ'), ('ऄ', 'ह'), ('ऽ', 'ऽ'),
+  ('ॐ', 'ॐ'), ('क़', 'ॡ'), ('ॱ', 'ঀ'), ('অ', 'ঌ'),
+  ('এ', 'ঐ'), ('ও', 'ন'), ('প', 'র'), ('ল', 'ল'),
+  ('শ', 'হ'), ('ঽ', 'ঽ'), ('ৎ', 'ৎ'), ('ড়', 'ঢ়'),
+  ('য়', 'ৡ'), ('ৰ', 'ৱ'), ('ৼ', 'ৼ'), ('ਅ', 'ਊ'),
+  ('ਏ', 'ਐ'), ('ਓ', 'ਨ'), ('ਪ', 'ਰ'), ('ਲ', 'ਲ਼'),
+  ('ਵ', 'ਸ਼'), ('ਸ', 'ਹ'), ('ਖ਼', 'ੜ'), ('ਫ਼', 'ਫ਼'),
+  ('ੲ', 'ੴ'), ('અ', 'ઍ'), ('એ', 'ઑ'), ('ઓ', 'ન'),
+  ('પ', 'ર'), ('લ', 'ળ'), ('વ', 'હ'), ('ઽ', 'ઽ'),
+  ('ૐ', 'ૐ'), ('ૠ', 'ૡ'), ('ૹ', 'ૹ'), ('ଅ', 'ଌ'),
+  ('ଏ', 'ଐ'), ('ଓ', 'ନ'), ('ପ', 'ର'), ('ଲ', 'ଳ'),
+  ('ଵ', 'ହ'), ('ଽ', 'ଽ'), ('ଡ଼', 'ଢ଼'), ('ୟ', 'ୡ'),
+  ('ୱ', 'ୱ'), ('ஃ', 'ஃ'), ('அ', 'ஊ'), ('எ', 'ஐ'),
+  ('ஒ', 'க'), ('ங', 'ச'), ('ஜ', 'ஜ'), ('ஞ', 'ட'),
+  ('ண', 'த'), ('ந', 'ப'), ('ம', 'ஹ'), ('ௐ', 'ௐ'),
+  ('అ', 'ఌ'), ('ఎ', 'ఐ'), ('ఒ', 'న'), ('ప', 'హ'),
+  ('ఽ', 'ఽ'), ('ౘ', 'ౚ'), ('ౠ', 'ౡ'), ('ಀ', 'ಀ'),
+  ('ಅ', 'ಌ'), ('ಎ', 'ಐ'), ('ಒ', 'ನ'), ('ಪ', 'ಳ'),
+  ('ವ', 'ಹ'), ('ಽ', 'ಽ'), ('ೞ', 'ೞ'), ('ೠ', 'ೡ'),
+  ('ೱ', 'ೲ'), ('അ', 'ഌ'), ('എ', 'ഐ'), ('ഒ', 'ഺ'),
+  ('ഽ', 'ഽ'), ('ൎ', 'ൎ'), ('ൔ', 'ൖ'), ('ൟ', 'ൡ'),
+  ('ൺ', 'ൿ'), ('අ', 'ඖ'), ('ක', 'න'), ('ඳ', 'ර'),
+  ('ල', 'ල'), ('ව', 'ෆ'), ('ก', 'ะ'), ('า', 'า'),
+  ('เ', 'ๆ'), ('ກ', 'ຂ'), ('ຄ', 'ຄ'), ('\u{e86}', 'ຊ'),
+  ('\u{e8c}', 'ຣ'), ('ລ', 'ລ'), ('ວ', 'ະ'), ('າ', 'າ'),
+  ('ຽ', 'ຽ'), ('ເ', 'ໄ'), ('ໆ', 'ໆ'), ('ໜ', 'ໟ'),
+  ('ༀ', 'ༀ'), ('ཀ', 'ཇ'), ('ཉ', 'ཬ'), ('ྈ', 'ྌ'),
+  ('က', 'ဪ'), ('ဿ', 'ဿ'), ('ၐ', 'ၕ'), ('ၚ', 'ၝ'),
+  ('ၡ', 'ၡ'), ('ၥ', 'ၦ'), ('ၮ', 'ၰ'), ('ၵ', 'ႁ'),
+  ('ႎ', 'ႎ'), ('Ⴀ', 'Ⴥ'), ('Ⴧ', 'Ⴧ'), ('Ⴭ', 'Ⴭ'),
+  ('ა', 'ჺ'), ('ჼ', 'ቈ'), ('ቊ', 'ቍ'), ('ቐ', 'ቖ'),
+  ('ቘ', 'ቘ'), ('ቚ', 'ቝ'), ('በ', 'ኈ'), ('ኊ', 'ኍ'),
+  ('ነ', 'ኰ'), ('ኲ', 'ኵ'), ('ኸ', 'ኾ'), ('ዀ', 'ዀ'),
+  ('ዂ', 'ዅ'), ('ወ', 'ዖ'), ('ዘ', 'ጐ'), ('ጒ', 'ጕ'),
+  ('ጘ', 'ፚ'), ('ᎀ', 'ᎏ'), ('Ꭰ', 'Ᏽ'), ('ᏸ', 'ᏽ'),
+  ('ᐁ', 'ᙬ'), ('ᙯ', 'ᙿ'), ('ᚁ', 'ᚚ'), ('ᚠ', 'ᛪ'),
+  ('ᛮ', 'ᛸ'), ('ᜀ', 'ᜌ'), ('ᜎ', 'ᜑ'), ('ᜠ', 'ᜱ'),
+  ('ᝀ', 'ᝑ'), ('ᝠ', 'ᝬ'), ('ᝮ', 'ᝰ'), ('ក', 'ឳ'),
+  ('ៗ', 'ៗ'), ('ៜ', 'ៜ'), ('ᠠ', 'ᡸ'), ('ᢀ', 'ᢨ'),
+  ('ᢪ', 'ᢪ'), ('ᢰ', 'ᣵ'), ('ᤀ', 'ᤞ'), ('ᥐ', 'ᥭ'),
+  ('ᥰ', 'ᥴ'), ('ᦀ', 'ᦫ'), ('ᦰ', 'ᧉ'), ('ᨀ', 'ᨖ'),
+  ('ᨠ', 'ᩔ'), ('ᪧ', 'ᪧ'), ('ᬅ', 'ᬳ'), ('ᭅ', 'ᭋ'),
+  ('ᮃ', 'ᮠ'), ('ᮮ', 'ᮯ'), ('ᮺ', 'ᯥ'), ('ᰀ', 'ᰣ'),
+  ('ᱍ', 'ᱏ'), ('ᱚ', 'ᱽ'), ('ᲀ', 'ᲈ'), ('Ა', 'Ჺ'),
+  ('Ჽ', 'Ჿ'), ('ᳩ', 'ᳬ'), ('ᳮ', 'ᳳ'), ('ᳵ', 'ᳶ'),
+  ('\u{1cfa}', '\u{1cfa}'), ('ᴀ', 'ᶿ'), ('Ḁ', 'ἕ'), ('Ἐ', 'Ἕ'),
+  ('ἠ', 'ὅ'), ('Ὀ', 'Ὅ'), ('ὐ', 'ὗ'), ('Ὑ', 'Ὑ'),
+  ('Ὓ', 'Ὓ'), ('Ὕ', 'Ὕ'), ('Ὗ', 'ώ'), ('ᾀ', 'ᾴ'),
+  ('ᾶ', 'ᾼ'), ('ι', 'ι'), ('ῂ', 'ῄ'), ('ῆ', 'ῌ'),
+  ('ῐ', 'ΐ'), ('ῖ', 'Ί'), ('ῠ', 'Ῥ'), ('ῲ', 'ῴ'),
+  ('ῶ', 'ῼ'), ('ⁱ', 'ⁱ'), ('ⁿ', 'ⁿ'), ('ₐ', 'ₜ'),
+  ('ℂ', 'ℂ'), ('ℇ', 'ℇ'), ('ℊ', 'ℓ'), ('ℕ', 'ℕ'),
+  ('℘', 'ℝ'), ('ℤ', 'ℤ'), ('Ω', 'Ω'), ('ℨ', 'ℨ'),
+  ('K', 'ℹ'), ('ℼ', 'ℿ'), ('ⅅ', 'ⅉ'), ('ⅎ', 'ⅎ'),
+  ('Ⅰ', 'ↈ'), ('Ⰰ', 'Ⱞ'), ('ⰰ', 'ⱞ'), ('Ⱡ', 'ⳤ'),
+  ('Ⳬ', 'ⳮ'), ('Ⳳ', 'ⳳ'), ('ⴀ', 'ⴥ'), ('ⴧ', 'ⴧ'),
+  ('ⴭ', 'ⴭ'), ('ⴰ', 'ⵧ'), ('ⵯ', 'ⵯ'), ('ⶀ', 'ⶖ'),
+  ('ⶠ', 'ⶦ'), ('ⶨ', 'ⶮ'), ('ⶰ', 'ⶶ'), ('ⶸ', 'ⶾ'),
+  ('ⷀ', 'ⷆ'), ('ⷈ', 'ⷎ'), ('ⷐ', 'ⷖ'), ('ⷘ', 'ⷞ'),
+  ('々', '〇'), ('〡', '〩'), ('〱', '〵'), ('〸', '〼'),
+  ('ぁ', 'ゖ'), ('ゝ', 'ゟ'), ('ァ', 'ヺ'), ('ー', 'ヿ'),
+  ('ㄅ', 'ㄯ'), ('ㄱ', 'ㆎ'), ('ㆠ', 'ㆺ'), ('ㇰ', 'ㇿ'),
+  ('㐀', '䶵'), ('一', '鿯'), ('ꀀ', 'ꒌ'), ('ꓐ', 'ꓽ'),
+  ('ꔀ', 'ꘌ'), ('ꘐ', 'ꘟ'), ('ꘪ', 'ꘫ'), ('Ꙁ', 'ꙮ'),
+  ('ꙿ', 'ꚝ'), ('ꚠ', 'ꛯ'), ('ꜗ', 'ꜟ'), ('Ꜣ', 'ꞈ'),
+  ('Ꞌ', '\u{a7bf}'), ('\u{a7c2}', '\u{a7c6}'), ('ꟷ', 'ꠁ'),
+  ('ꠃ', 'ꠅ'), ('ꠇ', 'ꠊ'), ('ꠌ', 'ꠢ'), ('ꡀ', 'ꡳ'),
+  ('ꢂ', 'ꢳ'), ('ꣲ', 'ꣷ'), ('ꣻ', 'ꣻ'), ('ꣽ', 'ꣾ'),
+  ('ꤊ', 'ꤥ'), ('ꤰ', 'ꥆ'), ('ꥠ', 'ꥼ'), ('ꦄ', 'ꦲ'),
+  ('ꧏ', 'ꧏ'), ('ꧠ', 'ꧤ'), ('ꧦ', 'ꧯ'), ('ꧺ', 'ꧾ'),
+  ('ꨀ', 'ꨨ'), ('ꩀ', 'ꩂ'), ('ꩄ', 'ꩋ'), ('ꩠ', 'ꩶ'),
+  ('ꩺ', 'ꩺ'), ('ꩾ', 'ꪯ'), ('ꪱ', 'ꪱ'), ('ꪵ', 'ꪶ'),
+  ('ꪹ', 'ꪽ'), ('ꫀ', 'ꫀ'), ('ꫂ', 'ꫂ'), ('ꫛ', 'ꫝ'),
+  ('ꫠ', 'ꫪ'), ('ꫲ', 'ꫴ'), ('ꬁ', 'ꬆ'), ('ꬉ', 'ꬎ'),
+  ('ꬑ', 'ꬖ'), ('ꬠ', 'ꬦ'), ('ꬨ', 'ꬮ'), ('ꬰ', 'ꭚ'),
+  ('ꭜ', '\u{ab67}'), ('ꭰ', 'ꯢ'), ('가', '힣'), ('ힰ', 'ퟆ'),
+  ('ퟋ', 'ퟻ'), ('豈', '舘'), ('並', '龎'), ('ff', 'st'),
+  ('ﬓ', 'ﬗ'), ('יִ', 'יִ'), ('ײַ', 'ﬨ'), ('שׁ', 'זּ'),
+  ('טּ', 'לּ'), ('מּ', 'מּ'), ('נּ', 'סּ'), ('ףּ', 'פּ'),
+  ('צּ', 'ﮱ'), ('ﯓ', 'ﱝ'), ('ﱤ', 'ﴽ'), ('ﵐ', 'ﶏ'),
+  ('ﶒ', 'ﷇ'), ('ﷰ', 'ﷹ'), ('ﹱ', 'ﹱ'), ('ﹳ', 'ﹳ'),
+  ('ﹷ', 'ﹷ'), ('ﹹ', 'ﹹ'), ('ﹻ', 'ﹻ'), ('ﹽ', 'ﹽ'),
+  ('ﹿ', 'ﻼ'), ('A', 'Z'), ('a', 'z'), ('ヲ', 'ン'),
+  ('ᅠ', 'ᄒ'), ('ᅡ', 'ᅦ'), ('ᅧ', 'ᅬ'), ('ᅭ', 'ᅲ'),
+  ('ᅳ', 'ᅵ'), ('𐀀', '𐀋'), ('𐀍', '𐀦'), ('𐀨', '𐀺'),
+  ('𐀼', '𐀽'), ('𐀿', '𐁍'), ('𐁐', '𐁝'), ('𐂀', '𐃺'),
+  ('𐅀', '𐅴'), ('𐊀', '𐊜'), ('𐊠', '𐋐'), ('𐌀', '𐌟'),
+  ('𐌭', '𐍊'), ('𐍐', '𐍵'), ('𐎀', '𐎝'), ('𐎠', '𐏃'),
+  ('𐏈', '𐏏'), ('𐏑', '𐏕'), ('𐐀', '𐒝'), ('𐒰', '𐓓'),
+  ('𐓘', '𐓻'), ('𐔀', '𐔧'), ('𐔰', '𐕣'), ('𐘀', '𐜶'),
+  ('𐝀', '𐝕'), ('𐝠', '𐝧'), ('𐠀', '𐠅'), ('𐠈', '𐠈'),
+  ('𐠊', '𐠵'), ('𐠷', '𐠸'), ('𐠼', '𐠼'), ('𐠿', '𐡕'),
+  ('𐡠', '𐡶'), ('𐢀', '𐢞'), ('𐣠', '𐣲'), ('𐣴', '𐣵'),
+  ('𐤀', '𐤕'), ('𐤠', '𐤹'), ('𐦀', '𐦷'), ('𐦾', '𐦿'),
+  ('𐨀', '𐨀'), ('𐨐', '𐨓'), ('𐨕', '𐨗'), ('𐨙', '𐨵'),
+  ('𐩠', '𐩼'), ('𐪀', '𐪜'), ('𐫀', '𐫇'), ('𐫉', '𐫤'),
+  ('𐬀', '𐬵'), ('𐭀', '𐭕'), ('𐭠', '𐭲'), ('𐮀', '𐮑'),
+  ('𐰀', '𐱈'), ('𐲀', '𐲲'), ('𐳀', '𐳲'), ('𐴀', '𐴣'),
+  ('𐼀', '𐼜'), ('𐼧', '𐼧'), ('𐼰', '𐽅'),
+  ('\u{10fe0}', '\u{10ff6}'), ('𑀃', '𑀷'), ('𑂃', '𑂯'),
+  ('𑃐', '𑃨'), ('𑄃', '𑄦'), ('𑅄', '𑅄'), ('𑅐', '𑅲'),
+  ('𑅶', '𑅶'), ('𑆃', '𑆲'), ('𑇁', '𑇄'), ('𑇚', '𑇚'),
+  ('𑇜', '𑇜'), ('𑈀', '𑈑'), ('𑈓', '𑈫'), ('𑊀', '𑊆'),
+  ('𑊈', '𑊈'), ('𑊊', '𑊍'), ('𑊏', '𑊝'), ('𑊟', '𑊨'),
+  ('𑊰', '𑋞'), ('𑌅', '𑌌'), ('𑌏', '𑌐'), ('𑌓', '𑌨'),
+  ('𑌪', '𑌰'), ('𑌲', '𑌳'), ('𑌵', '𑌹'), ('𑌽', '𑌽'),
+  ('𑍐', '𑍐'), ('𑍝', '𑍡'), ('𑐀', '𑐴'), ('𑑇', '𑑊'),
+  ('\u{1145f}', '\u{1145f}'), ('𑒀', '𑒯'), ('𑓄', '𑓅'),
+  ('𑓇', '𑓇'), ('𑖀', '𑖮'), ('𑗘', '𑗛'), ('𑘀', '𑘯'),
+  ('𑙄', '𑙄'), ('𑚀', '𑚪'), ('\u{116b8}', '\u{116b8}'),
+  ('𑜀', '𑜚'), ('𑠀', '𑠫'), ('𑢠', '𑣟'), ('𑣿', '𑣿'),
+  ('\u{119a0}', '\u{119a7}'), ('\u{119aa}', '\u{119d0}'),
+  ('\u{119e1}', '\u{119e1}'), ('\u{119e3}', '\u{119e3}'), ('𑨀', '𑨀'),
+  ('𑨋', '𑨲'), ('𑨺', '𑨺'), ('𑩐', '𑩐'), ('𑩜', '𑪉'),
+  ('𑪝', '𑪝'), ('𑫀', '𑫸'), ('𑰀', '𑰈'), ('𑰊', '𑰮'),
+  ('𑱀', '𑱀'), ('𑱲', '𑲏'), ('𑴀', '𑴆'), ('𑴈', '𑴉'),
+  ('𑴋', '𑴰'), ('𑵆', '𑵆'), ('𑵠', '𑵥'), ('𑵧', '𑵨'),
+  ('𑵪', '𑶉'), ('𑶘', '𑶘'), ('𑻠', '𑻲'), ('𒀀', '𒎙'),
+  ('𒐀', '𒑮'), ('𒒀', '𒕃'), ('𓀀', '𓐮'), ('𔐀', '𔙆'),
+  ('𖠀', '𖨸'), ('𖩀', '𖩞'), ('𖫐', '𖫭'), ('𖬀', '𖬯'),
+  ('𖭀', '𖭃'), ('𖭣', '𖭷'), ('𖭽', '𖮏'), ('𖹀', '𖹿'),
+  ('𖼀', '\u{16f4a}'), ('𖽐', '𖽐'), ('𖾓', '𖾟'), ('𖿠', '𖿡'),
+  ('\u{16fe3}', '\u{16fe3}'), ('𗀀', '\u{187f7}'), ('𘠀', '𘫲'),
+  ('𛀀', '𛄞'), ('\u{1b150}', '\u{1b152}'), ('\u{1b164}', '\u{1b167}'),
+  ('𛅰', '𛋻'), ('𛰀', '𛱪'), ('𛱰', '𛱼'), ('𛲀', '𛲈'),
+  ('𛲐', '𛲙'), ('𝐀', '𝑔'), ('𝑖', '𝒜'), ('𝒞', '𝒟'),
+  ('𝒢', '𝒢'), ('𝒥', '𝒦'), ('𝒩', '𝒬'), ('𝒮', '𝒹'),
+  ('𝒻', '𝒻'), ('𝒽', '𝓃'), ('𝓅', '𝔅'), ('𝔇', '𝔊'),
+  ('𝔍', '𝔔'), ('𝔖', '𝔜'), ('𝔞', '𝔹'), ('𝔻', '𝔾'),
+  ('𝕀', '𝕄'), ('𝕆', '𝕆'), ('𝕊', '𝕐'), ('𝕒', '𝚥'),
+  ('𝚨', '𝛀'), ('𝛂', '𝛚'), ('𝛜', '𝛺'), ('𝛼', '𝜔'),
+  ('𝜖', '𝜴'), ('𝜶', '𝝎'), ('𝝐', '𝝮'), ('𝝰', '𝞈'),
+  ('𝞊', '𝞨'), ('𝞪', '𝟂'), ('𝟄', '𝟋'),
+  ('\u{1e100}', '\u{1e12c}'), ('\u{1e137}', '\u{1e13d}'),
+  ('\u{1e14e}', '\u{1e14e}'), ('\u{1e2c0}', '\u{1e2eb}'), ('𞠀', '𞣄'),
+  ('𞤀', '𞥃'), ('\u{1e94b}', '\u{1e94b}'), ('𞸀', '𞸃'),
+  ('𞸅', '𞸟'), ('𞸡', '𞸢'), ('𞸤', '𞸤'), ('𞸧', '𞸧'),
+  ('𞸩', '𞸲'), ('𞸴', '𞸷'), ('𞸹', '𞸹'), ('𞸻', '𞸻'),
+  ('𞹂', '𞹂'), ('𞹇', '𞹇'), ('𞹉', '𞹉'), ('𞹋', '𞹋'),
+  ('𞹍', '𞹏'), ('𞹑', '𞹒'), ('𞹔', '𞹔'), ('𞹗', '𞹗'),
+  ('𞹙', '𞹙'), ('𞹛', '𞹛'), ('𞹝', '𞹝'), ('𞹟', '𞹟'),
+  ('𞹡', '𞹢'), ('𞹤', '𞹤'), ('𞹧', '𞹪'), ('𞹬', '𞹲'),
+  ('𞹴', '𞹷'), ('𞹹', '𞹼'), ('𞹾', '𞹾'), ('𞺀', '𞺉'),
+  ('𞺋', '𞺛'), ('𞺡', '𞺣'), ('𞺥', '𞺩'), ('𞺫', '𞺻'),
+  ('𠀀', '𪛖'), ('𪜀', '𫜴'), ('𫝀', '𫠝'), ('𫠠', '𬺡'),
+  ('𬺰', '𮯠'), ('丽', '𪘀'),
+];
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/unicode_tables/property_names.rs.html b/target/doc/src/regex_syntax/unicode_tables/property_names.rs.html new file mode 100644 index 0000000..34e2ac1 --- /dev/null +++ b/target/doc/src/regex_syntax/unicode_tables/property_names.rs.html @@ -0,0 +1,305 @@ +property_names.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+
+// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
+//
+//  ucd-generate property-names /tmp/ucd-12.1.0/
+//
+// ucd-generate is available on crates.io.
+
+pub const PROPERTY_NAMES: &'static [(&'static str, &'static str)] = &[
+  ("age", "Age"), ("ahex", "ASCII_Hex_Digit"), ("alpha", "Alphabetic"),
+  ("alphabetic", "Alphabetic"), ("asciihexdigit", "ASCII_Hex_Digit"),
+  ("bc", "Bidi_Class"), ("bidic", "Bidi_Control"),
+  ("bidiclass", "Bidi_Class"), ("bidicontrol", "Bidi_Control"),
+  ("bidim", "Bidi_Mirrored"), ("bidimirrored", "Bidi_Mirrored"),
+  ("bidimirroringglyph", "Bidi_Mirroring_Glyph"),
+  ("bidipairedbracket", "Bidi_Paired_Bracket"),
+  ("bidipairedbrackettype", "Bidi_Paired_Bracket_Type"), ("blk", "Block"),
+  ("block", "Block"), ("bmg", "Bidi_Mirroring_Glyph"),
+  ("bpb", "Bidi_Paired_Bracket"), ("bpt", "Bidi_Paired_Bracket_Type"),
+  ("canonicalcombiningclass", "Canonical_Combining_Class"),
+  ("cased", "Cased"), ("casefolding", "Case_Folding"),
+  ("caseignorable", "Case_Ignorable"), ("ccc", "Canonical_Combining_Class"),
+  ("ce", "Composition_Exclusion"), ("cf", "Case_Folding"),
+  ("changeswhencasefolded", "Changes_When_Casefolded"),
+  ("changeswhencasemapped", "Changes_When_Casemapped"),
+  ("changeswhenlowercased", "Changes_When_Lowercased"),
+  ("changeswhennfkccasefolded", "Changes_When_NFKC_Casefolded"),
+  ("changeswhentitlecased", "Changes_When_Titlecased"),
+  ("changeswhenuppercased", "Changes_When_Uppercased"),
+  ("ci", "Case_Ignorable"), ("cjkaccountingnumeric", "kAccountingNumeric"),
+  ("cjkcompatibilityvariant", "kCompatibilityVariant"),
+  ("cjkiicore", "kIICore"), ("cjkirggsource", "kIRG_GSource"),
+  ("cjkirghsource", "kIRG_HSource"), ("cjkirgjsource", "kIRG_JSource"),
+  ("cjkirgkpsource", "kIRG_KPSource"), ("cjkirgksource", "kIRG_KSource"),
+  ("cjkirgmsource", "kIRG_MSource"), ("cjkirgtsource", "kIRG_TSource"),
+  ("cjkirgusource", "kIRG_USource"), ("cjkirgvsource", "kIRG_VSource"),
+  ("cjkothernumeric", "kOtherNumeric"),
+  ("cjkprimarynumeric", "kPrimaryNumeric"), ("cjkrsunicode", "kRSUnicode"),
+  ("compex", "Full_Composition_Exclusion"),
+  ("compositionexclusion", "Composition_Exclusion"),
+  ("cwcf", "Changes_When_Casefolded"), ("cwcm", "Changes_When_Casemapped"),
+  ("cwkcf", "Changes_When_NFKC_Casefolded"),
+  ("cwl", "Changes_When_Lowercased"), ("cwt", "Changes_When_Titlecased"),
+  ("cwu", "Changes_When_Uppercased"), ("dash", "Dash"),
+  ("decompositionmapping", "Decomposition_Mapping"),
+  ("decompositiontype", "Decomposition_Type"),
+  ("defaultignorablecodepoint", "Default_Ignorable_Code_Point"),
+  ("dep", "Deprecated"), ("deprecated", "Deprecated"),
+  ("di", "Default_Ignorable_Code_Point"), ("dia", "Diacritic"),
+  ("diacritic", "Diacritic"), ("dm", "Decomposition_Mapping"),
+  ("dt", "Decomposition_Type"), ("ea", "East_Asian_Width"),
+  ("eastasianwidth", "East_Asian_Width"), ("emoji", "Emoji"),
+  ("emojicomponent", "Emoji_Component"), ("emojimodifier", "Emoji_Modifier"),
+  ("emojimodifierbase", "Emoji_Modifier_Base"),
+  ("emojipresentation", "Emoji_Presentation"),
+  ("equideo", "Equivalent_Unified_Ideograph"),
+  ("equivalentunifiedideograph", "Equivalent_Unified_Ideograph"),
+  ("expandsonnfc", "Expands_On_NFC"), ("expandsonnfd", "Expands_On_NFD"),
+  ("expandsonnfkc", "Expands_On_NFKC"), ("expandsonnfkd", "Expands_On_NFKD"),
+  ("ext", "Extender"), ("extendedpictographic", "Extended_Pictographic"),
+  ("extender", "Extender"), ("fcnfkc", "FC_NFKC_Closure"),
+  ("fcnfkcclosure", "FC_NFKC_Closure"),
+  ("fullcompositionexclusion", "Full_Composition_Exclusion"),
+  ("gc", "General_Category"), ("gcb", "Grapheme_Cluster_Break"),
+  ("generalcategory", "General_Category"), ("graphemebase", "Grapheme_Base"),
+  ("graphemeclusterbreak", "Grapheme_Cluster_Break"),
+  ("graphemeextend", "Grapheme_Extend"), ("graphemelink", "Grapheme_Link"),
+  ("grbase", "Grapheme_Base"), ("grext", "Grapheme_Extend"),
+  ("grlink", "Grapheme_Link"), ("hangulsyllabletype", "Hangul_Syllable_Type"),
+  ("hex", "Hex_Digit"), ("hexdigit", "Hex_Digit"),
+  ("hst", "Hangul_Syllable_Type"), ("hyphen", "Hyphen"),
+  ("idc", "ID_Continue"), ("idcontinue", "ID_Continue"),
+  ("ideo", "Ideographic"), ("ideographic", "Ideographic"),
+  ("ids", "ID_Start"), ("idsb", "IDS_Binary_Operator"),
+  ("idsbinaryoperator", "IDS_Binary_Operator"),
+  ("idst", "IDS_Trinary_Operator"), ("idstart", "ID_Start"),
+  ("idstrinaryoperator", "IDS_Trinary_Operator"),
+  ("indicpositionalcategory", "Indic_Positional_Category"),
+  ("indicsyllabiccategory", "Indic_Syllabic_Category"),
+  ("inpc", "Indic_Positional_Category"), ("insc", "Indic_Syllabic_Category"),
+  ("isc", "ISO_Comment"), ("jamoshortname", "Jamo_Short_Name"),
+  ("jg", "Joining_Group"), ("joinc", "Join_Control"),
+  ("joincontrol", "Join_Control"), ("joininggroup", "Joining_Group"),
+  ("joiningtype", "Joining_Type"), ("jsn", "Jamo_Short_Name"),
+  ("jt", "Joining_Type"), ("kaccountingnumeric", "kAccountingNumeric"),
+  ("kcompatibilityvariant", "kCompatibilityVariant"), ("kiicore", "kIICore"),
+  ("kirggsource", "kIRG_GSource"), ("kirghsource", "kIRG_HSource"),
+  ("kirgjsource", "kIRG_JSource"), ("kirgkpsource", "kIRG_KPSource"),
+  ("kirgksource", "kIRG_KSource"), ("kirgmsource", "kIRG_MSource"),
+  ("kirgtsource", "kIRG_TSource"), ("kirgusource", "kIRG_USource"),
+  ("kirgvsource", "kIRG_VSource"), ("kothernumeric", "kOtherNumeric"),
+  ("kprimarynumeric", "kPrimaryNumeric"), ("krsunicode", "kRSUnicode"),
+  ("lb", "Line_Break"), ("lc", "Lowercase_Mapping"),
+  ("linebreak", "Line_Break"), ("loe", "Logical_Order_Exception"),
+  ("logicalorderexception", "Logical_Order_Exception"),
+  ("lower", "Lowercase"), ("lowercase", "Lowercase"),
+  ("lowercasemapping", "Lowercase_Mapping"), ("math", "Math"), ("na", "Name"),
+  ("na1", "Unicode_1_Name"), ("name", "Name"), ("namealias", "Name_Alias"),
+  ("nchar", "Noncharacter_Code_Point"), ("nfcqc", "NFC_Quick_Check"),
+  ("nfcquickcheck", "NFC_Quick_Check"), ("nfdqc", "NFD_Quick_Check"),
+  ("nfdquickcheck", "NFD_Quick_Check"), ("nfkccasefold", "NFKC_Casefold"),
+  ("nfkccf", "NFKC_Casefold"), ("nfkcqc", "NFKC_Quick_Check"),
+  ("nfkcquickcheck", "NFKC_Quick_Check"), ("nfkdqc", "NFKD_Quick_Check"),
+  ("nfkdquickcheck", "NFKD_Quick_Check"),
+  ("noncharactercodepoint", "Noncharacter_Code_Point"),
+  ("nt", "Numeric_Type"), ("numerictype", "Numeric_Type"),
+  ("numericvalue", "Numeric_Value"), ("nv", "Numeric_Value"),
+  ("oalpha", "Other_Alphabetic"), ("ocomment", "ISO_Comment"),
+  ("odi", "Other_Default_Ignorable_Code_Point"),
+  ("ogrext", "Other_Grapheme_Extend"), ("oidc", "Other_ID_Continue"),
+  ("oids", "Other_ID_Start"), ("olower", "Other_Lowercase"),
+  ("omath", "Other_Math"), ("otheralphabetic", "Other_Alphabetic"),
+  ("otherdefaultignorablecodepoint", "Other_Default_Ignorable_Code_Point"),
+  ("othergraphemeextend", "Other_Grapheme_Extend"),
+  ("otheridcontinue", "Other_ID_Continue"),
+  ("otheridstart", "Other_ID_Start"), ("otherlowercase", "Other_Lowercase"),
+  ("othermath", "Other_Math"), ("otheruppercase", "Other_Uppercase"),
+  ("oupper", "Other_Uppercase"), ("patsyn", "Pattern_Syntax"),
+  ("patternsyntax", "Pattern_Syntax"),
+  ("patternwhitespace", "Pattern_White_Space"),
+  ("patws", "Pattern_White_Space"), ("pcm", "Prepended_Concatenation_Mark"),
+  ("prependedconcatenationmark", "Prepended_Concatenation_Mark"),
+  ("qmark", "Quotation_Mark"), ("quotationmark", "Quotation_Mark"),
+  ("radical", "Radical"), ("regionalindicator", "Regional_Indicator"),
+  ("ri", "Regional_Indicator"), ("sb", "Sentence_Break"), ("sc", "Script"),
+  ("scf", "Simple_Case_Folding"), ("script", "Script"),
+  ("scriptextensions", "Script_Extensions"), ("scx", "Script_Extensions"),
+  ("sd", "Soft_Dotted"), ("sentencebreak", "Sentence_Break"),
+  ("sentenceterminal", "Sentence_Terminal"), ("sfc", "Simple_Case_Folding"),
+  ("simplecasefolding", "Simple_Case_Folding"),
+  ("simplelowercasemapping", "Simple_Lowercase_Mapping"),
+  ("simpletitlecasemapping", "Simple_Titlecase_Mapping"),
+  ("simpleuppercasemapping", "Simple_Uppercase_Mapping"),
+  ("slc", "Simple_Lowercase_Mapping"), ("softdotted", "Soft_Dotted"),
+  ("space", "White_Space"), ("stc", "Simple_Titlecase_Mapping"),
+  ("sterm", "Sentence_Terminal"), ("suc", "Simple_Uppercase_Mapping"),
+  ("tc", "Titlecase_Mapping"), ("term", "Terminal_Punctuation"),
+  ("terminalpunctuation", "Terminal_Punctuation"),
+  ("titlecasemapping", "Titlecase_Mapping"), ("uc", "Uppercase_Mapping"),
+  ("uideo", "Unified_Ideograph"), ("unicode1name", "Unicode_1_Name"),
+  ("unicoderadicalstroke", "kRSUnicode"),
+  ("unifiedideograph", "Unified_Ideograph"), ("upper", "Uppercase"),
+  ("uppercase", "Uppercase"), ("uppercasemapping", "Uppercase_Mapping"),
+  ("urs", "kRSUnicode"), ("variationselector", "Variation_Selector"),
+  ("verticalorientation", "Vertical_Orientation"),
+  ("vo", "Vertical_Orientation"), ("vs", "Variation_Selector"),
+  ("wb", "Word_Break"), ("whitespace", "White_Space"),
+  ("wordbreak", "Word_Break"), ("wspace", "White_Space"),
+  ("xidc", "XID_Continue"), ("xidcontinue", "XID_Continue"),
+  ("xids", "XID_Start"), ("xidstart", "XID_Start"),
+  ("xonfc", "Expands_On_NFC"), ("xonfd", "Expands_On_NFD"),
+  ("xonfkc", "Expands_On_NFKC"), ("xonfkd", "Expands_On_NFKD"),
+];
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/unicode_tables/property_values.rs.html b/target/doc/src/regex_syntax/unicode_tables/property_values.rs.html new file mode 100644 index 0000000..2eb3d76 --- /dev/null +++ b/target/doc/src/regex_syntax/unicode_tables/property_values.rs.html @@ -0,0 +1,669 @@ +property_values.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+
+// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
+//
+//  ucd-generate property-values /tmp/ucd-12.1.0/ --include gc,script,scx,age,gcb,wb,sb
+//
+// ucd-generate is available on crates.io.
+
+pub const PROPERTY_VALUES: &'static [(&'static str, &'static [(&'static str, &'static str)])] = &[
+  ("Age", &[("1.1", "V1_1"), ("10.0", "V10_0"), ("11.0", "V11_0"),
+  ("12.0", "V12_0"), ("12.1", "V12_1"), ("2.0", "V2_0"), ("2.1", "V2_1"),
+  ("3.0", "V3_0"), ("3.1", "V3_1"), ("3.2", "V3_2"), ("4.0", "V4_0"),
+  ("4.1", "V4_1"), ("5.0", "V5_0"), ("5.1", "V5_1"), ("5.2", "V5_2"),
+  ("6.0", "V6_0"), ("6.1", "V6_1"), ("6.2", "V6_2"), ("6.3", "V6_3"),
+  ("7.0", "V7_0"), ("8.0", "V8_0"), ("9.0", "V9_0"), ("na", "Unassigned"),
+  ("unassigned", "Unassigned"), ("v100", "V10_0"), ("v11", "V1_1"),
+  ("v110", "V11_0"), ("v120", "V12_0"), ("v121", "V12_1"), ("v20", "V2_0"),
+  ("v21", "V2_1"), ("v30", "V3_0"), ("v31", "V3_1"), ("v32", "V3_2"),
+  ("v40", "V4_0"), ("v41", "V4_1"), ("v50", "V5_0"), ("v51", "V5_1"),
+  ("v52", "V5_2"), ("v60", "V6_0"), ("v61", "V6_1"), ("v62", "V6_2"),
+  ("v63", "V6_3"), ("v70", "V7_0"), ("v80", "V8_0"), ("v90", "V9_0"), ]),
+
+  ("General_Category", &[("c", "Other"), ("casedletter", "Cased_Letter"),
+  ("cc", "Control"), ("cf", "Format"),
+  ("closepunctuation", "Close_Punctuation"), ("cn", "Unassigned"),
+  ("cntrl", "Control"), ("co", "Private_Use"), ("combiningmark", "Mark"),
+  ("connectorpunctuation", "Connector_Punctuation"), ("control", "Control"),
+  ("cs", "Surrogate"), ("currencysymbol", "Currency_Symbol"),
+  ("dashpunctuation", "Dash_Punctuation"),
+  ("decimalnumber", "Decimal_Number"), ("digit", "Decimal_Number"),
+  ("enclosingmark", "Enclosing_Mark"),
+  ("finalpunctuation", "Final_Punctuation"), ("format", "Format"),
+  ("initialpunctuation", "Initial_Punctuation"), ("l", "Letter"),
+  ("lc", "Cased_Letter"), ("letter", "Letter"),
+  ("letternumber", "Letter_Number"), ("lineseparator", "Line_Separator"),
+  ("ll", "Lowercase_Letter"), ("lm", "Modifier_Letter"),
+  ("lo", "Other_Letter"), ("lowercaseletter", "Lowercase_Letter"),
+  ("lt", "Titlecase_Letter"), ("lu", "Uppercase_Letter"), ("m", "Mark"),
+  ("mark", "Mark"), ("mathsymbol", "Math_Symbol"), ("mc", "Spacing_Mark"),
+  ("me", "Enclosing_Mark"), ("mn", "Nonspacing_Mark"),
+  ("modifierletter", "Modifier_Letter"),
+  ("modifiersymbol", "Modifier_Symbol"), ("n", "Number"),
+  ("nd", "Decimal_Number"), ("nl", "Letter_Number"), ("no", "Other_Number"),
+  ("nonspacingmark", "Nonspacing_Mark"), ("number", "Number"),
+  ("openpunctuation", "Open_Punctuation"), ("other", "Other"),
+  ("otherletter", "Other_Letter"), ("othernumber", "Other_Number"),
+  ("otherpunctuation", "Other_Punctuation"), ("othersymbol", "Other_Symbol"),
+  ("p", "Punctuation"), ("paragraphseparator", "Paragraph_Separator"),
+  ("pc", "Connector_Punctuation"), ("pd", "Dash_Punctuation"),
+  ("pe", "Close_Punctuation"), ("pf", "Final_Punctuation"),
+  ("pi", "Initial_Punctuation"), ("po", "Other_Punctuation"),
+  ("privateuse", "Private_Use"), ("ps", "Open_Punctuation"),
+  ("punct", "Punctuation"), ("punctuation", "Punctuation"), ("s", "Symbol"),
+  ("sc", "Currency_Symbol"), ("separator", "Separator"),
+  ("sk", "Modifier_Symbol"), ("sm", "Math_Symbol"), ("so", "Other_Symbol"),
+  ("spaceseparator", "Space_Separator"), ("spacingmark", "Spacing_Mark"),
+  ("surrogate", "Surrogate"), ("symbol", "Symbol"),
+  ("titlecaseletter", "Titlecase_Letter"), ("unassigned", "Unassigned"),
+  ("uppercaseletter", "Uppercase_Letter"), ("z", "Separator"),
+  ("zl", "Line_Separator"), ("zp", "Paragraph_Separator"),
+  ("zs", "Space_Separator"), ]),
+
+  ("Grapheme_Cluster_Break", &[("cn", "Control"), ("control", "Control"),
+  ("cr", "CR"), ("eb", "E_Base"), ("ebase", "E_Base"),
+  ("ebasegaz", "E_Base_GAZ"), ("ebg", "E_Base_GAZ"), ("em", "E_Modifier"),
+  ("emodifier", "E_Modifier"), ("ex", "Extend"), ("extend", "Extend"),
+  ("gaz", "Glue_After_Zwj"), ("glueafterzwj", "Glue_After_Zwj"), ("l", "L"),
+  ("lf", "LF"), ("lv", "LV"), ("lvt", "LVT"), ("other", "Other"),
+  ("pp", "Prepend"), ("prepend", "Prepend"),
+  ("regionalindicator", "Regional_Indicator"), ("ri", "Regional_Indicator"),
+  ("sm", "SpacingMark"), ("spacingmark", "SpacingMark"), ("t", "T"),
+  ("v", "V"), ("xx", "Other"), ("zwj", "ZWJ"), ]),
+
+  ("Script", &[("adlam", "Adlam"), ("adlm", "Adlam"),
+  ("aghb", "Caucasian_Albanian"), ("ahom", "Ahom"),
+  ("anatolianhieroglyphs", "Anatolian_Hieroglyphs"), ("arab", "Arabic"),
+  ("arabic", "Arabic"), ("armenian", "Armenian"),
+  ("armi", "Imperial_Aramaic"), ("armn", "Armenian"), ("avestan", "Avestan"),
+  ("avst", "Avestan"), ("bali", "Balinese"), ("balinese", "Balinese"),
+  ("bamu", "Bamum"), ("bamum", "Bamum"), ("bass", "Bassa_Vah"),
+  ("bassavah", "Bassa_Vah"), ("batak", "Batak"), ("batk", "Batak"),
+  ("beng", "Bengali"), ("bengali", "Bengali"), ("bhaiksuki", "Bhaiksuki"),
+  ("bhks", "Bhaiksuki"), ("bopo", "Bopomofo"), ("bopomofo", "Bopomofo"),
+  ("brah", "Brahmi"), ("brahmi", "Brahmi"), ("brai", "Braille"),
+  ("braille", "Braille"), ("bugi", "Buginese"), ("buginese", "Buginese"),
+  ("buhd", "Buhid"), ("buhid", "Buhid"), ("cakm", "Chakma"),
+  ("canadianaboriginal", "Canadian_Aboriginal"),
+  ("cans", "Canadian_Aboriginal"), ("cari", "Carian"), ("carian", "Carian"),
+  ("caucasianalbanian", "Caucasian_Albanian"), ("chakma", "Chakma"),
+  ("cham", "Cham"), ("cher", "Cherokee"), ("cherokee", "Cherokee"),
+  ("common", "Common"), ("copt", "Coptic"), ("coptic", "Coptic"),
+  ("cprt", "Cypriot"), ("cuneiform", "Cuneiform"), ("cypriot", "Cypriot"),
+  ("cyrillic", "Cyrillic"), ("cyrl", "Cyrillic"), ("deseret", "Deseret"),
+  ("deva", "Devanagari"), ("devanagari", "Devanagari"), ("dogr", "Dogra"),
+  ("dogra", "Dogra"), ("dsrt", "Deseret"), ("dupl", "Duployan"),
+  ("duployan", "Duployan"), ("egyp", "Egyptian_Hieroglyphs"),
+  ("egyptianhieroglyphs", "Egyptian_Hieroglyphs"), ("elba", "Elbasan"),
+  ("elbasan", "Elbasan"), ("elym", "Elymaic"), ("elymaic", "Elymaic"),
+  ("ethi", "Ethiopic"), ("ethiopic", "Ethiopic"), ("geor", "Georgian"),
+  ("georgian", "Georgian"), ("glag", "Glagolitic"),
+  ("glagolitic", "Glagolitic"), ("gong", "Gunjala_Gondi"),
+  ("gonm", "Masaram_Gondi"), ("goth", "Gothic"), ("gothic", "Gothic"),
+  ("gran", "Grantha"), ("grantha", "Grantha"), ("greek", "Greek"),
+  ("grek", "Greek"), ("gujarati", "Gujarati"), ("gujr", "Gujarati"),
+  ("gunjalagondi", "Gunjala_Gondi"), ("gurmukhi", "Gurmukhi"),
+  ("guru", "Gurmukhi"), ("han", "Han"), ("hang", "Hangul"),
+  ("hangul", "Hangul"), ("hani", "Han"),
+  ("hanifirohingya", "Hanifi_Rohingya"), ("hano", "Hanunoo"),
+  ("hanunoo", "Hanunoo"), ("hatr", "Hatran"), ("hatran", "Hatran"),
+  ("hebr", "Hebrew"), ("hebrew", "Hebrew"), ("hira", "Hiragana"),
+  ("hiragana", "Hiragana"), ("hluw", "Anatolian_Hieroglyphs"),
+  ("hmng", "Pahawh_Hmong"), ("hmnp", "Nyiakeng_Puachue_Hmong"),
+  ("hrkt", "Katakana_Or_Hiragana"), ("hung", "Old_Hungarian"),
+  ("imperialaramaic", "Imperial_Aramaic"), ("inherited", "Inherited"),
+  ("inscriptionalpahlavi", "Inscriptional_Pahlavi"),
+  ("inscriptionalparthian", "Inscriptional_Parthian"), ("ital", "Old_Italic"),
+  ("java", "Javanese"), ("javanese", "Javanese"), ("kaithi", "Kaithi"),
+  ("kali", "Kayah_Li"), ("kana", "Katakana"), ("kannada", "Kannada"),
+  ("katakana", "Katakana"), ("katakanaorhiragana", "Katakana_Or_Hiragana"),
+  ("kayahli", "Kayah_Li"), ("khar", "Kharoshthi"),
+  ("kharoshthi", "Kharoshthi"), ("khmer", "Khmer"), ("khmr", "Khmer"),
+  ("khoj", "Khojki"), ("khojki", "Khojki"), ("khudawadi", "Khudawadi"),
+  ("knda", "Kannada"), ("kthi", "Kaithi"), ("lana", "Tai_Tham"),
+  ("lao", "Lao"), ("laoo", "Lao"), ("latin", "Latin"), ("latn", "Latin"),
+  ("lepc", "Lepcha"), ("lepcha", "Lepcha"), ("limb", "Limbu"),
+  ("limbu", "Limbu"), ("lina", "Linear_A"), ("linb", "Linear_B"),
+  ("lineara", "Linear_A"), ("linearb", "Linear_B"), ("lisu", "Lisu"),
+  ("lyci", "Lycian"), ("lycian", "Lycian"), ("lydi", "Lydian"),
+  ("lydian", "Lydian"), ("mahajani", "Mahajani"), ("mahj", "Mahajani"),
+  ("maka", "Makasar"), ("makasar", "Makasar"), ("malayalam", "Malayalam"),
+  ("mand", "Mandaic"), ("mandaic", "Mandaic"), ("mani", "Manichaean"),
+  ("manichaean", "Manichaean"), ("marc", "Marchen"), ("marchen", "Marchen"),
+  ("masaramgondi", "Masaram_Gondi"), ("medefaidrin", "Medefaidrin"),
+  ("medf", "Medefaidrin"), ("meeteimayek", "Meetei_Mayek"),
+  ("mend", "Mende_Kikakui"), ("mendekikakui", "Mende_Kikakui"),
+  ("merc", "Meroitic_Cursive"), ("mero", "Meroitic_Hieroglyphs"),
+  ("meroiticcursive", "Meroitic_Cursive"),
+  ("meroitichieroglyphs", "Meroitic_Hieroglyphs"), ("miao", "Miao"),
+  ("mlym", "Malayalam"), ("modi", "Modi"), ("mong", "Mongolian"),
+  ("mongolian", "Mongolian"), ("mro", "Mro"), ("mroo", "Mro"),
+  ("mtei", "Meetei_Mayek"), ("mult", "Multani"), ("multani", "Multani"),
+  ("myanmar", "Myanmar"), ("mymr", "Myanmar"), ("nabataean", "Nabataean"),
+  ("nand", "Nandinagari"), ("nandinagari", "Nandinagari"),
+  ("narb", "Old_North_Arabian"), ("nbat", "Nabataean"), ("newa", "Newa"),
+  ("newtailue", "New_Tai_Lue"), ("nko", "Nko"), ("nkoo", "Nko"),
+  ("nshu", "Nushu"), ("nushu", "Nushu"),
+  ("nyiakengpuachuehmong", "Nyiakeng_Puachue_Hmong"), ("ogam", "Ogham"),
+  ("ogham", "Ogham"), ("olchiki", "Ol_Chiki"), ("olck", "Ol_Chiki"),
+  ("oldhungarian", "Old_Hungarian"), ("olditalic", "Old_Italic"),
+  ("oldnortharabian", "Old_North_Arabian"), ("oldpermic", "Old_Permic"),
+  ("oldpersian", "Old_Persian"), ("oldsogdian", "Old_Sogdian"),
+  ("oldsoutharabian", "Old_South_Arabian"), ("oldturkic", "Old_Turkic"),
+  ("oriya", "Oriya"), ("orkh", "Old_Turkic"), ("orya", "Oriya"),
+  ("osage", "Osage"), ("osge", "Osage"), ("osma", "Osmanya"),
+  ("osmanya", "Osmanya"), ("pahawhhmong", "Pahawh_Hmong"),
+  ("palm", "Palmyrene"), ("palmyrene", "Palmyrene"), ("pauc", "Pau_Cin_Hau"),
+  ("paucinhau", "Pau_Cin_Hau"), ("perm", "Old_Permic"), ("phag", "Phags_Pa"),
+  ("phagspa", "Phags_Pa"), ("phli", "Inscriptional_Pahlavi"),
+  ("phlp", "Psalter_Pahlavi"), ("phnx", "Phoenician"),
+  ("phoenician", "Phoenician"), ("plrd", "Miao"),
+  ("prti", "Inscriptional_Parthian"), ("psalterpahlavi", "Psalter_Pahlavi"),
+  ("qaac", "Coptic"), ("qaai", "Inherited"), ("rejang", "Rejang"),
+  ("rjng", "Rejang"), ("rohg", "Hanifi_Rohingya"), ("runic", "Runic"),
+  ("runr", "Runic"), ("samaritan", "Samaritan"), ("samr", "Samaritan"),
+  ("sarb", "Old_South_Arabian"), ("saur", "Saurashtra"),
+  ("saurashtra", "Saurashtra"), ("sgnw", "SignWriting"),
+  ("sharada", "Sharada"), ("shavian", "Shavian"), ("shaw", "Shavian"),
+  ("shrd", "Sharada"), ("sidd", "Siddham"), ("siddham", "Siddham"),
+  ("signwriting", "SignWriting"), ("sind", "Khudawadi"), ("sinh", "Sinhala"),
+  ("sinhala", "Sinhala"), ("sogd", "Sogdian"), ("sogdian", "Sogdian"),
+  ("sogo", "Old_Sogdian"), ("sora", "Sora_Sompeng"),
+  ("sorasompeng", "Sora_Sompeng"), ("soyo", "Soyombo"),
+  ("soyombo", "Soyombo"), ("sund", "Sundanese"), ("sundanese", "Sundanese"),
+  ("sylo", "Syloti_Nagri"), ("sylotinagri", "Syloti_Nagri"),
+  ("syrc", "Syriac"), ("syriac", "Syriac"), ("tagalog", "Tagalog"),
+  ("tagb", "Tagbanwa"), ("tagbanwa", "Tagbanwa"), ("taile", "Tai_Le"),
+  ("taitham", "Tai_Tham"), ("taiviet", "Tai_Viet"), ("takr", "Takri"),
+  ("takri", "Takri"), ("tale", "Tai_Le"), ("talu", "New_Tai_Lue"),
+  ("tamil", "Tamil"), ("taml", "Tamil"), ("tang", "Tangut"),
+  ("tangut", "Tangut"), ("tavt", "Tai_Viet"), ("telu", "Telugu"),
+  ("telugu", "Telugu"), ("tfng", "Tifinagh"), ("tglg", "Tagalog"),
+  ("thaa", "Thaana"), ("thaana", "Thaana"), ("thai", "Thai"),
+  ("tibetan", "Tibetan"), ("tibt", "Tibetan"), ("tifinagh", "Tifinagh"),
+  ("tirh", "Tirhuta"), ("tirhuta", "Tirhuta"), ("ugar", "Ugaritic"),
+  ("ugaritic", "Ugaritic"), ("unknown", "Unknown"), ("vai", "Vai"),
+  ("vaii", "Vai"), ("wancho", "Wancho"), ("wara", "Warang_Citi"),
+  ("warangciti", "Warang_Citi"), ("wcho", "Wancho"), ("xpeo", "Old_Persian"),
+  ("xsux", "Cuneiform"), ("yi", "Yi"), ("yiii", "Yi"),
+  ("zanabazarsquare", "Zanabazar_Square"), ("zanb", "Zanabazar_Square"),
+  ("zinh", "Inherited"), ("zyyy", "Common"), ("zzzz", "Unknown"), ]),
+
+  ("Script_Extensions", &[("adlam", "Adlam"), ("adlm", "Adlam"),
+  ("aghb", "Caucasian_Albanian"), ("ahom", "Ahom"),
+  ("anatolianhieroglyphs", "Anatolian_Hieroglyphs"), ("arab", "Arabic"),
+  ("arabic", "Arabic"), ("armenian", "Armenian"),
+  ("armi", "Imperial_Aramaic"), ("armn", "Armenian"), ("avestan", "Avestan"),
+  ("avst", "Avestan"), ("bali", "Balinese"), ("balinese", "Balinese"),
+  ("bamu", "Bamum"), ("bamum", "Bamum"), ("bass", "Bassa_Vah"),
+  ("bassavah", "Bassa_Vah"), ("batak", "Batak"), ("batk", "Batak"),
+  ("beng", "Bengali"), ("bengali", "Bengali"), ("bhaiksuki", "Bhaiksuki"),
+  ("bhks", "Bhaiksuki"), ("bopo", "Bopomofo"), ("bopomofo", "Bopomofo"),
+  ("brah", "Brahmi"), ("brahmi", "Brahmi"), ("brai", "Braille"),
+  ("braille", "Braille"), ("bugi", "Buginese"), ("buginese", "Buginese"),
+  ("buhd", "Buhid"), ("buhid", "Buhid"), ("cakm", "Chakma"),
+  ("canadianaboriginal", "Canadian_Aboriginal"),
+  ("cans", "Canadian_Aboriginal"), ("cari", "Carian"), ("carian", "Carian"),
+  ("caucasianalbanian", "Caucasian_Albanian"), ("chakma", "Chakma"),
+  ("cham", "Cham"), ("cher", "Cherokee"), ("cherokee", "Cherokee"),
+  ("common", "Common"), ("copt", "Coptic"), ("coptic", "Coptic"),
+  ("cprt", "Cypriot"), ("cuneiform", "Cuneiform"), ("cypriot", "Cypriot"),
+  ("cyrillic", "Cyrillic"), ("cyrl", "Cyrillic"), ("deseret", "Deseret"),
+  ("deva", "Devanagari"), ("devanagari", "Devanagari"), ("dogr", "Dogra"),
+  ("dogra", "Dogra"), ("dsrt", "Deseret"), ("dupl", "Duployan"),
+  ("duployan", "Duployan"), ("egyp", "Egyptian_Hieroglyphs"),
+  ("egyptianhieroglyphs", "Egyptian_Hieroglyphs"), ("elba", "Elbasan"),
+  ("elbasan", "Elbasan"), ("elym", "Elymaic"), ("elymaic", "Elymaic"),
+  ("ethi", "Ethiopic"), ("ethiopic", "Ethiopic"), ("geor", "Georgian"),
+  ("georgian", "Georgian"), ("glag", "Glagolitic"),
+  ("glagolitic", "Glagolitic"), ("gong", "Gunjala_Gondi"),
+  ("gonm", "Masaram_Gondi"), ("goth", "Gothic"), ("gothic", "Gothic"),
+  ("gran", "Grantha"), ("grantha", "Grantha"), ("greek", "Greek"),
+  ("grek", "Greek"), ("gujarati", "Gujarati"), ("gujr", "Gujarati"),
+  ("gunjalagondi", "Gunjala_Gondi"), ("gurmukhi", "Gurmukhi"),
+  ("guru", "Gurmukhi"), ("han", "Han"), ("hang", "Hangul"),
+  ("hangul", "Hangul"), ("hani", "Han"),
+  ("hanifirohingya", "Hanifi_Rohingya"), ("hano", "Hanunoo"),
+  ("hanunoo", "Hanunoo"), ("hatr", "Hatran"), ("hatran", "Hatran"),
+  ("hebr", "Hebrew"), ("hebrew", "Hebrew"), ("hira", "Hiragana"),
+  ("hiragana", "Hiragana"), ("hluw", "Anatolian_Hieroglyphs"),
+  ("hmng", "Pahawh_Hmong"), ("hmnp", "Nyiakeng_Puachue_Hmong"),
+  ("hrkt", "Katakana_Or_Hiragana"), ("hung", "Old_Hungarian"),
+  ("imperialaramaic", "Imperial_Aramaic"), ("inherited", "Inherited"),
+  ("inscriptionalpahlavi", "Inscriptional_Pahlavi"),
+  ("inscriptionalparthian", "Inscriptional_Parthian"), ("ital", "Old_Italic"),
+  ("java", "Javanese"), ("javanese", "Javanese"), ("kaithi", "Kaithi"),
+  ("kali", "Kayah_Li"), ("kana", "Katakana"), ("kannada", "Kannada"),
+  ("katakana", "Katakana"), ("katakanaorhiragana", "Katakana_Or_Hiragana"),
+  ("kayahli", "Kayah_Li"), ("khar", "Kharoshthi"),
+  ("kharoshthi", "Kharoshthi"), ("khmer", "Khmer"), ("khmr", "Khmer"),
+  ("khoj", "Khojki"), ("khojki", "Khojki"), ("khudawadi", "Khudawadi"),
+  ("knda", "Kannada"), ("kthi", "Kaithi"), ("lana", "Tai_Tham"),
+  ("lao", "Lao"), ("laoo", "Lao"), ("latin", "Latin"), ("latn", "Latin"),
+  ("lepc", "Lepcha"), ("lepcha", "Lepcha"), ("limb", "Limbu"),
+  ("limbu", "Limbu"), ("lina", "Linear_A"), ("linb", "Linear_B"),
+  ("lineara", "Linear_A"), ("linearb", "Linear_B"), ("lisu", "Lisu"),
+  ("lyci", "Lycian"), ("lycian", "Lycian"), ("lydi", "Lydian"),
+  ("lydian", "Lydian"), ("mahajani", "Mahajani"), ("mahj", "Mahajani"),
+  ("maka", "Makasar"), ("makasar", "Makasar"), ("malayalam", "Malayalam"),
+  ("mand", "Mandaic"), ("mandaic", "Mandaic"), ("mani", "Manichaean"),
+  ("manichaean", "Manichaean"), ("marc", "Marchen"), ("marchen", "Marchen"),
+  ("masaramgondi", "Masaram_Gondi"), ("medefaidrin", "Medefaidrin"),
+  ("medf", "Medefaidrin"), ("meeteimayek", "Meetei_Mayek"),
+  ("mend", "Mende_Kikakui"), ("mendekikakui", "Mende_Kikakui"),
+  ("merc", "Meroitic_Cursive"), ("mero", "Meroitic_Hieroglyphs"),
+  ("meroiticcursive", "Meroitic_Cursive"),
+  ("meroitichieroglyphs", "Meroitic_Hieroglyphs"), ("miao", "Miao"),
+  ("mlym", "Malayalam"), ("modi", "Modi"), ("mong", "Mongolian"),
+  ("mongolian", "Mongolian"), ("mro", "Mro"), ("mroo", "Mro"),
+  ("mtei", "Meetei_Mayek"), ("mult", "Multani"), ("multani", "Multani"),
+  ("myanmar", "Myanmar"), ("mymr", "Myanmar"), ("nabataean", "Nabataean"),
+  ("nand", "Nandinagari"), ("nandinagari", "Nandinagari"),
+  ("narb", "Old_North_Arabian"), ("nbat", "Nabataean"), ("newa", "Newa"),
+  ("newtailue", "New_Tai_Lue"), ("nko", "Nko"), ("nkoo", "Nko"),
+  ("nshu", "Nushu"), ("nushu", "Nushu"),
+  ("nyiakengpuachuehmong", "Nyiakeng_Puachue_Hmong"), ("ogam", "Ogham"),
+  ("ogham", "Ogham"), ("olchiki", "Ol_Chiki"), ("olck", "Ol_Chiki"),
+  ("oldhungarian", "Old_Hungarian"), ("olditalic", "Old_Italic"),
+  ("oldnortharabian", "Old_North_Arabian"), ("oldpermic", "Old_Permic"),
+  ("oldpersian", "Old_Persian"), ("oldsogdian", "Old_Sogdian"),
+  ("oldsoutharabian", "Old_South_Arabian"), ("oldturkic", "Old_Turkic"),
+  ("oriya", "Oriya"), ("orkh", "Old_Turkic"), ("orya", "Oriya"),
+  ("osage", "Osage"), ("osge", "Osage"), ("osma", "Osmanya"),
+  ("osmanya", "Osmanya"), ("pahawhhmong", "Pahawh_Hmong"),
+  ("palm", "Palmyrene"), ("palmyrene", "Palmyrene"), ("pauc", "Pau_Cin_Hau"),
+  ("paucinhau", "Pau_Cin_Hau"), ("perm", "Old_Permic"), ("phag", "Phags_Pa"),
+  ("phagspa", "Phags_Pa"), ("phli", "Inscriptional_Pahlavi"),
+  ("phlp", "Psalter_Pahlavi"), ("phnx", "Phoenician"),
+  ("phoenician", "Phoenician"), ("plrd", "Miao"),
+  ("prti", "Inscriptional_Parthian"), ("psalterpahlavi", "Psalter_Pahlavi"),
+  ("qaac", "Coptic"), ("qaai", "Inherited"), ("rejang", "Rejang"),
+  ("rjng", "Rejang"), ("rohg", "Hanifi_Rohingya"), ("runic", "Runic"),
+  ("runr", "Runic"), ("samaritan", "Samaritan"), ("samr", "Samaritan"),
+  ("sarb", "Old_South_Arabian"), ("saur", "Saurashtra"),
+  ("saurashtra", "Saurashtra"), ("sgnw", "SignWriting"),
+  ("sharada", "Sharada"), ("shavian", "Shavian"), ("shaw", "Shavian"),
+  ("shrd", "Sharada"), ("sidd", "Siddham"), ("siddham", "Siddham"),
+  ("signwriting", "SignWriting"), ("sind", "Khudawadi"), ("sinh", "Sinhala"),
+  ("sinhala", "Sinhala"), ("sogd", "Sogdian"), ("sogdian", "Sogdian"),
+  ("sogo", "Old_Sogdian"), ("sora", "Sora_Sompeng"),
+  ("sorasompeng", "Sora_Sompeng"), ("soyo", "Soyombo"),
+  ("soyombo", "Soyombo"), ("sund", "Sundanese"), ("sundanese", "Sundanese"),
+  ("sylo", "Syloti_Nagri"), ("sylotinagri", "Syloti_Nagri"),
+  ("syrc", "Syriac"), ("syriac", "Syriac"), ("tagalog", "Tagalog"),
+  ("tagb", "Tagbanwa"), ("tagbanwa", "Tagbanwa"), ("taile", "Tai_Le"),
+  ("taitham", "Tai_Tham"), ("taiviet", "Tai_Viet"), ("takr", "Takri"),
+  ("takri", "Takri"), ("tale", "Tai_Le"), ("talu", "New_Tai_Lue"),
+  ("tamil", "Tamil"), ("taml", "Tamil"), ("tang", "Tangut"),
+  ("tangut", "Tangut"), ("tavt", "Tai_Viet"), ("telu", "Telugu"),
+  ("telugu", "Telugu"), ("tfng", "Tifinagh"), ("tglg", "Tagalog"),
+  ("thaa", "Thaana"), ("thaana", "Thaana"), ("thai", "Thai"),
+  ("tibetan", "Tibetan"), ("tibt", "Tibetan"), ("tifinagh", "Tifinagh"),
+  ("tirh", "Tirhuta"), ("tirhuta", "Tirhuta"), ("ugar", "Ugaritic"),
+  ("ugaritic", "Ugaritic"), ("unknown", "Unknown"), ("vai", "Vai"),
+  ("vaii", "Vai"), ("wancho", "Wancho"), ("wara", "Warang_Citi"),
+  ("warangciti", "Warang_Citi"), ("wcho", "Wancho"), ("xpeo", "Old_Persian"),
+  ("xsux", "Cuneiform"), ("yi", "Yi"), ("yiii", "Yi"),
+  ("zanabazarsquare", "Zanabazar_Square"), ("zanb", "Zanabazar_Square"),
+  ("zinh", "Inherited"), ("zyyy", "Common"), ("zzzz", "Unknown"), ]),
+
+  ("Sentence_Break", &[("at", "ATerm"), ("aterm", "ATerm"), ("cl", "Close"),
+  ("close", "Close"), ("cr", "CR"), ("ex", "Extend"), ("extend", "Extend"),
+  ("fo", "Format"), ("format", "Format"), ("le", "OLetter"), ("lf", "LF"),
+  ("lo", "Lower"), ("lower", "Lower"), ("nu", "Numeric"),
+  ("numeric", "Numeric"), ("oletter", "OLetter"), ("other", "Other"),
+  ("sc", "SContinue"), ("scontinue", "SContinue"), ("se", "Sep"),
+  ("sep", "Sep"), ("sp", "Sp"), ("st", "STerm"), ("sterm", "STerm"),
+  ("up", "Upper"), ("upper", "Upper"), ("xx", "Other"), ]),
+
+  ("Word_Break", &[("aletter", "ALetter"), ("cr", "CR"),
+  ("doublequote", "Double_Quote"), ("dq", "Double_Quote"), ("eb", "E_Base"),
+  ("ebase", "E_Base"), ("ebasegaz", "E_Base_GAZ"), ("ebg", "E_Base_GAZ"),
+  ("em", "E_Modifier"), ("emodifier", "E_Modifier"), ("ex", "ExtendNumLet"),
+  ("extend", "Extend"), ("extendnumlet", "ExtendNumLet"), ("fo", "Format"),
+  ("format", "Format"), ("gaz", "Glue_After_Zwj"),
+  ("glueafterzwj", "Glue_After_Zwj"), ("hebrewletter", "Hebrew_Letter"),
+  ("hl", "Hebrew_Letter"), ("ka", "Katakana"), ("katakana", "Katakana"),
+  ("le", "ALetter"), ("lf", "LF"), ("mb", "MidNumLet"),
+  ("midletter", "MidLetter"), ("midnum", "MidNum"),
+  ("midnumlet", "MidNumLet"), ("ml", "MidLetter"), ("mn", "MidNum"),
+  ("newline", "Newline"), ("nl", "Newline"), ("nu", "Numeric"),
+  ("numeric", "Numeric"), ("other", "Other"),
+  ("regionalindicator", "Regional_Indicator"), ("ri", "Regional_Indicator"),
+  ("singlequote", "Single_Quote"), ("sq", "Single_Quote"),
+  ("wsegspace", "WSegSpace"), ("xx", "Other"), ("zwj", "ZWJ"), ]),
+];
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/unicode_tables/script.rs.html b/target/doc/src/regex_syntax/unicode_tables/script.rs.html new file mode 100644 index 0000000..03d8598 --- /dev/null +++ b/target/doc/src/regex_syntax/unicode_tables/script.rs.html @@ -0,0 +1,1681 @@ +script.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+
+// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
+//
+//  ucd-generate script /tmp/ucd-12.1.0/ --chars
+//
+// ucd-generate is available on crates.io.
+
+pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
+  ("Adlam", ADLAM), ("Ahom", AHOM),
+  ("Anatolian_Hieroglyphs", ANATOLIAN_HIEROGLYPHS), ("Arabic", ARABIC),
+  ("Armenian", ARMENIAN), ("Avestan", AVESTAN), ("Balinese", BALINESE),
+  ("Bamum", BAMUM), ("Bassa_Vah", BASSA_VAH), ("Batak", BATAK),
+  ("Bengali", BENGALI), ("Bhaiksuki", BHAIKSUKI), ("Bopomofo", BOPOMOFO),
+  ("Brahmi", BRAHMI), ("Braille", BRAILLE), ("Buginese", BUGINESE),
+  ("Buhid", BUHID), ("Canadian_Aboriginal", CANADIAN_ABORIGINAL),
+  ("Carian", CARIAN), ("Caucasian_Albanian", CAUCASIAN_ALBANIAN),
+  ("Chakma", CHAKMA), ("Cham", CHAM), ("Cherokee", CHEROKEE),
+  ("Common", COMMON), ("Coptic", COPTIC), ("Cuneiform", CUNEIFORM),
+  ("Cypriot", CYPRIOT), ("Cyrillic", CYRILLIC), ("Deseret", DESERET),
+  ("Devanagari", DEVANAGARI), ("Dogra", DOGRA), ("Duployan", DUPLOYAN),
+  ("Egyptian_Hieroglyphs", EGYPTIAN_HIEROGLYPHS), ("Elbasan", ELBASAN),
+  ("Elymaic", ELYMAIC), ("Ethiopic", ETHIOPIC), ("Georgian", GEORGIAN),
+  ("Glagolitic", GLAGOLITIC), ("Gothic", GOTHIC), ("Grantha", GRANTHA),
+  ("Greek", GREEK), ("Gujarati", GUJARATI), ("Gunjala_Gondi", GUNJALA_GONDI),
+  ("Gurmukhi", GURMUKHI), ("Han", HAN), ("Hangul", HANGUL),
+  ("Hanifi_Rohingya", HANIFI_ROHINGYA), ("Hanunoo", HANUNOO),
+  ("Hatran", HATRAN), ("Hebrew", HEBREW), ("Hiragana", HIRAGANA),
+  ("Imperial_Aramaic", IMPERIAL_ARAMAIC), ("Inherited", INHERITED),
+  ("Inscriptional_Pahlavi", INSCRIPTIONAL_PAHLAVI),
+  ("Inscriptional_Parthian", INSCRIPTIONAL_PARTHIAN), ("Javanese", JAVANESE),
+  ("Kaithi", KAITHI), ("Kannada", KANNADA), ("Katakana", KATAKANA),
+  ("Kayah_Li", KAYAH_LI), ("Kharoshthi", KHAROSHTHI), ("Khmer", KHMER),
+  ("Khojki", KHOJKI), ("Khudawadi", KHUDAWADI), ("Lao", LAO),
+  ("Latin", LATIN), ("Lepcha", LEPCHA), ("Limbu", LIMBU),
+  ("Linear_A", LINEAR_A), ("Linear_B", LINEAR_B), ("Lisu", LISU),
+  ("Lycian", LYCIAN), ("Lydian", LYDIAN), ("Mahajani", MAHAJANI),
+  ("Makasar", MAKASAR), ("Malayalam", MALAYALAM), ("Mandaic", MANDAIC),
+  ("Manichaean", MANICHAEAN), ("Marchen", MARCHEN),
+  ("Masaram_Gondi", MASARAM_GONDI), ("Medefaidrin", MEDEFAIDRIN),
+  ("Meetei_Mayek", MEETEI_MAYEK), ("Mende_Kikakui", MENDE_KIKAKUI),
+  ("Meroitic_Cursive", MEROITIC_CURSIVE),
+  ("Meroitic_Hieroglyphs", MEROITIC_HIEROGLYPHS), ("Miao", MIAO),
+  ("Modi", MODI), ("Mongolian", MONGOLIAN), ("Mro", MRO),
+  ("Multani", MULTANI), ("Myanmar", MYANMAR), ("Nabataean", NABATAEAN),
+  ("Nandinagari", NANDINAGARI), ("New_Tai_Lue", NEW_TAI_LUE), ("Newa", NEWA),
+  ("Nko", NKO), ("Nushu", NUSHU),
+  ("Nyiakeng_Puachue_Hmong", NYIAKENG_PUACHUE_HMONG), ("Ogham", OGHAM),
+  ("Ol_Chiki", OL_CHIKI), ("Old_Hungarian", OLD_HUNGARIAN),
+  ("Old_Italic", OLD_ITALIC), ("Old_North_Arabian", OLD_NORTH_ARABIAN),
+  ("Old_Permic", OLD_PERMIC), ("Old_Persian", OLD_PERSIAN),
+  ("Old_Sogdian", OLD_SOGDIAN), ("Old_South_Arabian", OLD_SOUTH_ARABIAN),
+  ("Old_Turkic", OLD_TURKIC), ("Oriya", ORIYA), ("Osage", OSAGE),
+  ("Osmanya", OSMANYA), ("Pahawh_Hmong", PAHAWH_HMONG),
+  ("Palmyrene", PALMYRENE), ("Pau_Cin_Hau", PAU_CIN_HAU),
+  ("Phags_Pa", PHAGS_PA), ("Phoenician", PHOENICIAN),
+  ("Psalter_Pahlavi", PSALTER_PAHLAVI), ("Rejang", REJANG), ("Runic", RUNIC),
+  ("Samaritan", SAMARITAN), ("Saurashtra", SAURASHTRA), ("Sharada", SHARADA),
+  ("Shavian", SHAVIAN), ("Siddham", SIDDHAM), ("SignWriting", SIGNWRITING),
+  ("Sinhala", SINHALA), ("Sogdian", SOGDIAN), ("Sora_Sompeng", SORA_SOMPENG),
+  ("Soyombo", SOYOMBO), ("Sundanese", SUNDANESE),
+  ("Syloti_Nagri", SYLOTI_NAGRI), ("Syriac", SYRIAC), ("Tagalog", TAGALOG),
+  ("Tagbanwa", TAGBANWA), ("Tai_Le", TAI_LE), ("Tai_Tham", TAI_THAM),
+  ("Tai_Viet", TAI_VIET), ("Takri", TAKRI), ("Tamil", TAMIL),
+  ("Tangut", TANGUT), ("Telugu", TELUGU), ("Thaana", THAANA), ("Thai", THAI),
+  ("Tibetan", TIBETAN), ("Tifinagh", TIFINAGH), ("Tirhuta", TIRHUTA),
+  ("Ugaritic", UGARITIC), ("Vai", VAI), ("Wancho", WANCHO),
+  ("Warang_Citi", WARANG_CITI), ("Yi", YI),
+  ("Zanabazar_Square", ZANABAZAR_SQUARE),
+];
+
+pub const ADLAM: &'static [(char, char)] = &[
+  ('𞤀', '\u{1e94b}'), ('𞥐', '𞥙'), ('𞥞', '𞥟'),
+];
+
+pub const AHOM: &'static [(char, char)] = &[
+  ('𑜀', '𑜚'), ('\u{1171d}', '\u{1172b}'), ('𑜰', '𑜿'),
+];
+
+pub const ANATOLIAN_HIEROGLYPHS: &'static [(char, char)] = &[
+  ('𔐀', '𔙆'),
+];
+
+pub const ARABIC: &'static [(char, char)] = &[
+  ('\u{600}', '\u{604}'), ('؆', '؋'), ('؍', '\u{61a}'),
+  ('\u{61c}', '\u{61c}'), ('؞', '؞'), ('ؠ', 'ؿ'), ('ف', 'ي'),
+  ('\u{656}', 'ٯ'), ('ٱ', '\u{6dc}'), ('۞', 'ۿ'), ('ݐ', 'ݿ'),
+  ('ࢠ', 'ࢴ'), ('ࢶ', 'ࢽ'), ('\u{8d3}', '\u{8e1}'),
+  ('\u{8e3}', '\u{8ff}'), ('ﭐ', '﯁'), ('ﯓ', 'ﴽ'), ('ﵐ', 'ﶏ'),
+  ('ﶒ', 'ﷇ'), ('ﷰ', '﷽'), ('ﹰ', 'ﹴ'), ('ﹶ', 'ﻼ'),
+  ('𐹠', '𐹾'), ('𞸀', '𞸃'), ('𞸅', '𞸟'), ('𞸡', '𞸢'),
+  ('𞸤', '𞸤'), ('𞸧', '𞸧'), ('𞸩', '𞸲'), ('𞸴', '𞸷'),
+  ('𞸹', '𞸹'), ('𞸻', '𞸻'), ('𞹂', '𞹂'), ('𞹇', '𞹇'),
+  ('𞹉', '𞹉'), ('𞹋', '𞹋'), ('𞹍', '𞹏'), ('𞹑', '𞹒'),
+  ('𞹔', '𞹔'), ('𞹗', '𞹗'), ('𞹙', '𞹙'), ('𞹛', '𞹛'),
+  ('𞹝', '𞹝'), ('𞹟', '𞹟'), ('𞹡', '𞹢'), ('𞹤', '𞹤'),
+  ('𞹧', '𞹪'), ('𞹬', '𞹲'), ('𞹴', '𞹷'), ('𞹹', '𞹼'),
+  ('𞹾', '𞹾'), ('𞺀', '𞺉'), ('𞺋', '𞺛'), ('𞺡', '𞺣'),
+  ('𞺥', '𞺩'), ('𞺫', '𞺻'), ('𞻰', '𞻱'),
+];
+
+pub const ARMENIAN: &'static [(char, char)] = &[
+  ('Ա', 'Ֆ'), ('ՙ', 'ֈ'), ('֊', '֊'), ('֍', '֏'), ('ﬓ', 'ﬗ'),
+];
+
+pub const AVESTAN: &'static [(char, char)] = &[
+  ('𐬀', '𐬵'), ('𐬹', '𐬿'),
+];
+
+pub const BALINESE: &'static [(char, char)] = &[
+  ('\u{1b00}', 'ᭋ'), ('᭐', '᭼'),
+];
+
+pub const BAMUM: &'static [(char, char)] = &[
+  ('ꚠ', '꛷'), ('𖠀', '𖨸'),
+];
+
+pub const BASSA_VAH: &'static [(char, char)] = &[
+  ('𖫐', '𖫭'), ('\u{16af0}', '𖫵'),
+];
+
+pub const BATAK: &'static [(char, char)] = &[
+  ('ᯀ', '᯳'), ('᯼', '᯿'),
+];
+
+pub const BENGALI: &'static [(char, char)] = &[
+  ('ঀ', 'ঃ'), ('অ', 'ঌ'), ('এ', 'ঐ'), ('ও', 'ন'),
+  ('প', 'র'), ('ল', 'ল'), ('শ', 'হ'), ('\u{9bc}', '\u{9c4}'),
+  ('ে', 'ৈ'), ('ো', 'ৎ'), ('\u{9d7}', '\u{9d7}'), ('ড়', 'ঢ়'),
+  ('য়', '\u{9e3}'), ('০', '\u{9fe}'),
+];
+
+pub const BHAIKSUKI: &'static [(char, char)] = &[
+  ('𑰀', '𑰈'), ('𑰊', '\u{11c36}'), ('\u{11c38}', '𑱅'),
+  ('𑱐', '𑱬'),
+];
+
+pub const BOPOMOFO: &'static [(char, char)] = &[
+  ('˪', '˫'), ('ㄅ', 'ㄯ'), ('ㆠ', 'ㆺ'),
+];
+
+pub const BRAHMI: &'static [(char, char)] = &[
+  ('𑀀', '𑁍'), ('𑁒', '𑁯'), ('\u{1107f}', '\u{1107f}'),
+];
+
+pub const BRAILLE: &'static [(char, char)] = &[
+  ('⠀', '⣿'),
+];
+
+pub const BUGINESE: &'static [(char, char)] = &[
+  ('ᨀ', '\u{1a1b}'), ('᨞', '᨟'),
+];
+
+pub const BUHID: &'static [(char, char)] = &[
+  ('ᝀ', '\u{1753}'),
+];
+
+pub const CANADIAN_ABORIGINAL: &'static [(char, char)] = &[
+  ('᐀', 'ᙿ'), ('ᢰ', 'ᣵ'),
+];
+
+pub const CARIAN: &'static [(char, char)] = &[
+  ('𐊠', '𐋐'),
+];
+
+pub const CAUCASIAN_ALBANIAN: &'static [(char, char)] = &[
+  ('𐔰', '𐕣'), ('𐕯', '𐕯'),
+];
+
+pub const CHAKMA: &'static [(char, char)] = &[
+  ('\u{11100}', '\u{11134}'), ('𑄶', '𑅆'),
+];
+
+pub const CHAM: &'static [(char, char)] = &[
+  ('ꨀ', '\u{aa36}'), ('ꩀ', 'ꩍ'), ('꩐', '꩙'), ('꩜', '꩟'),
+];
+
+pub const CHEROKEE: &'static [(char, char)] = &[
+  ('Ꭰ', 'Ᏽ'), ('ᏸ', 'ᏽ'), ('ꭰ', 'ꮿ'),
+];
+
+pub const COMMON: &'static [(char, char)] = &[
+  ('\u{0}', '@'), ('[', '`'), ('{', '©'), ('«', '¹'), ('»', '¿'),
+  ('×', '×'), ('÷', '÷'), ('ʹ', '˟'), ('˥', '˩'), ('ˬ', '˿'),
+  ('ʹ', 'ʹ'), (';', ';'), ('΅', '΅'), ('·', '·'), ('։', '։'),
+  ('\u{605}', '\u{605}'), ('،', '،'), ('؛', '؛'), ('؟', '؟'),
+  ('ـ', 'ـ'), ('\u{6dd}', '\u{6dd}'), ('\u{8e2}', '\u{8e2}'),
+  ('।', '॥'), ('฿', '฿'), ('࿕', '࿘'), ('჻', '჻'),
+  ('᛫', '᛭'), ('᜵', '᜶'), ('᠂', '᠃'), ('᠅', '᠅'),
+  ('᳓', '᳓'), ('᳡', '᳡'), ('ᳩ', 'ᳬ'), ('ᳮ', 'ᳳ'),
+  ('ᳵ', '᳷'), ('\u{1cfa}', '\u{1cfa}'), ('\u{2000}', '\u{200b}'),
+  ('\u{200e}', '\u{2064}'), ('\u{2066}', '⁰'), ('⁴', '⁾'),
+  ('₀', '₎'), ('₠', '₿'), ('℀', '℥'), ('℧', '℩'),
+  ('ℬ', 'ℱ'), ('ℳ', '⅍'), ('⅏', '⅟'), ('↉', '↋'),
+  ('←', '␦'), ('⑀', '⑊'), ('①', '⟿'), ('⤀', '⭳'),
+  ('⭶', '⮕'), ('⮘', '\u{2bff}'), ('⸀', '\u{2e4f}'), ('⿰', '⿻'),
+  ('\u{3000}', '〄'), ('〆', '〆'), ('〈', '〠'), ('〰', '〷'),
+  ('〼', '〿'), ('゛', '゜'), ('゠', '゠'), ('・', 'ー'),
+  ('㆐', '㆟'), ('㇀', '㇣'), ('㈠', '㉟'), ('㉿', '㋏'),
+  ('\u{32ff}', '\u{32ff}'), ('㍘', '㏿'), ('䷀', '䷿'), ('꜀', '꜡'),
+  ('ꞈ', '꞊'), ('꠰', '꠹'), ('꤮', '꤮'), ('ꧏ', 'ꧏ'),
+  ('꭛', '꭛'), ('﴾', '﴿'), ('︐', '︙'), ('︰', '﹒'),
+  ('﹔', '﹦'), ('﹨', '﹫'), ('\u{feff}', '\u{feff}'), ('!', '@'),
+  ('[', '`'), ('{', '・'), ('ー', 'ー'), ('\u{ff9e}', '\u{ff9f}'),
+  ('¢', '₩'), ('│', '○'), ('\u{fff9}', '�'), ('𐄀', '𐄂'),
+  ('𐄇', '𐄳'), ('𐄷', '𐄿'), ('𐆐', '𐆛'), ('𐇐', '𐇼'),
+  ('𐋡', '𐋻'), ('\u{16fe2}', '\u{16fe3}'), ('\u{1bca0}', '\u{1bca3}'),
+  ('𝀀', '𝃵'), ('𝄀', '𝄦'), ('𝄩', '𝅦'), ('𝅪', '\u{1d17a}'),
+  ('𝆃', '𝆄'), ('𝆌', '𝆩'), ('𝆮', '𝇨'), ('𝋠', '𝋳'),
+  ('𝌀', '𝍖'), ('𝍠', '𝍸'), ('𝐀', '𝑔'), ('𝑖', '𝒜'),
+  ('𝒞', '𝒟'), ('𝒢', '𝒢'), ('𝒥', '𝒦'), ('𝒩', '𝒬'),
+  ('𝒮', '𝒹'), ('𝒻', '𝒻'), ('𝒽', '𝓃'), ('𝓅', '𝔅'),
+  ('𝔇', '𝔊'), ('𝔍', '𝔔'), ('𝔖', '𝔜'), ('𝔞', '𝔹'),
+  ('𝔻', '𝔾'), ('𝕀', '𝕄'), ('𝕆', '𝕆'), ('𝕊', '𝕐'),
+  ('𝕒', '𝚥'), ('𝚨', '𝟋'), ('𝟎', '𝟿'), ('𞱱', '𞲴'),
+  ('\u{1ed01}', '\u{1ed3d}'), ('🀀', '🀫'), ('🀰', '🂓'),
+  ('🂠', '🂮'), ('🂱', '🂿'), ('🃁', '🃏'), ('🃑', '🃵'),
+  ('🄀', '🄌'), ('🄐', '\u{1f16c}'), ('🅰', '🆬'), ('🇦', '🇿'),
+  ('🈁', '🈂'), ('🈐', '🈻'), ('🉀', '🉈'), ('🉐', '🉑'),
+  ('🉠', '🉥'), ('🌀', '\u{1f6d5}'), ('🛠', '🛬'),
+  ('🛰', '\u{1f6fa}'), ('🜀', '🝳'), ('🞀', '🟘'),
+  ('\u{1f7e0}', '\u{1f7eb}'), ('🠀', '🠋'), ('🠐', '🡇'),
+  ('🡐', '🡙'), ('🡠', '🢇'), ('🢐', '🢭'), ('🤀', '🤋'),
+  ('\u{1f90d}', '\u{1f971}'), ('🥳', '🥶'), ('🥺', '🦢'),
+  ('\u{1f9a5}', '\u{1f9aa}'), ('\u{1f9ae}', '\u{1f9ca}'),
+  ('\u{1f9cd}', '\u{1fa53}'), ('🩠', '🩭'), ('\u{1fa70}', '\u{1fa73}'),
+  ('\u{1fa78}', '\u{1fa7a}'), ('\u{1fa80}', '\u{1fa82}'),
+  ('\u{1fa90}', '\u{1fa95}'), ('\u{e0001}', '\u{e0001}'),
+  ('\u{e0020}', '\u{e007f}'),
+];
+
+pub const COPTIC: &'static [(char, char)] = &[
+  ('Ϣ', 'ϯ'), ('Ⲁ', 'ⳳ'), ('⳹', '⳿'),
+];
+
+pub const CUNEIFORM: &'static [(char, char)] = &[
+  ('𒀀', '𒎙'), ('𒐀', '𒑮'), ('𒑰', '𒑴'), ('𒒀', '𒕃'),
+];
+
+pub const CYPRIOT: &'static [(char, char)] = &[
+  ('𐠀', '𐠅'), ('𐠈', '𐠈'), ('𐠊', '𐠵'), ('𐠷', '𐠸'),
+  ('𐠼', '𐠼'), ('𐠿', '𐠿'),
+];
+
+pub const CYRILLIC: &'static [(char, char)] = &[
+  ('Ѐ', '\u{484}'), ('\u{487}', 'ԯ'), ('ᲀ', 'ᲈ'), ('ᴫ', 'ᴫ'),
+  ('ᵸ', 'ᵸ'), ('\u{2de0}', '\u{2dff}'), ('Ꙁ', '\u{a69f}'),
+  ('\u{fe2e}', '\u{fe2f}'),
+];
+
+pub const DESERET: &'static [(char, char)] = &[
+  ('𐐀', '𐑏'),
+];
+
+pub const DEVANAGARI: &'static [(char, char)] = &[
+  ('\u{900}', 'ॐ'), ('\u{955}', '\u{963}'), ('०', 'ॿ'),
+  ('\u{a8e0}', '\u{a8ff}'),
+];
+
+pub const DOGRA: &'static [(char, char)] = &[
+  ('𑠀', '𑠻'),
+];
+
+pub const DUPLOYAN: &'static [(char, char)] = &[
+  ('𛰀', '𛱪'), ('𛱰', '𛱼'), ('𛲀', '𛲈'), ('𛲐', '𛲙'),
+  ('𛲜', '𛲟'),
+];
+
+pub const EGYPTIAN_HIEROGLYPHS: &'static [(char, char)] = &[
+  ('𓀀', '𓐮'), ('\u{13430}', '\u{13438}'),
+];
+
+pub const ELBASAN: &'static [(char, char)] = &[
+  ('𐔀', '𐔧'),
+];
+
+pub const ELYMAIC: &'static [(char, char)] = &[
+  ('\u{10fe0}', '\u{10ff6}'),
+];
+
+pub const ETHIOPIC: &'static [(char, char)] = &[
+  ('ሀ', 'ቈ'), ('ቊ', 'ቍ'), ('ቐ', 'ቖ'), ('ቘ', 'ቘ'),
+  ('ቚ', 'ቝ'), ('በ', 'ኈ'), ('ኊ', 'ኍ'), ('ነ', 'ኰ'),
+  ('ኲ', 'ኵ'), ('ኸ', 'ኾ'), ('ዀ', 'ዀ'), ('ዂ', 'ዅ'),
+  ('ወ', 'ዖ'), ('ዘ', 'ጐ'), ('ጒ', 'ጕ'), ('ጘ', 'ፚ'),
+  ('\u{135d}', '፼'), ('ᎀ', '᎙'), ('ⶀ', 'ⶖ'), ('ⶠ', 'ⶦ'),
+  ('ⶨ', 'ⶮ'), ('ⶰ', 'ⶶ'), ('ⶸ', 'ⶾ'), ('ⷀ', 'ⷆ'),
+  ('ⷈ', 'ⷎ'), ('ⷐ', 'ⷖ'), ('ⷘ', 'ⷞ'), ('ꬁ', 'ꬆ'),
+  ('ꬉ', 'ꬎ'), ('ꬑ', 'ꬖ'), ('ꬠ', 'ꬦ'), ('ꬨ', 'ꬮ'),
+];
+
+pub const GEORGIAN: &'static [(char, char)] = &[
+  ('Ⴀ', 'Ⴥ'), ('Ⴧ', 'Ⴧ'), ('Ⴭ', 'Ⴭ'), ('ა', 'ჺ'),
+  ('ჼ', 'ჿ'), ('Ა', 'Ჺ'), ('Ჽ', 'Ჿ'), ('ⴀ', 'ⴥ'),
+  ('ⴧ', 'ⴧ'), ('ⴭ', 'ⴭ'),
+];
+
+pub const GLAGOLITIC: &'static [(char, char)] = &[
+  ('Ⰰ', 'Ⱞ'), ('ⰰ', 'ⱞ'), ('\u{1e000}', '\u{1e006}'),
+  ('\u{1e008}', '\u{1e018}'), ('\u{1e01b}', '\u{1e021}'),
+  ('\u{1e023}', '\u{1e024}'), ('\u{1e026}', '\u{1e02a}'),
+];
+
+pub const GOTHIC: &'static [(char, char)] = &[
+  ('𐌰', '𐍊'),
+];
+
+pub const GRANTHA: &'static [(char, char)] = &[
+  ('\u{11300}', '𑌃'), ('𑌅', '𑌌'), ('𑌏', '𑌐'), ('𑌓', '𑌨'),
+  ('𑌪', '𑌰'), ('𑌲', '𑌳'), ('𑌵', '𑌹'), ('\u{1133c}', '𑍄'),
+  ('𑍇', '𑍈'), ('𑍋', '𑍍'), ('𑍐', '𑍐'),
+  ('\u{11357}', '\u{11357}'), ('𑍝', '𑍣'), ('\u{11366}', '\u{1136c}'),
+  ('\u{11370}', '\u{11374}'),
+];
+
+pub const GREEK: &'static [(char, char)] = &[
+  ('Ͱ', 'ͳ'), ('͵', 'ͷ'), ('ͺ', 'ͽ'), ('Ϳ', 'Ϳ'), ('΄', '΄'),
+  ('Ά', 'Ά'), ('Έ', 'Ί'), ('Ό', 'Ό'), ('Ύ', 'Ρ'), ('Σ', 'ϡ'),
+  ('ϰ', 'Ͽ'), ('ᴦ', 'ᴪ'), ('ᵝ', 'ᵡ'), ('ᵦ', 'ᵪ'),
+  ('ᶿ', 'ᶿ'), ('ἀ', 'ἕ'), ('Ἐ', 'Ἕ'), ('ἠ', 'ὅ'),
+  ('Ὀ', 'Ὅ'), ('ὐ', 'ὗ'), ('Ὑ', 'Ὑ'), ('Ὓ', 'Ὓ'),
+  ('Ὕ', 'Ὕ'), ('Ὗ', 'ώ'), ('ᾀ', 'ᾴ'), ('ᾶ', 'ῄ'),
+  ('ῆ', 'ΐ'), ('ῖ', 'Ί'), ('῝', '`'), ('ῲ', 'ῴ'),
+  ('ῶ', '῾'), ('Ω', 'Ω'), ('ꭥ', 'ꭥ'), ('𐅀', '𐆎'),
+  ('𐆠', '𐆠'), ('𝈀', '𝉅'),
+];
+
+pub const GUJARATI: &'static [(char, char)] = &[
+  ('\u{a81}', 'ઃ'), ('અ', 'ઍ'), ('એ', 'ઑ'), ('ઓ', 'ન'),
+  ('પ', 'ર'), ('લ', 'ળ'), ('વ', 'હ'), ('\u{abc}', '\u{ac5}'),
+  ('\u{ac7}', 'ૉ'), ('ો', '\u{acd}'), ('ૐ', 'ૐ'), ('ૠ', '\u{ae3}'),
+  ('૦', '૱'), ('ૹ', '\u{aff}'),
+];
+
+pub const GUNJALA_GONDI: &'static [(char, char)] = &[
+  ('𑵠', '𑵥'), ('𑵧', '𑵨'), ('𑵪', '𑶎'),
+  ('\u{11d90}', '\u{11d91}'), ('𑶓', '𑶘'), ('𑶠', '𑶩'),
+];
+
+pub const GURMUKHI: &'static [(char, char)] = &[
+  ('\u{a01}', 'ਃ'), ('ਅ', 'ਊ'), ('ਏ', 'ਐ'), ('ਓ', 'ਨ'),
+  ('ਪ', 'ਰ'), ('ਲ', 'ਲ਼'), ('ਵ', 'ਸ਼'), ('ਸ', 'ਹ'),
+  ('\u{a3c}', '\u{a3c}'), ('ਾ', '\u{a42}'), ('\u{a47}', '\u{a48}'),
+  ('\u{a4b}', '\u{a4d}'), ('\u{a51}', '\u{a51}'), ('ਖ਼', 'ੜ'),
+  ('ਫ਼', 'ਫ਼'), ('੦', '੶'),
+];
+
+pub const HAN: &'static [(char, char)] = &[
+  ('⺀', '⺙'), ('⺛', '⻳'), ('⼀', '⿕'), ('々', '々'),
+  ('〇', '〇'), ('〡', '〩'), ('〸', '〻'), ('㐀', '䶵'),
+  ('一', '鿯'), ('豈', '舘'), ('並', '龎'), ('𠀀', '𪛖'),
+  ('𪜀', '𫜴'), ('𫝀', '𫠝'), ('𫠠', '𬺡'), ('𬺰', '𮯠'),
+  ('丽', '𪘀'),
+];
+
+pub const HANGUL: &'static [(char, char)] = &[
+  ('ᄀ', 'ᇿ'), ('\u{302e}', '\u{302f}'), ('ㄱ', 'ㆎ'), ('㈀', '㈞'),
+  ('㉠', '㉾'), ('ꥠ', 'ꥼ'), ('가', '힣'), ('ힰ', 'ퟆ'),
+  ('ퟋ', 'ퟻ'), ('ᅠ', 'ᄒ'), ('ᅡ', 'ᅦ'), ('ᅧ', 'ᅬ'),
+  ('ᅭ', 'ᅲ'), ('ᅳ', 'ᅵ'),
+];
+
+pub const HANIFI_ROHINGYA: &'static [(char, char)] = &[
+  ('𐴀', '\u{10d27}'), ('𐴰', '𐴹'),
+];
+
+pub const HANUNOO: &'static [(char, char)] = &[
+  ('ᜠ', '\u{1734}'),
+];
+
+pub const HATRAN: &'static [(char, char)] = &[
+  ('𐣠', '𐣲'), ('𐣴', '𐣵'), ('𐣻', '𐣿'),
+];
+
+pub const HEBREW: &'static [(char, char)] = &[
+  ('\u{591}', '\u{5c7}'), ('א', 'ת'), ('ׯ', '״'), ('יִ', 'זּ'),
+  ('טּ', 'לּ'), ('מּ', 'מּ'), ('נּ', 'סּ'), ('ףּ', 'פּ'),
+  ('צּ', 'ﭏ'),
+];
+
+pub const HIRAGANA: &'static [(char, char)] = &[
+  ('ぁ', 'ゖ'), ('ゝ', 'ゟ'), ('𛀁', '𛄞'),
+  ('\u{1b150}', '\u{1b152}'), ('🈀', '🈀'),
+];
+
+pub const IMPERIAL_ARAMAIC: &'static [(char, char)] = &[
+  ('𐡀', '𐡕'), ('𐡗', '𐡟'),
+];
+
+pub const INHERITED: &'static [(char, char)] = &[
+  ('\u{300}', '\u{36f}'), ('\u{485}', '\u{486}'), ('\u{64b}', '\u{655}'),
+  ('\u{670}', '\u{670}'), ('\u{951}', '\u{954}'), ('\u{1ab0}', '\u{1abe}'),
+  ('\u{1cd0}', '\u{1cd2}'), ('\u{1cd4}', '\u{1ce0}'),
+  ('\u{1ce2}', '\u{1ce8}'), ('\u{1ced}', '\u{1ced}'),
+  ('\u{1cf4}', '\u{1cf4}'), ('\u{1cf8}', '\u{1cf9}'),
+  ('\u{1dc0}', '\u{1df9}'), ('\u{1dfb}', '\u{1dff}'),
+  ('\u{200c}', '\u{200d}'), ('\u{20d0}', '\u{20f0}'),
+  ('\u{302a}', '\u{302d}'), ('\u{3099}', '\u{309a}'),
+  ('\u{fe00}', '\u{fe0f}'), ('\u{fe20}', '\u{fe2d}'),
+  ('\u{101fd}', '\u{101fd}'), ('\u{102e0}', '\u{102e0}'),
+  ('\u{1133b}', '\u{1133b}'), ('\u{1d167}', '\u{1d169}'),
+  ('\u{1d17b}', '\u{1d182}'), ('\u{1d185}', '\u{1d18b}'),
+  ('\u{1d1aa}', '\u{1d1ad}'), ('\u{e0100}', '\u{e01ef}'),
+];
+
+pub const INSCRIPTIONAL_PAHLAVI: &'static [(char, char)] = &[
+  ('𐭠', '𐭲'), ('𐭸', '𐭿'),
+];
+
+pub const INSCRIPTIONAL_PARTHIAN: &'static [(char, char)] = &[
+  ('𐭀', '𐭕'), ('𐭘', '𐭟'),
+];
+
+pub const JAVANESE: &'static [(char, char)] = &[
+  ('\u{a980}', '꧍'), ('꧐', '꧙'), ('꧞', '꧟'),
+];
+
+pub const KAITHI: &'static [(char, char)] = &[
+  ('\u{11080}', '𑃁'), ('\u{110cd}', '\u{110cd}'),
+];
+
+pub const KANNADA: &'static [(char, char)] = &[
+  ('ಀ', 'ಌ'), ('ಎ', 'ಐ'), ('ಒ', 'ನ'), ('ಪ', 'ಳ'),
+  ('ವ', 'ಹ'), ('\u{cbc}', 'ೄ'), ('\u{cc6}', 'ೈ'), ('ೊ', '\u{ccd}'),
+  ('\u{cd5}', '\u{cd6}'), ('ೞ', 'ೞ'), ('ೠ', '\u{ce3}'), ('೦', '೯'),
+  ('ೱ', 'ೲ'),
+];
+
+pub const KATAKANA: &'static [(char, char)] = &[
+  ('ァ', 'ヺ'), ('ヽ', 'ヿ'), ('ㇰ', 'ㇿ'), ('㋐', '㋾'),
+  ('㌀', '㍗'), ('ヲ', 'ッ'), ('ア', 'ン'), ('𛀀', '𛀀'),
+  ('\u{1b164}', '\u{1b167}'),
+];
+
+pub const KAYAH_LI: &'static [(char, char)] = &[
+  ('꤀', '\u{a92d}'), ('꤯', '꤯'),
+];
+
+pub const KHAROSHTHI: &'static [(char, char)] = &[
+  ('𐨀', '\u{10a03}'), ('\u{10a05}', '\u{10a06}'), ('\u{10a0c}', '𐨓'),
+  ('𐨕', '𐨗'), ('𐨙', '𐨵'), ('\u{10a38}', '\u{10a3a}'),
+  ('\u{10a3f}', '𐩈'), ('𐩐', '𐩘'),
+];
+
+pub const KHMER: &'static [(char, char)] = &[
+  ('ក', '\u{17dd}'), ('០', '៩'), ('៰', '៹'), ('᧠', '᧿'),
+];
+
+pub const KHOJKI: &'static [(char, char)] = &[
+  ('𑈀', '𑈑'), ('𑈓', '\u{1123e}'),
+];
+
+pub const KHUDAWADI: &'static [(char, char)] = &[
+  ('𑊰', '\u{112ea}'), ('𑋰', '𑋹'),
+];
+
+pub const LAO: &'static [(char, char)] = &[
+  ('ກ', 'ຂ'), ('ຄ', 'ຄ'), ('\u{e86}', 'ຊ'), ('\u{e8c}', 'ຣ'),
+  ('ລ', 'ລ'), ('ວ', 'ຽ'), ('ເ', 'ໄ'), ('ໆ', 'ໆ'),
+  ('\u{ec8}', '\u{ecd}'), ('໐', '໙'), ('ໜ', 'ໟ'),
+];
+
+pub const LATIN: &'static [(char, char)] = &[
+  ('A', 'Z'), ('a', 'z'), ('ª', 'ª'), ('º', 'º'), ('À', 'Ö'),
+  ('Ø', 'ö'), ('ø', 'ʸ'), ('ˠ', 'ˤ'), ('ᴀ', 'ᴥ'), ('ᴬ', 'ᵜ'),
+  ('ᵢ', 'ᵥ'), ('ᵫ', 'ᵷ'), ('ᵹ', 'ᶾ'), ('Ḁ', 'ỿ'),
+  ('ⁱ', 'ⁱ'), ('ⁿ', 'ⁿ'), ('ₐ', 'ₜ'), ('K', 'Å'),
+  ('Ⅎ', 'Ⅎ'), ('ⅎ', 'ⅎ'), ('Ⅰ', 'ↈ'), ('Ⱡ', 'Ɀ'),
+  ('Ꜣ', 'ꞇ'), ('Ꞌ', '\u{a7bf}'), ('\u{a7c2}', '\u{a7c6}'),
+  ('ꟷ', 'ꟿ'), ('ꬰ', 'ꭚ'), ('ꭜ', 'ꭤ'), ('\u{ab66}', '\u{ab67}'),
+  ('ff', 'st'), ('A', 'Z'), ('a', 'z'),
+];
+
+pub const LEPCHA: &'static [(char, char)] = &[
+  ('ᰀ', '\u{1c37}'), ('᰻', '᱉'), ('ᱍ', 'ᱏ'),
+];
+
+pub const LIMBU: &'static [(char, char)] = &[
+  ('ᤀ', 'ᤞ'), ('\u{1920}', 'ᤫ'), ('ᤰ', '\u{193b}'), ('᥀', '᥀'),
+  ('᥄', '᥏'),
+];
+
+pub const LINEAR_A: &'static [(char, char)] = &[
+  ('𐘀', '𐜶'), ('𐝀', '𐝕'), ('𐝠', '𐝧'),
+];
+
+pub const LINEAR_B: &'static [(char, char)] = &[
+  ('𐀀', '𐀋'), ('𐀍', '𐀦'), ('𐀨', '𐀺'), ('𐀼', '𐀽'),
+  ('𐀿', '𐁍'), ('𐁐', '𐁝'), ('𐂀', '𐃺'),
+];
+
+pub const LISU: &'static [(char, char)] = &[
+  ('ꓐ', '꓿'),
+];
+
+pub const LYCIAN: &'static [(char, char)] = &[
+  ('𐊀', '𐊜'),
+];
+
+pub const LYDIAN: &'static [(char, char)] = &[
+  ('𐤠', '𐤹'), ('𐤿', '𐤿'),
+];
+
+pub const MAHAJANI: &'static [(char, char)] = &[
+  ('𑅐', '𑅶'),
+];
+
+pub const MAKASAR: &'static [(char, char)] = &[
+  ('𑻠', '𑻸'),
+];
+
+pub const MALAYALAM: &'static [(char, char)] = &[
+  ('\u{d00}', 'ഃ'), ('അ', 'ഌ'), ('എ', 'ഐ'), ('ഒ', '\u{d44}'),
+  ('െ', 'ൈ'), ('ൊ', '൏'), ('ൔ', '\u{d63}'), ('൦', 'ൿ'),
+];
+
+pub const MANDAIC: &'static [(char, char)] = &[
+  ('ࡀ', '\u{85b}'), ('࡞', '࡞'),
+];
+
+pub const MANICHAEAN: &'static [(char, char)] = &[
+  ('𐫀', '\u{10ae6}'), ('𐫫', '𐫶'),
+];
+
+pub const MARCHEN: &'static [(char, char)] = &[
+  ('𑱰', '𑲏'), ('\u{11c92}', '\u{11ca7}'), ('𑲩', '\u{11cb6}'),
+];
+
+pub const MASARAM_GONDI: &'static [(char, char)] = &[
+  ('𑴀', '𑴆'), ('𑴈', '𑴉'), ('𑴋', '\u{11d36}'),
+  ('\u{11d3a}', '\u{11d3a}'), ('\u{11d3c}', '\u{11d3d}'),
+  ('\u{11d3f}', '\u{11d47}'), ('𑵐', '𑵙'),
+];
+
+pub const MEDEFAIDRIN: &'static [(char, char)] = &[
+  ('𖹀', '𖺚'),
+];
+
+pub const MEETEI_MAYEK: &'static [(char, char)] = &[
+  ('ꫠ', '\u{aaf6}'), ('ꯀ', '\u{abed}'), ('꯰', '꯹'),
+];
+
+pub const MENDE_KIKAKUI: &'static [(char, char)] = &[
+  ('𞠀', '𞣄'), ('𞣇', '\u{1e8d6}'),
+];
+
+pub const MEROITIC_CURSIVE: &'static [(char, char)] = &[
+  ('𐦠', '𐦷'), ('𐦼', '𐧏'), ('𐧒', '𐧿'),
+];
+
+pub const MEROITIC_HIEROGLYPHS: &'static [(char, char)] = &[
+  ('𐦀', '𐦟'),
+];
+
+pub const MIAO: &'static [(char, char)] = &[
+  ('𖼀', '\u{16f4a}'), ('\u{16f4f}', '\u{16f87}'), ('\u{16f8f}', '𖾟'),
+];
+
+pub const MODI: &'static [(char, char)] = &[
+  ('𑘀', '𑙄'), ('𑙐', '𑙙'),
+];
+
+pub const MONGOLIAN: &'static [(char, char)] = &[
+  ('᠀', '᠁'), ('᠄', '᠄'), ('᠆', '\u{180e}'), ('᠐', '᠙'),
+  ('ᠠ', 'ᡸ'), ('ᢀ', 'ᢪ'), ('𑙠', '𑙬'),
+];
+
+pub const MRO: &'static [(char, char)] = &[
+  ('𖩀', '𖩞'), ('𖩠', '𖩩'), ('𖩮', '𖩯'),
+];
+
+pub const MULTANI: &'static [(char, char)] = &[
+  ('𑊀', '𑊆'), ('𑊈', '𑊈'), ('𑊊', '𑊍'), ('𑊏', '𑊝'),
+  ('𑊟', '𑊩'),
+];
+
+pub const MYANMAR: &'static [(char, char)] = &[
+  ('က', '႟'), ('ꧠ', 'ꧾ'), ('ꩠ', 'ꩿ'),
+];
+
+pub const NABATAEAN: &'static [(char, char)] = &[
+  ('𐢀', '𐢞'), ('𐢧', '𐢯'),
+];
+
+pub const NANDINAGARI: &'static [(char, char)] = &[
+  ('\u{119a0}', '\u{119a7}'), ('\u{119aa}', '\u{119d7}'),
+  ('\u{119da}', '\u{119e4}'),
+];
+
+pub const NEW_TAI_LUE: &'static [(char, char)] = &[
+  ('ᦀ', 'ᦫ'), ('ᦰ', 'ᧉ'), ('᧐', '᧚'), ('᧞', '᧟'),
+];
+
+pub const NEWA: &'static [(char, char)] = &[
+  ('𑐀', '𑑙'), ('𑑛', '𑑛'), ('𑑝', '\u{1145f}'),
+];
+
+pub const NKO: &'static [(char, char)] = &[
+  ('߀', 'ߺ'), ('\u{7fd}', '߿'),
+];
+
+pub const NUSHU: &'static [(char, char)] = &[
+  ('𖿡', '𖿡'), ('𛅰', '𛋻'),
+];
+
+pub const NYIAKENG_PUACHUE_HMONG: &'static [(char, char)] = &[
+  ('\u{1e100}', '\u{1e12c}'), ('\u{1e130}', '\u{1e13d}'),
+  ('\u{1e140}', '\u{1e149}'), ('\u{1e14e}', '\u{1e14f}'),
+];
+
+pub const OGHAM: &'static [(char, char)] = &[
+  ('\u{1680}', '᚜'),
+];
+
+pub const OL_CHIKI: &'static [(char, char)] = &[
+  ('᱐', '᱿'),
+];
+
+pub const OLD_HUNGARIAN: &'static [(char, char)] = &[
+  ('𐲀', '𐲲'), ('𐳀', '𐳲'), ('𐳺', '𐳿'),
+];
+
+pub const OLD_ITALIC: &'static [(char, char)] = &[
+  ('𐌀', '𐌣'), ('𐌭', '𐌯'),
+];
+
+pub const OLD_NORTH_ARABIAN: &'static [(char, char)] = &[
+  ('𐪀', '𐪟'),
+];
+
+pub const OLD_PERMIC: &'static [(char, char)] = &[
+  ('𐍐', '\u{1037a}'),
+];
+
+pub const OLD_PERSIAN: &'static [(char, char)] = &[
+  ('𐎠', '𐏃'), ('𐏈', '𐏕'),
+];
+
+pub const OLD_SOGDIAN: &'static [(char, char)] = &[
+  ('𐼀', '𐼧'),
+];
+
+pub const OLD_SOUTH_ARABIAN: &'static [(char, char)] = &[
+  ('𐩠', '𐩿'),
+];
+
+pub const OLD_TURKIC: &'static [(char, char)] = &[
+  ('𐰀', '𐱈'),
+];
+
+pub const ORIYA: &'static [(char, char)] = &[
+  ('\u{b01}', 'ଃ'), ('ଅ', 'ଌ'), ('ଏ', 'ଐ'), ('ଓ', 'ନ'),
+  ('ପ', 'ର'), ('ଲ', 'ଳ'), ('ଵ', 'ହ'), ('\u{b3c}', '\u{b44}'),
+  ('େ', 'ୈ'), ('ୋ', '\u{b4d}'), ('\u{b56}', '\u{b57}'), ('ଡ଼', 'ଢ଼'),
+  ('ୟ', '\u{b63}'), ('୦', '୷'),
+];
+
+pub const OSAGE: &'static [(char, char)] = &[
+  ('𐒰', '𐓓'), ('𐓘', '𐓻'),
+];
+
+pub const OSMANYA: &'static [(char, char)] = &[
+  ('𐒀', '𐒝'), ('𐒠', '𐒩'),
+];
+
+pub const PAHAWH_HMONG: &'static [(char, char)] = &[
+  ('𖬀', '𖭅'), ('𖭐', '𖭙'), ('𖭛', '𖭡'), ('𖭣', '𖭷'),
+  ('𖭽', '𖮏'),
+];
+
+pub const PALMYRENE: &'static [(char, char)] = &[
+  ('𐡠', '𐡿'),
+];
+
+pub const PAU_CIN_HAU: &'static [(char, char)] = &[
+  ('𑫀', '𑫸'),
+];
+
+pub const PHAGS_PA: &'static [(char, char)] = &[
+  ('ꡀ', '꡷'),
+];
+
+pub const PHOENICIAN: &'static [(char, char)] = &[
+  ('𐤀', '𐤛'), ('𐤟', '𐤟'),
+];
+
+pub const PSALTER_PAHLAVI: &'static [(char, char)] = &[
+  ('𐮀', '𐮑'), ('𐮙', '𐮜'), ('𐮩', '𐮯'),
+];
+
+pub const REJANG: &'static [(char, char)] = &[
+  ('ꤰ', '꥓'), ('꥟', '꥟'),
+];
+
+pub const RUNIC: &'static [(char, char)] = &[
+  ('ᚠ', 'ᛪ'), ('ᛮ', 'ᛸ'),
+];
+
+pub const SAMARITAN: &'static [(char, char)] = &[
+  ('ࠀ', '\u{82d}'), ('࠰', '࠾'),
+];
+
+pub const SAURASHTRA: &'static [(char, char)] = &[
+  ('ꢀ', '\u{a8c5}'), ('꣎', '꣙'),
+];
+
+pub const SHARADA: &'static [(char, char)] = &[
+  ('\u{11180}', '𑇍'), ('𑇐', '𑇟'),
+];
+
+pub const SHAVIAN: &'static [(char, char)] = &[
+  ('𐑐', '𐑿'),
+];
+
+pub const SIDDHAM: &'static [(char, char)] = &[
+  ('𑖀', '\u{115b5}'), ('𑖸', '\u{115dd}'),
+];
+
+pub const SIGNWRITING: &'static [(char, char)] = &[
+  ('𝠀', '𝪋'), ('\u{1da9b}', '\u{1da9f}'), ('\u{1daa1}', '\u{1daaf}'),
+];
+
+pub const SINHALA: &'static [(char, char)] = &[
+  ('ං', 'ඃ'), ('අ', 'ඖ'), ('ක', 'න'), ('ඳ', 'ර'),
+  ('ල', 'ල'), ('ව', 'ෆ'), ('\u{dca}', '\u{dca}'),
+  ('\u{dcf}', '\u{dd4}'), ('\u{dd6}', '\u{dd6}'), ('ෘ', '\u{ddf}'),
+  ('෦', '෯'), ('ෲ', '෴'), ('𑇡', '𑇴'),
+];
+
+pub const SOGDIAN: &'static [(char, char)] = &[
+  ('𐼰', '𐽙'),
+];
+
+pub const SORA_SOMPENG: &'static [(char, char)] = &[
+  ('𑃐', '𑃨'), ('𑃰', '𑃹'),
+];
+
+pub const SOYOMBO: &'static [(char, char)] = &[
+  ('𑩐', '𑪢'),
+];
+
+pub const SUNDANESE: &'static [(char, char)] = &[
+  ('\u{1b80}', 'ᮿ'), ('᳀', '᳇'),
+];
+
+pub const SYLOTI_NAGRI: &'static [(char, char)] = &[
+  ('ꠀ', '꠫'),
+];
+
+pub const SYRIAC: &'static [(char, char)] = &[
+  ('܀', '܍'), ('\u{70f}', '\u{74a}'), ('ݍ', 'ݏ'), ('ࡠ', 'ࡪ'),
+];
+
+pub const TAGALOG: &'static [(char, char)] = &[
+  ('ᜀ', 'ᜌ'), ('ᜎ', '\u{1714}'),
+];
+
+pub const TAGBANWA: &'static [(char, char)] = &[
+  ('ᝠ', 'ᝬ'), ('ᝮ', 'ᝰ'), ('\u{1772}', '\u{1773}'),
+];
+
+pub const TAI_LE: &'static [(char, char)] = &[
+  ('ᥐ', 'ᥭ'), ('ᥰ', 'ᥴ'),
+];
+
+pub const TAI_THAM: &'static [(char, char)] = &[
+  ('ᨠ', '\u{1a5e}'), ('\u{1a60}', '\u{1a7c}'), ('\u{1a7f}', '᪉'),
+  ('᪐', '᪙'), ('᪠', '᪭'),
+];
+
+pub const TAI_VIET: &'static [(char, char)] = &[
+  ('ꪀ', 'ꫂ'), ('ꫛ', '꫟'),
+];
+
+pub const TAKRI: &'static [(char, char)] = &[
+  ('𑚀', '\u{116b8}'), ('𑛀', '𑛉'),
+];
+
+pub const TAMIL: &'static [(char, char)] = &[
+  ('\u{b82}', 'ஃ'), ('அ', 'ஊ'), ('எ', 'ஐ'), ('ஒ', 'க'),
+  ('ங', 'ச'), ('ஜ', 'ஜ'), ('ஞ', 'ட'), ('ண', 'த'),
+  ('ந', 'ப'), ('ம', 'ஹ'), ('\u{bbe}', 'ூ'), ('ெ', 'ை'),
+  ('ொ', '\u{bcd}'), ('ௐ', 'ௐ'), ('\u{bd7}', '\u{bd7}'), ('௦', '௺'),
+  ('\u{11fc0}', '\u{11ff1}'), ('\u{11fff}', '\u{11fff}'),
+];
+
+pub const TANGUT: &'static [(char, char)] = &[
+  ('𖿠', '𖿠'), ('𗀀', '\u{187f7}'), ('𘠀', '𘫲'),
+];
+
+pub const TELUGU: &'static [(char, char)] = &[
+  ('\u{c00}', 'ఌ'), ('ఎ', 'ఐ'), ('ఒ', 'న'), ('ప', 'హ'),
+  ('ఽ', 'ౄ'), ('\u{c46}', '\u{c48}'), ('\u{c4a}', '\u{c4d}'),
+  ('\u{c55}', '\u{c56}'), ('ౘ', 'ౚ'), ('ౠ', '\u{c63}'), ('౦', '౯'),
+  ('\u{c77}', '౿'),
+];
+
+pub const THAANA: &'static [(char, char)] = &[
+  ('ހ', 'ޱ'),
+];
+
+pub const THAI: &'static [(char, char)] = &[
+  ('ก', '\u{e3a}'), ('เ', '๛'),
+];
+
+pub const TIBETAN: &'static [(char, char)] = &[
+  ('ༀ', 'ཇ'), ('ཉ', 'ཬ'), ('\u{f71}', '\u{f97}'),
+  ('\u{f99}', '\u{fbc}'), ('྾', '࿌'), ('࿎', '࿔'), ('࿙', '࿚'),
+];
+
+pub const TIFINAGH: &'static [(char, char)] = &[
+  ('ⴰ', 'ⵧ'), ('ⵯ', '⵰'), ('\u{2d7f}', '\u{2d7f}'),
+];
+
+pub const TIRHUTA: &'static [(char, char)] = &[
+  ('𑒀', '𑓇'), ('𑓐', '𑓙'),
+];
+
+pub const UGARITIC: &'static [(char, char)] = &[
+  ('𐎀', '𐎝'), ('𐎟', '𐎟'),
+];
+
+pub const VAI: &'static [(char, char)] = &[
+  ('ꔀ', 'ꘫ'),
+];
+
+pub const WANCHO: &'static [(char, char)] = &[
+  ('\u{1e2c0}', '\u{1e2f9}'), ('\u{1e2ff}', '\u{1e2ff}'),
+];
+
+pub const WARANG_CITI: &'static [(char, char)] = &[
+  ('𑢠', '𑣲'), ('𑣿', '𑣿'),
+];
+
+pub const YI: &'static [(char, char)] = &[
+  ('ꀀ', 'ꒌ'), ('꒐', '꓆'),
+];
+
+pub const ZANABAZAR_SQUARE: &'static [(char, char)] = &[
+  ('𑨀', '\u{11a47}'),
+];
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/unicode_tables/script_extension.rs.html b/target/doc/src/regex_syntax/unicode_tables/script_extension.rs.html new file mode 100644 index 0000000..e5bf178 --- /dev/null +++ b/target/doc/src/regex_syntax/unicode_tables/script_extension.rs.html @@ -0,0 +1,1749 @@ +script_extension.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+
+// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
+//
+//  ucd-generate script-extension /tmp/ucd-12.1.0/ --chars
+//
+// ucd-generate is available on crates.io.
+
+pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
+  ("Adlam", ADLAM), ("Ahom", AHOM),
+  ("Anatolian_Hieroglyphs", ANATOLIAN_HIEROGLYPHS), ("Arabic", ARABIC),
+  ("Armenian", ARMENIAN), ("Avestan", AVESTAN), ("Balinese", BALINESE),
+  ("Bamum", BAMUM), ("Bassa_Vah", BASSA_VAH), ("Batak", BATAK),
+  ("Bengali", BENGALI), ("Bhaiksuki", BHAIKSUKI), ("Bopomofo", BOPOMOFO),
+  ("Brahmi", BRAHMI), ("Braille", BRAILLE), ("Buginese", BUGINESE),
+  ("Buhid", BUHID), ("Canadian_Aboriginal", CANADIAN_ABORIGINAL),
+  ("Carian", CARIAN), ("Caucasian_Albanian", CAUCASIAN_ALBANIAN),
+  ("Chakma", CHAKMA), ("Cham", CHAM), ("Cherokee", CHEROKEE),
+  ("Common", COMMON), ("Coptic", COPTIC), ("Cuneiform", CUNEIFORM),
+  ("Cypriot", CYPRIOT), ("Cyrillic", CYRILLIC), ("Deseret", DESERET),
+  ("Devanagari", DEVANAGARI), ("Dogra", DOGRA), ("Duployan", DUPLOYAN),
+  ("Egyptian_Hieroglyphs", EGYPTIAN_HIEROGLYPHS), ("Elbasan", ELBASAN),
+  ("Elymaic", ELYMAIC), ("Ethiopic", ETHIOPIC), ("Georgian", GEORGIAN),
+  ("Glagolitic", GLAGOLITIC), ("Gothic", GOTHIC), ("Grantha", GRANTHA),
+  ("Greek", GREEK), ("Gujarati", GUJARATI), ("Gunjala_Gondi", GUNJALA_GONDI),
+  ("Gurmukhi", GURMUKHI), ("Han", HAN), ("Hangul", HANGUL),
+  ("Hanifi_Rohingya", HANIFI_ROHINGYA), ("Hanunoo", HANUNOO),
+  ("Hatran", HATRAN), ("Hebrew", HEBREW), ("Hiragana", HIRAGANA),
+  ("Imperial_Aramaic", IMPERIAL_ARAMAIC), ("Inherited", INHERITED),
+  ("Inscriptional_Pahlavi", INSCRIPTIONAL_PAHLAVI),
+  ("Inscriptional_Parthian", INSCRIPTIONAL_PARTHIAN), ("Javanese", JAVANESE),
+  ("Kaithi", KAITHI), ("Kannada", KANNADA), ("Katakana", KATAKANA),
+  ("Kayah_Li", KAYAH_LI), ("Kharoshthi", KHAROSHTHI), ("Khmer", KHMER),
+  ("Khojki", KHOJKI), ("Khudawadi", KHUDAWADI), ("Lao", LAO),
+  ("Latin", LATIN), ("Lepcha", LEPCHA), ("Limbu", LIMBU),
+  ("Linear_A", LINEAR_A), ("Linear_B", LINEAR_B), ("Lisu", LISU),
+  ("Lycian", LYCIAN), ("Lydian", LYDIAN), ("Mahajani", MAHAJANI),
+  ("Makasar", MAKASAR), ("Malayalam", MALAYALAM), ("Mandaic", MANDAIC),
+  ("Manichaean", MANICHAEAN), ("Marchen", MARCHEN),
+  ("Masaram_Gondi", MASARAM_GONDI), ("Medefaidrin", MEDEFAIDRIN),
+  ("Meetei_Mayek", MEETEI_MAYEK), ("Mende_Kikakui", MENDE_KIKAKUI),
+  ("Meroitic_Cursive", MEROITIC_CURSIVE),
+  ("Meroitic_Hieroglyphs", MEROITIC_HIEROGLYPHS), ("Miao", MIAO),
+  ("Modi", MODI), ("Mongolian", MONGOLIAN), ("Mro", MRO),
+  ("Multani", MULTANI), ("Myanmar", MYANMAR), ("Nabataean", NABATAEAN),
+  ("Nandinagari", NANDINAGARI), ("New_Tai_Lue", NEW_TAI_LUE), ("Newa", NEWA),
+  ("Nko", NKO), ("Nushu", NUSHU),
+  ("Nyiakeng_Puachue_Hmong", NYIAKENG_PUACHUE_HMONG), ("Ogham", OGHAM),
+  ("Ol_Chiki", OL_CHIKI), ("Old_Hungarian", OLD_HUNGARIAN),
+  ("Old_Italic", OLD_ITALIC), ("Old_North_Arabian", OLD_NORTH_ARABIAN),
+  ("Old_Permic", OLD_PERMIC), ("Old_Persian", OLD_PERSIAN),
+  ("Old_Sogdian", OLD_SOGDIAN), ("Old_South_Arabian", OLD_SOUTH_ARABIAN),
+  ("Old_Turkic", OLD_TURKIC), ("Oriya", ORIYA), ("Osage", OSAGE),
+  ("Osmanya", OSMANYA), ("Pahawh_Hmong", PAHAWH_HMONG),
+  ("Palmyrene", PALMYRENE), ("Pau_Cin_Hau", PAU_CIN_HAU),
+  ("Phags_Pa", PHAGS_PA), ("Phoenician", PHOENICIAN),
+  ("Psalter_Pahlavi", PSALTER_PAHLAVI), ("Rejang", REJANG), ("Runic", RUNIC),
+  ("Samaritan", SAMARITAN), ("Saurashtra", SAURASHTRA), ("Sharada", SHARADA),
+  ("Shavian", SHAVIAN), ("Siddham", SIDDHAM), ("SignWriting", SIGNWRITING),
+  ("Sinhala", SINHALA), ("Sogdian", SOGDIAN), ("Sora_Sompeng", SORA_SOMPENG),
+  ("Soyombo", SOYOMBO), ("Sundanese", SUNDANESE),
+  ("Syloti_Nagri", SYLOTI_NAGRI), ("Syriac", SYRIAC), ("Tagalog", TAGALOG),
+  ("Tagbanwa", TAGBANWA), ("Tai_Le", TAI_LE), ("Tai_Tham", TAI_THAM),
+  ("Tai_Viet", TAI_VIET), ("Takri", TAKRI), ("Tamil", TAMIL),
+  ("Tangut", TANGUT), ("Telugu", TELUGU), ("Thaana", THAANA), ("Thai", THAI),
+  ("Tibetan", TIBETAN), ("Tifinagh", TIFINAGH), ("Tirhuta", TIRHUTA),
+  ("Ugaritic", UGARITIC), ("Vai", VAI), ("Wancho", WANCHO),
+  ("Warang_Citi", WARANG_CITI), ("Yi", YI),
+  ("Zanabazar_Square", ZANABAZAR_SQUARE),
+];
+
+pub const ADLAM: &'static [(char, char)] = &[
+  ('ـ', 'ـ'), ('𞤀', '\u{1e94b}'), ('𞥐', '𞥙'), ('𞥞', '𞥟'),
+];
+
+pub const AHOM: &'static [(char, char)] = &[
+  ('𑜀', '𑜚'), ('\u{1171d}', '\u{1172b}'), ('𑜰', '𑜿'),
+];
+
+pub const ANATOLIAN_HIEROGLYPHS: &'static [(char, char)] = &[
+  ('𔐀', '𔙆'),
+];
+
+pub const ARABIC: &'static [(char, char)] = &[
+  ('\u{600}', '\u{604}'), ('؆', '\u{61c}'), ('؞', '\u{6dc}'), ('۞', 'ۿ'),
+  ('ݐ', 'ݿ'), ('ࢠ', 'ࢴ'), ('ࢶ', 'ࢽ'), ('\u{8d3}', '\u{8e1}'),
+  ('\u{8e3}', '\u{8ff}'), ('ﭐ', '﯁'), ('ﯓ', 'ﴽ'), ('ﵐ', 'ﶏ'),
+  ('ﶒ', 'ﷇ'), ('ﷰ', '﷽'), ('ﹰ', 'ﹴ'), ('ﹶ', 'ﻼ'),
+  ('\u{102e0}', '𐋻'), ('𐹠', '𐹾'), ('𞸀', '𞸃'), ('𞸅', '𞸟'),
+  ('𞸡', '𞸢'), ('𞸤', '𞸤'), ('𞸧', '𞸧'), ('𞸩', '𞸲'),
+  ('𞸴', '𞸷'), ('𞸹', '𞸹'), ('𞸻', '𞸻'), ('𞹂', '𞹂'),
+  ('𞹇', '𞹇'), ('𞹉', '𞹉'), ('𞹋', '𞹋'), ('𞹍', '𞹏'),
+  ('𞹑', '𞹒'), ('𞹔', '𞹔'), ('𞹗', '𞹗'), ('𞹙', '𞹙'),
+  ('𞹛', '𞹛'), ('𞹝', '𞹝'), ('𞹟', '𞹟'), ('𞹡', '𞹢'),
+  ('𞹤', '𞹤'), ('𞹧', '𞹪'), ('𞹬', '𞹲'), ('𞹴', '𞹷'),
+  ('𞹹', '𞹼'), ('𞹾', '𞹾'), ('𞺀', '𞺉'), ('𞺋', '𞺛'),
+  ('𞺡', '𞺣'), ('𞺥', '𞺩'), ('𞺫', '𞺻'), ('𞻰', '𞻱'),
+];
+
+pub const ARMENIAN: &'static [(char, char)] = &[
+  ('Ա', 'Ֆ'), ('ՙ', '֊'), ('֍', '֏'), ('ﬓ', 'ﬗ'),
+];
+
+pub const AVESTAN: &'static [(char, char)] = &[
+  ('𐬀', '𐬵'), ('𐬹', '𐬿'),
+];
+
+pub const BALINESE: &'static [(char, char)] = &[
+  ('\u{1b00}', 'ᭋ'), ('᭐', '᭼'),
+];
+
+pub const BAMUM: &'static [(char, char)] = &[
+  ('ꚠ', '꛷'), ('𖠀', '𖨸'),
+];
+
+pub const BASSA_VAH: &'static [(char, char)] = &[
+  ('𖫐', '𖫭'), ('\u{16af0}', '𖫵'),
+];
+
+pub const BATAK: &'static [(char, char)] = &[
+  ('ᯀ', '᯳'), ('᯼', '᯿'),
+];
+
+pub const BENGALI: &'static [(char, char)] = &[
+  ('\u{951}', '\u{952}'), ('।', '॥'), ('ঀ', 'ঃ'), ('অ', 'ঌ'),
+  ('এ', 'ঐ'), ('ও', 'ন'), ('প', 'র'), ('ল', 'ল'),
+  ('শ', 'হ'), ('\u{9bc}', '\u{9c4}'), ('ে', 'ৈ'), ('ো', 'ৎ'),
+  ('\u{9d7}', '\u{9d7}'), ('ড়', 'ঢ়'), ('য়', '\u{9e3}'),
+  ('০', '\u{9fe}'), ('\u{1cd0}', '\u{1cd0}'), ('\u{1cd2}', '\u{1cd2}'),
+  ('\u{1cd5}', '\u{1cd6}'), ('\u{1cd8}', '\u{1cd8}'), ('᳡', '᳡'),
+  ('ᳪ', 'ᳪ'), ('\u{1ced}', '\u{1ced}'), ('ᳲ', 'ᳲ'), ('ᳵ', '᳷'),
+  ('\u{a8f1}', '\u{a8f1}'),
+];
+
+pub const BHAIKSUKI: &'static [(char, char)] = &[
+  ('𑰀', '𑰈'), ('𑰊', '\u{11c36}'), ('\u{11c38}', '𑱅'),
+  ('𑱐', '𑱬'),
+];
+
+pub const BOPOMOFO: &'static [(char, char)] = &[
+  ('˪', '˫'), ('、', '〃'), ('〈', '】'), ('〓', '〟'),
+  ('\u{302a}', '\u{302d}'), ('〰', '〰'), ('〷', '〷'), ('・', '・'),
+  ('ㄅ', 'ㄯ'), ('ㆠ', 'ㆺ'), ('﹅', '﹆'), ('。', '・'),
+];
+
+pub const BRAHMI: &'static [(char, char)] = &[
+  ('𑀀', '𑁍'), ('𑁒', '𑁯'), ('\u{1107f}', '\u{1107f}'),
+];
+
+pub const BRAILLE: &'static [(char, char)] = &[
+  ('⠀', '⣿'),
+];
+
+pub const BUGINESE: &'static [(char, char)] = &[
+  ('ᨀ', '\u{1a1b}'), ('᨞', '᨟'), ('ꧏ', 'ꧏ'),
+];
+
+pub const BUHID: &'static [(char, char)] = &[
+  ('᜵', '᜶'), ('ᝀ', '\u{1753}'),
+];
+
+pub const CANADIAN_ABORIGINAL: &'static [(char, char)] = &[
+  ('᐀', 'ᙿ'), ('ᢰ', 'ᣵ'),
+];
+
+pub const CARIAN: &'static [(char, char)] = &[
+  ('𐊠', '𐋐'),
+];
+
+pub const CAUCASIAN_ALBANIAN: &'static [(char, char)] = &[
+  ('𐔰', '𐕣'), ('𐕯', '𐕯'),
+];
+
+pub const CHAKMA: &'static [(char, char)] = &[
+  ('০', '৯'), ('၀', '၉'), ('\u{11100}', '\u{11134}'),
+  ('𑄶', '𑅆'),
+];
+
+pub const CHAM: &'static [(char, char)] = &[
+  ('ꨀ', '\u{aa36}'), ('ꩀ', 'ꩍ'), ('꩐', '꩙'), ('꩜', '꩟'),
+];
+
+pub const CHEROKEE: &'static [(char, char)] = &[
+  ('Ꭰ', 'Ᏽ'), ('ᏸ', 'ᏽ'), ('ꭰ', 'ꮿ'),
+];
+
+pub const COMMON: &'static [(char, char)] = &[
+  ('\u{0}', '@'), ('[', '`'), ('{', '©'), ('«', '¹'), ('»', '¿'),
+  ('×', '×'), ('÷', '÷'), ('ʹ', '˟'), ('˥', '˩'), ('ˬ', '˿'),
+  ('ʹ', 'ʹ'), (';', ';'), ('΅', '΅'), ('·', '·'),
+  ('\u{605}', '\u{605}'), ('\u{6dd}', '\u{6dd}'), ('\u{8e2}', '\u{8e2}'),
+  ('฿', '฿'), ('࿕', '࿘'), ('᛫', '᛭'), ('\u{2000}', '\u{200b}'),
+  ('\u{200e}', '\u{202e}'), ('‰', '\u{2064}'), ('\u{2066}', '⁰'),
+  ('⁴', '⁾'), ('₀', '₎'), ('₠', '₿'), ('℀', '℥'),
+  ('℧', '℩'), ('ℬ', 'ℱ'), ('ℳ', '⅍'), ('⅏', '⅟'),
+  ('↉', '↋'), ('←', '␦'), ('⑀', '⑊'), ('①', '⟿'),
+  ('⤀', '⭳'), ('⭶', '⮕'), ('⮘', '\u{2bff}'), ('⸀', '⹂'),
+  ('⹄', '\u{2e4f}'), ('⿰', '⿻'), ('\u{3000}', '\u{3000}'),
+  ('〄', '〄'), ('〒', '〒'), ('〠', '〠'), ('〶', '〶'),
+  ('㉈', '㉟'), ('㉿', '㉿'), ('㊱', '㊿'), ('㋌', '㋏'),
+  ('㍱', '㍺'), ('㎀', '㏟'), ('㏿', '㏿'), ('䷀', '䷿'),
+  ('꜀', '꜡'), ('ꞈ', '꞊'), ('꭛', '꭛'), ('﴾', '﴿'),
+  ('︐', '︙'), ('︰', '﹄'), ('﹇', '﹒'), ('﹔', '﹦'),
+  ('﹨', '﹫'), ('\u{feff}', '\u{feff}'), ('!', '@'), ('[', '`'),
+  ('{', '⦆'), ('¢', '₩'), ('│', '○'), ('\u{fff9}', '�'),
+  ('𐆐', '𐆛'), ('𐇐', '𐇼'), ('\u{16fe2}', '\u{16fe3}'),
+  ('𝀀', '𝃵'), ('𝄀', '𝄦'), ('𝄩', '𝅦'), ('𝅪', '\u{1d17a}'),
+  ('𝆃', '𝆄'), ('𝆌', '𝆩'), ('𝆮', '𝇨'), ('𝋠', '𝋳'),
+  ('𝌀', '𝍖'), ('𝍲', '𝍸'), ('𝐀', '𝑔'), ('𝑖', '𝒜'),
+  ('𝒞', '𝒟'), ('𝒢', '𝒢'), ('𝒥', '𝒦'), ('𝒩', '𝒬'),
+  ('𝒮', '𝒹'), ('𝒻', '𝒻'), ('𝒽', '𝓃'), ('𝓅', '𝔅'),
+  ('𝔇', '𝔊'), ('𝔍', '𝔔'), ('𝔖', '𝔜'), ('𝔞', '𝔹'),
+  ('𝔻', '𝔾'), ('𝕀', '𝕄'), ('𝕆', '𝕆'), ('𝕊', '𝕐'),
+  ('𝕒', '𝚥'), ('𝚨', '𝟋'), ('𝟎', '𝟿'), ('𞱱', '𞲴'),
+  ('\u{1ed01}', '\u{1ed3d}'), ('🀀', '🀫'), ('🀰', '🂓'),
+  ('🂠', '🂮'), ('🂱', '🂿'), ('🃁', '🃏'), ('🃑', '🃵'),
+  ('🄀', '🄌'), ('🄐', '\u{1f16c}'), ('🅰', '🆬'), ('🇦', '🇿'),
+  ('🈁', '🈂'), ('🈐', '🈻'), ('🉀', '🉈'), ('🉠', '🉥'),
+  ('🌀', '\u{1f6d5}'), ('🛠', '🛬'), ('🛰', '\u{1f6fa}'),
+  ('🜀', '🝳'), ('🞀', '🟘'), ('\u{1f7e0}', '\u{1f7eb}'),
+  ('🠀', '🠋'), ('🠐', '🡇'), ('🡐', '🡙'), ('🡠', '🢇'),
+  ('🢐', '🢭'), ('🤀', '🤋'), ('\u{1f90d}', '\u{1f971}'),
+  ('🥳', '🥶'), ('🥺', '🦢'), ('\u{1f9a5}', '\u{1f9aa}'),
+  ('\u{1f9ae}', '\u{1f9ca}'), ('\u{1f9cd}', '\u{1fa53}'), ('🩠', '🩭'),
+  ('\u{1fa70}', '\u{1fa73}'), ('\u{1fa78}', '\u{1fa7a}'),
+  ('\u{1fa80}', '\u{1fa82}'), ('\u{1fa90}', '\u{1fa95}'),
+  ('\u{e0001}', '\u{e0001}'), ('\u{e0020}', '\u{e007f}'),
+];
+
+pub const COPTIC: &'static [(char, char)] = &[
+  ('Ϣ', 'ϯ'), ('Ⲁ', 'ⳳ'), ('⳹', '⳿'), ('\u{102e0}', '𐋻'),
+];
+
+pub const CUNEIFORM: &'static [(char, char)] = &[
+  ('𒀀', '𒎙'), ('𒐀', '𒑮'), ('𒑰', '𒑴'), ('𒒀', '𒕃'),
+];
+
+pub const CYPRIOT: &'static [(char, char)] = &[
+  ('𐄀', '𐄂'), ('𐄇', '𐄳'), ('𐄷', '𐄿'), ('𐠀', '𐠅'),
+  ('𐠈', '𐠈'), ('𐠊', '𐠵'), ('𐠷', '𐠸'), ('𐠼', '𐠼'),
+  ('𐠿', '𐠿'),
+];
+
+pub const CYRILLIC: &'static [(char, char)] = &[
+  ('Ѐ', 'ԯ'), ('ᲀ', 'ᲈ'), ('ᴫ', 'ᴫ'), ('ᵸ', 'ᵸ'),
+  ('\u{2de0}', '\u{2dff}'), ('⹃', '⹃'), ('Ꙁ', '\u{a69f}'),
+  ('\u{fe2e}', '\u{fe2f}'),
+];
+
+pub const DESERET: &'static [(char, char)] = &[
+  ('𐐀', '𐑏'),
+];
+
+pub const DEVANAGARI: &'static [(char, char)] = &[
+  ('\u{900}', '\u{952}'), ('\u{955}', 'ॿ'), ('\u{1cd0}', 'ᳶ'),
+  ('\u{1cf8}', '\u{1cf9}'), ('\u{20f0}', '\u{20f0}'), ('꠰', '꠹'),
+  ('\u{a8e0}', '\u{a8ff}'),
+];
+
+pub const DOGRA: &'static [(char, char)] = &[
+  ('।', '९'), ('꠰', '꠹'), ('𑠀', '𑠻'),
+];
+
+pub const DUPLOYAN: &'static [(char, char)] = &[
+  ('𛰀', '𛱪'), ('𛱰', '𛱼'), ('𛲀', '𛲈'), ('𛲐', '𛲙'),
+  ('𛲜', '\u{1bca3}'),
+];
+
+pub const EGYPTIAN_HIEROGLYPHS: &'static [(char, char)] = &[
+  ('𓀀', '𓐮'), ('\u{13430}', '\u{13438}'),
+];
+
+pub const ELBASAN: &'static [(char, char)] = &[
+  ('𐔀', '𐔧'),
+];
+
+pub const ELYMAIC: &'static [(char, char)] = &[
+  ('\u{10fe0}', '\u{10ff6}'),
+];
+
+pub const ETHIOPIC: &'static [(char, char)] = &[
+  ('ሀ', 'ቈ'), ('ቊ', 'ቍ'), ('ቐ', 'ቖ'), ('ቘ', 'ቘ'),
+  ('ቚ', 'ቝ'), ('በ', 'ኈ'), ('ኊ', 'ኍ'), ('ነ', 'ኰ'),
+  ('ኲ', 'ኵ'), ('ኸ', 'ኾ'), ('ዀ', 'ዀ'), ('ዂ', 'ዅ'),
+  ('ወ', 'ዖ'), ('ዘ', 'ጐ'), ('ጒ', 'ጕ'), ('ጘ', 'ፚ'),
+  ('\u{135d}', '፼'), ('ᎀ', '᎙'), ('ⶀ', 'ⶖ'), ('ⶠ', 'ⶦ'),
+  ('ⶨ', 'ⶮ'), ('ⶰ', 'ⶶ'), ('ⶸ', 'ⶾ'), ('ⷀ', 'ⷆ'),
+  ('ⷈ', 'ⷎ'), ('ⷐ', 'ⷖ'), ('ⷘ', 'ⷞ'), ('ꬁ', 'ꬆ'),
+  ('ꬉ', 'ꬎ'), ('ꬑ', 'ꬖ'), ('ꬠ', 'ꬦ'), ('ꬨ', 'ꬮ'),
+];
+
+pub const GEORGIAN: &'static [(char, char)] = &[
+  ('։', '։'), ('Ⴀ', 'Ⴥ'), ('Ⴧ', 'Ⴧ'), ('Ⴭ', 'Ⴭ'),
+  ('ა', 'ჿ'), ('Ა', 'Ჺ'), ('Ჽ', 'Ჿ'), ('ⴀ', 'ⴥ'),
+  ('ⴧ', 'ⴧ'), ('ⴭ', 'ⴭ'),
+];
+
+pub const GLAGOLITIC: &'static [(char, char)] = &[
+  ('\u{484}', '\u{484}'), ('\u{487}', '\u{487}'), ('Ⰰ', 'Ⱞ'),
+  ('ⰰ', 'ⱞ'), ('⹃', '⹃'), ('\u{a66f}', '\u{a66f}'),
+  ('\u{1e000}', '\u{1e006}'), ('\u{1e008}', '\u{1e018}'),
+  ('\u{1e01b}', '\u{1e021}'), ('\u{1e023}', '\u{1e024}'),
+  ('\u{1e026}', '\u{1e02a}'),
+];
+
+pub const GOTHIC: &'static [(char, char)] = &[
+  ('𐌰', '𐍊'),
+];
+
+pub const GRANTHA: &'static [(char, char)] = &[
+  ('\u{951}', '\u{952}'), ('।', '॥'), ('௦', '௳'),
+  ('\u{1cd0}', '\u{1cd0}'), ('\u{1cd2}', '᳓'), ('ᳲ', '\u{1cf4}'),
+  ('\u{1cf8}', '\u{1cf9}'), ('\u{20f0}', '\u{20f0}'), ('\u{11300}', '𑌃'),
+  ('𑌅', '𑌌'), ('𑌏', '𑌐'), ('𑌓', '𑌨'), ('𑌪', '𑌰'),
+  ('𑌲', '𑌳'), ('𑌵', '𑌹'), ('\u{1133b}', '𑍄'), ('𑍇', '𑍈'),
+  ('𑍋', '𑍍'), ('𑍐', '𑍐'), ('\u{11357}', '\u{11357}'),
+  ('𑍝', '𑍣'), ('\u{11366}', '\u{1136c}'), ('\u{11370}', '\u{11374}'),
+  ('\u{11fd0}', '\u{11fd1}'), ('\u{11fd3}', '\u{11fd3}'),
+];
+
+pub const GREEK: &'static [(char, char)] = &[
+  ('\u{342}', '\u{342}'), ('\u{345}', '\u{345}'), ('Ͱ', 'ͳ'), ('͵', 'ͷ'),
+  ('ͺ', 'ͽ'), ('Ϳ', 'Ϳ'), ('΄', '΄'), ('Ά', 'Ά'), ('Έ', 'Ί'),
+  ('Ό', 'Ό'), ('Ύ', 'Ρ'), ('Σ', 'ϡ'), ('ϰ', 'Ͽ'), ('ᴦ', 'ᴪ'),
+  ('ᵝ', 'ᵡ'), ('ᵦ', 'ᵪ'), ('ᶿ', '\u{1dc1}'), ('ἀ', 'ἕ'),
+  ('Ἐ', 'Ἕ'), ('ἠ', 'ὅ'), ('Ὀ', 'Ὅ'), ('ὐ', 'ὗ'),
+  ('Ὑ', 'Ὑ'), ('Ὓ', 'Ὓ'), ('Ὕ', 'Ὕ'), ('Ὗ', 'ώ'),
+  ('ᾀ', 'ᾴ'), ('ᾶ', 'ῄ'), ('ῆ', 'ΐ'), ('ῖ', 'Ί'),
+  ('῝', '`'), ('ῲ', 'ῴ'), ('ῶ', '῾'), ('Ω', 'Ω'),
+  ('ꭥ', 'ꭥ'), ('𐅀', '𐆎'), ('𐆠', '𐆠'), ('𝈀', '𝉅'),
+];
+
+pub const GUJARATI: &'static [(char, char)] = &[
+  ('\u{951}', '\u{952}'), ('।', '॥'), ('\u{a81}', 'ઃ'), ('અ', 'ઍ'),
+  ('એ', 'ઑ'), ('ઓ', 'ન'), ('પ', 'ર'), ('લ', 'ળ'),
+  ('વ', 'હ'), ('\u{abc}', '\u{ac5}'), ('\u{ac7}', 'ૉ'),
+  ('ો', '\u{acd}'), ('ૐ', 'ૐ'), ('ૠ', '\u{ae3}'), ('૦', '૱'),
+  ('ૹ', '\u{aff}'), ('꠰', '꠹'),
+];
+
+pub const GUNJALA_GONDI: &'static [(char, char)] = &[
+  ('।', '॥'), ('𑵠', '𑵥'), ('𑵧', '𑵨'), ('𑵪', '𑶎'),
+  ('\u{11d90}', '\u{11d91}'), ('𑶓', '𑶘'), ('𑶠', '𑶩'),
+];
+
+pub const GURMUKHI: &'static [(char, char)] = &[
+  ('\u{951}', '\u{952}'), ('।', '॥'), ('\u{a01}', 'ਃ'), ('ਅ', 'ਊ'),
+  ('ਏ', 'ਐ'), ('ਓ', 'ਨ'), ('ਪ', 'ਰ'), ('ਲ', 'ਲ਼'),
+  ('ਵ', 'ਸ਼'), ('ਸ', 'ਹ'), ('\u{a3c}', '\u{a3c}'), ('ਾ', '\u{a42}'),
+  ('\u{a47}', '\u{a48}'), ('\u{a4b}', '\u{a4d}'), ('\u{a51}', '\u{a51}'),
+  ('ਖ਼', 'ੜ'), ('ਫ਼', 'ਫ਼'), ('੦', '੶'), ('꠰', '꠹'),
+];
+
+pub const HAN: &'static [(char, char)] = &[
+  ('⺀', '⺙'), ('⺛', '⻳'), ('⼀', '⿕'), ('、', '〃'),
+  ('々', '】'), ('〓', '〟'), ('〡', '\u{302d}'), ('〰', '〰'),
+  ('〷', '〿'), ('・', '・'), ('㆐', '㆟'), ('㇀', '㇣'),
+  ('㈠', '㉇'), ('㊀', '㊰'), ('㋀', '㋋'), ('\u{32ff}', '\u{32ff}'),
+  ('㍘', '㍰'), ('㍻', '㍿'), ('㏠', '㏾'), ('㐀', '䶵'),
+  ('一', '鿯'), ('豈', '舘'), ('並', '龎'), ('﹅', '﹆'),
+  ('。', '・'), ('𝍠', '𝍱'), ('🉐', '🉑'), ('𠀀', '𪛖'),
+  ('𪜀', '𫜴'), ('𫝀', '𫠝'), ('𫠠', '𬺡'), ('𬺰', '𮯠'),
+  ('丽', '𪘀'),
+];
+
+pub const HANGUL: &'static [(char, char)] = &[
+  ('ᄀ', 'ᇿ'), ('、', '〃'), ('〈', '】'), ('〓', '〟'),
+  ('\u{302e}', '〰'), ('〷', '〷'), ('・', '・'), ('ㄱ', 'ㆎ'),
+  ('㈀', '㈞'), ('㉠', '㉾'), ('ꥠ', 'ꥼ'), ('가', '힣'),
+  ('ힰ', 'ퟆ'), ('ퟋ', 'ퟻ'), ('﹅', '﹆'), ('。', '・'),
+  ('ᅠ', 'ᄒ'), ('ᅡ', 'ᅦ'), ('ᅧ', 'ᅬ'), ('ᅭ', 'ᅲ'),
+  ('ᅳ', 'ᅵ'),
+];
+
+pub const HANIFI_ROHINGYA: &'static [(char, char)] = &[
+  ('،', '،'), ('؛', '؛'), ('؟', '؟'), ('ـ', 'ـ'), ('۔', '۔'),
+  ('𐴀', '\u{10d27}'), ('𐴰', '𐴹'),
+];
+
+pub const HANUNOO: &'static [(char, char)] = &[
+  ('ᜠ', '᜶'),
+];
+
+pub const HATRAN: &'static [(char, char)] = &[
+  ('𐣠', '𐣲'), ('𐣴', '𐣵'), ('𐣻', '𐣿'),
+];
+
+pub const HEBREW: &'static [(char, char)] = &[
+  ('\u{591}', '\u{5c7}'), ('א', 'ת'), ('ׯ', '״'), ('יִ', 'זּ'),
+  ('טּ', 'לּ'), ('מּ', 'מּ'), ('נּ', 'סּ'), ('ףּ', 'פּ'),
+  ('צּ', 'ﭏ'),
+];
+
+pub const HIRAGANA: &'static [(char, char)] = &[
+  ('、', '〃'), ('〈', '】'), ('〓', '〟'), ('〰', '〵'),
+  ('〷', '〷'), ('〼', '〽'), ('ぁ', 'ゖ'), ('\u{3099}', '゠'),
+  ('・', 'ー'), ('﹅', '﹆'), ('。', '・'), ('ー', 'ー'),
+  ('\u{ff9e}', '\u{ff9f}'), ('𛀁', '𛄞'), ('\u{1b150}', '\u{1b152}'),
+  ('🈀', '🈀'),
+];
+
+pub const IMPERIAL_ARAMAIC: &'static [(char, char)] = &[
+  ('𐡀', '𐡕'), ('𐡗', '𐡟'),
+];
+
+pub const INHERITED: &'static [(char, char)] = &[
+  ('\u{300}', '\u{341}'), ('\u{343}', '\u{344}'), ('\u{346}', '\u{362}'),
+  ('\u{953}', '\u{954}'), ('\u{1ab0}', '\u{1abe}'), ('\u{1dc2}', '\u{1df9}'),
+  ('\u{1dfb}', '\u{1dff}'), ('\u{200c}', '\u{200d}'),
+  ('\u{20d0}', '\u{20ef}'), ('\u{fe00}', '\u{fe0f}'),
+  ('\u{fe20}', '\u{fe2d}'), ('\u{101fd}', '\u{101fd}'),
+  ('\u{1d167}', '\u{1d169}'), ('\u{1d17b}', '\u{1d182}'),
+  ('\u{1d185}', '\u{1d18b}'), ('\u{1d1aa}', '\u{1d1ad}'),
+  ('\u{e0100}', '\u{e01ef}'),
+];
+
+pub const INSCRIPTIONAL_PAHLAVI: &'static [(char, char)] = &[
+  ('𐭠', '𐭲'), ('𐭸', '𐭿'),
+];
+
+pub const INSCRIPTIONAL_PARTHIAN: &'static [(char, char)] = &[
+  ('𐭀', '𐭕'), ('𐭘', '𐭟'),
+];
+
+pub const JAVANESE: &'static [(char, char)] = &[
+  ('\u{a980}', '꧍'), ('ꧏ', '꧙'), ('꧞', '꧟'),
+];
+
+pub const KAITHI: &'static [(char, char)] = &[
+  ('०', '९'), ('꠰', '꠹'), ('\u{11080}', '𑃁'),
+  ('\u{110cd}', '\u{110cd}'),
+];
+
+pub const KANNADA: &'static [(char, char)] = &[
+  ('\u{951}', '\u{952}'), ('।', '॥'), ('ಀ', 'ಌ'), ('ಎ', 'ಐ'),
+  ('ಒ', 'ನ'), ('ಪ', 'ಳ'), ('ವ', 'ಹ'), ('\u{cbc}', 'ೄ'),
+  ('\u{cc6}', 'ೈ'), ('ೊ', '\u{ccd}'), ('\u{cd5}', '\u{cd6}'),
+  ('ೞ', 'ೞ'), ('ೠ', '\u{ce3}'), ('೦', '೯'), ('ೱ', 'ೲ'),
+  ('\u{1cd0}', '\u{1cd0}'), ('\u{1cd2}', '\u{1cd2}'),
+  ('\u{1cda}', '\u{1cda}'), ('ᳲ', 'ᳲ'), ('\u{1cf4}', '\u{1cf4}'),
+  ('꠰', '꠵'),
+];
+
+pub const KATAKANA: &'static [(char, char)] = &[
+  ('、', '〃'), ('〈', '】'), ('〓', '〟'), ('〰', '〵'),
+  ('〷', '〷'), ('〼', '〽'), ('\u{3099}', '゜'), ('゠', 'ヿ'),
+  ('ㇰ', 'ㇿ'), ('㋐', '㋾'), ('㌀', '㍗'), ('﹅', '﹆'),
+  ('。', '\u{ff9f}'), ('𛀀', '𛀀'), ('\u{1b164}', '\u{1b167}'),
+];
+
+pub const KAYAH_LI: &'static [(char, char)] = &[
+  ('꤀', '꤯'),
+];
+
+pub const KHAROSHTHI: &'static [(char, char)] = &[
+  ('𐨀', '\u{10a03}'), ('\u{10a05}', '\u{10a06}'), ('\u{10a0c}', '𐨓'),
+  ('𐨕', '𐨗'), ('𐨙', '𐨵'), ('\u{10a38}', '\u{10a3a}'),
+  ('\u{10a3f}', '𐩈'), ('𐩐', '𐩘'),
+];
+
+pub const KHMER: &'static [(char, char)] = &[
+  ('ក', '\u{17dd}'), ('០', '៩'), ('៰', '៹'), ('᧠', '᧿'),
+];
+
+pub const KHOJKI: &'static [(char, char)] = &[
+  ('૦', '૯'), ('꠰', '꠹'), ('𑈀', '𑈑'), ('𑈓', '\u{1123e}'),
+];
+
+pub const KHUDAWADI: &'static [(char, char)] = &[
+  ('।', '॥'), ('꠰', '꠹'), ('𑊰', '\u{112ea}'), ('𑋰', '𑋹'),
+];
+
+pub const LAO: &'static [(char, char)] = &[
+  ('ກ', 'ຂ'), ('ຄ', 'ຄ'), ('\u{e86}', 'ຊ'), ('\u{e8c}', 'ຣ'),
+  ('ລ', 'ລ'), ('ວ', 'ຽ'), ('ເ', 'ໄ'), ('ໆ', 'ໆ'),
+  ('\u{ec8}', '\u{ecd}'), ('໐', '໙'), ('ໜ', 'ໟ'),
+];
+
+pub const LATIN: &'static [(char, char)] = &[
+  ('A', 'Z'), ('a', 'z'), ('ª', 'ª'), ('º', 'º'), ('À', 'Ö'),
+  ('Ø', 'ö'), ('ø', 'ʸ'), ('ˠ', 'ˤ'), ('\u{363}', '\u{36f}'),
+  ('\u{485}', '\u{486}'), ('\u{951}', '\u{952}'), ('჻', '჻'),
+  ('ᴀ', 'ᴥ'), ('ᴬ', 'ᵜ'), ('ᵢ', 'ᵥ'), ('ᵫ', 'ᵷ'),
+  ('ᵹ', 'ᶾ'), ('Ḁ', 'ỿ'), ('\u{202f}', '\u{202f}'), ('ⁱ', 'ⁱ'),
+  ('ⁿ', 'ⁿ'), ('ₐ', 'ₜ'), ('\u{20f0}', '\u{20f0}'), ('K', 'Å'),
+  ('Ⅎ', 'Ⅎ'), ('ⅎ', 'ⅎ'), ('Ⅰ', 'ↈ'), ('Ⱡ', 'Ɀ'),
+  ('Ꜣ', 'ꞇ'), ('Ꞌ', '\u{a7bf}'), ('\u{a7c2}', '\u{a7c6}'),
+  ('ꟷ', 'ꟿ'), ('꤮', '꤮'), ('ꬰ', 'ꭚ'), ('ꭜ', 'ꭤ'),
+  ('\u{ab66}', '\u{ab67}'), ('ff', 'st'), ('A', 'Z'), ('a', 'z'),
+];
+
+pub const LEPCHA: &'static [(char, char)] = &[
+  ('ᰀ', '\u{1c37}'), ('᰻', '᱉'), ('ᱍ', 'ᱏ'),
+];
+
+pub const LIMBU: &'static [(char, char)] = &[
+  ('॥', '॥'), ('ᤀ', 'ᤞ'), ('\u{1920}', 'ᤫ'), ('ᤰ', '\u{193b}'),
+  ('᥀', '᥀'), ('᥄', '᥏'),
+];
+
+pub const LINEAR_A: &'static [(char, char)] = &[
+  ('𐄇', '𐄳'), ('𐘀', '𐜶'), ('𐝀', '𐝕'), ('𐝠', '𐝧'),
+];
+
+pub const LINEAR_B: &'static [(char, char)] = &[
+  ('𐀀', '𐀋'), ('𐀍', '𐀦'), ('𐀨', '𐀺'), ('𐀼', '𐀽'),
+  ('𐀿', '𐁍'), ('𐁐', '𐁝'), ('𐂀', '𐃺'), ('𐄀', '𐄂'),
+  ('𐄇', '𐄳'), ('𐄷', '𐄿'),
+];
+
+pub const LISU: &'static [(char, char)] = &[
+  ('ꓐ', '꓿'),
+];
+
+pub const LYCIAN: &'static [(char, char)] = &[
+  ('𐊀', '𐊜'),
+];
+
+pub const LYDIAN: &'static [(char, char)] = &[
+  ('𐤠', '𐤹'), ('𐤿', '𐤿'),
+];
+
+pub const MAHAJANI: &'static [(char, char)] = &[
+  ('।', '९'), ('꠰', '꠹'), ('𑅐', '𑅶'),
+];
+
+pub const MAKASAR: &'static [(char, char)] = &[
+  ('𑻠', '𑻸'),
+];
+
+pub const MALAYALAM: &'static [(char, char)] = &[
+  ('\u{951}', '\u{952}'), ('।', '॥'), ('\u{d00}', 'ഃ'), ('അ', 'ഌ'),
+  ('എ', 'ഐ'), ('ഒ', '\u{d44}'), ('െ', 'ൈ'), ('ൊ', '൏'),
+  ('ൔ', '\u{d63}'), ('൦', 'ൿ'), ('\u{1cda}', '\u{1cda}'),
+  ('꠰', '꠲'),
+];
+
+pub const MANDAIC: &'static [(char, char)] = &[
+  ('ـ', 'ـ'), ('ࡀ', '\u{85b}'), ('࡞', '࡞'),
+];
+
+pub const MANICHAEAN: &'static [(char, char)] = &[
+  ('ـ', 'ـ'), ('𐫀', '\u{10ae6}'), ('𐫫', '𐫶'),
+];
+
+pub const MARCHEN: &'static [(char, char)] = &[
+  ('𑱰', '𑲏'), ('\u{11c92}', '\u{11ca7}'), ('𑲩', '\u{11cb6}'),
+];
+
+pub const MASARAM_GONDI: &'static [(char, char)] = &[
+  ('।', '॥'), ('𑴀', '𑴆'), ('𑴈', '𑴉'), ('𑴋', '\u{11d36}'),
+  ('\u{11d3a}', '\u{11d3a}'), ('\u{11d3c}', '\u{11d3d}'),
+  ('\u{11d3f}', '\u{11d47}'), ('𑵐', '𑵙'),
+];
+
+pub const MEDEFAIDRIN: &'static [(char, char)] = &[
+  ('𖹀', '𖺚'),
+];
+
+pub const MEETEI_MAYEK: &'static [(char, char)] = &[
+  ('ꫠ', '\u{aaf6}'), ('ꯀ', '\u{abed}'), ('꯰', '꯹'),
+];
+
+pub const MENDE_KIKAKUI: &'static [(char, char)] = &[
+  ('𞠀', '𞣄'), ('𞣇', '\u{1e8d6}'),
+];
+
+pub const MEROITIC_CURSIVE: &'static [(char, char)] = &[
+  ('𐦠', '𐦷'), ('𐦼', '𐧏'), ('𐧒', '𐧿'),
+];
+
+pub const MEROITIC_HIEROGLYPHS: &'static [(char, char)] = &[
+  ('𐦀', '𐦟'),
+];
+
+pub const MIAO: &'static [(char, char)] = &[
+  ('𖼀', '\u{16f4a}'), ('\u{16f4f}', '\u{16f87}'), ('\u{16f8f}', '𖾟'),
+];
+
+pub const MODI: &'static [(char, char)] = &[
+  ('꠰', '꠹'), ('𑘀', '𑙄'), ('𑙐', '𑙙'),
+];
+
+pub const MONGOLIAN: &'static [(char, char)] = &[
+  ('᠀', '\u{180e}'), ('᠐', '᠙'), ('ᠠ', 'ᡸ'), ('ᢀ', 'ᢪ'),
+  ('\u{202f}', '\u{202f}'), ('𑙠', '𑙬'),
+];
+
+pub const MRO: &'static [(char, char)] = &[
+  ('𖩀', '𖩞'), ('𖩠', '𖩩'), ('𖩮', '𖩯'),
+];
+
+pub const MULTANI: &'static [(char, char)] = &[
+  ('੦', '੯'), ('𑊀', '𑊆'), ('𑊈', '𑊈'), ('𑊊', '𑊍'),
+  ('𑊏', '𑊝'), ('𑊟', '𑊩'),
+];
+
+pub const MYANMAR: &'static [(char, char)] = &[
+  ('က', '႟'), ('꤮', '꤮'), ('ꧠ', 'ꧾ'), ('ꩠ', 'ꩿ'),
+];
+
+pub const NABATAEAN: &'static [(char, char)] = &[
+  ('𐢀', '𐢞'), ('𐢧', '𐢯'),
+];
+
+pub const NANDINAGARI: &'static [(char, char)] = &[
+  ('।', '॥'), ('೦', '೯'), ('ᳩ', 'ᳩ'), ('ᳲ', 'ᳲ'),
+  ('\u{1cfa}', '\u{1cfa}'), ('꠰', '꠵'), ('\u{119a0}', '\u{119a7}'),
+  ('\u{119aa}', '\u{119d7}'), ('\u{119da}', '\u{119e4}'),
+];
+
+pub const NEW_TAI_LUE: &'static [(char, char)] = &[
+  ('ᦀ', 'ᦫ'), ('ᦰ', 'ᧉ'), ('᧐', '᧚'), ('᧞', '᧟'),
+];
+
+pub const NEWA: &'static [(char, char)] = &[
+  ('𑐀', '𑑙'), ('𑑛', '𑑛'), ('𑑝', '\u{1145f}'),
+];
+
+pub const NKO: &'static [(char, char)] = &[
+  ('߀', 'ߺ'), ('\u{7fd}', '߿'),
+];
+
+pub const NUSHU: &'static [(char, char)] = &[
+  ('𖿡', '𖿡'), ('𛅰', '𛋻'),
+];
+
+pub const NYIAKENG_PUACHUE_HMONG: &'static [(char, char)] = &[
+  ('\u{1e100}', '\u{1e12c}'), ('\u{1e130}', '\u{1e13d}'),
+  ('\u{1e140}', '\u{1e149}'), ('\u{1e14e}', '\u{1e14f}'),
+];
+
+pub const OGHAM: &'static [(char, char)] = &[
+  ('\u{1680}', '᚜'),
+];
+
+pub const OL_CHIKI: &'static [(char, char)] = &[
+  ('᱐', '᱿'),
+];
+
+pub const OLD_HUNGARIAN: &'static [(char, char)] = &[
+  ('𐲀', '𐲲'), ('𐳀', '𐳲'), ('𐳺', '𐳿'),
+];
+
+pub const OLD_ITALIC: &'static [(char, char)] = &[
+  ('𐌀', '𐌣'), ('𐌭', '𐌯'),
+];
+
+pub const OLD_NORTH_ARABIAN: &'static [(char, char)] = &[
+  ('𐪀', '𐪟'),
+];
+
+pub const OLD_PERMIC: &'static [(char, char)] = &[
+  ('\u{483}', '\u{483}'), ('𐍐', '\u{1037a}'),
+];
+
+pub const OLD_PERSIAN: &'static [(char, char)] = &[
+  ('𐎠', '𐏃'), ('𐏈', '𐏕'),
+];
+
+pub const OLD_SOGDIAN: &'static [(char, char)] = &[
+  ('𐼀', '𐼧'),
+];
+
+pub const OLD_SOUTH_ARABIAN: &'static [(char, char)] = &[
+  ('𐩠', '𐩿'),
+];
+
+pub const OLD_TURKIC: &'static [(char, char)] = &[
+  ('𐰀', '𐱈'),
+];
+
+pub const ORIYA: &'static [(char, char)] = &[
+  ('\u{951}', '\u{952}'), ('।', '॥'), ('\u{b01}', 'ଃ'), ('ଅ', 'ଌ'),
+  ('ଏ', 'ଐ'), ('ଓ', 'ନ'), ('ପ', 'ର'), ('ଲ', 'ଳ'),
+  ('ଵ', 'ହ'), ('\u{b3c}', '\u{b44}'), ('େ', 'ୈ'), ('ୋ', '\u{b4d}'),
+  ('\u{b56}', '\u{b57}'), ('ଡ଼', 'ଢ଼'), ('ୟ', '\u{b63}'), ('୦', '୷'),
+  ('\u{1cda}', '\u{1cda}'), ('ᳲ', 'ᳲ'),
+];
+
+pub const OSAGE: &'static [(char, char)] = &[
+  ('𐒰', '𐓓'), ('𐓘', '𐓻'),
+];
+
+pub const OSMANYA: &'static [(char, char)] = &[
+  ('𐒀', '𐒝'), ('𐒠', '𐒩'),
+];
+
+pub const PAHAWH_HMONG: &'static [(char, char)] = &[
+  ('𖬀', '𖭅'), ('𖭐', '𖭙'), ('𖭛', '𖭡'), ('𖭣', '𖭷'),
+  ('𖭽', '𖮏'),
+];
+
+pub const PALMYRENE: &'static [(char, char)] = &[
+  ('𐡠', '𐡿'),
+];
+
+pub const PAU_CIN_HAU: &'static [(char, char)] = &[
+  ('𑫀', '𑫸'),
+];
+
+pub const PHAGS_PA: &'static [(char, char)] = &[
+  ('᠂', '᠃'), ('᠅', '᠅'), ('ꡀ', '꡷'),
+];
+
+pub const PHOENICIAN: &'static [(char, char)] = &[
+  ('𐤀', '𐤛'), ('𐤟', '𐤟'),
+];
+
+pub const PSALTER_PAHLAVI: &'static [(char, char)] = &[
+  ('ـ', 'ـ'), ('𐮀', '𐮑'), ('𐮙', '𐮜'), ('𐮩', '𐮯'),
+];
+
+pub const REJANG: &'static [(char, char)] = &[
+  ('ꤰ', '꥓'), ('꥟', '꥟'),
+];
+
+pub const RUNIC: &'static [(char, char)] = &[
+  ('ᚠ', 'ᛪ'), ('ᛮ', 'ᛸ'),
+];
+
+pub const SAMARITAN: &'static [(char, char)] = &[
+  ('ࠀ', '\u{82d}'), ('࠰', '࠾'),
+];
+
+pub const SAURASHTRA: &'static [(char, char)] = &[
+  ('ꢀ', '\u{a8c5}'), ('꣎', '꣙'),
+];
+
+pub const SHARADA: &'static [(char, char)] = &[
+  ('\u{951}', '\u{951}'), ('\u{1cd7}', '\u{1cd7}'), ('\u{1cd9}', '\u{1cd9}'),
+  ('\u{1cdc}', '\u{1cdd}'), ('\u{1ce0}', '\u{1ce0}'), ('\u{11180}', '𑇍'),
+  ('𑇐', '𑇟'),
+];
+
+pub const SHAVIAN: &'static [(char, char)] = &[
+  ('𐑐', '𐑿'),
+];
+
+pub const SIDDHAM: &'static [(char, char)] = &[
+  ('𑖀', '\u{115b5}'), ('𑖸', '\u{115dd}'),
+];
+
+pub const SIGNWRITING: &'static [(char, char)] = &[
+  ('𝠀', '𝪋'), ('\u{1da9b}', '\u{1da9f}'), ('\u{1daa1}', '\u{1daaf}'),
+];
+
+pub const SINHALA: &'static [(char, char)] = &[
+  ('।', '॥'), ('ං', 'ඃ'), ('අ', 'ඖ'), ('ක', 'න'),
+  ('ඳ', 'ර'), ('ල', 'ල'), ('ව', 'ෆ'), ('\u{dca}', '\u{dca}'),
+  ('\u{dcf}', '\u{dd4}'), ('\u{dd6}', '\u{dd6}'), ('ෘ', '\u{ddf}'),
+  ('෦', '෯'), ('ෲ', '෴'), ('𑇡', '𑇴'),
+];
+
+pub const SOGDIAN: &'static [(char, char)] = &[
+  ('ـ', 'ـ'), ('𐼰', '𐽙'),
+];
+
+pub const SORA_SOMPENG: &'static [(char, char)] = &[
+  ('𑃐', '𑃨'), ('𑃰', '𑃹'),
+];
+
+pub const SOYOMBO: &'static [(char, char)] = &[
+  ('𑩐', '𑪢'),
+];
+
+pub const SUNDANESE: &'static [(char, char)] = &[
+  ('\u{1b80}', 'ᮿ'), ('᳀', '᳇'),
+];
+
+pub const SYLOTI_NAGRI: &'static [(char, char)] = &[
+  ('।', '॥'), ('০', '৯'), ('ꠀ', '꠫'),
+];
+
+pub const SYRIAC: &'static [(char, char)] = &[
+  ('،', '،'), ('؛', '\u{61c}'), ('؟', '؟'), ('ـ', 'ـ'),
+  ('\u{64b}', '\u{655}'), ('\u{670}', '\u{670}'), ('܀', '܍'),
+  ('\u{70f}', '\u{74a}'), ('ݍ', 'ݏ'), ('ࡠ', 'ࡪ'),
+];
+
+pub const TAGALOG: &'static [(char, char)] = &[
+  ('ᜀ', 'ᜌ'), ('ᜎ', '\u{1714}'), ('᜵', '᜶'),
+];
+
+pub const TAGBANWA: &'static [(char, char)] = &[
+  ('᜵', '᜶'), ('ᝠ', 'ᝬ'), ('ᝮ', 'ᝰ'), ('\u{1772}', '\u{1773}'),
+];
+
+pub const TAI_LE: &'static [(char, char)] = &[
+  ('၀', '၉'), ('ᥐ', 'ᥭ'), ('ᥰ', 'ᥴ'),
+];
+
+pub const TAI_THAM: &'static [(char, char)] = &[
+  ('ᨠ', '\u{1a5e}'), ('\u{1a60}', '\u{1a7c}'), ('\u{1a7f}', '᪉'),
+  ('᪐', '᪙'), ('᪠', '᪭'),
+];
+
+pub const TAI_VIET: &'static [(char, char)] = &[
+  ('ꪀ', 'ꫂ'), ('ꫛ', '꫟'),
+];
+
+pub const TAKRI: &'static [(char, char)] = &[
+  ('।', '॥'), ('꠰', '꠹'), ('𑚀', '\u{116b8}'), ('𑛀', '𑛉'),
+];
+
+pub const TAMIL: &'static [(char, char)] = &[
+  ('\u{951}', '\u{952}'), ('।', '॥'), ('\u{b82}', 'ஃ'), ('அ', 'ஊ'),
+  ('எ', 'ஐ'), ('ஒ', 'க'), ('ங', 'ச'), ('ஜ', 'ஜ'),
+  ('ஞ', 'ட'), ('ண', 'த'), ('ந', 'ப'), ('ம', 'ஹ'),
+  ('\u{bbe}', 'ூ'), ('ெ', 'ை'), ('ொ', '\u{bcd}'), ('ௐ', 'ௐ'),
+  ('\u{bd7}', '\u{bd7}'), ('௦', '௺'), ('\u{1cda}', '\u{1cda}'),
+  ('ꣳ', 'ꣳ'), ('\u{11301}', '\u{11301}'), ('𑌃', '𑌃'),
+  ('\u{1133b}', '\u{1133c}'), ('\u{11fc0}', '\u{11ff1}'),
+  ('\u{11fff}', '\u{11fff}'),
+];
+
+pub const TANGUT: &'static [(char, char)] = &[
+  ('𖿠', '𖿠'), ('𗀀', '\u{187f7}'), ('𘠀', '𘫲'),
+];
+
+pub const TELUGU: &'static [(char, char)] = &[
+  ('\u{951}', '\u{952}'), ('।', '॥'), ('\u{c00}', 'ఌ'), ('ఎ', 'ఐ'),
+  ('ఒ', 'న'), ('ప', 'హ'), ('ఽ', 'ౄ'), ('\u{c46}', '\u{c48}'),
+  ('\u{c4a}', '\u{c4d}'), ('\u{c55}', '\u{c56}'), ('ౘ', 'ౚ'),
+  ('ౠ', '\u{c63}'), ('౦', '౯'), ('\u{c77}', '౿'),
+  ('\u{1cda}', '\u{1cda}'), ('ᳲ', 'ᳲ'),
+];
+
+pub const THAANA: &'static [(char, char)] = &[
+  ('،', '،'), ('؛', '\u{61c}'), ('؟', '؟'), ('٠', '٩'), ('ހ', 'ޱ'),
+  ('ﷲ', 'ﷲ'), ('﷽', '﷽'),
+];
+
+pub const THAI: &'static [(char, char)] = &[
+  ('ก', '\u{e3a}'), ('เ', '๛'),
+];
+
+pub const TIBETAN: &'static [(char, char)] = &[
+  ('ༀ', 'ཇ'), ('ཉ', 'ཬ'), ('\u{f71}', '\u{f97}'),
+  ('\u{f99}', '\u{fbc}'), ('྾', '࿌'), ('࿎', '࿔'), ('࿙', '࿚'),
+];
+
+pub const TIFINAGH: &'static [(char, char)] = &[
+  ('ⴰ', 'ⵧ'), ('ⵯ', '⵰'), ('\u{2d7f}', '\u{2d7f}'),
+];
+
+pub const TIRHUTA: &'static [(char, char)] = &[
+  ('\u{951}', '\u{952}'), ('।', '॥'), ('ᳲ', 'ᳲ'), ('꠰', '꠹'),
+  ('𑒀', '𑓇'), ('𑓐', '𑓙'),
+];
+
+pub const UGARITIC: &'static [(char, char)] = &[
+  ('𐎀', '𐎝'), ('𐎟', '𐎟'),
+];
+
+pub const VAI: &'static [(char, char)] = &[
+  ('ꔀ', 'ꘫ'),
+];
+
+pub const WANCHO: &'static [(char, char)] = &[
+  ('\u{1e2c0}', '\u{1e2f9}'), ('\u{1e2ff}', '\u{1e2ff}'),
+];
+
+pub const WARANG_CITI: &'static [(char, char)] = &[
+  ('𑢠', '𑣲'), ('𑣿', '𑣿'),
+];
+
+pub const YI: &'static [(char, char)] = &[
+  ('、', '。'), ('〈', '】'), ('〔', '〛'), ('・', '・'),
+  ('ꀀ', 'ꒌ'), ('꒐', '꓆'), ('。', '・'),
+];
+
+pub const ZANABAZAR_SQUARE: &'static [(char, char)] = &[
+  ('𑨀', '\u{11a47}'),
+];
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/unicode_tables/sentence_break.rs.html b/target/doc/src/regex_syntax/unicode_tables/sentence_break.rs.html new file mode 100644 index 0000000..7f2a6bf --- /dev/null +++ b/target/doc/src/regex_syntax/unicode_tables/sentence_break.rs.html @@ -0,0 +1,1315 @@ +sentence_break.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+
+// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
+//
+//  ucd-generate sentence-break /tmp/ucd-12.1.0/ --chars
+//
+// ucd-generate is available on crates.io.
+
+pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
+  ("ATerm", ATERM), ("CR", CR), ("Close", CLOSE), ("Extend", EXTEND),
+  ("Format", FORMAT), ("LF", LF), ("Lower", LOWER), ("Numeric", NUMERIC),
+  ("OLetter", OLETTER), ("SContinue", SCONTINUE), ("STerm", STERM),
+  ("Sep", SEP), ("Sp", SP), ("Upper", UPPER),
+];
+
+pub const ATERM: &'static [(char, char)] = &[
+  ('.', '.'), ('․', '․'), ('﹒', '﹒'), ('.', '.'),
+];
+
+pub const CR: &'static [(char, char)] = &[
+  ('\r', '\r'),
+];
+
+pub const CLOSE: &'static [(char, char)] = &[
+  ('\"', '\"'), ('\'', ')'), ('[', '['), (']', ']'), ('{', '{'), ('}', '}'),
+  ('«', '«'), ('»', '»'), ('༺', '༽'), ('᚛', '᚜'), ('‘', '‟'),
+  ('‹', '›'), ('⁅', '⁆'), ('⁽', '⁾'), ('₍', '₎'),
+  ('⌈', '⌋'), ('〈', '〉'), ('❛', '❠'), ('❨', '❵'),
+  ('⟅', '⟆'), ('⟦', '⟯'), ('⦃', '⦘'), ('⧘', '⧛'),
+  ('⧼', '⧽'), ('⸀', '⸍'), ('⸜', '⸝'), ('⸠', '⸩'),
+  ('⹂', '⹂'), ('〈', '】'), ('〔', '〛'), ('〝', '〟'),
+  ('﴾', '﴿'), ('︗', '︘'), ('︵', '﹄'), ('﹇', '﹈'),
+  ('﹙', '﹞'), ('(', ')'), ('[', '['), (']', ']'),
+  ('{', '{'), ('}', '}'), ('⦅', '⦆'), ('「', '」'),
+  ('🙶', '🙸'),
+];
+
+pub const EXTEND: &'static [(char, char)] = &[
+  ('\u{300}', '\u{36f}'), ('\u{483}', '\u{489}'), ('\u{591}', '\u{5bd}'),
+  ('\u{5bf}', '\u{5bf}'), ('\u{5c1}', '\u{5c2}'), ('\u{5c4}', '\u{5c5}'),
+  ('\u{5c7}', '\u{5c7}'), ('\u{610}', '\u{61a}'), ('\u{64b}', '\u{65f}'),
+  ('\u{670}', '\u{670}'), ('\u{6d6}', '\u{6dc}'), ('\u{6df}', '\u{6e4}'),
+  ('\u{6e7}', '\u{6e8}'), ('\u{6ea}', '\u{6ed}'), ('\u{711}', '\u{711}'),
+  ('\u{730}', '\u{74a}'), ('\u{7a6}', '\u{7b0}'), ('\u{7eb}', '\u{7f3}'),
+  ('\u{7fd}', '\u{7fd}'), ('\u{816}', '\u{819}'), ('\u{81b}', '\u{823}'),
+  ('\u{825}', '\u{827}'), ('\u{829}', '\u{82d}'), ('\u{859}', '\u{85b}'),
+  ('\u{8d3}', '\u{8e1}'), ('\u{8e3}', 'ः'), ('\u{93a}', '\u{93c}'),
+  ('ा', 'ॏ'), ('\u{951}', '\u{957}'), ('\u{962}', '\u{963}'),
+  ('\u{981}', 'ঃ'), ('\u{9bc}', '\u{9bc}'), ('\u{9be}', '\u{9c4}'),
+  ('ে', 'ৈ'), ('ো', '\u{9cd}'), ('\u{9d7}', '\u{9d7}'),
+  ('\u{9e2}', '\u{9e3}'), ('\u{9fe}', '\u{9fe}'), ('\u{a01}', 'ਃ'),
+  ('\u{a3c}', '\u{a3c}'), ('ਾ', '\u{a42}'), ('\u{a47}', '\u{a48}'),
+  ('\u{a4b}', '\u{a4d}'), ('\u{a51}', '\u{a51}'), ('\u{a70}', '\u{a71}'),
+  ('\u{a75}', '\u{a75}'), ('\u{a81}', 'ઃ'), ('\u{abc}', '\u{abc}'),
+  ('ા', '\u{ac5}'), ('\u{ac7}', 'ૉ'), ('ો', '\u{acd}'),
+  ('\u{ae2}', '\u{ae3}'), ('\u{afa}', '\u{aff}'), ('\u{b01}', 'ଃ'),
+  ('\u{b3c}', '\u{b3c}'), ('\u{b3e}', '\u{b44}'), ('େ', 'ୈ'),
+  ('ୋ', '\u{b4d}'), ('\u{b56}', '\u{b57}'), ('\u{b62}', '\u{b63}'),
+  ('\u{b82}', '\u{b82}'), ('\u{bbe}', 'ூ'), ('ெ', 'ை'),
+  ('ொ', '\u{bcd}'), ('\u{bd7}', '\u{bd7}'), ('\u{c00}', '\u{c04}'),
+  ('\u{c3e}', 'ౄ'), ('\u{c46}', '\u{c48}'), ('\u{c4a}', '\u{c4d}'),
+  ('\u{c55}', '\u{c56}'), ('\u{c62}', '\u{c63}'), ('\u{c81}', 'ಃ'),
+  ('\u{cbc}', '\u{cbc}'), ('ಾ', 'ೄ'), ('\u{cc6}', 'ೈ'),
+  ('ೊ', '\u{ccd}'), ('\u{cd5}', '\u{cd6}'), ('\u{ce2}', '\u{ce3}'),
+  ('\u{d00}', 'ഃ'), ('\u{d3b}', '\u{d3c}'), ('\u{d3e}', '\u{d44}'),
+  ('െ', 'ൈ'), ('ൊ', '\u{d4d}'), ('\u{d57}', '\u{d57}'),
+  ('\u{d62}', '\u{d63}'), ('ං', 'ඃ'), ('\u{dca}', '\u{dca}'),
+  ('\u{dcf}', '\u{dd4}'), ('\u{dd6}', '\u{dd6}'), ('ෘ', '\u{ddf}'),
+  ('ෲ', 'ෳ'), ('\u{e31}', '\u{e31}'), ('\u{e34}', '\u{e3a}'),
+  ('\u{e47}', '\u{e4e}'), ('\u{eb1}', '\u{eb1}'), ('\u{eb4}', '\u{ebc}'),
+  ('\u{ec8}', '\u{ecd}'), ('\u{f18}', '\u{f19}'), ('\u{f35}', '\u{f35}'),
+  ('\u{f37}', '\u{f37}'), ('\u{f39}', '\u{f39}'), ('༾', '༿'),
+  ('\u{f71}', '\u{f84}'), ('\u{f86}', '\u{f87}'), ('\u{f8d}', '\u{f97}'),
+  ('\u{f99}', '\u{fbc}'), ('\u{fc6}', '\u{fc6}'), ('ါ', '\u{103e}'),
+  ('ၖ', '\u{1059}'), ('\u{105e}', '\u{1060}'), ('ၢ', 'ၤ'),
+  ('ၧ', 'ၭ'), ('\u{1071}', '\u{1074}'), ('\u{1082}', '\u{108d}'),
+  ('ႏ', 'ႏ'), ('ႚ', '\u{109d}'), ('\u{135d}', '\u{135f}'),
+  ('\u{1712}', '\u{1714}'), ('\u{1732}', '\u{1734}'),
+  ('\u{1752}', '\u{1753}'), ('\u{1772}', '\u{1773}'),
+  ('\u{17b4}', '\u{17d3}'), ('\u{17dd}', '\u{17dd}'),
+  ('\u{180b}', '\u{180d}'), ('\u{1885}', '\u{1886}'),
+  ('\u{18a9}', '\u{18a9}'), ('\u{1920}', 'ᤫ'), ('ᤰ', '\u{193b}'),
+  ('\u{1a17}', '\u{1a1b}'), ('ᩕ', '\u{1a5e}'), ('\u{1a60}', '\u{1a7c}'),
+  ('\u{1a7f}', '\u{1a7f}'), ('\u{1ab0}', '\u{1abe}'), ('\u{1b00}', 'ᬄ'),
+  ('\u{1b34}', '᭄'), ('\u{1b6b}', '\u{1b73}'), ('\u{1b80}', 'ᮂ'),
+  ('ᮡ', '\u{1bad}'), ('\u{1be6}', '᯳'), ('ᰤ', '\u{1c37}'),
+  ('\u{1cd0}', '\u{1cd2}'), ('\u{1cd4}', '\u{1ce8}'),
+  ('\u{1ced}', '\u{1ced}'), ('\u{1cf4}', '\u{1cf4}'), ('᳷', '\u{1cf9}'),
+  ('\u{1dc0}', '\u{1df9}'), ('\u{1dfb}', '\u{1dff}'),
+  ('\u{200c}', '\u{200d}'), ('\u{20d0}', '\u{20f0}'),
+  ('\u{2cef}', '\u{2cf1}'), ('\u{2d7f}', '\u{2d7f}'),
+  ('\u{2de0}', '\u{2dff}'), ('\u{302a}', '\u{302f}'),
+  ('\u{3099}', '\u{309a}'), ('\u{a66f}', '\u{a672}'),
+  ('\u{a674}', '\u{a67d}'), ('\u{a69e}', '\u{a69f}'),
+  ('\u{a6f0}', '\u{a6f1}'), ('\u{a802}', '\u{a802}'),
+  ('\u{a806}', '\u{a806}'), ('\u{a80b}', '\u{a80b}'), ('ꠣ', 'ꠧ'),
+  ('ꢀ', 'ꢁ'), ('ꢴ', '\u{a8c5}'), ('\u{a8e0}', '\u{a8f1}'),
+  ('\u{a8ff}', '\u{a8ff}'), ('\u{a926}', '\u{a92d}'), ('\u{a947}', '꥓'),
+  ('\u{a980}', 'ꦃ'), ('\u{a9b3}', '꧀'), ('\u{a9e5}', '\u{a9e5}'),
+  ('\u{aa29}', '\u{aa36}'), ('\u{aa43}', '\u{aa43}'), ('\u{aa4c}', 'ꩍ'),
+  ('ꩻ', 'ꩽ'), ('\u{aab0}', '\u{aab0}'), ('\u{aab2}', '\u{aab4}'),
+  ('\u{aab7}', '\u{aab8}'), ('\u{aabe}', '\u{aabf}'),
+  ('\u{aac1}', '\u{aac1}'), ('ꫫ', 'ꫯ'), ('ꫵ', '\u{aaf6}'),
+  ('ꯣ', 'ꯪ'), ('꯬', '\u{abed}'), ('\u{fb1e}', '\u{fb1e}'),
+  ('\u{fe00}', '\u{fe0f}'), ('\u{fe20}', '\u{fe2f}'),
+  ('\u{ff9e}', '\u{ff9f}'), ('\u{101fd}', '\u{101fd}'),
+  ('\u{102e0}', '\u{102e0}'), ('\u{10376}', '\u{1037a}'),
+  ('\u{10a01}', '\u{10a03}'), ('\u{10a05}', '\u{10a06}'),
+  ('\u{10a0c}', '\u{10a0f}'), ('\u{10a38}', '\u{10a3a}'),
+  ('\u{10a3f}', '\u{10a3f}'), ('\u{10ae5}', '\u{10ae6}'),
+  ('\u{10d24}', '\u{10d27}'), ('\u{10f46}', '\u{10f50}'), ('𑀀', '𑀂'),
+  ('\u{11038}', '\u{11046}'), ('\u{1107f}', '𑂂'), ('𑂰', '\u{110ba}'),
+  ('\u{11100}', '\u{11102}'), ('\u{11127}', '\u{11134}'), ('𑅅', '𑅆'),
+  ('\u{11173}', '\u{11173}'), ('\u{11180}', '𑆂'), ('𑆳', '𑇀'),
+  ('\u{111c9}', '\u{111cc}'), ('𑈬', '\u{11237}'),
+  ('\u{1123e}', '\u{1123e}'), ('\u{112df}', '\u{112ea}'),
+  ('\u{11300}', '𑌃'), ('\u{1133b}', '\u{1133c}'), ('\u{1133e}', '𑍄'),
+  ('𑍇', '𑍈'), ('𑍋', '𑍍'), ('\u{11357}', '\u{11357}'),
+  ('𑍢', '𑍣'), ('\u{11366}', '\u{1136c}'), ('\u{11370}', '\u{11374}'),
+  ('𑐵', '\u{11446}'), ('\u{1145e}', '\u{1145e}'),
+  ('\u{114b0}', '\u{114c3}'), ('\u{115af}', '\u{115b5}'),
+  ('𑖸', '\u{115c0}'), ('\u{115dc}', '\u{115dd}'), ('𑘰', '\u{11640}'),
+  ('\u{116ab}', '\u{116b7}'), ('\u{1171d}', '\u{1172b}'),
+  ('𑠬', '\u{1183a}'), ('\u{119d1}', '\u{119d7}'),
+  ('\u{119da}', '\u{119e0}'), ('\u{119e4}', '\u{119e4}'),
+  ('\u{11a01}', '\u{11a0a}'), ('\u{11a33}', '𑨹'),
+  ('\u{11a3b}', '\u{11a3e}'), ('\u{11a47}', '\u{11a47}'),
+  ('\u{11a51}', '\u{11a5b}'), ('\u{11a8a}', '\u{11a99}'),
+  ('𑰯', '\u{11c36}'), ('\u{11c38}', '\u{11c3f}'),
+  ('\u{11c92}', '\u{11ca7}'), ('𑲩', '\u{11cb6}'),
+  ('\u{11d31}', '\u{11d36}'), ('\u{11d3a}', '\u{11d3a}'),
+  ('\u{11d3c}', '\u{11d3d}'), ('\u{11d3f}', '\u{11d45}'),
+  ('\u{11d47}', '\u{11d47}'), ('𑶊', '𑶎'), ('\u{11d90}', '\u{11d91}'),
+  ('𑶓', '\u{11d97}'), ('\u{11ef3}', '𑻶'), ('\u{16af0}', '\u{16af4}'),
+  ('\u{16b30}', '\u{16b36}'), ('\u{16f4f}', '\u{16f4f}'),
+  ('𖽑', '\u{16f87}'), ('\u{16f8f}', '\u{16f92}'),
+  ('\u{1bc9d}', '\u{1bc9e}'), ('\u{1d165}', '\u{1d169}'),
+  ('𝅭', '\u{1d172}'), ('\u{1d17b}', '\u{1d182}'),
+  ('\u{1d185}', '\u{1d18b}'), ('\u{1d1aa}', '\u{1d1ad}'),
+  ('\u{1d242}', '\u{1d244}'), ('\u{1da00}', '\u{1da36}'),
+  ('\u{1da3b}', '\u{1da6c}'), ('\u{1da75}', '\u{1da75}'),
+  ('\u{1da84}', '\u{1da84}'), ('\u{1da9b}', '\u{1da9f}'),
+  ('\u{1daa1}', '\u{1daaf}'), ('\u{1e000}', '\u{1e006}'),
+  ('\u{1e008}', '\u{1e018}'), ('\u{1e01b}', '\u{1e021}'),
+  ('\u{1e023}', '\u{1e024}'), ('\u{1e026}', '\u{1e02a}'),
+  ('\u{1e130}', '\u{1e136}'), ('\u{1e2ec}', '\u{1e2ef}'),
+  ('\u{1e8d0}', '\u{1e8d6}'), ('\u{1e944}', '\u{1e94a}'),
+  ('\u{e0020}', '\u{e007f}'), ('\u{e0100}', '\u{e01ef}'),
+];
+
+pub const FORMAT: &'static [(char, char)] = &[
+  ('\u{ad}', '\u{ad}'), ('\u{600}', '\u{605}'), ('\u{61c}', '\u{61c}'),
+  ('\u{6dd}', '\u{6dd}'), ('\u{70f}', '\u{70f}'), ('\u{8e2}', '\u{8e2}'),
+  ('\u{180e}', '\u{180e}'), ('\u{200b}', '\u{200b}'),
+  ('\u{200e}', '\u{200f}'), ('\u{202a}', '\u{202e}'),
+  ('\u{2060}', '\u{2064}'), ('\u{2066}', '\u{206f}'),
+  ('\u{feff}', '\u{feff}'), ('\u{fff9}', '\u{fffb}'),
+  ('\u{110bd}', '\u{110bd}'), ('\u{110cd}', '\u{110cd}'),
+  ('\u{13430}', '\u{13438}'), ('\u{1bca0}', '\u{1bca3}'),
+  ('\u{1d173}', '\u{1d17a}'), ('\u{e0001}', '\u{e0001}'),
+];
+
+pub const LF: &'static [(char, char)] = &[
+  ('\n', '\n'),
+];
+
+pub const LOWER: &'static [(char, char)] = &[
+  ('a', 'z'), ('ª', 'ª'), ('µ', 'µ'), ('º', 'º'), ('ß', 'ö'),
+  ('ø', 'ÿ'), ('ā', 'ā'), ('ă', 'ă'), ('ą', 'ą'), ('ć', 'ć'),
+  ('ĉ', 'ĉ'), ('ċ', 'ċ'), ('č', 'č'), ('ď', 'ď'), ('đ', 'đ'),
+  ('ē', 'ē'), ('ĕ', 'ĕ'), ('ė', 'ė'), ('ę', 'ę'), ('ě', 'ě'),
+  ('ĝ', 'ĝ'), ('ğ', 'ğ'), ('ġ', 'ġ'), ('ģ', 'ģ'), ('ĥ', 'ĥ'),
+  ('ħ', 'ħ'), ('ĩ', 'ĩ'), ('ī', 'ī'), ('ĭ', 'ĭ'), ('į', 'į'),
+  ('ı', 'ı'), ('ij', 'ij'), ('ĵ', 'ĵ'), ('ķ', 'ĸ'), ('ĺ', 'ĺ'),
+  ('ļ', 'ļ'), ('ľ', 'ľ'), ('ŀ', 'ŀ'), ('ł', 'ł'), ('ń', 'ń'),
+  ('ņ', 'ņ'), ('ň', 'ʼn'), ('ŋ', 'ŋ'), ('ō', 'ō'), ('ŏ', 'ŏ'),
+  ('ő', 'ő'), ('œ', 'œ'), ('ŕ', 'ŕ'), ('ŗ', 'ŗ'), ('ř', 'ř'),
+  ('ś', 'ś'), ('ŝ', 'ŝ'), ('ş', 'ş'), ('š', 'š'), ('ţ', 'ţ'),
+  ('ť', 'ť'), ('ŧ', 'ŧ'), ('ũ', 'ũ'), ('ū', 'ū'), ('ŭ', 'ŭ'),
+  ('ů', 'ů'), ('ű', 'ű'), ('ų', 'ų'), ('ŵ', 'ŵ'), ('ŷ', 'ŷ'),
+  ('ź', 'ź'), ('ż', 'ż'), ('ž', 'ƀ'), ('ƃ', 'ƃ'), ('ƅ', 'ƅ'),
+  ('ƈ', 'ƈ'), ('ƌ', 'ƍ'), ('ƒ', 'ƒ'), ('ƕ', 'ƕ'), ('ƙ', 'ƛ'),
+  ('ƞ', 'ƞ'), ('ơ', 'ơ'), ('ƣ', 'ƣ'), ('ƥ', 'ƥ'), ('ƨ', 'ƨ'),
+  ('ƪ', 'ƫ'), ('ƭ', 'ƭ'), ('ư', 'ư'), ('ƴ', 'ƴ'), ('ƶ', 'ƶ'),
+  ('ƹ', 'ƺ'), ('ƽ', 'ƿ'), ('dž', 'dž'), ('lj', 'lj'), ('nj', 'nj'),
+  ('ǎ', 'ǎ'), ('ǐ', 'ǐ'), ('ǒ', 'ǒ'), ('ǔ', 'ǔ'), ('ǖ', 'ǖ'),
+  ('ǘ', 'ǘ'), ('ǚ', 'ǚ'), ('ǜ', 'ǝ'), ('ǟ', 'ǟ'), ('ǡ', 'ǡ'),
+  ('ǣ', 'ǣ'), ('ǥ', 'ǥ'), ('ǧ', 'ǧ'), ('ǩ', 'ǩ'), ('ǫ', 'ǫ'),
+  ('ǭ', 'ǭ'), ('ǯ', 'ǰ'), ('dz', 'dz'), ('ǵ', 'ǵ'), ('ǹ', 'ǹ'),
+  ('ǻ', 'ǻ'), ('ǽ', 'ǽ'), ('ǿ', 'ǿ'), ('ȁ', 'ȁ'), ('ȃ', 'ȃ'),
+  ('ȅ', 'ȅ'), ('ȇ', 'ȇ'), ('ȉ', 'ȉ'), ('ȋ', 'ȋ'), ('ȍ', 'ȍ'),
+  ('ȏ', 'ȏ'), ('ȑ', 'ȑ'), ('ȓ', 'ȓ'), ('ȕ', 'ȕ'), ('ȗ', 'ȗ'),
+  ('ș', 'ș'), ('ț', 'ț'), ('ȝ', 'ȝ'), ('ȟ', 'ȟ'), ('ȡ', 'ȡ'),
+  ('ȣ', 'ȣ'), ('ȥ', 'ȥ'), ('ȧ', 'ȧ'), ('ȩ', 'ȩ'), ('ȫ', 'ȫ'),
+  ('ȭ', 'ȭ'), ('ȯ', 'ȯ'), ('ȱ', 'ȱ'), ('ȳ', 'ȹ'), ('ȼ', 'ȼ'),
+  ('ȿ', 'ɀ'), ('ɂ', 'ɂ'), ('ɇ', 'ɇ'), ('ɉ', 'ɉ'), ('ɋ', 'ɋ'),
+  ('ɍ', 'ɍ'), ('ɏ', 'ʓ'), ('ʕ', 'ʸ'), ('ˀ', 'ˁ'), ('ˠ', 'ˤ'),
+  ('ͱ', 'ͱ'), ('ͳ', 'ͳ'), ('ͷ', 'ͷ'), ('ͺ', 'ͽ'), ('ΐ', 'ΐ'),
+  ('ά', 'ώ'), ('ϐ', 'ϑ'), ('ϕ', 'ϗ'), ('ϙ', 'ϙ'), ('ϛ', 'ϛ'),
+  ('ϝ', 'ϝ'), ('ϟ', 'ϟ'), ('ϡ', 'ϡ'), ('ϣ', 'ϣ'), ('ϥ', 'ϥ'),
+  ('ϧ', 'ϧ'), ('ϩ', 'ϩ'), ('ϫ', 'ϫ'), ('ϭ', 'ϭ'), ('ϯ', 'ϳ'),
+  ('ϵ', 'ϵ'), ('ϸ', 'ϸ'), ('ϻ', 'ϼ'), ('а', 'џ'), ('ѡ', 'ѡ'),
+  ('ѣ', 'ѣ'), ('ѥ', 'ѥ'), ('ѧ', 'ѧ'), ('ѩ', 'ѩ'), ('ѫ', 'ѫ'),
+  ('ѭ', 'ѭ'), ('ѯ', 'ѯ'), ('ѱ', 'ѱ'), ('ѳ', 'ѳ'), ('ѵ', 'ѵ'),
+  ('ѷ', 'ѷ'), ('ѹ', 'ѹ'), ('ѻ', 'ѻ'), ('ѽ', 'ѽ'), ('ѿ', 'ѿ'),
+  ('ҁ', 'ҁ'), ('ҋ', 'ҋ'), ('ҍ', 'ҍ'), ('ҏ', 'ҏ'), ('ґ', 'ґ'),
+  ('ғ', 'ғ'), ('ҕ', 'ҕ'), ('җ', 'җ'), ('ҙ', 'ҙ'), ('қ', 'қ'),
+  ('ҝ', 'ҝ'), ('ҟ', 'ҟ'), ('ҡ', 'ҡ'), ('ң', 'ң'), ('ҥ', 'ҥ'),
+  ('ҧ', 'ҧ'), ('ҩ', 'ҩ'), ('ҫ', 'ҫ'), ('ҭ', 'ҭ'), ('ү', 'ү'),
+  ('ұ', 'ұ'), ('ҳ', 'ҳ'), ('ҵ', 'ҵ'), ('ҷ', 'ҷ'), ('ҹ', 'ҹ'),
+  ('һ', 'һ'), ('ҽ', 'ҽ'), ('ҿ', 'ҿ'), ('ӂ', 'ӂ'), ('ӄ', 'ӄ'),
+  ('ӆ', 'ӆ'), ('ӈ', 'ӈ'), ('ӊ', 'ӊ'), ('ӌ', 'ӌ'), ('ӎ', 'ӏ'),
+  ('ӑ', 'ӑ'), ('ӓ', 'ӓ'), ('ӕ', 'ӕ'), ('ӗ', 'ӗ'), ('ә', 'ә'),
+  ('ӛ', 'ӛ'), ('ӝ', 'ӝ'), ('ӟ', 'ӟ'), ('ӡ', 'ӡ'), ('ӣ', 'ӣ'),
+  ('ӥ', 'ӥ'), ('ӧ', 'ӧ'), ('ө', 'ө'), ('ӫ', 'ӫ'), ('ӭ', 'ӭ'),
+  ('ӯ', 'ӯ'), ('ӱ', 'ӱ'), ('ӳ', 'ӳ'), ('ӵ', 'ӵ'), ('ӷ', 'ӷ'),
+  ('ӹ', 'ӹ'), ('ӻ', 'ӻ'), ('ӽ', 'ӽ'), ('ӿ', 'ӿ'), ('ԁ', 'ԁ'),
+  ('ԃ', 'ԃ'), ('ԅ', 'ԅ'), ('ԇ', 'ԇ'), ('ԉ', 'ԉ'), ('ԋ', 'ԋ'),
+  ('ԍ', 'ԍ'), ('ԏ', 'ԏ'), ('ԑ', 'ԑ'), ('ԓ', 'ԓ'), ('ԕ', 'ԕ'),
+  ('ԗ', 'ԗ'), ('ԙ', 'ԙ'), ('ԛ', 'ԛ'), ('ԝ', 'ԝ'), ('ԟ', 'ԟ'),
+  ('ԡ', 'ԡ'), ('ԣ', 'ԣ'), ('ԥ', 'ԥ'), ('ԧ', 'ԧ'), ('ԩ', 'ԩ'),
+  ('ԫ', 'ԫ'), ('ԭ', 'ԭ'), ('ԯ', 'ԯ'), ('ՠ', 'ֈ'), ('ᏸ', 'ᏽ'),
+  ('ᲀ', 'ᲈ'), ('ᴀ', 'ᶿ'), ('ḁ', 'ḁ'), ('ḃ', 'ḃ'),
+  ('ḅ', 'ḅ'), ('ḇ', 'ḇ'), ('ḉ', 'ḉ'), ('ḋ', 'ḋ'),
+  ('ḍ', 'ḍ'), ('ḏ', 'ḏ'), ('ḑ', 'ḑ'), ('ḓ', 'ḓ'),
+  ('ḕ', 'ḕ'), ('ḗ', 'ḗ'), ('ḙ', 'ḙ'), ('ḛ', 'ḛ'),
+  ('ḝ', 'ḝ'), ('ḟ', 'ḟ'), ('ḡ', 'ḡ'), ('ḣ', 'ḣ'),
+  ('ḥ', 'ḥ'), ('ḧ', 'ḧ'), ('ḩ', 'ḩ'), ('ḫ', 'ḫ'),
+  ('ḭ', 'ḭ'), ('ḯ', 'ḯ'), ('ḱ', 'ḱ'), ('ḳ', 'ḳ'),
+  ('ḵ', 'ḵ'), ('ḷ', 'ḷ'), ('ḹ', 'ḹ'), ('ḻ', 'ḻ'),
+  ('ḽ', 'ḽ'), ('ḿ', 'ḿ'), ('ṁ', 'ṁ'), ('ṃ', 'ṃ'),
+  ('ṅ', 'ṅ'), ('ṇ', 'ṇ'), ('ṉ', 'ṉ'), ('ṋ', 'ṋ'),
+  ('ṍ', 'ṍ'), ('ṏ', 'ṏ'), ('ṑ', 'ṑ'), ('ṓ', 'ṓ'),
+  ('ṕ', 'ṕ'), ('ṗ', 'ṗ'), ('ṙ', 'ṙ'), ('ṛ', 'ṛ'),
+  ('ṝ', 'ṝ'), ('ṟ', 'ṟ'), ('ṡ', 'ṡ'), ('ṣ', 'ṣ'),
+  ('ṥ', 'ṥ'), ('ṧ', 'ṧ'), ('ṩ', 'ṩ'), ('ṫ', 'ṫ'),
+  ('ṭ', 'ṭ'), ('ṯ', 'ṯ'), ('ṱ', 'ṱ'), ('ṳ', 'ṳ'),
+  ('ṵ', 'ṵ'), ('ṷ', 'ṷ'), ('ṹ', 'ṹ'), ('ṻ', 'ṻ'),
+  ('ṽ', 'ṽ'), ('ṿ', 'ṿ'), ('ẁ', 'ẁ'), ('ẃ', 'ẃ'),
+  ('ẅ', 'ẅ'), ('ẇ', 'ẇ'), ('ẉ', 'ẉ'), ('ẋ', 'ẋ'),
+  ('ẍ', 'ẍ'), ('ẏ', 'ẏ'), ('ẑ', 'ẑ'), ('ẓ', 'ẓ'),
+  ('ẕ', 'ẝ'), ('ẟ', 'ẟ'), ('ạ', 'ạ'), ('ả', 'ả'),
+  ('ấ', 'ấ'), ('ầ', 'ầ'), ('ẩ', 'ẩ'), ('ẫ', 'ẫ'),
+  ('ậ', 'ậ'), ('ắ', 'ắ'), ('ằ', 'ằ'), ('ẳ', 'ẳ'),
+  ('ẵ', 'ẵ'), ('ặ', 'ặ'), ('ẹ', 'ẹ'), ('ẻ', 'ẻ'),
+  ('ẽ', 'ẽ'), ('ế', 'ế'), ('ề', 'ề'), ('ể', 'ể'),
+  ('ễ', 'ễ'), ('ệ', 'ệ'), ('ỉ', 'ỉ'), ('ị', 'ị'),
+  ('ọ', 'ọ'), ('ỏ', 'ỏ'), ('ố', 'ố'), ('ồ', 'ồ'),
+  ('ổ', 'ổ'), ('ỗ', 'ỗ'), ('ộ', 'ộ'), ('ớ', 'ớ'),
+  ('ờ', 'ờ'), ('ở', 'ở'), ('ỡ', 'ỡ'), ('ợ', 'ợ'),
+  ('ụ', 'ụ'), ('ủ', 'ủ'), ('ứ', 'ứ'), ('ừ', 'ừ'),
+  ('ử', 'ử'), ('ữ', 'ữ'), ('ự', 'ự'), ('ỳ', 'ỳ'),
+  ('ỵ', 'ỵ'), ('ỷ', 'ỷ'), ('ỹ', 'ỹ'), ('ỻ', 'ỻ'),
+  ('ỽ', 'ỽ'), ('ỿ', 'ἇ'), ('ἐ', 'ἕ'), ('ἠ', 'ἧ'),
+  ('ἰ', 'ἷ'), ('ὀ', 'ὅ'), ('ὐ', 'ὗ'), ('ὠ', 'ὧ'),
+  ('ὰ', 'ώ'), ('ᾀ', 'ᾇ'), ('ᾐ', 'ᾗ'), ('ᾠ', 'ᾧ'),
+  ('ᾰ', 'ᾴ'), ('ᾶ', 'ᾷ'), ('ι', 'ι'), ('ῂ', 'ῄ'),
+  ('ῆ', 'ῇ'), ('ῐ', 'ΐ'), ('ῖ', 'ῗ'), ('ῠ', 'ῧ'),
+  ('ῲ', 'ῴ'), ('ῶ', 'ῷ'), ('ⁱ', 'ⁱ'), ('ⁿ', 'ⁿ'),
+  ('ₐ', 'ₜ'), ('ℊ', 'ℊ'), ('ℎ', 'ℏ'), ('ℓ', 'ℓ'),
+  ('ℯ', 'ℯ'), ('ℴ', 'ℴ'), ('ℹ', 'ℹ'), ('ℼ', 'ℽ'),
+  ('ⅆ', 'ⅉ'), ('ⅎ', 'ⅎ'), ('ⅰ', 'ⅿ'), ('ↄ', 'ↄ'),
+  ('ⓐ', 'ⓩ'), ('ⰰ', 'ⱞ'), ('ⱡ', 'ⱡ'), ('ⱥ', 'ⱦ'),
+  ('ⱨ', 'ⱨ'), ('ⱪ', 'ⱪ'), ('ⱬ', 'ⱬ'), ('ⱱ', 'ⱱ'),
+  ('ⱳ', 'ⱴ'), ('ⱶ', 'ⱽ'), ('ⲁ', 'ⲁ'), ('ⲃ', 'ⲃ'),
+  ('ⲅ', 'ⲅ'), ('ⲇ', 'ⲇ'), ('ⲉ', 'ⲉ'), ('ⲋ', 'ⲋ'),
+  ('ⲍ', 'ⲍ'), ('ⲏ', 'ⲏ'), ('ⲑ', 'ⲑ'), ('ⲓ', 'ⲓ'),
+  ('ⲕ', 'ⲕ'), ('ⲗ', 'ⲗ'), ('ⲙ', 'ⲙ'), ('ⲛ', 'ⲛ'),
+  ('ⲝ', 'ⲝ'), ('ⲟ', 'ⲟ'), ('ⲡ', 'ⲡ'), ('ⲣ', 'ⲣ'),
+  ('ⲥ', 'ⲥ'), ('ⲧ', 'ⲧ'), ('ⲩ', 'ⲩ'), ('ⲫ', 'ⲫ'),
+  ('ⲭ', 'ⲭ'), ('ⲯ', 'ⲯ'), ('ⲱ', 'ⲱ'), ('ⲳ', 'ⲳ'),
+  ('ⲵ', 'ⲵ'), ('ⲷ', 'ⲷ'), ('ⲹ', 'ⲹ'), ('ⲻ', 'ⲻ'),
+  ('ⲽ', 'ⲽ'), ('ⲿ', 'ⲿ'), ('ⳁ', 'ⳁ'), ('ⳃ', 'ⳃ'),
+  ('ⳅ', 'ⳅ'), ('ⳇ', 'ⳇ'), ('ⳉ', 'ⳉ'), ('ⳋ', 'ⳋ'),
+  ('ⳍ', 'ⳍ'), ('ⳏ', 'ⳏ'), ('ⳑ', 'ⳑ'), ('ⳓ', 'ⳓ'),
+  ('ⳕ', 'ⳕ'), ('ⳗ', 'ⳗ'), ('ⳙ', 'ⳙ'), ('ⳛ', 'ⳛ'),
+  ('ⳝ', 'ⳝ'), ('ⳟ', 'ⳟ'), ('ⳡ', 'ⳡ'), ('ⳣ', 'ⳤ'),
+  ('ⳬ', 'ⳬ'), ('ⳮ', 'ⳮ'), ('ⳳ', 'ⳳ'), ('ⴀ', 'ⴥ'),
+  ('ⴧ', 'ⴧ'), ('ⴭ', 'ⴭ'), ('ꙁ', 'ꙁ'), ('ꙃ', 'ꙃ'),
+  ('ꙅ', 'ꙅ'), ('ꙇ', 'ꙇ'), ('ꙉ', 'ꙉ'), ('ꙋ', 'ꙋ'),
+  ('ꙍ', 'ꙍ'), ('ꙏ', 'ꙏ'), ('ꙑ', 'ꙑ'), ('ꙓ', 'ꙓ'),
+  ('ꙕ', 'ꙕ'), ('ꙗ', 'ꙗ'), ('ꙙ', 'ꙙ'), ('ꙛ', 'ꙛ'),
+  ('ꙝ', 'ꙝ'), ('ꙟ', 'ꙟ'), ('ꙡ', 'ꙡ'), ('ꙣ', 'ꙣ'),
+  ('ꙥ', 'ꙥ'), ('ꙧ', 'ꙧ'), ('ꙩ', 'ꙩ'), ('ꙫ', 'ꙫ'),
+  ('ꙭ', 'ꙭ'), ('ꚁ', 'ꚁ'), ('ꚃ', 'ꚃ'), ('ꚅ', 'ꚅ'),
+  ('ꚇ', 'ꚇ'), ('ꚉ', 'ꚉ'), ('ꚋ', 'ꚋ'), ('ꚍ', 'ꚍ'),
+  ('ꚏ', 'ꚏ'), ('ꚑ', 'ꚑ'), ('ꚓ', 'ꚓ'), ('ꚕ', 'ꚕ'),
+  ('ꚗ', 'ꚗ'), ('ꚙ', 'ꚙ'), ('ꚛ', 'ꚝ'), ('ꜣ', 'ꜣ'),
+  ('ꜥ', 'ꜥ'), ('ꜧ', 'ꜧ'), ('ꜩ', 'ꜩ'), ('ꜫ', 'ꜫ'),
+  ('ꜭ', 'ꜭ'), ('ꜯ', 'ꜱ'), ('ꜳ', 'ꜳ'), ('ꜵ', 'ꜵ'),
+  ('ꜷ', 'ꜷ'), ('ꜹ', 'ꜹ'), ('ꜻ', 'ꜻ'), ('ꜽ', 'ꜽ'),
+  ('ꜿ', 'ꜿ'), ('ꝁ', 'ꝁ'), ('ꝃ', 'ꝃ'), ('ꝅ', 'ꝅ'),
+  ('ꝇ', 'ꝇ'), ('ꝉ', 'ꝉ'), ('ꝋ', 'ꝋ'), ('ꝍ', 'ꝍ'),
+  ('ꝏ', 'ꝏ'), ('ꝑ', 'ꝑ'), ('ꝓ', 'ꝓ'), ('ꝕ', 'ꝕ'),
+  ('ꝗ', 'ꝗ'), ('ꝙ', 'ꝙ'), ('ꝛ', 'ꝛ'), ('ꝝ', 'ꝝ'),
+  ('ꝟ', 'ꝟ'), ('ꝡ', 'ꝡ'), ('ꝣ', 'ꝣ'), ('ꝥ', 'ꝥ'),
+  ('ꝧ', 'ꝧ'), ('ꝩ', 'ꝩ'), ('ꝫ', 'ꝫ'), ('ꝭ', 'ꝭ'),
+  ('ꝯ', 'ꝸ'), ('ꝺ', 'ꝺ'), ('ꝼ', 'ꝼ'), ('ꝿ', 'ꝿ'),
+  ('ꞁ', 'ꞁ'), ('ꞃ', 'ꞃ'), ('ꞅ', 'ꞅ'), ('ꞇ', 'ꞇ'),
+  ('ꞌ', 'ꞌ'), ('ꞎ', 'ꞎ'), ('ꞑ', 'ꞑ'), ('ꞓ', 'ꞕ'),
+  ('ꞗ', 'ꞗ'), ('ꞙ', 'ꞙ'), ('ꞛ', 'ꞛ'), ('ꞝ', 'ꞝ'),
+  ('ꞟ', 'ꞟ'), ('ꞡ', 'ꞡ'), ('ꞣ', 'ꞣ'), ('ꞥ', 'ꞥ'),
+  ('ꞧ', 'ꞧ'), ('ꞩ', 'ꞩ'), ('ꞯ', 'ꞯ'), ('ꞵ', 'ꞵ'),
+  ('ꞷ', 'ꞷ'), ('ꞹ', 'ꞹ'), ('\u{a7bb}', '\u{a7bb}'),
+  ('\u{a7bd}', '\u{a7bd}'), ('\u{a7bf}', '\u{a7bf}'),
+  ('\u{a7c3}', '\u{a7c3}'), ('ꟸ', 'ꟺ'), ('ꬰ', 'ꭚ'),
+  ('ꭜ', '\u{ab67}'), ('ꭰ', 'ꮿ'), ('ff', 'st'), ('ﬓ', 'ﬗ'),
+  ('a', 'z'), ('𐐨', '𐑏'), ('𐓘', '𐓻'), ('𐳀', '𐳲'),
+  ('𑣀', '𑣟'), ('𖹠', '𖹿'), ('𝐚', '𝐳'), ('𝑎', '𝑔'),
+  ('𝑖', '𝑧'), ('𝒂', '𝒛'), ('𝒶', '𝒹'), ('𝒻', '𝒻'),
+  ('𝒽', '𝓃'), ('𝓅', '𝓏'), ('𝓪', '𝔃'), ('𝔞', '𝔷'),
+  ('𝕒', '𝕫'), ('𝖆', '𝖟'), ('𝖺', '𝗓'), ('𝗮', '𝘇'),
+  ('𝘢', '𝘻'), ('𝙖', '𝙯'), ('𝚊', '𝚥'), ('𝛂', '𝛚'),
+  ('𝛜', '𝛡'), ('𝛼', '𝜔'), ('𝜖', '𝜛'), ('𝜶', '𝝎'),
+  ('𝝐', '𝝕'), ('𝝰', '𝞈'), ('𝞊', '𝞏'), ('𝞪', '𝟂'),
+  ('𝟄', '𝟉'), ('𝟋', '𝟋'), ('𞤢', '𞥃'),
+];
+
+pub const NUMERIC: &'static [(char, char)] = &[
+  ('0', '9'), ('٠', '٩'), ('٫', '٬'), ('۰', '۹'), ('߀', '߉'),
+  ('०', '९'), ('০', '৯'), ('੦', '੯'), ('૦', '૯'),
+  ('୦', '୯'), ('௦', '௯'), ('౦', '౯'), ('೦', '೯'),
+  ('൦', '൯'), ('෦', '෯'), ('๐', '๙'), ('໐', '໙'),
+  ('༠', '༩'), ('၀', '၉'), ('႐', '႙'), ('០', '៩'),
+  ('᠐', '᠙'), ('᥆', '᥏'), ('᧐', '᧙'), ('᪀', '᪉'),
+  ('᪐', '᪙'), ('᭐', '᭙'), ('᮰', '᮹'), ('᱀', '᱉'),
+  ('᱐', '᱙'), ('꘠', '꘩'), ('꣐', '꣙'), ('꤀', '꤉'),
+  ('꧐', '꧙'), ('꧰', '꧹'), ('꩐', '꩙'), ('꯰', '꯹'),
+  ('0', '9'), ('𐒠', '𐒩'), ('𐴰', '𐴹'), ('𑁦', '𑁯'),
+  ('𑃰', '𑃹'), ('𑄶', '𑄿'), ('𑇐', '𑇙'), ('𑋰', '𑋹'),
+  ('𑑐', '𑑙'), ('𑓐', '𑓙'), ('𑙐', '𑙙'), ('𑛀', '𑛉'),
+  ('𑜰', '𑜹'), ('𑣠', '𑣩'), ('𑱐', '𑱙'), ('𑵐', '𑵙'),
+  ('𑶠', '𑶩'), ('𖩠', '𖩩'), ('𖭐', '𖭙'), ('𝟎', '𝟿'),
+  ('\u{1e140}', '\u{1e149}'), ('\u{1e2f0}', '\u{1e2f9}'), ('𞥐', '𞥙'),
+];
+
+pub const OLETTER: &'static [(char, char)] = &[
+  ('ƻ', 'ƻ'), ('ǀ', 'ǃ'), ('ʔ', 'ʔ'), ('ʹ', 'ʿ'), ('ˆ', 'ˑ'),
+  ('ˬ', 'ˬ'), ('ˮ', 'ˮ'), ('ʹ', 'ʹ'), ('ՙ', 'ՙ'), ('א', 'ת'),
+  ('ׯ', '׳'), ('ؠ', 'ي'), ('ٮ', 'ٯ'), ('ٱ', 'ۓ'), ('ە', 'ە'),
+  ('ۥ', 'ۦ'), ('ۮ', 'ۯ'), ('ۺ', 'ۼ'), ('ۿ', 'ۿ'), ('ܐ', 'ܐ'),
+  ('ܒ', 'ܯ'), ('ݍ', 'ޥ'), ('ޱ', 'ޱ'), ('ߊ', 'ߪ'), ('ߴ', 'ߵ'),
+  ('ߺ', 'ߺ'), ('ࠀ', 'ࠕ'), ('ࠚ', 'ࠚ'), ('ࠤ', 'ࠤ'),
+  ('ࠨ', 'ࠨ'), ('ࡀ', 'ࡘ'), ('ࡠ', 'ࡪ'), ('ࢠ', 'ࢴ'),
+  ('ࢶ', 'ࢽ'), ('ऄ', 'ह'), ('ऽ', 'ऽ'), ('ॐ', 'ॐ'),
+  ('क़', 'ॡ'), ('ॱ', 'ঀ'), ('অ', 'ঌ'), ('এ', 'ঐ'),
+  ('ও', 'ন'), ('প', 'র'), ('ল', 'ল'), ('শ', 'হ'),
+  ('ঽ', 'ঽ'), ('ৎ', 'ৎ'), ('ড়', 'ঢ়'), ('য়', 'ৡ'),
+  ('ৰ', 'ৱ'), ('ৼ', 'ৼ'), ('ਅ', 'ਊ'), ('ਏ', 'ਐ'),
+  ('ਓ', 'ਨ'), ('ਪ', 'ਰ'), ('ਲ', 'ਲ਼'), ('ਵ', 'ਸ਼'),
+  ('ਸ', 'ਹ'), ('ਖ਼', 'ੜ'), ('ਫ਼', 'ਫ਼'), ('ੲ', 'ੴ'),
+  ('અ', 'ઍ'), ('એ', 'ઑ'), ('ઓ', 'ન'), ('પ', 'ર'),
+  ('લ', 'ળ'), ('વ', 'હ'), ('ઽ', 'ઽ'), ('ૐ', 'ૐ'),
+  ('ૠ', 'ૡ'), ('ૹ', 'ૹ'), ('ଅ', 'ଌ'), ('ଏ', 'ଐ'),
+  ('ଓ', 'ନ'), ('ପ', 'ର'), ('ଲ', 'ଳ'), ('ଵ', 'ହ'),
+  ('ଽ', 'ଽ'), ('ଡ଼', 'ଢ଼'), ('ୟ', 'ୡ'), ('ୱ', 'ୱ'),
+  ('ஃ', 'ஃ'), ('அ', 'ஊ'), ('எ', 'ஐ'), ('ஒ', 'க'),
+  ('ங', 'ச'), ('ஜ', 'ஜ'), ('ஞ', 'ட'), ('ண', 'த'),
+  ('ந', 'ப'), ('ம', 'ஹ'), ('ௐ', 'ௐ'), ('అ', 'ఌ'),
+  ('ఎ', 'ఐ'), ('ఒ', 'న'), ('ప', 'హ'), ('ఽ', 'ఽ'),
+  ('ౘ', 'ౚ'), ('ౠ', 'ౡ'), ('ಀ', 'ಀ'), ('ಅ', 'ಌ'),
+  ('ಎ', 'ಐ'), ('ಒ', 'ನ'), ('ಪ', 'ಳ'), ('ವ', 'ಹ'),
+  ('ಽ', 'ಽ'), ('ೞ', 'ೞ'), ('ೠ', 'ೡ'), ('ೱ', 'ೲ'),
+  ('അ', 'ഌ'), ('എ', 'ഐ'), ('ഒ', 'ഺ'), ('ഽ', 'ഽ'),
+  ('ൎ', 'ൎ'), ('ൔ', 'ൖ'), ('ൟ', 'ൡ'), ('ൺ', 'ൿ'),
+  ('අ', 'ඖ'), ('ක', 'න'), ('ඳ', 'ර'), ('ල', 'ල'),
+  ('ව', 'ෆ'), ('ก', 'ะ'), ('า', 'ำ'), ('เ', 'ๆ'),
+  ('ກ', 'ຂ'), ('ຄ', 'ຄ'), ('\u{e86}', 'ຊ'), ('\u{e8c}', 'ຣ'),
+  ('ລ', 'ລ'), ('ວ', 'ະ'), ('າ', 'ຳ'), ('ຽ', 'ຽ'),
+  ('ເ', 'ໄ'), ('ໆ', 'ໆ'), ('ໜ', 'ໟ'), ('ༀ', 'ༀ'),
+  ('ཀ', 'ཇ'), ('ཉ', 'ཬ'), ('ྈ', 'ྌ'), ('က', 'ဪ'),
+  ('ဿ', 'ဿ'), ('ၐ', 'ၕ'), ('ၚ', 'ၝ'), ('ၡ', 'ၡ'),
+  ('ၥ', 'ၦ'), ('ၮ', 'ၰ'), ('ၵ', 'ႁ'), ('ႎ', 'ႎ'),
+  ('ა', 'ჺ'), ('ჼ', 'ቈ'), ('ቊ', 'ቍ'), ('ቐ', 'ቖ'),
+  ('ቘ', 'ቘ'), ('ቚ', 'ቝ'), ('በ', 'ኈ'), ('ኊ', 'ኍ'),
+  ('ነ', 'ኰ'), ('ኲ', 'ኵ'), ('ኸ', 'ኾ'), ('ዀ', 'ዀ'),
+  ('ዂ', 'ዅ'), ('ወ', 'ዖ'), ('ዘ', 'ጐ'), ('ጒ', 'ጕ'),
+  ('ጘ', 'ፚ'), ('ᎀ', 'ᎏ'), ('ᐁ', 'ᙬ'), ('ᙯ', 'ᙿ'),
+  ('ᚁ', 'ᚚ'), ('ᚠ', 'ᛪ'), ('ᛮ', 'ᛸ'), ('ᜀ', 'ᜌ'),
+  ('ᜎ', 'ᜑ'), ('ᜠ', 'ᜱ'), ('ᝀ', 'ᝑ'), ('ᝠ', 'ᝬ'),
+  ('ᝮ', 'ᝰ'), ('ក', 'ឳ'), ('ៗ', 'ៗ'), ('ៜ', 'ៜ'),
+  ('ᠠ', 'ᡸ'), ('ᢀ', 'ᢄ'), ('ᢇ', 'ᢨ'), ('ᢪ', 'ᢪ'),
+  ('ᢰ', 'ᣵ'), ('ᤀ', 'ᤞ'), ('ᥐ', 'ᥭ'), ('ᥰ', 'ᥴ'),
+  ('ᦀ', 'ᦫ'), ('ᦰ', 'ᧉ'), ('ᨀ', 'ᨖ'), ('ᨠ', 'ᩔ'),
+  ('ᪧ', 'ᪧ'), ('ᬅ', 'ᬳ'), ('ᭅ', 'ᭋ'), ('ᮃ', 'ᮠ'),
+  ('ᮮ', 'ᮯ'), ('ᮺ', 'ᯥ'), ('ᰀ', 'ᰣ'), ('ᱍ', 'ᱏ'),
+  ('ᱚ', 'ᱽ'), ('Ა', 'Ჺ'), ('Ჽ', 'Ჿ'), ('ᳩ', 'ᳬ'),
+  ('ᳮ', 'ᳳ'), ('ᳵ', 'ᳶ'), ('\u{1cfa}', '\u{1cfa}'), ('ℵ', 'ℸ'),
+  ('ↀ', 'ↂ'), ('ↅ', 'ↈ'), ('ⴰ', 'ⵧ'), ('ⵯ', 'ⵯ'),
+  ('ⶀ', 'ⶖ'), ('ⶠ', 'ⶦ'), ('ⶨ', 'ⶮ'), ('ⶰ', 'ⶶ'),
+  ('ⶸ', 'ⶾ'), ('ⷀ', 'ⷆ'), ('ⷈ', 'ⷎ'), ('ⷐ', 'ⷖ'),
+  ('ⷘ', 'ⷞ'), ('ⸯ', 'ⸯ'), ('々', '〇'), ('〡', '〩'),
+  ('〱', '〵'), ('〸', '〼'), ('ぁ', 'ゖ'), ('ゝ', 'ゟ'),
+  ('ァ', 'ヺ'), ('ー', 'ヿ'), ('ㄅ', 'ㄯ'), ('ㄱ', 'ㆎ'),
+  ('ㆠ', 'ㆺ'), ('ㇰ', 'ㇿ'), ('㐀', '䶵'), ('一', '鿯'),
+  ('ꀀ', 'ꒌ'), ('ꓐ', 'ꓽ'), ('ꔀ', 'ꘌ'), ('ꘐ', 'ꘟ'),
+  ('ꘪ', 'ꘫ'), ('ꙮ', 'ꙮ'), ('ꙿ', 'ꙿ'), ('ꚠ', 'ꛯ'),
+  ('ꜗ', 'ꜟ'), ('ꞈ', 'ꞈ'), ('ꞏ', 'ꞏ'), ('ꟷ', 'ꟷ'),
+  ('ꟻ', 'ꠁ'), ('ꠃ', 'ꠅ'), ('ꠇ', 'ꠊ'), ('ꠌ', 'ꠢ'),
+  ('ꡀ', 'ꡳ'), ('ꢂ', 'ꢳ'), ('ꣲ', 'ꣷ'), ('ꣻ', 'ꣻ'),
+  ('ꣽ', 'ꣾ'), ('ꤊ', 'ꤥ'), ('ꤰ', 'ꥆ'), ('ꥠ', 'ꥼ'),
+  ('ꦄ', 'ꦲ'), ('ꧏ', 'ꧏ'), ('ꧠ', 'ꧤ'), ('ꧦ', 'ꧯ'),
+  ('ꧺ', 'ꧾ'), ('ꨀ', 'ꨨ'), ('ꩀ', 'ꩂ'), ('ꩄ', 'ꩋ'),
+  ('ꩠ', 'ꩶ'), ('ꩺ', 'ꩺ'), ('ꩾ', 'ꪯ'), ('ꪱ', 'ꪱ'),
+  ('ꪵ', 'ꪶ'), ('ꪹ', 'ꪽ'), ('ꫀ', 'ꫀ'), ('ꫂ', 'ꫂ'),
+  ('ꫛ', 'ꫝ'), ('ꫠ', 'ꫪ'), ('ꫲ', 'ꫴ'), ('ꬁ', 'ꬆ'),
+  ('ꬉ', 'ꬎ'), ('ꬑ', 'ꬖ'), ('ꬠ', 'ꬦ'), ('ꬨ', 'ꬮ'),
+  ('ꯀ', 'ꯢ'), ('가', '힣'), ('ힰ', 'ퟆ'), ('ퟋ', 'ퟻ'),
+  ('豈', '舘'), ('並', '龎'), ('יִ', 'יִ'), ('ײַ', 'ﬨ'),
+  ('שׁ', 'זּ'), ('טּ', 'לּ'), ('מּ', 'מּ'), ('נּ', 'סּ'),
+  ('ףּ', 'פּ'), ('צּ', 'ﮱ'), ('ﯓ', 'ﴽ'), ('ﵐ', 'ﶏ'),
+  ('ﶒ', 'ﷇ'), ('ﷰ', 'ﷻ'), ('ﹰ', 'ﹴ'), ('ﹶ', 'ﻼ'),
+  ('ヲ', 'ン'), ('ᅠ', 'ᄒ'), ('ᅡ', 'ᅦ'), ('ᅧ', 'ᅬ'),
+  ('ᅭ', 'ᅲ'), ('ᅳ', 'ᅵ'), ('𐀀', '𐀋'), ('𐀍', '𐀦'),
+  ('𐀨', '𐀺'), ('𐀼', '𐀽'), ('𐀿', '𐁍'), ('𐁐', '𐁝'),
+  ('𐂀', '𐃺'), ('𐅀', '𐅴'), ('𐊀', '𐊜'), ('𐊠', '𐋐'),
+  ('𐌀', '𐌟'), ('𐌭', '𐍊'), ('𐍐', '𐍵'), ('𐎀', '𐎝'),
+  ('𐎠', '𐏃'), ('𐏈', '𐏏'), ('𐏑', '𐏕'), ('𐑐', '𐒝'),
+  ('𐔀', '𐔧'), ('𐔰', '𐕣'), ('𐘀', '𐜶'), ('𐝀', '𐝕'),
+  ('𐝠', '𐝧'), ('𐠀', '𐠅'), ('𐠈', '𐠈'), ('𐠊', '𐠵'),
+  ('𐠷', '𐠸'), ('𐠼', '𐠼'), ('𐠿', '𐡕'), ('𐡠', '𐡶'),
+  ('𐢀', '𐢞'), ('𐣠', '𐣲'), ('𐣴', '𐣵'), ('𐤀', '𐤕'),
+  ('𐤠', '𐤹'), ('𐦀', '𐦷'), ('𐦾', '𐦿'), ('𐨀', '𐨀'),
+  ('𐨐', '𐨓'), ('𐨕', '𐨗'), ('𐨙', '𐨵'), ('𐩠', '𐩼'),
+  ('𐪀', '𐪜'), ('𐫀', '𐫇'), ('𐫉', '𐫤'), ('𐬀', '𐬵'),
+  ('𐭀', '𐭕'), ('𐭠', '𐭲'), ('𐮀', '𐮑'), ('𐰀', '𐱈'),
+  ('𐴀', '𐴣'), ('𐼀', '𐼜'), ('𐼧', '𐼧'), ('𐼰', '𐽅'),
+  ('\u{10fe0}', '\u{10ff6}'), ('𑀃', '𑀷'), ('𑂃', '𑂯'),
+  ('𑃐', '𑃨'), ('𑄃', '𑄦'), ('𑅄', '𑅄'), ('𑅐', '𑅲'),
+  ('𑅶', '𑅶'), ('𑆃', '𑆲'), ('𑇁', '𑇄'), ('𑇚', '𑇚'),
+  ('𑇜', '𑇜'), ('𑈀', '𑈑'), ('𑈓', '𑈫'), ('𑊀', '𑊆'),
+  ('𑊈', '𑊈'), ('𑊊', '𑊍'), ('𑊏', '𑊝'), ('𑊟', '𑊨'),
+  ('𑊰', '𑋞'), ('𑌅', '𑌌'), ('𑌏', '𑌐'), ('𑌓', '𑌨'),
+  ('𑌪', '𑌰'), ('𑌲', '𑌳'), ('𑌵', '𑌹'), ('𑌽', '𑌽'),
+  ('𑍐', '𑍐'), ('𑍝', '𑍡'), ('𑐀', '𑐴'), ('𑑇', '𑑊'),
+  ('\u{1145f}', '\u{1145f}'), ('𑒀', '𑒯'), ('𑓄', '𑓅'),
+  ('𑓇', '𑓇'), ('𑖀', '𑖮'), ('𑗘', '𑗛'), ('𑘀', '𑘯'),
+  ('𑙄', '𑙄'), ('𑚀', '𑚪'), ('\u{116b8}', '\u{116b8}'),
+  ('𑜀', '𑜚'), ('𑠀', '𑠫'), ('𑣿', '𑣿'),
+  ('\u{119a0}', '\u{119a7}'), ('\u{119aa}', '\u{119d0}'),
+  ('\u{119e1}', '\u{119e1}'), ('\u{119e3}', '\u{119e3}'), ('𑨀', '𑨀'),
+  ('𑨋', '𑨲'), ('𑨺', '𑨺'), ('𑩐', '𑩐'), ('𑩜', '𑪉'),
+  ('𑪝', '𑪝'), ('𑫀', '𑫸'), ('𑰀', '𑰈'), ('𑰊', '𑰮'),
+  ('𑱀', '𑱀'), ('𑱲', '𑲏'), ('𑴀', '𑴆'), ('𑴈', '𑴉'),
+  ('𑴋', '𑴰'), ('𑵆', '𑵆'), ('𑵠', '𑵥'), ('𑵧', '𑵨'),
+  ('𑵪', '𑶉'), ('𑶘', '𑶘'), ('𑻠', '𑻲'), ('𒀀', '𒎙'),
+  ('𒐀', '𒑮'), ('𒒀', '𒕃'), ('𓀀', '𓐮'), ('𔐀', '𔙆'),
+  ('𖠀', '𖨸'), ('𖩀', '𖩞'), ('𖫐', '𖫭'), ('𖬀', '𖬯'),
+  ('𖭀', '𖭃'), ('𖭣', '𖭷'), ('𖭽', '𖮏'), ('𖼀', '\u{16f4a}'),
+  ('𖽐', '𖽐'), ('𖾓', '𖾟'), ('𖿠', '𖿡'),
+  ('\u{16fe3}', '\u{16fe3}'), ('𗀀', '\u{187f7}'), ('𘠀', '𘫲'),
+  ('𛀀', '𛄞'), ('\u{1b150}', '\u{1b152}'), ('\u{1b164}', '\u{1b167}'),
+  ('𛅰', '𛋻'), ('𛰀', '𛱪'), ('𛱰', '𛱼'), ('𛲀', '𛲈'),
+  ('𛲐', '𛲙'), ('\u{1e100}', '\u{1e12c}'), ('\u{1e137}', '\u{1e13d}'),
+  ('\u{1e14e}', '\u{1e14e}'), ('\u{1e2c0}', '\u{1e2eb}'), ('𞠀', '𞣄'),
+  ('\u{1e94b}', '\u{1e94b}'), ('𞸀', '𞸃'), ('𞸅', '𞸟'),
+  ('𞸡', '𞸢'), ('𞸤', '𞸤'), ('𞸧', '𞸧'), ('𞸩', '𞸲'),
+  ('𞸴', '𞸷'), ('𞸹', '𞸹'), ('𞸻', '𞸻'), ('𞹂', '𞹂'),
+  ('𞹇', '𞹇'), ('𞹉', '𞹉'), ('𞹋', '𞹋'), ('𞹍', '𞹏'),
+  ('𞹑', '𞹒'), ('𞹔', '𞹔'), ('𞹗', '𞹗'), ('𞹙', '𞹙'),
+  ('𞹛', '𞹛'), ('𞹝', '𞹝'), ('𞹟', '𞹟'), ('𞹡', '𞹢'),
+  ('𞹤', '𞹤'), ('𞹧', '𞹪'), ('𞹬', '𞹲'), ('𞹴', '𞹷'),
+  ('𞹹', '𞹼'), ('𞹾', '𞹾'), ('𞺀', '𞺉'), ('𞺋', '𞺛'),
+  ('𞺡', '𞺣'), ('𞺥', '𞺩'), ('𞺫', '𞺻'), ('𠀀', '𪛖'),
+  ('𪜀', '𫜴'), ('𫝀', '𫠝'), ('𫠠', '𬺡'), ('𬺰', '𮯠'),
+  ('丽', '𪘀'),
+];
+
+pub const SCONTINUE: &'static [(char, char)] = &[
+  (',', '-'), (':', ':'), ('՝', '՝'), ('،', '؍'), ('߸', '߸'),
+  ('᠂', '᠂'), ('᠈', '᠈'), ('–', '—'), ('、', '、'),
+  ('︐', '︑'), ('︓', '︓'), ('︱', '︲'), ('﹐', '﹑'),
+  ('﹕', '﹕'), ('﹘', '﹘'), ('﹣', '﹣'), (',', '-'),
+  (':', ':'), ('、', '、'),
+];
+
+pub const STERM: &'static [(char, char)] = &[
+  ('!', '!'), ('?', '?'), ('։', '։'), ('؞', '؟'), ('۔', '۔'),
+  ('܀', '܂'), ('߹', '߹'), ('࠷', '࠷'), ('࠹', '࠹'), ('࠽', '࠾'),
+  ('।', '॥'), ('၊', '။'), ('።', '።'), ('፧', '፨'),
+  ('᙮', '᙮'), ('᜵', '᜶'), ('᠃', '᠃'), ('᠉', '᠉'),
+  ('᥄', '᥅'), ('᪨', '᪫'), ('᭚', '᭛'), ('᭞', '᭟'),
+  ('᰻', '᰼'), ('᱾', '᱿'), ('‼', '‽'), ('⁇', '⁉'),
+  ('⸮', '⸮'), ('⸼', '⸼'), ('。', '。'), ('꓿', '꓿'),
+  ('꘎', '꘏'), ('꛳', '꛳'), ('꛷', '꛷'), ('꡶', '꡷'),
+  ('꣎', '꣏'), ('꤯', '꤯'), ('꧈', '꧉'), ('꩝', '꩟'),
+  ('꫰', '꫱'), ('꯫', '꯫'), ('﹖', '﹗'), ('!', '!'),
+  ('?', '?'), ('。', '。'), ('𐩖', '𐩗'), ('𐽕', '𐽙'),
+  ('𑁇', '𑁈'), ('𑂾', '𑃁'), ('𑅁', '𑅃'), ('𑇅', '𑇆'),
+  ('𑇍', '𑇍'), ('𑇞', '𑇟'), ('𑈸', '𑈹'), ('𑈻', '𑈼'),
+  ('𑊩', '𑊩'), ('𑑋', '𑑌'), ('𑗂', '𑗃'), ('𑗉', '𑗗'),
+  ('𑙁', '𑙂'), ('𑜼', '𑜾'), ('𑩂', '𑩃'), ('𑪛', '𑪜'),
+  ('𑱁', '𑱂'), ('𑻷', '𑻸'), ('𖩮', '𖩯'), ('𖫵', '𖫵'),
+  ('𖬷', '𖬸'), ('𖭄', '𖭄'), ('𖺘', '𖺘'), ('𛲟', '𛲟'),
+  ('𝪈', '𝪈'),
+];
+
+pub const SEP: &'static [(char, char)] = &[
+  ('\u{85}', '\u{85}'), ('\u{2028}', '\u{2029}'),
+];
+
+pub const SP: &'static [(char, char)] = &[
+  ('\t', '\t'), ('\u{b}', '\u{c}'), (' ', ' '), ('\u{a0}', '\u{a0}'),
+  ('\u{1680}', '\u{1680}'), ('\u{2000}', '\u{200a}'),
+  ('\u{202f}', '\u{202f}'), ('\u{205f}', '\u{205f}'),
+  ('\u{3000}', '\u{3000}'),
+];
+
+pub const UPPER: &'static [(char, char)] = &[
+  ('A', 'Z'), ('À', 'Ö'), ('Ø', 'Þ'), ('Ā', 'Ā'), ('Ă', 'Ă'),
+  ('Ą', 'Ą'), ('Ć', 'Ć'), ('Ĉ', 'Ĉ'), ('Ċ', 'Ċ'), ('Č', 'Č'),
+  ('Ď', 'Ď'), ('Đ', 'Đ'), ('Ē', 'Ē'), ('Ĕ', 'Ĕ'), ('Ė', 'Ė'),
+  ('Ę', 'Ę'), ('Ě', 'Ě'), ('Ĝ', 'Ĝ'), ('Ğ', 'Ğ'), ('Ġ', 'Ġ'),
+  ('Ģ', 'Ģ'), ('Ĥ', 'Ĥ'), ('Ħ', 'Ħ'), ('Ĩ', 'Ĩ'), ('Ī', 'Ī'),
+  ('Ĭ', 'Ĭ'), ('Į', 'Į'), ('İ', 'İ'), ('IJ', 'IJ'), ('Ĵ', 'Ĵ'),
+  ('Ķ', 'Ķ'), ('Ĺ', 'Ĺ'), ('Ļ', 'Ļ'), ('Ľ', 'Ľ'), ('Ŀ', 'Ŀ'),
+  ('Ł', 'Ł'), ('Ń', 'Ń'), ('Ņ', 'Ņ'), ('Ň', 'Ň'), ('Ŋ', 'Ŋ'),
+  ('Ō', 'Ō'), ('Ŏ', 'Ŏ'), ('Ő', 'Ő'), ('Œ', 'Œ'), ('Ŕ', 'Ŕ'),
+  ('Ŗ', 'Ŗ'), ('Ř', 'Ř'), ('Ś', 'Ś'), ('Ŝ', 'Ŝ'), ('Ş', 'Ş'),
+  ('Š', 'Š'), ('Ţ', 'Ţ'), ('Ť', 'Ť'), ('Ŧ', 'Ŧ'), ('Ũ', 'Ũ'),
+  ('Ū', 'Ū'), ('Ŭ', 'Ŭ'), ('Ů', 'Ů'), ('Ű', 'Ű'), ('Ų', 'Ų'),
+  ('Ŵ', 'Ŵ'), ('Ŷ', 'Ŷ'), ('Ÿ', 'Ź'), ('Ż', 'Ż'), ('Ž', 'Ž'),
+  ('Ɓ', 'Ƃ'), ('Ƅ', 'Ƅ'), ('Ɔ', 'Ƈ'), ('Ɖ', 'Ƌ'), ('Ǝ', 'Ƒ'),
+  ('Ɠ', 'Ɣ'), ('Ɩ', 'Ƙ'), ('Ɯ', 'Ɲ'), ('Ɵ', 'Ơ'), ('Ƣ', 'Ƣ'),
+  ('Ƥ', 'Ƥ'), ('Ʀ', 'Ƨ'), ('Ʃ', 'Ʃ'), ('Ƭ', 'Ƭ'), ('Ʈ', 'Ư'),
+  ('Ʊ', 'Ƴ'), ('Ƶ', 'Ƶ'), ('Ʒ', 'Ƹ'), ('Ƽ', 'Ƽ'), ('DŽ', 'Dž'),
+  ('LJ', 'Lj'), ('NJ', 'Nj'), ('Ǎ', 'Ǎ'), ('Ǐ', 'Ǐ'), ('Ǒ', 'Ǒ'),
+  ('Ǔ', 'Ǔ'), ('Ǖ', 'Ǖ'), ('Ǘ', 'Ǘ'), ('Ǚ', 'Ǚ'), ('Ǜ', 'Ǜ'),
+  ('Ǟ', 'Ǟ'), ('Ǡ', 'Ǡ'), ('Ǣ', 'Ǣ'), ('Ǥ', 'Ǥ'), ('Ǧ', 'Ǧ'),
+  ('Ǩ', 'Ǩ'), ('Ǫ', 'Ǫ'), ('Ǭ', 'Ǭ'), ('Ǯ', 'Ǯ'), ('DZ', 'Dz'),
+  ('Ǵ', 'Ǵ'), ('Ƕ', 'Ǹ'), ('Ǻ', 'Ǻ'), ('Ǽ', 'Ǽ'), ('Ǿ', 'Ǿ'),
+  ('Ȁ', 'Ȁ'), ('Ȃ', 'Ȃ'), ('Ȅ', 'Ȅ'), ('Ȇ', 'Ȇ'), ('Ȉ', 'Ȉ'),
+  ('Ȋ', 'Ȋ'), ('Ȍ', 'Ȍ'), ('Ȏ', 'Ȏ'), ('Ȑ', 'Ȑ'), ('Ȓ', 'Ȓ'),
+  ('Ȕ', 'Ȕ'), ('Ȗ', 'Ȗ'), ('Ș', 'Ș'), ('Ț', 'Ț'), ('Ȝ', 'Ȝ'),
+  ('Ȟ', 'Ȟ'), ('Ƞ', 'Ƞ'), ('Ȣ', 'Ȣ'), ('Ȥ', 'Ȥ'), ('Ȧ', 'Ȧ'),
+  ('Ȩ', 'Ȩ'), ('Ȫ', 'Ȫ'), ('Ȭ', 'Ȭ'), ('Ȯ', 'Ȯ'), ('Ȱ', 'Ȱ'),
+  ('Ȳ', 'Ȳ'), ('Ⱥ', 'Ȼ'), ('Ƚ', 'Ⱦ'), ('Ɂ', 'Ɂ'), ('Ƀ', 'Ɇ'),
+  ('Ɉ', 'Ɉ'), ('Ɋ', 'Ɋ'), ('Ɍ', 'Ɍ'), ('Ɏ', 'Ɏ'), ('Ͱ', 'Ͱ'),
+  ('Ͳ', 'Ͳ'), ('Ͷ', 'Ͷ'), ('Ϳ', 'Ϳ'), ('Ά', 'Ά'), ('Έ', 'Ί'),
+  ('Ό', 'Ό'), ('Ύ', 'Ώ'), ('Α', 'Ρ'), ('Σ', 'Ϋ'), ('Ϗ', 'Ϗ'),
+  ('ϒ', 'ϔ'), ('Ϙ', 'Ϙ'), ('Ϛ', 'Ϛ'), ('Ϝ', 'Ϝ'), ('Ϟ', 'Ϟ'),
+  ('Ϡ', 'Ϡ'), ('Ϣ', 'Ϣ'), ('Ϥ', 'Ϥ'), ('Ϧ', 'Ϧ'), ('Ϩ', 'Ϩ'),
+  ('Ϫ', 'Ϫ'), ('Ϭ', 'Ϭ'), ('Ϯ', 'Ϯ'), ('ϴ', 'ϴ'), ('Ϸ', 'Ϸ'),
+  ('Ϲ', 'Ϻ'), ('Ͻ', 'Я'), ('Ѡ', 'Ѡ'), ('Ѣ', 'Ѣ'), ('Ѥ', 'Ѥ'),
+  ('Ѧ', 'Ѧ'), ('Ѩ', 'Ѩ'), ('Ѫ', 'Ѫ'), ('Ѭ', 'Ѭ'), ('Ѯ', 'Ѯ'),
+  ('Ѱ', 'Ѱ'), ('Ѳ', 'Ѳ'), ('Ѵ', 'Ѵ'), ('Ѷ', 'Ѷ'), ('Ѹ', 'Ѹ'),
+  ('Ѻ', 'Ѻ'), ('Ѽ', 'Ѽ'), ('Ѿ', 'Ѿ'), ('Ҁ', 'Ҁ'), ('Ҋ', 'Ҋ'),
+  ('Ҍ', 'Ҍ'), ('Ҏ', 'Ҏ'), ('Ґ', 'Ґ'), ('Ғ', 'Ғ'), ('Ҕ', 'Ҕ'),
+  ('Җ', 'Җ'), ('Ҙ', 'Ҙ'), ('Қ', 'Қ'), ('Ҝ', 'Ҝ'), ('Ҟ', 'Ҟ'),
+  ('Ҡ', 'Ҡ'), ('Ң', 'Ң'), ('Ҥ', 'Ҥ'), ('Ҧ', 'Ҧ'), ('Ҩ', 'Ҩ'),
+  ('Ҫ', 'Ҫ'), ('Ҭ', 'Ҭ'), ('Ү', 'Ү'), ('Ұ', 'Ұ'), ('Ҳ', 'Ҳ'),
+  ('Ҵ', 'Ҵ'), ('Ҷ', 'Ҷ'), ('Ҹ', 'Ҹ'), ('Һ', 'Һ'), ('Ҽ', 'Ҽ'),
+  ('Ҿ', 'Ҿ'), ('Ӏ', 'Ӂ'), ('Ӄ', 'Ӄ'), ('Ӆ', 'Ӆ'), ('Ӈ', 'Ӈ'),
+  ('Ӊ', 'Ӊ'), ('Ӌ', 'Ӌ'), ('Ӎ', 'Ӎ'), ('Ӑ', 'Ӑ'), ('Ӓ', 'Ӓ'),
+  ('Ӕ', 'Ӕ'), ('Ӗ', 'Ӗ'), ('Ә', 'Ә'), ('Ӛ', 'Ӛ'), ('Ӝ', 'Ӝ'),
+  ('Ӟ', 'Ӟ'), ('Ӡ', 'Ӡ'), ('Ӣ', 'Ӣ'), ('Ӥ', 'Ӥ'), ('Ӧ', 'Ӧ'),
+  ('Ө', 'Ө'), ('Ӫ', 'Ӫ'), ('Ӭ', 'Ӭ'), ('Ӯ', 'Ӯ'), ('Ӱ', 'Ӱ'),
+  ('Ӳ', 'Ӳ'), ('Ӵ', 'Ӵ'), ('Ӷ', 'Ӷ'), ('Ӹ', 'Ӹ'), ('Ӻ', 'Ӻ'),
+  ('Ӽ', 'Ӽ'), ('Ӿ', 'Ӿ'), ('Ԁ', 'Ԁ'), ('Ԃ', 'Ԃ'), ('Ԅ', 'Ԅ'),
+  ('Ԇ', 'Ԇ'), ('Ԉ', 'Ԉ'), ('Ԋ', 'Ԋ'), ('Ԍ', 'Ԍ'), ('Ԏ', 'Ԏ'),
+  ('Ԑ', 'Ԑ'), ('Ԓ', 'Ԓ'), ('Ԕ', 'Ԕ'), ('Ԗ', 'Ԗ'), ('Ԙ', 'Ԙ'),
+  ('Ԛ', 'Ԛ'), ('Ԝ', 'Ԝ'), ('Ԟ', 'Ԟ'), ('Ԡ', 'Ԡ'), ('Ԣ', 'Ԣ'),
+  ('Ԥ', 'Ԥ'), ('Ԧ', 'Ԧ'), ('Ԩ', 'Ԩ'), ('Ԫ', 'Ԫ'), ('Ԭ', 'Ԭ'),
+  ('Ԯ', 'Ԯ'), ('Ա', 'Ֆ'), ('Ⴀ', 'Ⴥ'), ('Ⴧ', 'Ⴧ'), ('Ⴭ', 'Ⴭ'),
+  ('Ꭰ', 'Ᏽ'), ('Ḁ', 'Ḁ'), ('Ḃ', 'Ḃ'), ('Ḅ', 'Ḅ'),
+  ('Ḇ', 'Ḇ'), ('Ḉ', 'Ḉ'), ('Ḋ', 'Ḋ'), ('Ḍ', 'Ḍ'),
+  ('Ḏ', 'Ḏ'), ('Ḑ', 'Ḑ'), ('Ḓ', 'Ḓ'), ('Ḕ', 'Ḕ'),
+  ('Ḗ', 'Ḗ'), ('Ḙ', 'Ḙ'), ('Ḛ', 'Ḛ'), ('Ḝ', 'Ḝ'),
+  ('Ḟ', 'Ḟ'), ('Ḡ', 'Ḡ'), ('Ḣ', 'Ḣ'), ('Ḥ', 'Ḥ'),
+  ('Ḧ', 'Ḧ'), ('Ḩ', 'Ḩ'), ('Ḫ', 'Ḫ'), ('Ḭ', 'Ḭ'),
+  ('Ḯ', 'Ḯ'), ('Ḱ', 'Ḱ'), ('Ḳ', 'Ḳ'), ('Ḵ', 'Ḵ'),
+  ('Ḷ', 'Ḷ'), ('Ḹ', 'Ḹ'), ('Ḻ', 'Ḻ'), ('Ḽ', 'Ḽ'),
+  ('Ḿ', 'Ḿ'), ('Ṁ', 'Ṁ'), ('Ṃ', 'Ṃ'), ('Ṅ', 'Ṅ'),
+  ('Ṇ', 'Ṇ'), ('Ṉ', 'Ṉ'), ('Ṋ', 'Ṋ'), ('Ṍ', 'Ṍ'),
+  ('Ṏ', 'Ṏ'), ('Ṑ', 'Ṑ'), ('Ṓ', 'Ṓ'), ('Ṕ', 'Ṕ'),
+  ('Ṗ', 'Ṗ'), ('Ṙ', 'Ṙ'), ('Ṛ', 'Ṛ'), ('Ṝ', 'Ṝ'),
+  ('Ṟ', 'Ṟ'), ('Ṡ', 'Ṡ'), ('Ṣ', 'Ṣ'), ('Ṥ', 'Ṥ'),
+  ('Ṧ', 'Ṧ'), ('Ṩ', 'Ṩ'), ('Ṫ', 'Ṫ'), ('Ṭ', 'Ṭ'),
+  ('Ṯ', 'Ṯ'), ('Ṱ', 'Ṱ'), ('Ṳ', 'Ṳ'), ('Ṵ', 'Ṵ'),
+  ('Ṷ', 'Ṷ'), ('Ṹ', 'Ṹ'), ('Ṻ', 'Ṻ'), ('Ṽ', 'Ṽ'),
+  ('Ṿ', 'Ṿ'), ('Ẁ', 'Ẁ'), ('Ẃ', 'Ẃ'), ('Ẅ', 'Ẅ'),
+  ('Ẇ', 'Ẇ'), ('Ẉ', 'Ẉ'), ('Ẋ', 'Ẋ'), ('Ẍ', 'Ẍ'),
+  ('Ẏ', 'Ẏ'), ('Ẑ', 'Ẑ'), ('Ẓ', 'Ẓ'), ('Ẕ', 'Ẕ'),
+  ('ẞ', 'ẞ'), ('Ạ', 'Ạ'), ('Ả', 'Ả'), ('Ấ', 'Ấ'),
+  ('Ầ', 'Ầ'), ('Ẩ', 'Ẩ'), ('Ẫ', 'Ẫ'), ('Ậ', 'Ậ'),
+  ('Ắ', 'Ắ'), ('Ằ', 'Ằ'), ('Ẳ', 'Ẳ'), ('Ẵ', 'Ẵ'),
+  ('Ặ', 'Ặ'), ('Ẹ', 'Ẹ'), ('Ẻ', 'Ẻ'), ('Ẽ', 'Ẽ'),
+  ('Ế', 'Ế'), ('Ề', 'Ề'), ('Ể', 'Ể'), ('Ễ', 'Ễ'),
+  ('Ệ', 'Ệ'), ('Ỉ', 'Ỉ'), ('Ị', 'Ị'), ('Ọ', 'Ọ'),
+  ('Ỏ', 'Ỏ'), ('Ố', 'Ố'), ('Ồ', 'Ồ'), ('Ổ', 'Ổ'),
+  ('Ỗ', 'Ỗ'), ('Ộ', 'Ộ'), ('Ớ', 'Ớ'), ('Ờ', 'Ờ'),
+  ('Ở', 'Ở'), ('Ỡ', 'Ỡ'), ('Ợ', 'Ợ'), ('Ụ', 'Ụ'),
+  ('Ủ', 'Ủ'), ('Ứ', 'Ứ'), ('Ừ', 'Ừ'), ('Ử', 'Ử'),
+  ('Ữ', 'Ữ'), ('Ự', 'Ự'), ('Ỳ', 'Ỳ'), ('Ỵ', 'Ỵ'),
+  ('Ỷ', 'Ỷ'), ('Ỹ', 'Ỹ'), ('Ỻ', 'Ỻ'), ('Ỽ', 'Ỽ'),
+  ('Ỿ', 'Ỿ'), ('Ἀ', 'Ἇ'), ('Ἐ', 'Ἕ'), ('Ἠ', 'Ἧ'),
+  ('Ἰ', 'Ἷ'), ('Ὀ', 'Ὅ'), ('Ὑ', 'Ὑ'), ('Ὓ', 'Ὓ'),
+  ('Ὕ', 'Ὕ'), ('Ὗ', 'Ὗ'), ('Ὠ', 'Ὧ'), ('ᾈ', 'ᾏ'),
+  ('ᾘ', 'ᾟ'), ('ᾨ', 'ᾯ'), ('Ᾰ', 'ᾼ'), ('Ὲ', 'ῌ'),
+  ('Ῐ', 'Ί'), ('Ῠ', 'Ῥ'), ('Ὸ', 'ῼ'), ('ℂ', 'ℂ'),
+  ('ℇ', 'ℇ'), ('ℋ', 'ℍ'), ('ℐ', 'ℒ'), ('ℕ', 'ℕ'),
+  ('ℙ', 'ℝ'), ('ℤ', 'ℤ'), ('Ω', 'Ω'), ('ℨ', 'ℨ'),
+  ('K', 'ℭ'), ('ℰ', 'ℳ'), ('ℾ', 'ℿ'), ('ⅅ', 'ⅅ'),
+  ('Ⅰ', 'Ⅿ'), ('Ↄ', 'Ↄ'), ('Ⓐ', 'Ⓩ'), ('Ⰰ', 'Ⱞ'),
+  ('Ⱡ', 'Ⱡ'), ('Ɫ', 'Ɽ'), ('Ⱨ', 'Ⱨ'), ('Ⱪ', 'Ⱪ'),
+  ('Ⱬ', 'Ⱬ'), ('Ɑ', 'Ɒ'), ('Ⱳ', 'Ⱳ'), ('Ⱶ', 'Ⱶ'),
+  ('Ȿ', 'Ⲁ'), ('Ⲃ', 'Ⲃ'), ('Ⲅ', 'Ⲅ'), ('Ⲇ', 'Ⲇ'),
+  ('Ⲉ', 'Ⲉ'), ('Ⲋ', 'Ⲋ'), ('Ⲍ', 'Ⲍ'), ('Ⲏ', 'Ⲏ'),
+  ('Ⲑ', 'Ⲑ'), ('Ⲓ', 'Ⲓ'), ('Ⲕ', 'Ⲕ'), ('Ⲗ', 'Ⲗ'),
+  ('Ⲙ', 'Ⲙ'), ('Ⲛ', 'Ⲛ'), ('Ⲝ', 'Ⲝ'), ('Ⲟ', 'Ⲟ'),
+  ('Ⲡ', 'Ⲡ'), ('Ⲣ', 'Ⲣ'), ('Ⲥ', 'Ⲥ'), ('Ⲧ', 'Ⲧ'),
+  ('Ⲩ', 'Ⲩ'), ('Ⲫ', 'Ⲫ'), ('Ⲭ', 'Ⲭ'), ('Ⲯ', 'Ⲯ'),
+  ('Ⲱ', 'Ⲱ'), ('Ⲳ', 'Ⲳ'), ('Ⲵ', 'Ⲵ'), ('Ⲷ', 'Ⲷ'),
+  ('Ⲹ', 'Ⲹ'), ('Ⲻ', 'Ⲻ'), ('Ⲽ', 'Ⲽ'), ('Ⲿ', 'Ⲿ'),
+  ('Ⳁ', 'Ⳁ'), ('Ⳃ', 'Ⳃ'), ('Ⳅ', 'Ⳅ'), ('Ⳇ', 'Ⳇ'),
+  ('Ⳉ', 'Ⳉ'), ('Ⳋ', 'Ⳋ'), ('Ⳍ', 'Ⳍ'), ('Ⳏ', 'Ⳏ'),
+  ('Ⳑ', 'Ⳑ'), ('Ⳓ', 'Ⳓ'), ('Ⳕ', 'Ⳕ'), ('Ⳗ', 'Ⳗ'),
+  ('Ⳙ', 'Ⳙ'), ('Ⳛ', 'Ⳛ'), ('Ⳝ', 'Ⳝ'), ('Ⳟ', 'Ⳟ'),
+  ('Ⳡ', 'Ⳡ'), ('Ⳣ', 'Ⳣ'), ('Ⳬ', 'Ⳬ'), ('Ⳮ', 'Ⳮ'),
+  ('Ⳳ', 'Ⳳ'), ('Ꙁ', 'Ꙁ'), ('Ꙃ', 'Ꙃ'), ('Ꙅ', 'Ꙅ'),
+  ('Ꙇ', 'Ꙇ'), ('Ꙉ', 'Ꙉ'), ('Ꙋ', 'Ꙋ'), ('Ꙍ', 'Ꙍ'),
+  ('Ꙏ', 'Ꙏ'), ('Ꙑ', 'Ꙑ'), ('Ꙓ', 'Ꙓ'), ('Ꙕ', 'Ꙕ'),
+  ('Ꙗ', 'Ꙗ'), ('Ꙙ', 'Ꙙ'), ('Ꙛ', 'Ꙛ'), ('Ꙝ', 'Ꙝ'),
+  ('Ꙟ', 'Ꙟ'), ('Ꙡ', 'Ꙡ'), ('Ꙣ', 'Ꙣ'), ('Ꙥ', 'Ꙥ'),
+  ('Ꙧ', 'Ꙧ'), ('Ꙩ', 'Ꙩ'), ('Ꙫ', 'Ꙫ'), ('Ꙭ', 'Ꙭ'),
+  ('Ꚁ', 'Ꚁ'), ('Ꚃ', 'Ꚃ'), ('Ꚅ', 'Ꚅ'), ('Ꚇ', 'Ꚇ'),
+  ('Ꚉ', 'Ꚉ'), ('Ꚋ', 'Ꚋ'), ('Ꚍ', 'Ꚍ'), ('Ꚏ', 'Ꚏ'),
+  ('Ꚑ', 'Ꚑ'), ('Ꚓ', 'Ꚓ'), ('Ꚕ', 'Ꚕ'), ('Ꚗ', 'Ꚗ'),
+  ('Ꚙ', 'Ꚙ'), ('Ꚛ', 'Ꚛ'), ('Ꜣ', 'Ꜣ'), ('Ꜥ', 'Ꜥ'),
+  ('Ꜧ', 'Ꜧ'), ('Ꜩ', 'Ꜩ'), ('Ꜫ', 'Ꜫ'), ('Ꜭ', 'Ꜭ'),
+  ('Ꜯ', 'Ꜯ'), ('Ꜳ', 'Ꜳ'), ('Ꜵ', 'Ꜵ'), ('Ꜷ', 'Ꜷ'),
+  ('Ꜹ', 'Ꜹ'), ('Ꜻ', 'Ꜻ'), ('Ꜽ', 'Ꜽ'), ('Ꜿ', 'Ꜿ'),
+  ('Ꝁ', 'Ꝁ'), ('Ꝃ', 'Ꝃ'), ('Ꝅ', 'Ꝅ'), ('Ꝇ', 'Ꝇ'),
+  ('Ꝉ', 'Ꝉ'), ('Ꝋ', 'Ꝋ'), ('Ꝍ', 'Ꝍ'), ('Ꝏ', 'Ꝏ'),
+  ('Ꝑ', 'Ꝑ'), ('Ꝓ', 'Ꝓ'), ('Ꝕ', 'Ꝕ'), ('Ꝗ', 'Ꝗ'),
+  ('Ꝙ', 'Ꝙ'), ('Ꝛ', 'Ꝛ'), ('Ꝝ', 'Ꝝ'), ('Ꝟ', 'Ꝟ'),
+  ('Ꝡ', 'Ꝡ'), ('Ꝣ', 'Ꝣ'), ('Ꝥ', 'Ꝥ'), ('Ꝧ', 'Ꝧ'),
+  ('Ꝩ', 'Ꝩ'), ('Ꝫ', 'Ꝫ'), ('Ꝭ', 'Ꝭ'), ('Ꝯ', 'Ꝯ'),
+  ('Ꝺ', 'Ꝺ'), ('Ꝼ', 'Ꝼ'), ('Ᵹ', 'Ꝿ'), ('Ꞁ', 'Ꞁ'),
+  ('Ꞃ', 'Ꞃ'), ('Ꞅ', 'Ꞅ'), ('Ꞇ', 'Ꞇ'), ('Ꞌ', 'Ꞌ'),
+  ('Ɥ', 'Ɥ'), ('Ꞑ', 'Ꞑ'), ('Ꞓ', 'Ꞓ'), ('Ꞗ', 'Ꞗ'),
+  ('Ꞙ', 'Ꞙ'), ('Ꞛ', 'Ꞛ'), ('Ꞝ', 'Ꞝ'), ('Ꞟ', 'Ꞟ'),
+  ('Ꞡ', 'Ꞡ'), ('Ꞣ', 'Ꞣ'), ('Ꞥ', 'Ꞥ'), ('Ꞧ', 'Ꞧ'),
+  ('Ꞩ', 'Ꞩ'), ('Ɦ', 'Ɪ'), ('Ʞ', 'Ꞵ'), ('Ꞷ', 'Ꞷ'),
+  ('Ꞹ', 'Ꞹ'), ('\u{a7ba}', '\u{a7ba}'), ('\u{a7bc}', '\u{a7bc}'),
+  ('\u{a7be}', '\u{a7be}'), ('\u{a7c2}', '\u{a7c2}'),
+  ('\u{a7c4}', '\u{a7c6}'), ('A', 'Z'), ('𐐀', '𐐧'),
+  ('𐒰', '𐓓'), ('𐲀', '𐲲'), ('𑢠', '𑢿'), ('𖹀', '𖹟'),
+  ('𝐀', '𝐙'), ('𝐴', '𝑍'), ('𝑨', '𝒁'), ('𝒜', '𝒜'),
+  ('𝒞', '𝒟'), ('𝒢', '𝒢'), ('𝒥', '𝒦'), ('𝒩', '𝒬'),
+  ('𝒮', '𝒵'), ('𝓐', '𝓩'), ('𝔄', '𝔅'), ('𝔇', '𝔊'),
+  ('𝔍', '𝔔'), ('𝔖', '𝔜'), ('𝔸', '𝔹'), ('𝔻', '𝔾'),
+  ('𝕀', '𝕄'), ('𝕆', '𝕆'), ('𝕊', '𝕐'), ('𝕬', '𝖅'),
+  ('𝖠', '𝖹'), ('𝗔', '𝗭'), ('𝘈', '𝘡'), ('𝘼', '𝙕'),
+  ('𝙰', '𝚉'), ('𝚨', '𝛀'), ('𝛢', '𝛺'), ('𝜜', '𝜴'),
+  ('𝝖', '𝝮'), ('𝞐', '𝞨'), ('𝟊', '𝟊'), ('𞤀', '𞤡'),
+  ('🄰', '🅉'), ('🅐', '🅩'), ('🅰', '🆉'),
+];
+
+
\ No newline at end of file diff --git a/target/doc/src/regex_syntax/unicode_tables/word_break.rs.html b/target/doc/src/regex_syntax/unicode_tables/word_break.rs.html new file mode 100644 index 0000000..8f9111d --- /dev/null +++ b/target/doc/src/regex_syntax/unicode_tables/word_break.rs.html @@ -0,0 +1,729 @@ +word_break.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+
+// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
+//
+//  ucd-generate word-break /tmp/ucd-12.1.0/ --chars
+//
+// ucd-generate is available on crates.io.
+
+pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
+  ("ALetter", ALETTER), ("CR", CR), ("Double_Quote", DOUBLE_QUOTE),
+  ("Extend", EXTEND), ("ExtendNumLet", EXTENDNUMLET), ("Format", FORMAT),
+  ("Hebrew_Letter", HEBREW_LETTER), ("Katakana", KATAKANA), ("LF", LF),
+  ("MidLetter", MIDLETTER), ("MidNum", MIDNUM), ("MidNumLet", MIDNUMLET),
+  ("Newline", NEWLINE), ("Numeric", NUMERIC),
+  ("Regional_Indicator", REGIONAL_INDICATOR), ("Single_Quote", SINGLE_QUOTE),
+  ("WSegSpace", WSEGSPACE), ("ZWJ", ZWJ),
+];
+
+pub const ALETTER: &'static [(char, char)] = &[
+  ('A', 'Z'), ('a', 'z'), ('ª', 'ª'), ('µ', 'µ'), ('º', 'º'),
+  ('À', 'Ö'), ('Ø', 'ö'), ('ø', '˗'), ('˞', 'ˤ'), ('ˬ', '˿'),
+  ('Ͱ', 'ʹ'), ('Ͷ', 'ͷ'), ('ͺ', 'ͽ'), ('Ϳ', 'Ϳ'), ('Ά', 'Ά'),
+  ('Έ', 'Ί'), ('Ό', 'Ό'), ('Ύ', 'Ρ'), ('Σ', 'ϵ'), ('Ϸ', 'ҁ'),
+  ('Ҋ', 'ԯ'), ('Ա', 'Ֆ'), ('ՙ', 'ՙ'), ('՛', '՜'), ('՞', '՞'),
+  ('ՠ', 'ֈ'), ('׳', '׳'), ('ؠ', 'ي'), ('ٮ', 'ٯ'), ('ٱ', 'ۓ'),
+  ('ە', 'ە'), ('ۥ', 'ۦ'), ('ۮ', 'ۯ'), ('ۺ', 'ۼ'), ('ۿ', 'ۿ'),
+  ('ܐ', 'ܐ'), ('ܒ', 'ܯ'), ('ݍ', 'ޥ'), ('ޱ', 'ޱ'), ('ߊ', 'ߪ'),
+  ('ߴ', 'ߵ'), ('ߺ', 'ߺ'), ('ࠀ', 'ࠕ'), ('ࠚ', 'ࠚ'), ('ࠤ', 'ࠤ'),
+  ('ࠨ', 'ࠨ'), ('ࡀ', 'ࡘ'), ('ࡠ', 'ࡪ'), ('ࢠ', 'ࢴ'),
+  ('ࢶ', 'ࢽ'), ('ऄ', 'ह'), ('ऽ', 'ऽ'), ('ॐ', 'ॐ'),
+  ('क़', 'ॡ'), ('ॱ', 'ঀ'), ('অ', 'ঌ'), ('এ', 'ঐ'),
+  ('ও', 'ন'), ('প', 'র'), ('ল', 'ল'), ('শ', 'হ'),
+  ('ঽ', 'ঽ'), ('ৎ', 'ৎ'), ('ড়', 'ঢ়'), ('য়', 'ৡ'),
+  ('ৰ', 'ৱ'), ('ৼ', 'ৼ'), ('ਅ', 'ਊ'), ('ਏ', 'ਐ'),
+  ('ਓ', 'ਨ'), ('ਪ', 'ਰ'), ('ਲ', 'ਲ਼'), ('ਵ', 'ਸ਼'),
+  ('ਸ', 'ਹ'), ('ਖ਼', 'ੜ'), ('ਫ਼', 'ਫ਼'), ('ੲ', 'ੴ'),
+  ('અ', 'ઍ'), ('એ', 'ઑ'), ('ઓ', 'ન'), ('પ', 'ર'),
+  ('લ', 'ળ'), ('વ', 'હ'), ('ઽ', 'ઽ'), ('ૐ', 'ૐ'),
+  ('ૠ', 'ૡ'), ('ૹ', 'ૹ'), ('ଅ', 'ଌ'), ('ଏ', 'ଐ'),
+  ('ଓ', 'ନ'), ('ପ', 'ର'), ('ଲ', 'ଳ'), ('ଵ', 'ହ'),
+  ('ଽ', 'ଽ'), ('ଡ଼', 'ଢ଼'), ('ୟ', 'ୡ'), ('ୱ', 'ୱ'),
+  ('ஃ', 'ஃ'), ('அ', 'ஊ'), ('எ', 'ஐ'), ('ஒ', 'க'),
+  ('ங', 'ச'), ('ஜ', 'ஜ'), ('ஞ', 'ட'), ('ண', 'த'),
+  ('ந', 'ப'), ('ம', 'ஹ'), ('ௐ', 'ௐ'), ('అ', 'ఌ'),
+  ('ఎ', 'ఐ'), ('ఒ', 'న'), ('ప', 'హ'), ('ఽ', 'ఽ'),
+  ('ౘ', 'ౚ'), ('ౠ', 'ౡ'), ('ಀ', 'ಀ'), ('ಅ', 'ಌ'),
+  ('ಎ', 'ಐ'), ('ಒ', 'ನ'), ('ಪ', 'ಳ'), ('ವ', 'ಹ'),
+  ('ಽ', 'ಽ'), ('ೞ', 'ೞ'), ('ೠ', 'ೡ'), ('ೱ', 'ೲ'),
+  ('അ', 'ഌ'), ('എ', 'ഐ'), ('ഒ', 'ഺ'), ('ഽ', 'ഽ'),
+  ('ൎ', 'ൎ'), ('ൔ', 'ൖ'), ('ൟ', 'ൡ'), ('ൺ', 'ൿ'),
+  ('අ', 'ඖ'), ('ක', 'න'), ('ඳ', 'ර'), ('ල', 'ල'),
+  ('ව', 'ෆ'), ('ༀ', 'ༀ'), ('ཀ', 'ཇ'), ('ཉ', 'ཬ'),
+  ('ྈ', 'ྌ'), ('Ⴀ', 'Ⴥ'), ('Ⴧ', 'Ⴧ'), ('Ⴭ', 'Ⴭ'),
+  ('ა', 'ჺ'), ('ჼ', 'ቈ'), ('ቊ', 'ቍ'), ('ቐ', 'ቖ'),
+  ('ቘ', 'ቘ'), ('ቚ', 'ቝ'), ('በ', 'ኈ'), ('ኊ', 'ኍ'),
+  ('ነ', 'ኰ'), ('ኲ', 'ኵ'), ('ኸ', 'ኾ'), ('ዀ', 'ዀ'),
+  ('ዂ', 'ዅ'), ('ወ', 'ዖ'), ('ዘ', 'ጐ'), ('ጒ', 'ጕ'),
+  ('ጘ', 'ፚ'), ('ᎀ', 'ᎏ'), ('Ꭰ', 'Ᏽ'), ('ᏸ', 'ᏽ'),
+  ('ᐁ', 'ᙬ'), ('ᙯ', 'ᙿ'), ('ᚁ', 'ᚚ'), ('ᚠ', 'ᛪ'),
+  ('ᛮ', 'ᛸ'), ('ᜀ', 'ᜌ'), ('ᜎ', 'ᜑ'), ('ᜠ', 'ᜱ'),
+  ('ᝀ', 'ᝑ'), ('ᝠ', 'ᝬ'), ('ᝮ', 'ᝰ'), ('ᠠ', 'ᡸ'),
+  ('ᢀ', 'ᢄ'), ('ᢇ', 'ᢨ'), ('ᢪ', 'ᢪ'), ('ᢰ', 'ᣵ'),
+  ('ᤀ', 'ᤞ'), ('ᨀ', 'ᨖ'), ('ᬅ', 'ᬳ'), ('ᭅ', 'ᭋ'),
+  ('ᮃ', 'ᮠ'), ('ᮮ', 'ᮯ'), ('ᮺ', 'ᯥ'), ('ᰀ', 'ᰣ'),
+  ('ᱍ', 'ᱏ'), ('ᱚ', 'ᱽ'), ('ᲀ', 'ᲈ'), ('Ა', 'Ჺ'),
+  ('Ჽ', 'Ჿ'), ('ᳩ', 'ᳬ'), ('ᳮ', 'ᳳ'), ('ᳵ', 'ᳶ'),
+  ('\u{1cfa}', '\u{1cfa}'), ('ᴀ', 'ᶿ'), ('Ḁ', 'ἕ'), ('Ἐ', 'Ἕ'),
+  ('ἠ', 'ὅ'), ('Ὀ', 'Ὅ'), ('ὐ', 'ὗ'), ('Ὑ', 'Ὑ'),
+  ('Ὓ', 'Ὓ'), ('Ὕ', 'Ὕ'), ('Ὗ', 'ώ'), ('ᾀ', 'ᾴ'),
+  ('ᾶ', 'ᾼ'), ('ι', 'ι'), ('ῂ', 'ῄ'), ('ῆ', 'ῌ'),
+  ('ῐ', 'ΐ'), ('ῖ', 'Ί'), ('ῠ', 'Ῥ'), ('ῲ', 'ῴ'),
+  ('ῶ', 'ῼ'), ('ⁱ', 'ⁱ'), ('ⁿ', 'ⁿ'), ('ₐ', 'ₜ'),
+  ('ℂ', 'ℂ'), ('ℇ', 'ℇ'), ('ℊ', 'ℓ'), ('ℕ', 'ℕ'),
+  ('ℙ', 'ℝ'), ('ℤ', 'ℤ'), ('Ω', 'Ω'), ('ℨ', 'ℨ'),
+  ('K', 'ℭ'), ('ℯ', 'ℹ'), ('ℼ', 'ℿ'), ('ⅅ', 'ⅉ'),
+  ('ⅎ', 'ⅎ'), ('Ⅰ', 'ↈ'), ('Ⓐ', 'ⓩ'), ('Ⰰ', 'Ⱞ'),
+  ('ⰰ', 'ⱞ'), ('Ⱡ', 'ⳤ'), ('Ⳬ', 'ⳮ'), ('Ⳳ', 'ⳳ'),
+  ('ⴀ', 'ⴥ'), ('ⴧ', 'ⴧ'), ('ⴭ', 'ⴭ'), ('ⴰ', 'ⵧ'),
+  ('ⵯ', 'ⵯ'), ('ⶀ', 'ⶖ'), ('ⶠ', 'ⶦ'), ('ⶨ', 'ⶮ'),
+  ('ⶰ', 'ⶶ'), ('ⶸ', 'ⶾ'), ('ⷀ', 'ⷆ'), ('ⷈ', 'ⷎ'),
+  ('ⷐ', 'ⷖ'), ('ⷘ', 'ⷞ'), ('ⸯ', 'ⸯ'), ('々', '々'),
+  ('〻', '〼'), ('ㄅ', 'ㄯ'), ('ㄱ', 'ㆎ'), ('ㆠ', 'ㆺ'),
+  ('ꀀ', 'ꒌ'), ('ꓐ', 'ꓽ'), ('ꔀ', 'ꘌ'), ('ꘐ', 'ꘟ'),
+  ('ꘪ', 'ꘫ'), ('Ꙁ', 'ꙮ'), ('ꙿ', 'ꚝ'), ('ꚠ', 'ꛯ'),
+  ('ꜗ', '\u{a7bf}'), ('\u{a7c2}', '\u{a7c6}'), ('ꟷ', 'ꠁ'),
+  ('ꠃ', 'ꠅ'), ('ꠇ', 'ꠊ'), ('ꠌ', 'ꠢ'), ('ꡀ', 'ꡳ'),
+  ('ꢂ', 'ꢳ'), ('ꣲ', 'ꣷ'), ('ꣻ', 'ꣻ'), ('ꣽ', 'ꣾ'),
+  ('ꤊ', 'ꤥ'), ('ꤰ', 'ꥆ'), ('ꥠ', 'ꥼ'), ('ꦄ', 'ꦲ'),
+  ('ꧏ', 'ꧏ'), ('ꨀ', 'ꨨ'), ('ꩀ', 'ꩂ'), ('ꩄ', 'ꩋ'),
+  ('ꫠ', 'ꫪ'), ('ꫲ', 'ꫴ'), ('ꬁ', 'ꬆ'), ('ꬉ', 'ꬎ'),
+  ('ꬑ', 'ꬖ'), ('ꬠ', 'ꬦ'), ('ꬨ', 'ꬮ'), ('ꬰ', '\u{ab67}'),
+  ('ꭰ', 'ꯢ'), ('가', '힣'), ('ힰ', 'ퟆ'), ('ퟋ', 'ퟻ'),
+  ('ff', 'st'), ('ﬓ', 'ﬗ'), ('ﭐ', 'ﮱ'), ('ﯓ', 'ﴽ'),
+  ('ﵐ', 'ﶏ'), ('ﶒ', 'ﷇ'), ('ﷰ', 'ﷻ'), ('ﹰ', 'ﹴ'),
+  ('ﹶ', 'ﻼ'), ('A', 'Z'), ('a', 'z'), ('ᅠ', 'ᄒ'),
+  ('ᅡ', 'ᅦ'), ('ᅧ', 'ᅬ'), ('ᅭ', 'ᅲ'), ('ᅳ', 'ᅵ'),
+  ('𐀀', '𐀋'), ('𐀍', '𐀦'), ('𐀨', '𐀺'), ('𐀼', '𐀽'),
+  ('𐀿', '𐁍'), ('𐁐', '𐁝'), ('𐂀', '𐃺'), ('𐅀', '𐅴'),
+  ('𐊀', '𐊜'), ('𐊠', '𐋐'), ('𐌀', '𐌟'), ('𐌭', '𐍊'),
+  ('𐍐', '𐍵'), ('𐎀', '𐎝'), ('𐎠', '𐏃'), ('𐏈', '𐏏'),
+  ('𐏑', '𐏕'), ('𐐀', '𐒝'), ('𐒰', '𐓓'), ('𐓘', '𐓻'),
+  ('𐔀', '𐔧'), ('𐔰', '𐕣'), ('𐘀', '𐜶'), ('𐝀', '𐝕'),
+  ('𐝠', '𐝧'), ('𐠀', '𐠅'), ('𐠈', '𐠈'), ('𐠊', '𐠵'),
+  ('𐠷', '𐠸'), ('𐠼', '𐠼'), ('𐠿', '𐡕'), ('𐡠', '𐡶'),
+  ('𐢀', '𐢞'), ('𐣠', '𐣲'), ('𐣴', '𐣵'), ('𐤀', '𐤕'),
+  ('𐤠', '𐤹'), ('𐦀', '𐦷'), ('𐦾', '𐦿'), ('𐨀', '𐨀'),
+  ('𐨐', '𐨓'), ('𐨕', '𐨗'), ('𐨙', '𐨵'), ('𐩠', '𐩼'),
+  ('𐪀', '𐪜'), ('𐫀', '𐫇'), ('𐫉', '𐫤'), ('𐬀', '𐬵'),
+  ('𐭀', '𐭕'), ('𐭠', '𐭲'), ('𐮀', '𐮑'), ('𐰀', '𐱈'),
+  ('𐲀', '𐲲'), ('𐳀', '𐳲'), ('𐴀', '𐴣'), ('𐼀', '𐼜'),
+  ('𐼧', '𐼧'), ('𐼰', '𐽅'), ('\u{10fe0}', '\u{10ff6}'),
+  ('𑀃', '𑀷'), ('𑂃', '𑂯'), ('𑃐', '𑃨'), ('𑄃', '𑄦'),
+  ('𑅄', '𑅄'), ('𑅐', '𑅲'), ('𑅶', '𑅶'), ('𑆃', '𑆲'),
+  ('𑇁', '𑇄'), ('𑇚', '𑇚'), ('𑇜', '𑇜'), ('𑈀', '𑈑'),
+  ('𑈓', '𑈫'), ('𑊀', '𑊆'), ('𑊈', '𑊈'), ('𑊊', '𑊍'),
+  ('𑊏', '𑊝'), ('𑊟', '𑊨'), ('𑊰', '𑋞'), ('𑌅', '𑌌'),
+  ('𑌏', '𑌐'), ('𑌓', '𑌨'), ('𑌪', '𑌰'), ('𑌲', '𑌳'),
+  ('𑌵', '𑌹'), ('𑌽', '𑌽'), ('𑍐', '𑍐'), ('𑍝', '𑍡'),
+  ('𑐀', '𑐴'), ('𑑇', '𑑊'), ('\u{1145f}', '\u{1145f}'),
+  ('𑒀', '𑒯'), ('𑓄', '𑓅'), ('𑓇', '𑓇'), ('𑖀', '𑖮'),
+  ('𑗘', '𑗛'), ('𑘀', '𑘯'), ('𑙄', '𑙄'), ('𑚀', '𑚪'),
+  ('\u{116b8}', '\u{116b8}'), ('𑠀', '𑠫'), ('𑢠', '𑣟'),
+  ('𑣿', '𑣿'), ('\u{119a0}', '\u{119a7}'), ('\u{119aa}', '\u{119d0}'),
+  ('\u{119e1}', '\u{119e1}'), ('\u{119e3}', '\u{119e3}'), ('𑨀', '𑨀'),
+  ('𑨋', '𑨲'), ('𑨺', '𑨺'), ('𑩐', '𑩐'), ('𑩜', '𑪉'),
+  ('𑪝', '𑪝'), ('𑫀', '𑫸'), ('𑰀', '𑰈'), ('𑰊', '𑰮'),
+  ('𑱀', '𑱀'), ('𑱲', '𑲏'), ('𑴀', '𑴆'), ('𑴈', '𑴉'),
+  ('𑴋', '𑴰'), ('𑵆', '𑵆'), ('𑵠', '𑵥'), ('𑵧', '𑵨'),
+  ('𑵪', '𑶉'), ('𑶘', '𑶘'), ('𑻠', '𑻲'), ('𒀀', '𒎙'),
+  ('𒐀', '𒑮'), ('𒒀', '𒕃'), ('𓀀', '𓐮'), ('𔐀', '𔙆'),
+  ('𖠀', '𖨸'), ('𖩀', '𖩞'), ('𖫐', '𖫭'), ('𖬀', '𖬯'),
+  ('𖭀', '𖭃'), ('𖭣', '𖭷'), ('𖭽', '𖮏'), ('𖹀', '𖹿'),
+  ('𖼀', '\u{16f4a}'), ('𖽐', '𖽐'), ('𖾓', '𖾟'), ('𖿠', '𖿡'),
+  ('\u{16fe3}', '\u{16fe3}'), ('𛰀', '𛱪'), ('𛱰', '𛱼'),
+  ('𛲀', '𛲈'), ('𛲐', '𛲙'), ('𝐀', '𝑔'), ('𝑖', '𝒜'),
+  ('𝒞', '𝒟'), ('𝒢', '𝒢'), ('𝒥', '𝒦'), ('𝒩', '𝒬'),
+  ('𝒮', '𝒹'), ('𝒻', '𝒻'), ('𝒽', '𝓃'), ('𝓅', '𝔅'),
+  ('𝔇', '𝔊'), ('𝔍', '𝔔'), ('𝔖', '𝔜'), ('𝔞', '𝔹'),
+  ('𝔻', '𝔾'), ('𝕀', '𝕄'), ('𝕆', '𝕆'), ('𝕊', '𝕐'),
+  ('𝕒', '𝚥'), ('𝚨', '𝛀'), ('𝛂', '𝛚'), ('𝛜', '𝛺'),
+  ('𝛼', '𝜔'), ('𝜖', '𝜴'), ('𝜶', '𝝎'), ('𝝐', '𝝮'),
+  ('𝝰', '𝞈'), ('𝞊', '𝞨'), ('𝞪', '𝟂'), ('𝟄', '𝟋'),
+  ('\u{1e100}', '\u{1e12c}'), ('\u{1e137}', '\u{1e13d}'),
+  ('\u{1e14e}', '\u{1e14e}'), ('\u{1e2c0}', '\u{1e2eb}'), ('𞠀', '𞣄'),
+  ('𞤀', '𞥃'), ('\u{1e94b}', '\u{1e94b}'), ('𞸀', '𞸃'),
+  ('𞸅', '𞸟'), ('𞸡', '𞸢'), ('𞸤', '𞸤'), ('𞸧', '𞸧'),
+  ('𞸩', '𞸲'), ('𞸴', '𞸷'), ('𞸹', '𞸹'), ('𞸻', '𞸻'),
+  ('𞹂', '𞹂'), ('𞹇', '𞹇'), ('𞹉', '𞹉'), ('𞹋', '𞹋'),
+  ('𞹍', '𞹏'), ('𞹑', '𞹒'), ('𞹔', '𞹔'), ('𞹗', '𞹗'),
+  ('𞹙', '𞹙'), ('𞹛', '𞹛'), ('𞹝', '𞹝'), ('𞹟', '𞹟'),
+  ('𞹡', '𞹢'), ('𞹤', '𞹤'), ('𞹧', '𞹪'), ('𞹬', '𞹲'),
+  ('𞹴', '𞹷'), ('𞹹', '𞹼'), ('𞹾', '𞹾'), ('𞺀', '𞺉'),
+  ('𞺋', '𞺛'), ('𞺡', '𞺣'), ('𞺥', '𞺩'), ('𞺫', '𞺻'),
+  ('🄰', '🅉'), ('🅐', '🅩'), ('🅰', '🆉'),
+];
+
+pub const CR: &'static [(char, char)] = &[
+  ('\r', '\r'),
+];
+
+pub const DOUBLE_QUOTE: &'static [(char, char)] = &[
+  ('\"', '\"'),
+];
+
+pub const EXTEND: &'static [(char, char)] = &[
+  ('\u{300}', '\u{36f}'), ('\u{483}', '\u{489}'), ('\u{591}', '\u{5bd}'),
+  ('\u{5bf}', '\u{5bf}'), ('\u{5c1}', '\u{5c2}'), ('\u{5c4}', '\u{5c5}'),
+  ('\u{5c7}', '\u{5c7}'), ('\u{610}', '\u{61a}'), ('\u{64b}', '\u{65f}'),
+  ('\u{670}', '\u{670}'), ('\u{6d6}', '\u{6dc}'), ('\u{6df}', '\u{6e4}'),
+  ('\u{6e7}', '\u{6e8}'), ('\u{6ea}', '\u{6ed}'), ('\u{711}', '\u{711}'),
+  ('\u{730}', '\u{74a}'), ('\u{7a6}', '\u{7b0}'), ('\u{7eb}', '\u{7f3}'),
+  ('\u{7fd}', '\u{7fd}'), ('\u{816}', '\u{819}'), ('\u{81b}', '\u{823}'),
+  ('\u{825}', '\u{827}'), ('\u{829}', '\u{82d}'), ('\u{859}', '\u{85b}'),
+  ('\u{8d3}', '\u{8e1}'), ('\u{8e3}', 'ः'), ('\u{93a}', '\u{93c}'),
+  ('ा', 'ॏ'), ('\u{951}', '\u{957}'), ('\u{962}', '\u{963}'),
+  ('\u{981}', 'ঃ'), ('\u{9bc}', '\u{9bc}'), ('\u{9be}', '\u{9c4}'),
+  ('ে', 'ৈ'), ('ো', '\u{9cd}'), ('\u{9d7}', '\u{9d7}'),
+  ('\u{9e2}', '\u{9e3}'), ('\u{9fe}', '\u{9fe}'), ('\u{a01}', 'ਃ'),
+  ('\u{a3c}', '\u{a3c}'), ('ਾ', '\u{a42}'), ('\u{a47}', '\u{a48}'),
+  ('\u{a4b}', '\u{a4d}'), ('\u{a51}', '\u{a51}'), ('\u{a70}', '\u{a71}'),
+  ('\u{a75}', '\u{a75}'), ('\u{a81}', 'ઃ'), ('\u{abc}', '\u{abc}'),
+  ('ા', '\u{ac5}'), ('\u{ac7}', 'ૉ'), ('ો', '\u{acd}'),
+  ('\u{ae2}', '\u{ae3}'), ('\u{afa}', '\u{aff}'), ('\u{b01}', 'ଃ'),
+  ('\u{b3c}', '\u{b3c}'), ('\u{b3e}', '\u{b44}'), ('େ', 'ୈ'),
+  ('ୋ', '\u{b4d}'), ('\u{b56}', '\u{b57}'), ('\u{b62}', '\u{b63}'),
+  ('\u{b82}', '\u{b82}'), ('\u{bbe}', 'ூ'), ('ெ', 'ை'),
+  ('ொ', '\u{bcd}'), ('\u{bd7}', '\u{bd7}'), ('\u{c00}', '\u{c04}'),
+  ('\u{c3e}', 'ౄ'), ('\u{c46}', '\u{c48}'), ('\u{c4a}', '\u{c4d}'),
+  ('\u{c55}', '\u{c56}'), ('\u{c62}', '\u{c63}'), ('\u{c81}', 'ಃ'),
+  ('\u{cbc}', '\u{cbc}'), ('ಾ', 'ೄ'), ('\u{cc6}', 'ೈ'),
+  ('ೊ', '\u{ccd}'), ('\u{cd5}', '\u{cd6}'), ('\u{ce2}', '\u{ce3}'),
+  ('\u{d00}', 'ഃ'), ('\u{d3b}', '\u{d3c}'), ('\u{d3e}', '\u{d44}'),
+  ('െ', 'ൈ'), ('ൊ', '\u{d4d}'), ('\u{d57}', '\u{d57}'),
+  ('\u{d62}', '\u{d63}'), ('ං', 'ඃ'), ('\u{dca}', '\u{dca}'),
+  ('\u{dcf}', '\u{dd4}'), ('\u{dd6}', '\u{dd6}'), ('ෘ', '\u{ddf}'),
+  ('ෲ', 'ෳ'), ('\u{e31}', '\u{e31}'), ('\u{e34}', '\u{e3a}'),
+  ('\u{e47}', '\u{e4e}'), ('\u{eb1}', '\u{eb1}'), ('\u{eb4}', '\u{ebc}'),
+  ('\u{ec8}', '\u{ecd}'), ('\u{f18}', '\u{f19}'), ('\u{f35}', '\u{f35}'),
+  ('\u{f37}', '\u{f37}'), ('\u{f39}', '\u{f39}'), ('༾', '༿'),
+  ('\u{f71}', '\u{f84}'), ('\u{f86}', '\u{f87}'), ('\u{f8d}', '\u{f97}'),
+  ('\u{f99}', '\u{fbc}'), ('\u{fc6}', '\u{fc6}'), ('ါ', '\u{103e}'),
+  ('ၖ', '\u{1059}'), ('\u{105e}', '\u{1060}'), ('ၢ', 'ၤ'),
+  ('ၧ', 'ၭ'), ('\u{1071}', '\u{1074}'), ('\u{1082}', '\u{108d}'),
+  ('ႏ', 'ႏ'), ('ႚ', '\u{109d}'), ('\u{135d}', '\u{135f}'),
+  ('\u{1712}', '\u{1714}'), ('\u{1732}', '\u{1734}'),
+  ('\u{1752}', '\u{1753}'), ('\u{1772}', '\u{1773}'),
+  ('\u{17b4}', '\u{17d3}'), ('\u{17dd}', '\u{17dd}'),
+  ('\u{180b}', '\u{180d}'), ('\u{1885}', '\u{1886}'),
+  ('\u{18a9}', '\u{18a9}'), ('\u{1920}', 'ᤫ'), ('ᤰ', '\u{193b}'),
+  ('\u{1a17}', '\u{1a1b}'), ('ᩕ', '\u{1a5e}'), ('\u{1a60}', '\u{1a7c}'),
+  ('\u{1a7f}', '\u{1a7f}'), ('\u{1ab0}', '\u{1abe}'), ('\u{1b00}', 'ᬄ'),
+  ('\u{1b34}', '᭄'), ('\u{1b6b}', '\u{1b73}'), ('\u{1b80}', 'ᮂ'),
+  ('ᮡ', '\u{1bad}'), ('\u{1be6}', '᯳'), ('ᰤ', '\u{1c37}'),
+  ('\u{1cd0}', '\u{1cd2}'), ('\u{1cd4}', '\u{1ce8}'),
+  ('\u{1ced}', '\u{1ced}'), ('\u{1cf4}', '\u{1cf4}'), ('᳷', '\u{1cf9}'),
+  ('\u{1dc0}', '\u{1df9}'), ('\u{1dfb}', '\u{1dff}'),
+  ('\u{200c}', '\u{200c}'), ('\u{20d0}', '\u{20f0}'),
+  ('\u{2cef}', '\u{2cf1}'), ('\u{2d7f}', '\u{2d7f}'),
+  ('\u{2de0}', '\u{2dff}'), ('\u{302a}', '\u{302f}'),
+  ('\u{3099}', '\u{309a}'), ('\u{a66f}', '\u{a672}'),
+  ('\u{a674}', '\u{a67d}'), ('\u{a69e}', '\u{a69f}'),
+  ('\u{a6f0}', '\u{a6f1}'), ('\u{a802}', '\u{a802}'),
+  ('\u{a806}', '\u{a806}'), ('\u{a80b}', '\u{a80b}'), ('ꠣ', 'ꠧ'),
+  ('ꢀ', 'ꢁ'), ('ꢴ', '\u{a8c5}'), ('\u{a8e0}', '\u{a8f1}'),
+  ('\u{a8ff}', '\u{a8ff}'), ('\u{a926}', '\u{a92d}'), ('\u{a947}', '꥓'),
+  ('\u{a980}', 'ꦃ'), ('\u{a9b3}', '꧀'), ('\u{a9e5}', '\u{a9e5}'),
+  ('\u{aa29}', '\u{aa36}'), ('\u{aa43}', '\u{aa43}'), ('\u{aa4c}', 'ꩍ'),
+  ('ꩻ', 'ꩽ'), ('\u{aab0}', '\u{aab0}'), ('\u{aab2}', '\u{aab4}'),
+  ('\u{aab7}', '\u{aab8}'), ('\u{aabe}', '\u{aabf}'),
+  ('\u{aac1}', '\u{aac1}'), ('ꫫ', 'ꫯ'), ('ꫵ', '\u{aaf6}'),
+  ('ꯣ', 'ꯪ'), ('꯬', '\u{abed}'), ('\u{fb1e}', '\u{fb1e}'),
+  ('\u{fe00}', '\u{fe0f}'), ('\u{fe20}', '\u{fe2f}'),
+  ('\u{ff9e}', '\u{ff9f}'), ('\u{101fd}', '\u{101fd}'),
+  ('\u{102e0}', '\u{102e0}'), ('\u{10376}', '\u{1037a}'),
+  ('\u{10a01}', '\u{10a03}'), ('\u{10a05}', '\u{10a06}'),
+  ('\u{10a0c}', '\u{10a0f}'), ('\u{10a38}', '\u{10a3a}'),
+  ('\u{10a3f}', '\u{10a3f}'), ('\u{10ae5}', '\u{10ae6}'),
+  ('\u{10d24}', '\u{10d27}'), ('\u{10f46}', '\u{10f50}'), ('𑀀', '𑀂'),
+  ('\u{11038}', '\u{11046}'), ('\u{1107f}', '𑂂'), ('𑂰', '\u{110ba}'),
+  ('\u{11100}', '\u{11102}'), ('\u{11127}', '\u{11134}'), ('𑅅', '𑅆'),
+  ('\u{11173}', '\u{11173}'), ('\u{11180}', '𑆂'), ('𑆳', '𑇀'),
+  ('\u{111c9}', '\u{111cc}'), ('𑈬', '\u{11237}'),
+  ('\u{1123e}', '\u{1123e}'), ('\u{112df}', '\u{112ea}'),
+  ('\u{11300}', '𑌃'), ('\u{1133b}', '\u{1133c}'), ('\u{1133e}', '𑍄'),
+  ('𑍇', '𑍈'), ('𑍋', '𑍍'), ('\u{11357}', '\u{11357}'),
+  ('𑍢', '𑍣'), ('\u{11366}', '\u{1136c}'), ('\u{11370}', '\u{11374}'),
+  ('𑐵', '\u{11446}'), ('\u{1145e}', '\u{1145e}'),
+  ('\u{114b0}', '\u{114c3}'), ('\u{115af}', '\u{115b5}'),
+  ('𑖸', '\u{115c0}'), ('\u{115dc}', '\u{115dd}'), ('𑘰', '\u{11640}'),
+  ('\u{116ab}', '\u{116b7}'), ('\u{1171d}', '\u{1172b}'),
+  ('𑠬', '\u{1183a}'), ('\u{119d1}', '\u{119d7}'),
+  ('\u{119da}', '\u{119e0}'), ('\u{119e4}', '\u{119e4}'),
+  ('\u{11a01}', '\u{11a0a}'), ('\u{11a33}', '𑨹'),
+  ('\u{11a3b}', '\u{11a3e}'), ('\u{11a47}', '\u{11a47}'),
+  ('\u{11a51}', '\u{11a5b}'), ('\u{11a8a}', '\u{11a99}'),
+  ('𑰯', '\u{11c36}'), ('\u{11c38}', '\u{11c3f}'),
+  ('\u{11c92}', '\u{11ca7}'), ('𑲩', '\u{11cb6}'),
+  ('\u{11d31}', '\u{11d36}'), ('\u{11d3a}', '\u{11d3a}'),
+  ('\u{11d3c}', '\u{11d3d}'), ('\u{11d3f}', '\u{11d45}'),
+  ('\u{11d47}', '\u{11d47}'), ('𑶊', '𑶎'), ('\u{11d90}', '\u{11d91}'),
+  ('𑶓', '\u{11d97}'), ('\u{11ef3}', '𑻶'), ('\u{16af0}', '\u{16af4}'),
+  ('\u{16b30}', '\u{16b36}'), ('\u{16f4f}', '\u{16f4f}'),
+  ('𖽑', '\u{16f87}'), ('\u{16f8f}', '\u{16f92}'),
+  ('\u{1bc9d}', '\u{1bc9e}'), ('\u{1d165}', '\u{1d169}'),
+  ('𝅭', '\u{1d172}'), ('\u{1d17b}', '\u{1d182}'),
+  ('\u{1d185}', '\u{1d18b}'), ('\u{1d1aa}', '\u{1d1ad}'),
+  ('\u{1d242}', '\u{1d244}'), ('\u{1da00}', '\u{1da36}'),
+  ('\u{1da3b}', '\u{1da6c}'), ('\u{1da75}', '\u{1da75}'),
+  ('\u{1da84}', '\u{1da84}'), ('\u{1da9b}', '\u{1da9f}'),
+  ('\u{1daa1}', '\u{1daaf}'), ('\u{1e000}', '\u{1e006}'),
+  ('\u{1e008}', '\u{1e018}'), ('\u{1e01b}', '\u{1e021}'),
+  ('\u{1e023}', '\u{1e024}'), ('\u{1e026}', '\u{1e02a}'),
+  ('\u{1e130}', '\u{1e136}'), ('\u{1e2ec}', '\u{1e2ef}'),
+  ('\u{1e8d0}', '\u{1e8d6}'), ('\u{1e944}', '\u{1e94a}'), ('🏻', '🏿'),
+  ('\u{e0020}', '\u{e007f}'), ('\u{e0100}', '\u{e01ef}'),
+];
+
+pub const EXTENDNUMLET: &'static [(char, char)] = &[
+  ('_', '_'), ('\u{202f}', '\u{202f}'), ('‿', '⁀'), ('⁔', '⁔'),
+  ('︳', '︴'), ('﹍', '﹏'), ('_', '_'),
+];
+
+pub const FORMAT: &'static [(char, char)] = &[
+  ('\u{ad}', '\u{ad}'), ('\u{600}', '\u{605}'), ('\u{61c}', '\u{61c}'),
+  ('\u{6dd}', '\u{6dd}'), ('\u{70f}', '\u{70f}'), ('\u{8e2}', '\u{8e2}'),
+  ('\u{180e}', '\u{180e}'), ('\u{200e}', '\u{200f}'),
+  ('\u{202a}', '\u{202e}'), ('\u{2060}', '\u{2064}'),
+  ('\u{2066}', '\u{206f}'), ('\u{feff}', '\u{feff}'),
+  ('\u{fff9}', '\u{fffb}'), ('\u{110bd}', '\u{110bd}'),
+  ('\u{110cd}', '\u{110cd}'), ('\u{13430}', '\u{13438}'),
+  ('\u{1bca0}', '\u{1bca3}'), ('\u{1d173}', '\u{1d17a}'),
+  ('\u{e0001}', '\u{e0001}'),
+];
+
+pub const HEBREW_LETTER: &'static [(char, char)] = &[
+  ('א', 'ת'), ('ׯ', 'ײ'), ('יִ', 'יִ'), ('ײַ', 'ﬨ'), ('שׁ', 'זּ'),
+  ('טּ', 'לּ'), ('מּ', 'מּ'), ('נּ', 'סּ'), ('ףּ', 'פּ'),
+  ('צּ', 'ﭏ'),
+];
+
+pub const KATAKANA: &'static [(char, char)] = &[
+  ('〱', '〵'), ('゛', '゜'), ('゠', 'ヺ'), ('ー', 'ヿ'),
+  ('ㇰ', 'ㇿ'), ('㋐', '㋾'), ('㌀', '㍗'), ('ヲ', 'ン'),
+  ('𛀀', '𛀀'), ('\u{1b164}', '\u{1b167}'),
+];
+
+pub const LF: &'static [(char, char)] = &[
+  ('\n', '\n'),
+];
+
+pub const MIDLETTER: &'static [(char, char)] = &[
+  (':', ':'), ('·', '·'), ('·', '·'), ('״', '״'), ('‧', '‧'),
+  ('︓', '︓'), ('﹕', '﹕'), (':', ':'),
+];
+
+pub const MIDNUM: &'static [(char, char)] = &[
+  (',', ','), (';', ';'), (';', ';'), ('։', '։'), ('،', '؍'),
+  ('٬', '٬'), ('߸', '߸'), ('⁄', '⁄'), ('︐', '︐'), ('︔', '︔'),
+  ('﹐', '﹐'), ('﹔', '﹔'), (',', ','), (';', ';'),
+];
+
+pub const MIDNUMLET: &'static [(char, char)] = &[
+  ('.', '.'), ('‘', '’'), ('․', '․'), ('﹒', '﹒'), (''', '''),
+  ('.', '.'),
+];
+
+pub const NEWLINE: &'static [(char, char)] = &[
+  ('\u{b}', '\u{c}'), ('\u{85}', '\u{85}'), ('\u{2028}', '\u{2029}'),
+];
+
+pub const NUMERIC: &'static [(char, char)] = &[
+  ('0', '9'), ('٠', '٩'), ('٫', '٫'), ('۰', '۹'), ('߀', '߉'),
+  ('०', '९'), ('০', '৯'), ('੦', '੯'), ('૦', '૯'),
+  ('୦', '୯'), ('௦', '௯'), ('౦', '౯'), ('೦', '೯'),
+  ('൦', '൯'), ('෦', '෯'), ('๐', '๙'), ('໐', '໙'),
+  ('༠', '༩'), ('၀', '၉'), ('႐', '႙'), ('០', '៩'),
+  ('᠐', '᠙'), ('᥆', '᥏'), ('᧐', '᧙'), ('᪀', '᪉'),
+  ('᪐', '᪙'), ('᭐', '᭙'), ('᮰', '᮹'), ('᱀', '᱉'),
+  ('᱐', '᱙'), ('꘠', '꘩'), ('꣐', '꣙'), ('꤀', '꤉'),
+  ('꧐', '꧙'), ('꧰', '꧹'), ('꩐', '꩙'), ('꯰', '꯹'),
+  ('0', '9'), ('𐒠', '𐒩'), ('𐴰', '𐴹'), ('𑁦', '𑁯'),
+  ('𑃰', '𑃹'), ('𑄶', '𑄿'), ('𑇐', '𑇙'), ('𑋰', '𑋹'),
+  ('𑑐', '𑑙'), ('𑓐', '𑓙'), ('𑙐', '𑙙'), ('𑛀', '𑛉'),
+  ('𑜰', '𑜹'), ('𑣠', '𑣩'), ('𑱐', '𑱙'), ('𑵐', '𑵙'),
+  ('𑶠', '𑶩'), ('𖩠', '𖩩'), ('𖭐', '𖭙'), ('𝟎', '𝟿'),
+  ('\u{1e140}', '\u{1e149}'), ('\u{1e2f0}', '\u{1e2f9}'), ('𞥐', '𞥙'),
+];
+
+pub const REGIONAL_INDICATOR: &'static [(char, char)] = &[
+  ('🇦', '🇿'),
+];
+
+pub const SINGLE_QUOTE: &'static [(char, char)] = &[
+  ('\'', '\''),
+];
+
+pub const WSEGSPACE: &'static [(char, char)] = &[
+  (' ', ' '), ('\u{1680}', '\u{1680}'), ('\u{2000}', '\u{2006}'),
+  ('\u{2008}', '\u{200a}'), ('\u{205f}', '\u{205f}'),
+  ('\u{3000}', '\u{3000}'),
+];
+
+pub const ZWJ: &'static [(char, char)] = &[
+  ('\u{200d}', '\u{200d}'),
+];
+
+
\ No newline at end of file diff --git a/target/doc/src/thread_local/lib.rs.html b/target/doc/src/thread_local/lib.rs.html new file mode 100644 index 0000000..e2a97db --- /dev/null +++ b/target/doc/src/thread_local/lib.rs.html @@ -0,0 +1,1517 @@ +lib.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+
+// Copyright 2017 Amanieu d'Antras
+//
+// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
+// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
+// http://opensource.org/licenses/MIT>, at your option. This file may not be
+// copied, modified, or distributed except according to those terms.
+
+//! Per-object thread-local storage
+//!
+//! This library provides the `ThreadLocal` type which allows a separate copy of
+//! an object to be used for each thread. This allows for per-object
+//! thread-local storage, unlike the standard library's `thread_local!` macro
+//! which only allows static thread-local storage.
+//!
+//! Per-thread objects are not destroyed when a thread exits. Instead, objects
+//! are only destroyed when the `ThreadLocal` containing them is destroyed.
+//!
+//! You can also iterate over the thread-local values of all thread in a
+//! `ThreadLocal` object using the `iter_mut` and `into_iter` methods. This can
+//! only be done if you have mutable access to the `ThreadLocal` object, which
+//! guarantees that you are the only thread currently accessing it.
+//!
+//! A `CachedThreadLocal` type is also provided which wraps a `ThreadLocal` but
+//! also uses a special fast path for the first thread that writes into it. The
+//! fast path has very low overhead (<1ns per access) while keeping the same
+//! performance as `ThreadLocal` for other threads.
+//!
+//! Note that since thread IDs are recycled when a thread exits, it is possible
+//! for one thread to retrieve the object of another thread. Since this can only
+//! occur after a thread has exited this does not lead to any race conditions.
+//!
+//! # Examples
+//!
+//! Basic usage of `ThreadLocal`:
+//!
+//! ```rust
+//! use thread_local::ThreadLocal;
+//! let tls: ThreadLocal<u32> = ThreadLocal::new();
+//! assert_eq!(tls.get(), None);
+//! assert_eq!(tls.get_or(|| Box::new(5)), &5);
+//! assert_eq!(tls.get(), Some(&5));
+//! ```
+//!
+//! Combining thread-local values into a single result:
+//!
+//! ```rust
+//! use thread_local::ThreadLocal;
+//! use std::sync::Arc;
+//! use std::cell::Cell;
+//! use std::thread;
+//!
+//! let tls = Arc::new(ThreadLocal::new());
+//!
+//! // Create a bunch of threads to do stuff
+//! for _ in 0..5 {
+//!     let tls2 = tls.clone();
+//!     thread::spawn(move || {
+//!         // Increment a counter to count some event...
+//!         let cell = tls2.get_or(|| Box::new(Cell::new(0)));
+//!         cell.set(cell.get() + 1);
+//!     }).join().unwrap();
+//! }
+//!
+//! // Once all threads are done, collect the counter values and return the
+//! // sum of all thread-local counter values.
+//! let tls = Arc::try_unwrap(tls).unwrap();
+//! let total = tls.into_iter().fold(0, |x, y| x + y.get());
+//! assert_eq!(total, 5);
+//! ```
+
+#![warn(missing_docs)]
+
+#[macro_use]
+extern crate lazy_static;
+
+mod thread_id;
+mod unreachable;
+
+use std::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
+use std::sync::Mutex;
+use std::marker::PhantomData;
+use std::cell::UnsafeCell;
+use std::fmt;
+use std::iter::Chain;
+use std::option::IntoIter as OptionIter;
+use std::panic::UnwindSafe;
+use unreachable::{UncheckedOptionExt, UncheckedResultExt};
+
+/// Thread-local variable wrapper
+///
+/// See the [module-level documentation](index.html) for more.
+pub struct ThreadLocal<T: ?Sized + Send> {
+    // Pointer to the current top-level hash table
+    table: AtomicPtr<Table<T>>,
+
+    // Lock used to guard against concurrent modifications. This is only taken
+    // while writing to the table, not when reading from it. This also guards
+    // the counter for the total number of values in the hash table.
+    lock: Mutex<usize>,
+
+    // PhantomData to indicate that we logically own T
+    marker: PhantomData<T>,
+}
+
+struct Table<T: ?Sized + Send> {
+    // Hash entries for the table
+    entries: Box<[TableEntry<T>]>,
+
+    // Number of bits used for the hash function
+    hash_bits: usize,
+
+    // Previous table, half the size of the current one
+    prev: Option<Box<Table<T>>>,
+}
+
+struct TableEntry<T: ?Sized + Send> {
+    // Current owner of this entry, or 0 if this is an empty entry
+    owner: AtomicUsize,
+
+    // The object associated with this entry. This is only ever accessed by the
+    // owner of the entry.
+    data: UnsafeCell<Option<Box<T>>>,
+}
+
+// ThreadLocal is always Sync, even if T isn't
+unsafe impl<T: ?Sized + Send> Sync for ThreadLocal<T> {}
+
+impl<T: ?Sized + Send> Default for ThreadLocal<T> {
+    fn default() -> ThreadLocal<T> {
+        ThreadLocal::new()
+    }
+}
+
+impl<T: ?Sized + Send> Drop for ThreadLocal<T> {
+    fn drop(&mut self) {
+        unsafe {
+            Box::from_raw(self.table.load(Ordering::Relaxed));
+        }
+    }
+}
+
+// Implementation of Clone for TableEntry, needed to make vec![] work
+impl<T: ?Sized + Send> Clone for TableEntry<T> {
+    fn clone(&self) -> TableEntry<T> {
+        TableEntry {
+            owner: AtomicUsize::new(0),
+            data: UnsafeCell::new(None),
+        }
+    }
+}
+
+// Hash function for the thread id
+#[cfg(target_pointer_width = "32")]
+#[inline]
+fn hash(id: usize, bits: usize) -> usize {
+    id.wrapping_mul(0x9E3779B9) >> (32 - bits)
+}
+#[cfg(target_pointer_width = "64")]
+#[inline]
+fn hash(id: usize, bits: usize) -> usize {
+    id.wrapping_mul(0x9E37_79B9_7F4A_7C15) >> (64 - bits)
+}
+
+impl<T: ?Sized + Send> ThreadLocal<T> {
+    /// Creates a new empty `ThreadLocal`.
+    pub fn new() -> ThreadLocal<T> {
+        let entry = TableEntry {
+            owner: AtomicUsize::new(0),
+            data: UnsafeCell::new(None),
+        };
+        let table = Table {
+            entries: vec![entry; 2].into_boxed_slice(),
+            hash_bits: 1,
+            prev: None,
+        };
+        ThreadLocal {
+            table: AtomicPtr::new(Box::into_raw(Box::new(table))),
+            lock: Mutex::new(0),
+            marker: PhantomData,
+        }
+    }
+
+    /// Returns the element for the current thread, if it exists.
+    pub fn get(&self) -> Option<&T> {
+        let id = thread_id::get();
+        self.get_fast(id)
+    }
+
+    /// Returns the element for the current thread, or creates it if it doesn't
+    /// exist.
+    pub fn get_or<F>(&self, create: F) -> &T
+    where
+        F: FnOnce() -> Box<T>,
+    {
+        unsafe {
+            self.get_or_try(|| Ok::<Box<T>, ()>(create()))
+                .unchecked_unwrap_ok()
+        }
+    }
+
+    /// Returns the element for the current thread, or creates it if it doesn't
+    /// exist. If `create` fails, that error is returned and no element is
+    /// added.
+    pub fn get_or_try<F, E>(&self, create: F) -> Result<&T, E>
+    where
+        F: FnOnce() -> Result<Box<T>, E>,
+    {
+        let id = thread_id::get();
+        match self.get_fast(id) {
+            Some(x) => Ok(x),
+            None => Ok(self.insert(id, try!(create()), true)),
+        }
+    }
+
+    // Simple hash table lookup function
+    fn lookup(id: usize, table: &Table<T>) -> Option<&UnsafeCell<Option<Box<T>>>> {
+        // Because we use a Mutex to prevent concurrent modifications (but not
+        // reads) of the hash table, we can avoid any memory barriers here. No
+        // elements between our hash bucket and our value can have been modified
+        // since we inserted our thread-local value into the table.
+        for entry in table.entries.iter().cycle().skip(hash(id, table.hash_bits)) {
+            let owner = entry.owner.load(Ordering::Relaxed);
+            if owner == id {
+                return Some(&entry.data);
+            }
+            if owner == 0 {
+                return None;
+            }
+        }
+        unreachable!();
+    }
+
+    // Fast path: try to find our thread in the top-level hash table
+    fn get_fast(&self, id: usize) -> Option<&T> {
+        let table = unsafe { &*self.table.load(Ordering::Relaxed) };
+        match Self::lookup(id, table) {
+            Some(x) => unsafe { Some((*x.get()).as_ref().unchecked_unwrap()) },
+            None => self.get_slow(id, table),
+        }
+    }
+
+    // Slow path: try to find our thread in the other hash tables, and then
+    // move it to the top-level hash table.
+    #[cold]
+    fn get_slow(&self, id: usize, table_top: &Table<T>) -> Option<&T> {
+        let mut current = &table_top.prev;
+        while let Some(ref table) = *current {
+            if let Some(x) = Self::lookup(id, table) {
+                let data = unsafe { (*x.get()).take().unchecked_unwrap() };
+                return Some(self.insert(id, data, false));
+            }
+            current = &table.prev;
+        }
+        None
+    }
+
+    #[cold]
+    fn insert(&self, id: usize, data: Box<T>, new: bool) -> &T {
+        // Lock the Mutex to ensure only a single thread is modify the hash
+        // table at once.
+        let mut count = self.lock.lock().unwrap();
+        if new {
+            *count += 1;
+        }
+        let table_raw = self.table.load(Ordering::Relaxed);
+        let table = unsafe { &*table_raw };
+
+        // If the current top-level hash table is more than 75% full, add a new
+        // level with 2x the capacity. Elements will be moved up to the new top
+        // level table as they are accessed.
+        let table = if *count > table.entries.len() * 3 / 4 {
+            let entry = TableEntry {
+                owner: AtomicUsize::new(0),
+                data: UnsafeCell::new(None),
+            };
+            let new_table = Box::into_raw(Box::new(Table {
+                entries: vec![entry; table.entries.len() * 2].into_boxed_slice(),
+                hash_bits: table.hash_bits + 1,
+                prev: unsafe { Some(Box::from_raw(table_raw)) },
+            }));
+            self.table.store(new_table, Ordering::Release);
+            unsafe { &*new_table }
+        } else {
+            table
+        };
+
+        // Insert the new element into the top-level hash table
+        for entry in table.entries.iter().cycle().skip(hash(id, table.hash_bits)) {
+            let owner = entry.owner.load(Ordering::Relaxed);
+            if owner == 0 {
+                unsafe {
+                    entry.owner.store(id, Ordering::Relaxed);
+                    *entry.data.get() = Some(data);
+                    return (*entry.data.get()).as_ref().unchecked_unwrap();
+                }
+            }
+            if owner == id {
+                // This can happen if create() inserted a value into this
+                // ThreadLocal between our calls to get_fast() and insert(). We
+                // just return the existing value and drop the newly-allocated
+                // Box.
+                unsafe {
+                    return (*entry.data.get()).as_ref().unchecked_unwrap();
+                }
+            }
+        }
+        unreachable!();
+    }
+
+    /// Returns a mutable iterator over the local values of all threads.
+    ///
+    /// Since this call borrows the `ThreadLocal` mutably, this operation can
+    /// be done safely---the mutable borrow statically guarantees no other
+    /// threads are currently accessing their associated values.
+    pub fn iter_mut(&mut self) -> IterMut<T> {
+        let raw = RawIter {
+            remaining: *self.lock.lock().unwrap(),
+            index: 0,
+            table: self.table.load(Ordering::Relaxed),
+        };
+        IterMut {
+            raw: raw,
+            marker: PhantomData,
+        }
+    }
+
+    /// Removes all thread-specific values from the `ThreadLocal`, effectively
+    /// reseting it to its original state.
+    ///
+    /// Since this call borrows the `ThreadLocal` mutably, this operation can
+    /// be done safely---the mutable borrow statically guarantees no other
+    /// threads are currently accessing their associated values.
+    pub fn clear(&mut self) {
+        *self = ThreadLocal::new();
+    }
+}
+
+impl<T: ?Sized + Send> IntoIterator for ThreadLocal<T> {
+    type Item = Box<T>;
+    type IntoIter = IntoIter<T>;
+
+    fn into_iter(self) -> IntoIter<T> {
+        let raw = RawIter {
+            remaining: *self.lock.lock().unwrap(),
+            index: 0,
+            table: self.table.load(Ordering::Relaxed),
+        };
+        IntoIter {
+            raw: raw,
+            _thread_local: self,
+        }
+    }
+}
+
+impl<'a, T: ?Sized + Send + 'a> IntoIterator for &'a mut ThreadLocal<T> {
+    type Item = &'a mut Box<T>;
+    type IntoIter = IterMut<'a, T>;
+
+    fn into_iter(self) -> IterMut<'a, T> {
+        self.iter_mut()
+    }
+}
+
+impl<T: Send + Default> ThreadLocal<T> {
+    /// Returns the element for the current thread, or creates a default one if
+    /// it doesn't exist.
+    pub fn get_default(&self) -> &T {
+        self.get_or(|| Box::new(T::default()))
+    }
+}
+
+impl<T: ?Sized + Send + fmt::Debug> fmt::Debug for ThreadLocal<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "ThreadLocal {{ local_data: {:?} }}", self.get())
+    }
+}
+
+impl<T: ?Sized + Send + UnwindSafe> UnwindSafe for ThreadLocal<T> {}
+
+struct RawIter<T: ?Sized + Send> {
+    remaining: usize,
+    index: usize,
+    table: *const Table<T>,
+}
+
+impl<T: ?Sized + Send> RawIter<T> {
+    fn next(&mut self) -> Option<*mut Option<Box<T>>> {
+        if self.remaining == 0 {
+            return None;
+        }
+
+        loop {
+            let entries = unsafe { &(*self.table).entries[..] };
+            while self.index < entries.len() {
+                let val = entries[self.index].data.get();
+                self.index += 1;
+                if unsafe { (*val).is_some() } {
+                    self.remaining -= 1;
+                    return Some(val);
+                }
+            }
+            self.index = 0;
+            self.table = unsafe { &**(*self.table).prev.as_ref().unchecked_unwrap() };
+        }
+    }
+}
+
+/// Mutable iterator over the contents of a `ThreadLocal`.
+pub struct IterMut<'a, T: ?Sized + Send + 'a> {
+    raw: RawIter<T>,
+    marker: PhantomData<&'a mut ThreadLocal<T>>,
+}
+
+impl<'a, T: ?Sized + Send + 'a> Iterator for IterMut<'a, T> {
+    type Item = &'a mut Box<T>;
+
+    fn next(&mut self) -> Option<&'a mut Box<T>> {
+        self.raw.next().map(|x| unsafe {
+            (*x).as_mut().unchecked_unwrap()
+        })
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (self.raw.remaining, Some(self.raw.remaining))
+    }
+}
+
+impl<'a, T: ?Sized + Send + 'a> ExactSizeIterator for IterMut<'a, T> {}
+
+/// An iterator that moves out of a `ThreadLocal`.
+pub struct IntoIter<T: ?Sized + Send> {
+    raw: RawIter<T>,
+    _thread_local: ThreadLocal<T>,
+}
+
+impl<T: ?Sized + Send> Iterator for IntoIter<T> {
+    type Item = Box<T>;
+
+    fn next(&mut self) -> Option<Box<T>> {
+        self.raw.next().map(
+            |x| unsafe { (*x).take().unchecked_unwrap() },
+        )
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (self.raw.remaining, Some(self.raw.remaining))
+    }
+}
+
+impl<T: ?Sized + Send> ExactSizeIterator for IntoIter<T> {}
+
+/// Wrapper around `ThreadLocal` which adds a fast path for a single thread.
+///
+/// This has the same API as `ThreadLocal`, but will register the first thread
+/// that sets a value as its owner. All accesses by the owner will go through
+/// a special fast path which is much faster than the normal `ThreadLocal` path.
+pub struct CachedThreadLocal<T: ?Sized + Send> {
+    owner: AtomicUsize,
+    local: UnsafeCell<Option<Box<T>>>,
+    global: ThreadLocal<T>,
+}
+
+// CachedThreadLocal is always Sync, even if T isn't
+unsafe impl<T: ?Sized + Send> Sync for CachedThreadLocal<T> {}
+
+impl<T: ?Sized + Send> Default for CachedThreadLocal<T> {
+    fn default() -> CachedThreadLocal<T> {
+        CachedThreadLocal::new()
+    }
+}
+
+impl<T: ?Sized + Send> CachedThreadLocal<T> {
+    /// Creates a new empty `CachedThreadLocal`.
+    pub fn new() -> CachedThreadLocal<T> {
+        CachedThreadLocal {
+            owner: AtomicUsize::new(0),
+            local: UnsafeCell::new(None),
+            global: ThreadLocal::new(),
+        }
+    }
+
+    /// Returns the element for the current thread, if it exists.
+    pub fn get(&self) -> Option<&T> {
+        let id = thread_id::get();
+        let owner = self.owner.load(Ordering::Relaxed);
+        if owner == id {
+            return unsafe { Some((*self.local.get()).as_ref().unchecked_unwrap()) };
+        }
+        if owner == 0 {
+            return None;
+        }
+        self.global.get_fast(id)
+    }
+
+    /// Returns the element for the current thread, or creates it if it doesn't
+    /// exist.
+    #[inline(always)]
+    pub fn get_or<F>(&self, create: F) -> &T
+    where
+        F: FnOnce() -> Box<T>,
+    {
+        unsafe {
+            self.get_or_try(|| Ok::<Box<T>, ()>(create()))
+                .unchecked_unwrap_ok()
+        }
+    }
+
+    /// Returns the element for the current thread, or creates it if it doesn't
+    /// exist. If `create` fails, that error is returned and no element is
+    /// added.
+    pub fn get_or_try<F, E>(&self, create: F) -> Result<&T, E>
+    where
+        F: FnOnce() -> Result<Box<T>, E>,
+    {
+        let id = thread_id::get();
+        let owner = self.owner.load(Ordering::Relaxed);
+        if owner == id {
+            return Ok(unsafe { (*self.local.get()).as_ref().unchecked_unwrap() });
+        }
+        self.get_or_try_slow(id, owner, create)
+    }
+
+    #[cold]
+    #[inline(never)]
+    fn get_or_try_slow<F, E>(&self, id: usize, owner: usize, create: F) -> Result<&T, E>
+    where
+        F: FnOnce() -> Result<Box<T>, E>,
+    {
+        if owner == 0 && self.owner.compare_and_swap(0, id, Ordering::Relaxed) == 0 {
+            unsafe {
+                (*self.local.get()) = Some(try!(create()));
+                return Ok((*self.local.get()).as_ref().unchecked_unwrap());
+            }
+        }
+        match self.global.get_fast(id) {
+            Some(x) => Ok(x),
+            None => Ok(self.global.insert(id, try!(create()), true)),
+        }
+    }
+
+    /// Returns a mutable iterator over the local values of all threads.
+    ///
+    /// Since this call borrows the `ThreadLocal` mutably, this operation can
+    /// be done safely---the mutable borrow statically guarantees no other
+    /// threads are currently accessing their associated values.
+    pub fn iter_mut(&mut self) -> CachedIterMut<T> {
+        unsafe {
+            (*self.local.get()).as_mut().into_iter().chain(
+                self.global
+                    .iter_mut(),
+            )
+        }
+    }
+
+    /// Removes all thread-specific values from the `ThreadLocal`, effectively
+    /// reseting it to its original state.
+    ///
+    /// Since this call borrows the `ThreadLocal` mutably, this operation can
+    /// be done safely---the mutable borrow statically guarantees no other
+    /// threads are currently accessing their associated values.
+    pub fn clear(&mut self) {
+        *self = CachedThreadLocal::new();
+    }
+}
+
+impl<T: ?Sized + Send> IntoIterator for CachedThreadLocal<T> {
+    type Item = Box<T>;
+    type IntoIter = CachedIntoIter<T>;
+
+    fn into_iter(self) -> CachedIntoIter<T> {
+        unsafe {
+            (*self.local.get()).take().into_iter().chain(
+                self.global
+                    .into_iter(),
+            )
+        }
+    }
+}
+
+impl<'a, T: ?Sized + Send + 'a> IntoIterator for &'a mut CachedThreadLocal<T> {
+    type Item = &'a mut Box<T>;
+    type IntoIter = CachedIterMut<'a, T>;
+
+    fn into_iter(self) -> CachedIterMut<'a, T> {
+        self.iter_mut()
+    }
+}
+
+impl<T: Send + Default> CachedThreadLocal<T> {
+    /// Returns the element for the current thread, or creates a default one if
+    /// it doesn't exist.
+    pub fn get_default(&self) -> &T {
+        self.get_or(|| Box::new(T::default()))
+    }
+}
+
+impl<T: ?Sized + Send + fmt::Debug> fmt::Debug for CachedThreadLocal<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "ThreadLocal {{ local_data: {:?} }}", self.get())
+    }
+}
+
+/// Mutable iterator over the contents of a `CachedThreadLocal`.
+pub type CachedIterMut<'a, T> = Chain<OptionIter<&'a mut Box<T>>, IterMut<'a, T>>;
+
+/// An iterator that moves out of a `CachedThreadLocal`.
+pub type CachedIntoIter<T> = Chain<OptionIter<Box<T>>, IntoIter<T>>;
+
+impl<T: ?Sized + Send + UnwindSafe> UnwindSafe for CachedThreadLocal<T> {}
+
+#[cfg(test)]
+mod tests {
+    use std::cell::RefCell;
+    use std::sync::Arc;
+    use std::sync::atomic::AtomicUsize;
+    use std::sync::atomic::Ordering::Relaxed;
+    use std::thread;
+    use super::{ThreadLocal, CachedThreadLocal};
+
+    fn make_create() -> Arc<Fn() -> Box<usize> + Send + Sync> {
+        let count = AtomicUsize::new(0);
+        Arc::new(move || Box::new(count.fetch_add(1, Relaxed)))
+    }
+
+    #[test]
+    fn same_thread() {
+        let create = make_create();
+        let mut tls = ThreadLocal::new();
+        assert_eq!(None, tls.get());
+        assert_eq!("ThreadLocal { local_data: None }", format!("{:?}", &tls));
+        assert_eq!(0, *tls.get_or(|| create()));
+        assert_eq!(Some(&0), tls.get());
+        assert_eq!(0, *tls.get_or(|| create()));
+        assert_eq!(Some(&0), tls.get());
+        assert_eq!(0, *tls.get_or(|| create()));
+        assert_eq!(Some(&0), tls.get());
+        assert_eq!("ThreadLocal { local_data: Some(0) }", format!("{:?}", &tls));
+        tls.clear();
+        assert_eq!(None, tls.get());
+    }
+
+    #[test]
+    fn same_thread_cached() {
+        let create = make_create();
+        let mut tls = CachedThreadLocal::new();
+        assert_eq!(None, tls.get());
+        assert_eq!("ThreadLocal { local_data: None }", format!("{:?}", &tls));
+        assert_eq!(0, *tls.get_or(|| create()));
+        assert_eq!(Some(&0), tls.get());
+        assert_eq!(0, *tls.get_or(|| create()));
+        assert_eq!(Some(&0), tls.get());
+        assert_eq!(0, *tls.get_or(|| create()));
+        assert_eq!(Some(&0), tls.get());
+        assert_eq!("ThreadLocal { local_data: Some(0) }", format!("{:?}", &tls));
+        tls.clear();
+        assert_eq!(None, tls.get());
+    }
+
+    #[test]
+    fn different_thread() {
+        let create = make_create();
+        let tls = Arc::new(ThreadLocal::new());
+        assert_eq!(None, tls.get());
+        assert_eq!(0, *tls.get_or(|| create()));
+        assert_eq!(Some(&0), tls.get());
+
+        let tls2 = tls.clone();
+        let create2 = create.clone();
+        thread::spawn(move || {
+            assert_eq!(None, tls2.get());
+            assert_eq!(1, *tls2.get_or(|| create2()));
+            assert_eq!(Some(&1), tls2.get());
+        }).join()
+            .unwrap();
+
+        assert_eq!(Some(&0), tls.get());
+        assert_eq!(0, *tls.get_or(|| create()));
+    }
+
+    #[test]
+    fn different_thread_cached() {
+        let create = make_create();
+        let tls = Arc::new(CachedThreadLocal::new());
+        assert_eq!(None, tls.get());
+        assert_eq!(0, *tls.get_or(|| create()));
+        assert_eq!(Some(&0), tls.get());
+
+        let tls2 = tls.clone();
+        let create2 = create.clone();
+        thread::spawn(move || {
+            assert_eq!(None, tls2.get());
+            assert_eq!(1, *tls2.get_or(|| create2()));
+            assert_eq!(Some(&1), tls2.get());
+        }).join()
+            .unwrap();
+
+        assert_eq!(Some(&0), tls.get());
+        assert_eq!(0, *tls.get_or(|| create()));
+    }
+
+    #[test]
+    fn iter() {
+        let tls = Arc::new(ThreadLocal::new());
+        tls.get_or(|| Box::new(1));
+
+        let tls2 = tls.clone();
+        thread::spawn(move || {
+            tls2.get_or(|| Box::new(2));
+            let tls3 = tls2.clone();
+            thread::spawn(move || { tls3.get_or(|| Box::new(3)); })
+                .join()
+                .unwrap();
+        }).join()
+            .unwrap();
+
+        let mut tls = Arc::try_unwrap(tls).unwrap();
+        let mut v = tls.iter_mut().map(|x| **x).collect::<Vec<i32>>();
+        v.sort();
+        assert_eq!(vec![1, 2, 3], v);
+        let mut v = tls.into_iter().map(|x| *x).collect::<Vec<i32>>();
+        v.sort();
+        assert_eq!(vec![1, 2, 3], v);
+    }
+
+    #[test]
+    fn iter_cached() {
+        let tls = Arc::new(CachedThreadLocal::new());
+        tls.get_or(|| Box::new(1));
+
+        let tls2 = tls.clone();
+        thread::spawn(move || {
+            tls2.get_or(|| Box::new(2));
+            let tls3 = tls2.clone();
+            thread::spawn(move || { tls3.get_or(|| Box::new(3)); })
+                .join()
+                .unwrap();
+        }).join()
+            .unwrap();
+
+        let mut tls = Arc::try_unwrap(tls).unwrap();
+        let mut v = tls.iter_mut().map(|x| **x).collect::<Vec<i32>>();
+        v.sort();
+        assert_eq!(vec![1, 2, 3], v);
+        let mut v = tls.into_iter().map(|x| *x).collect::<Vec<i32>>();
+        v.sort();
+        assert_eq!(vec![1, 2, 3], v);
+    }
+
+    #[test]
+    fn is_sync() {
+        fn foo<T: Sync>() {}
+        foo::<ThreadLocal<String>>();
+        foo::<ThreadLocal<RefCell<String>>>();
+        foo::<CachedThreadLocal<String>>();
+        foo::<CachedThreadLocal<RefCell<String>>>();
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/thread_local/thread_id.rs.html b/target/doc/src/thread_local/thread_id.rs.html new file mode 100644 index 0000000..1330154 --- /dev/null +++ b/target/doc/src/thread_local/thread_id.rs.html @@ -0,0 +1,125 @@ +thread_id.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+
+// Copyright 2017 Amanieu d'Antras
+//
+// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
+// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
+// http://opensource.org/licenses/MIT>, at your option. This file may not be
+// copied, modified, or distributed except according to those terms.
+
+use std::collections::BinaryHeap;
+use std::sync::Mutex;
+use std::usize;
+
+// Thread ID manager which allocates thread IDs. It attempts to aggressively
+// reuse thread IDs where possible to avoid cases where a ThreadLocal grows
+// indefinitely when it is used by many short-lived threads.
+struct ThreadIdManager {
+    limit: usize,
+    free_list: BinaryHeap<usize>,
+}
+impl ThreadIdManager {
+    fn new() -> ThreadIdManager {
+        ThreadIdManager {
+            limit: usize::MAX,
+            free_list: BinaryHeap::new(),
+        }
+    }
+    fn alloc(&mut self) -> usize {
+        if let Some(id) = self.free_list.pop() {
+            id
+        } else {
+            let id = self.limit;
+            self.limit = self.limit.checked_sub(1).expect("Ran out of thread IDs");
+            id
+        }
+    }
+    fn free(&mut self, id: usize) {
+        self.free_list.push(id);
+    }
+}
+lazy_static! {
+    static ref THREAD_ID_MANAGER: Mutex<ThreadIdManager> = Mutex::new(ThreadIdManager::new());
+}
+
+// Non-zero integer which is unique to the current thread while it is running.
+// A thread ID may be reused after a thread exits.
+struct ThreadId(usize);
+impl ThreadId {
+    fn new() -> ThreadId {
+        ThreadId(THREAD_ID_MANAGER.lock().unwrap().alloc())
+    }
+}
+impl Drop for ThreadId {
+    fn drop(&mut self) {
+        THREAD_ID_MANAGER.lock().unwrap().free(self.0);
+    }
+}
+thread_local!(static THREAD_ID: ThreadId = ThreadId::new());
+
+/// Returns a non-zero ID for the current thread
+pub fn get() -> usize {
+    THREAD_ID.with(|x| x.0)
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/thread_local/unreachable.rs.html b/target/doc/src/thread_local/unreachable.rs.html new file mode 100644 index 0000000..4ba4c42 --- /dev/null +++ b/target/doc/src/thread_local/unreachable.rs.html @@ -0,0 +1,150 @@ +unreachable.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+
+// Copyright 2017 Amanieu d'Antras
+//
+// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
+// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
+// http://opensource.org/licenses/MIT>, at your option. This file may not be
+// copied, modified, or distributed except according to those terms.
+
+//! # unreachable
+//! inlined from https://github.com/reem/rust-unreachable/
+//!
+//! An unreachable code optimization hint in stable rust, and some useful
+//! extension traits for `Option` and `Result`.
+//!
+
+/// Hint to the optimizer that any code path which calls this function is
+/// statically unreachable and can be removed.
+///
+/// Calling this function in reachable code invokes undefined behavior. Be
+/// very, very sure this is what you want; often, a simple `panic!` is more
+/// suitable.
+#[inline]
+pub unsafe fn unreachable() -> ! {
+    /// The empty type for cases which can't occur.
+    enum Void { }
+    let x: &Void = ::std::mem::transmute(1usize);
+    match *x {}
+}
+
+/// An extension trait for `Option<T>` providing unchecked unwrapping methods.
+pub trait UncheckedOptionExt<T> {
+    /// Get the value out of this Option without checking for None.
+    unsafe fn unchecked_unwrap(self) -> T;
+
+    /// Assert that this Option is a None to the optimizer.
+    unsafe fn unchecked_unwrap_none(self);
+}
+
+/// An extension trait for `Result<T, E>` providing unchecked unwrapping methods.
+pub trait UncheckedResultExt<T, E> {
+    /// Get the value out of this Result without checking for Err.
+    unsafe fn unchecked_unwrap_ok(self) -> T;
+
+    /// Get the error out of this Result without checking for Ok.
+    unsafe fn unchecked_unwrap_err(self) -> E;
+}
+
+impl<T> UncheckedOptionExt<T> for Option<T> {
+    unsafe fn unchecked_unwrap(self) -> T {
+        match self {
+            Some(x) => x,
+            None => unreachable()
+        }
+    }
+
+    unsafe fn unchecked_unwrap_none(self) {
+        if self.is_some() { unreachable() }
+    }
+}
+
+impl<T, E> UncheckedResultExt<T, E> for Result<T, E> {
+    unsafe fn unchecked_unwrap_ok(self) -> T {
+        match self {
+            Ok(x) => x,
+            Err(_) => unreachable()
+        }
+    }
+
+    unsafe fn unchecked_unwrap_err(self) -> E {
+        match self {
+            Ok(_) => unreachable(),
+            Err(e) => e
+        }
+    }
+}
+
\ No newline at end of file diff --git a/target/doc/src/ucd_util/hangul.rs.html b/target/doc/src/ucd_util/hangul.rs.html new file mode 100644 index 0000000..686ce57 --- /dev/null +++ b/target/doc/src/ucd_util/hangul.rs.html @@ -0,0 +1,213 @@ +hangul.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+
+use unicode_tables::jamo_short_name::JAMO_SHORT_NAME;
+
+// This implementation should correspond to the algorithms described in
+// Unicode 3.12.
+
+/// A set of ranges that corresponds to the set of all Hangul syllable
+/// codepoints.
+///
+/// These ranges are defined in Unicode 4.8 Table 4-13.
+pub const RANGE_HANGUL_SYLLABLE: &'static [(u32, u32)] = &[
+    (0xAC00, 0xD7A3),
+];
+
+const S_BASE: u32 = 0xAC00;
+const L_BASE: u32 = 0x1100;
+const V_BASE: u32 = 0x1161;
+const T_BASE: u32 = 0x11A7;
+const T_COUNT: u32 = 28;
+const N_COUNT: u32 = 588;
+
+/// Return the character name of the given precomposed Hangul codepoint.
+///
+/// If the given codepoint does not correspond to a precomposed Hangul
+/// codepoint in the inclusive range `AC00..D7A3`, then this returns `None`.
+///
+/// This implements the algorithms described in Unicode 3.12 and Unicode 4.8.
+pub fn hangul_name(cp: u32) -> Option<String> {
+    let mut name = "HANGUL SYLLABLE ".to_string();
+    let (lpart, vpart, tpart) = match hangul_full_canonical_decomposition(cp) {
+        None => return None,
+        Some(triple) => triple,
+    };
+
+    name.push_str(jamo_short_name(lpart));
+    name.push_str(jamo_short_name(vpart));
+    name.push_str(tpart.map_or("", jamo_short_name));
+    Some(name)
+}
+
+/// Return the full canonical decomposition of the given precomposed Hangul
+/// codepoint.
+///
+/// If the decomposition does not have any trailing consonant, then the third
+/// part of the tuple returned is `None`.
+///
+/// If the given codepoint does not correspond to a precomposed Hangul
+/// codepoint in the inclusive range `AC00..D7A3`, then this returns `None`.
+///
+/// This implements the algorithms described in Unicode 3.12 and Unicode 4.8.
+pub fn hangul_full_canonical_decomposition(
+    cp: u32,
+) -> Option<(u32, u32, Option<u32>)> {
+    if !(0xAC00 <= cp && cp <= 0xD7A3) {
+        return None;
+    }
+
+    let s_index = cp - S_BASE;
+    let l_index = s_index / N_COUNT;
+    let v_index = (s_index % N_COUNT) / T_COUNT;
+    let t_index = s_index % T_COUNT;
+
+    let l_part = L_BASE + l_index;
+    let v_part = V_BASE + v_index;
+    let t_part =
+        if t_index == 0 {
+            None
+        } else {
+            Some(T_BASE + t_index)
+        };
+    Some((l_part, v_part, t_part))
+}
+
+fn jamo_short_name(cp: u32) -> &'static str {
+    let i = JAMO_SHORT_NAME.binary_search_by_key(&cp, |p| p.0).unwrap();
+    JAMO_SHORT_NAME[i].1
+}
+
+#[cfg(test)]
+mod tests {
+    use super::{hangul_name, hangul_full_canonical_decomposition};
+
+    #[test]
+    fn canon_decomp() {
+        assert_eq!(
+            hangul_full_canonical_decomposition(0xD4DB),
+            Some((0x1111, 0x1171, Some(0x11B6))));
+    }
+
+    #[test]
+    fn name() {
+        assert_eq!(hangul_name(0xD4DB).unwrap(), "HANGUL SYLLABLE PWILH");
+    }
+
+    #[test]
+    fn all() {
+        for cp in 0xAC00..(0xD7A3 + 1) {
+            hangul_name(cp).unwrap();
+        }
+    }
+
+    #[test]
+    fn invalid() {
+        assert!(hangul_name(0).is_none());
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/ucd_util/ideograph.rs.html b/target/doc/src/ucd_util/ideograph.rs.html new file mode 100644 index 0000000..4811fb8 --- /dev/null +++ b/target/doc/src/ucd_util/ideograph.rs.html @@ -0,0 +1,169 @@ +ideograph.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+
+/// A set of ranges that corresponds to the set of all ideograph codepoints.
+///
+/// These ranges are defined in Unicode 4.8 Table 4-13.
+pub const RANGE_IDEOGRAPH: &'static [(u32, u32)] = &[
+    (0x3400, 0x4DB5),
+    (0x4E00, 0x9FD5),
+    (0x4E00, 0x9FD5),
+    (0x20000, 0x2A6D6),
+    (0x2A700, 0x2B734),
+    (0x2B740, 0x2B81D),
+    (0x2B820, 0x2CEA1),
+    (0x17000, 0x187EC),
+    (0xF900, 0xFA6D),
+    (0xFA70, 0xFAD9),
+    (0x2F800, 0x2FA1D),
+];
+
+/// Return the character name of the given ideograph codepoint.
+///
+/// This operation is only defined on ideographic codepoints. This includes
+/// precisely the following inclusive ranges:
+///
+/// * `3400..4DB5`
+/// * `4E00..9FD5`
+/// * `20000..2A6D6`
+/// * `2A700..2B734`
+/// * `2B740..2B81D`
+/// * `2B820..2CEA1`
+/// * `17000..187EC`
+/// * `F900..FA6D`
+/// * `FA70..FAD9`
+/// * `2F800..2FA1D`
+///
+/// If the given codepoint is not in any of the above ranges, then `None` is
+/// returned.
+///
+/// This implements the algorithm described in Unicode 4.8.
+pub fn ideograph_name(cp: u32) -> Option<String> {
+    // This match should be in sync with the `RANGE_IDEOGRAPH` constant.
+    match cp {
+        0x3400...0x4DB5
+        | 0x4E00...0x9FD5
+        | 0x20000...0x2A6D6
+        | 0x2A700...0x2B734
+        | 0x2B740...0x2B81D
+        | 0x2B820...0x2CEA1 => {
+            Some(format!("CJK UNIFIED IDEOGRAPH-{:04X}", cp))
+        }
+        0x17000...0x187EC => {
+            Some(format!("TANGUT IDEOGRAPH-{:04X}", cp))
+        }
+        0xF900...0xFA6D | 0xFA70...0xFAD9 | 0x2F800...0x2FA1D => {
+            Some(format!("CJK COMPATIBILITY IDEOGRAPH-{:04X}", cp))
+        }
+        _ => None,
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::ideograph_name;
+
+    #[test]
+    fn name() {
+        assert_eq!(
+            ideograph_name(0x4E00).unwrap(),
+            "CJK UNIFIED IDEOGRAPH-4E00");
+        assert_eq!(
+            ideograph_name(0x9FD5).unwrap(),
+            "CJK UNIFIED IDEOGRAPH-9FD5");
+        assert_eq!(
+            ideograph_name(0x17000).unwrap(),
+            "TANGUT IDEOGRAPH-17000");
+        assert_eq!(
+            ideograph_name(0xF900).unwrap(),
+            "CJK COMPATIBILITY IDEOGRAPH-F900");
+    }
+
+    #[test]
+    fn invalid() {
+        assert!(ideograph_name(0).is_none());
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/ucd_util/lib.rs.html b/target/doc/src/ucd_util/lib.rs.html new file mode 100644 index 0000000..326edf0 --- /dev/null +++ b/target/doc/src/ucd_util/lib.rs.html @@ -0,0 +1,63 @@ +lib.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+
+/*!
+The `ucd-util` crate contains a smattering of utility functions that implement
+various algorithms specified by Unicode. There is no specific goal for
+exhaustiveness. Instead, implementations should be added on an as-needed basis.
+
+A *current* design constraint of this crate is that it should not bring in any
+large Unicode tables. For example, to use the various property name and value
+canonicalization functions, you'll need to supply your own table, which can
+be generated using `ucd-generate`.
+*/
+
+#![deny(missing_docs)]
+#![allow(unknown_lints)]
+#![allow(ellipsis_inclusive_range_patterns)]
+
+mod hangul;
+mod ideograph;
+mod name;
+mod property;
+mod unicode_tables;
+
+pub use hangul::{
+    RANGE_HANGUL_SYLLABLE, hangul_name, hangul_full_canonical_decomposition,
+};
+pub use ideograph::{RANGE_IDEOGRAPH, ideograph_name};
+pub use name::{character_name_normalize, symbolic_name_normalize};
+pub use property::{
+    PropertyTable, PropertyValueTable, PropertyValues,
+    canonical_property_name, property_values, canonical_property_value,
+};
+
+
\ No newline at end of file diff --git a/target/doc/src/ucd_util/name.rs.html b/target/doc/src/ucd_util/name.rs.html new file mode 100644 index 0000000..64cb42e --- /dev/null +++ b/target/doc/src/ucd_util/name.rs.html @@ -0,0 +1,411 @@ +name.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+
+/// Normalize the given character name in place according to UAX44-LM2.
+///
+/// See: http://unicode.org/reports/tr44/#UAX44-LM2
+pub fn character_name_normalize(string: &mut String) {
+    let bytes = unsafe {
+        // SAFETY: `character_name_normalize_bytes` guarantees that
+        // `bytes[..len]` is valid UTF-8.
+        string.as_mut_vec()
+    };
+    let len = character_name_normalize_bytes(bytes).len();
+    bytes.truncate(len);
+}
+
+/// Normalize the given character name in place according to UAX44-LM2.
+///
+/// The slice returned is guaranteed to be valid UTF-8 for all possible values
+/// of `slice`.
+///
+/// See: http://unicode.org/reports/tr44/#UAX44-LM2
+fn character_name_normalize_bytes(slice: &mut [u8]) -> &mut [u8] {
+    // According to Unicode 4.8, character names consist only of Latin
+    // capital letters A to Z, ASCII digits, ASCII space or ASCII hypen.
+    // Therefore, we can do very simplistic case folding and operate on the
+    // raw bytes, since everything is ASCII. Note that we don't actually know
+    // whether `slice` is all ASCII or not, so we drop all non-ASCII bytes.
+    let mut next_write = 0;
+    let mut prev_letter = false;
+    // let mut prev_space = true;
+    for i in 0..slice.len() {
+        // SAFETY ARGUMENT: To guarantee that the resulting slice is valid
+        // UTF-8, we ensure that the slice contains only ASCII bytes. In
+        // particular, we drop every non-ASCII byte from the normalized string.
+        let b = slice[i];
+        if b == b' ' {
+            // Drop spaces.
+        } else if b == b'_' {
+            // Drop the underscore.
+        } else if b == b'-' {
+            let medial = prev_letter
+                && slice.get(i+1).map_or(false, |b| b.is_ascii_alphabetic());
+            let mut keep_hyphen = !medial;
+            // We want to keep the hypen only if it isn't medial. However,
+            // there is one exception. We need to keep the hypen in the
+            // character (U+1180) named `HANGUL JUNGSEONG O-E`. So we check for
+            // that here.
+            let next_e = slice
+                .get(i+1)
+                .map_or(false, |&b| b == b'E' || b == b'e');
+            // More characters after the final E are fine, as long as they are
+            // underscores and spaces.
+            let rest_empty = i+2 >= slice.len()
+                || slice[i+2..].iter().all(|&b| b == b' ' || b == b'_');
+            if !keep_hyphen && next_e && rest_empty {
+                keep_hyphen = slice[..next_write] == b"hanguljungseongo"[..];
+            }
+            if keep_hyphen {
+                slice[next_write] = b;
+                next_write += 1;
+            }
+        } else if b'A' <= b && b <= b'Z' {
+            slice[next_write] = b + (b'a' - b'A');
+            next_write += 1;
+        } else if b <= 0x7F {
+            slice[next_write] = b;
+            next_write += 1;
+        }
+        // prev_space = false;
+        prev_letter = b.is_ascii_alphabetic();
+    }
+    &mut slice[..next_write]
+}
+
+/// Normalize the given symbolic name in place according to UAX44-LM3.
+///
+/// A "symbolic name" typically corresponds to property names and property
+/// value aliases. Note, though, that it should not be applied to property
+/// string values.
+///
+/// See: http://unicode.org/reports/tr44/#UAX44-LM2
+pub fn symbolic_name_normalize(string: &mut String) {
+    let bytes = unsafe {
+        // SAFETY: `symbolic_name_normalize_bytes` guarantees that
+        // `bytes[..len]` is valid UTF-8.
+        string.as_mut_vec()
+    };
+    let len = symbolic_name_normalize_bytes(bytes).len();
+    bytes.truncate(len);
+}
+
+/// Normalize the given symbolic name in place according to UAX44-LM3.
+///
+/// A "symbolic name" typically corresponds to property names and property
+/// value aliases. Note, though, that it should not be applied to property
+/// string values.
+///
+/// The slice returned is guaranteed to be valid UTF-8 for all possible values
+/// of `slice`.
+///
+/// See: http://unicode.org/reports/tr44/#UAX44-LM3
+fn symbolic_name_normalize_bytes(slice: &mut [u8]) -> &mut [u8] {
+    // I couldn't find a place in the standard that specified that property
+    // names/aliases had a particular structure (unlike character names), but
+    // we assume that it's ASCII only and drop anything that isn't ASCII.
+    let mut start = 0;
+    let mut starts_with_is = false;
+    if slice.len() >= 2 {
+        // Ignore any "is" prefix.
+        starts_with_is =
+            slice[0..2] == b"is"[..]
+            || slice[0..2] == b"IS"[..]
+            || slice[0..2] == b"iS"[..]
+            || slice[0..2] == b"Is"[..];
+        if starts_with_is {
+            start = 2;
+        }
+    }
+    let mut next_write = 0;
+    for i in start..slice.len() {
+        // SAFETY ARGUMENT: To guarantee that the resulting slice is valid
+        // UTF-8, we ensure that the slice contains only ASCII bytes. In
+        // particular, we drop every non-ASCII byte from the normalized string.
+        let b = slice[i];
+        if b == b' ' || b == b'_' || b == b'-' {
+            continue;
+        } else if b'A' <= b && b <= b'Z' {
+            slice[next_write] = b + (b'a' - b'A');
+            next_write += 1;
+        } else if b <= 0x7F {
+            slice[next_write] = b;
+            next_write += 1;
+        }
+    }
+    // Special case: ISO_Comment has a 'isc' abbreviation. Since we generally
+    // ignore 'is' prefixes, the 'isc' abbreviation gets caught in the cross
+    // fire and ends up creating an alias for 'c' to 'ISO_Comment', but it
+    // is actually an alias for the 'Other' general category.
+    if starts_with_is && next_write == 1 && slice[0] == b'c' {
+        slice[0] = b'i';
+        slice[1] = b's';
+        slice[2] = b'c';
+        next_write = 3;
+    }
+    &mut slice[..next_write]
+}
+
+#[cfg(test)]
+mod tests {
+    use super::{
+        character_name_normalize, character_name_normalize_bytes,
+        symbolic_name_normalize, symbolic_name_normalize_bytes,
+    };
+
+    fn char_norm(s: &str) -> String {
+        let mut s = s.to_string();
+        character_name_normalize(&mut s);
+        s
+    }
+
+    fn sym_norm(s: &str) -> String {
+        let mut s = s.to_string();
+        symbolic_name_normalize(&mut s);
+        s
+    }
+
+    #[test]
+    fn char_normalize() {
+        assert_eq!(char_norm("HANGUL JUNGSEONG O-E"), "hanguljungseongo-e");
+        assert_eq!(char_norm("HANGUL JUNGSEONG O-E _"), "hanguljungseongo-e");
+        assert_eq!(char_norm("zero-width space"), "zerowidthspace");
+        assert_eq!(char_norm("zerowidthspace"), "zerowidthspace");
+        assert_eq!(char_norm("ZERO WIDTH SPACE"), "zerowidthspace");
+        assert_eq!(char_norm("TIBETAN MARK TSA -PHRU"), "tibetanmarktsa-phru");
+        assert_eq!(char_norm("tibetan_letter_-a"), "tibetanletter-a");
+    }
+
+    #[test]
+    fn sym_normalize() {
+        assert_eq!(sym_norm("Line_Break"), "linebreak");
+        assert_eq!(sym_norm("Line-break"), "linebreak");
+        assert_eq!(sym_norm("linebreak"), "linebreak");
+        assert_eq!(sym_norm("BA"), "ba");
+        assert_eq!(sym_norm("ba"), "ba");
+        assert_eq!(sym_norm("Greek"), "greek");
+        assert_eq!(sym_norm("isGreek"), "greek");
+        assert_eq!(sym_norm("IS_Greek"), "greek");
+        assert_eq!(sym_norm("isc"), "isc");
+        assert_eq!(sym_norm("is c"), "isc");
+        assert_eq!(sym_norm("is_c"), "isc");
+    }
+
+    #[test]
+    fn valid_utf8_character() {
+        let mut x = b"abc\xFFxyz".to_vec();
+        let y = character_name_normalize_bytes(&mut x);
+        assert_eq!(y, b"abcxyz");
+    }
+
+    #[test]
+    fn valid_utf8_symbolic() {
+        let mut x = b"abc\xFFxyz".to_vec();
+        let y = symbolic_name_normalize_bytes(&mut x);
+        assert_eq!(y, b"abcxyz");
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/ucd_util/property.rs.html b/target/doc/src/ucd_util/property.rs.html new file mode 100644 index 0000000..f60094c --- /dev/null +++ b/target/doc/src/ucd_util/property.rs.html @@ -0,0 +1,251 @@ +property.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+
+/// The type of a property name table.
+///
+/// A property name table is a sequence of sorted tuples, where the first
+/// value in each tuple is a normalized property name and the second value of
+/// each tuple is the corresponding canonical property name.
+pub type PropertyTable = &'static [(&'static str, &'static str)];
+
+/// Find the canonical property name for the given normalized property name.
+///
+/// If no such property exists, then `None` is returned.
+///
+/// The normalized property name must have been normalized according to
+/// UAX44 LM3, which can be done using `symbolic_name_normalize`.
+pub fn canonical_property_name(
+    property_table: PropertyTable,
+    normalized_property_name: &str,
+) -> Option<&'static str> {
+    property_table
+        .binary_search_by_key(&normalized_property_name, |&(n, _)| n)
+        .ok()
+        .map(|i| property_table[i].1)
+}
+
+/// Type of a property value table.
+///
+/// A property value table maps property names to a mapping of property values,
+/// where the mapping of property values is represented by a sequence of
+/// tuples. The first element of each tuple is a normalized property value
+/// while the second element of each tuple is the corresponding canonical
+/// property value.
+///
+/// Note that a property value table only includes values for properties that
+/// are catalogs, enumerations or binary properties. Properties that have
+/// string values (such as case or decomposition mappings), numeric values
+/// or are miscellaneous are not represented in this table.
+pub type PropertyValueTable = &'static [(&'static str, PropertyValues)];
+
+/// A mapping of property values for a specific property.
+///
+/// The first element of each tuple is a normalized property value while the
+/// second element of each tuple is the corresponding canonical property
+/// value.
+pub type PropertyValues = &'static [(&'static str, &'static str)];
+
+/// Find the set of possible property values for a given property.
+///
+/// The set returned is a mapping expressed as a sorted list of tuples.
+/// The first element of each tuple is a normalized property value while the
+/// second element of each tuple is the corresponding canonical property
+/// value.
+///
+/// If no such property exists, then `None` is returned.
+///
+/// The given property name must be in its canonical form, which can be
+/// found using `canonical_property_name`.
+pub fn property_values(
+    property_value_table: PropertyValueTable,
+    canonical_property_name: &str,
+) -> Option<PropertyValues> {
+    property_value_table
+        .binary_search_by_key(&canonical_property_name, |&(n, _)| n)
+        .ok()
+        .map(|i| property_value_table[i].1)
+}
+
+/// Find the canonical property value for the given normalized property
+/// value.
+///
+/// The given property values should correspond to the values for the property
+/// under question, which can be found using `property_values`.
+///
+/// If no such property value exists, then `None` is returned.
+///
+/// The normalized property value must have been normalized according to
+/// UAX44 LM3, which can be done using `symbolic_name_normalize`.
+pub fn canonical_property_value(
+    property_values: PropertyValues,
+    normalized_property_value: &str,
+) -> Option<&'static str> {
+    // This is cute. The types line up, so why not?
+    canonical_property_name(property_values, normalized_property_value)
+}
+
+
+#[cfg(test)]
+mod tests {
+    use unicode_tables::property_names::PROPERTY_NAMES;
+    use unicode_tables::property_values::PROPERTY_VALUES;
+
+    use super::{
+        canonical_property_name, property_values, canonical_property_value,
+    };
+
+    #[test]
+    fn canonical_property_name_1() {
+        assert_eq!(
+            canonical_property_name(PROPERTY_NAMES, "gc"),
+            Some("General_Category"));
+        assert_eq!(
+            canonical_property_name(PROPERTY_NAMES, "generalcategory"),
+            Some("General_Category"));
+        assert_eq!(
+            canonical_property_name(PROPERTY_NAMES, "g c"),
+            None);
+    }
+
+    #[test]
+    fn property_values_1() {
+        assert_eq!(
+            property_values(PROPERTY_VALUES, "White_Space"),
+            Some(&[
+                ("f", "No"), ("false", "No"), ("n", "No"), ("no", "No"),
+                ("t", "Yes"), ("true", "Yes"), ("y", "Yes"), ("yes", "Yes"),
+            ][..]));
+    }
+
+    #[test]
+    fn canonical_property_value_1() {
+        let values = property_values(PROPERTY_VALUES, "White_Space").unwrap();
+        assert_eq!(canonical_property_value(values, "false"), Some("No"));
+        assert_eq!(canonical_property_value(values, "t"), Some("Yes"));
+        assert_eq!(canonical_property_value(values, "F"), None);
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/ucd_util/unicode_tables/jamo_short_name.rs.html b/target/doc/src/ucd_util/unicode_tables/jamo_short_name.rs.html new file mode 100644 index 0000000..369dbb3 --- /dev/null +++ b/target/doc/src/ucd_util/unicode_tables/jamo_short_name.rs.html @@ -0,0 +1,47 @@ +jamo_short_name.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+
+// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
+//
+//  ucd-generate jamo-short-name /home/andrew/tmp/ucd/12.1.0/
+//
+// ucd-generate is available on crates.io.
+
+pub const JAMO_SHORT_NAME: &'static [(u32, &'static str)] = &[
+  (4352, "G"), (4353, "GG"), (4354, "N"), (4355, "D"), (4356, "DD"),
+  (4357, "R"), (4358, "M"), (4359, "B"), (4360, "BB"), (4361, "S"),
+  (4362, "SS"), (4363, ""), (4364, "J"), (4365, "JJ"), (4366, "C"),
+  (4367, "K"), (4368, "T"), (4369, "P"), (4370, "H"), (4449, "A"),
+  (4450, "AE"), (4451, "YA"), (4452, "YAE"), (4453, "EO"), (4454, "E"),
+  (4455, "YEO"), (4456, "YE"), (4457, "O"), (4458, "WA"), (4459, "WAE"),
+  (4460, "OE"), (4461, "YO"), (4462, "U"), (4463, "WEO"), (4464, "WE"),
+  (4465, "WI"), (4466, "YU"), (4467, "EU"), (4468, "YI"), (4469, "I"),
+  (4520, "G"), (4521, "GG"), (4522, "GS"), (4523, "N"), (4524, "NJ"),
+  (4525, "NH"), (4526, "D"), (4527, "L"), (4528, "LG"), (4529, "LM"),
+  (4530, "LB"), (4531, "LS"), (4532, "LT"), (4533, "LP"), (4534, "LH"),
+  (4535, "M"), (4536, "B"), (4537, "BS"), (4538, "S"), (4539, "SS"),
+  (4540, "NG"), (4541, "J"), (4542, "C"), (4543, "K"), (4544, "T"),
+  (4545, "P"), (4546, "H"),
+];
+
+
\ No newline at end of file diff --git a/target/doc/src/ucd_util/unicode_tables/mod.rs.html b/target/doc/src/ucd_util/unicode_tables/mod.rs.html new file mode 100644 index 0000000..73758d4 --- /dev/null +++ b/target/doc/src/ucd_util/unicode_tables/mod.rs.html @@ -0,0 +1,13 @@ +mod.rs.html -- source
1
+2
+3
+4
+5
+
+pub mod jamo_short_name;
+#[cfg(test)]
+pub mod property_names;
+#[cfg(test)]
+pub mod property_values;
+
+
\ No newline at end of file diff --git a/target/doc/src/utf8_ranges/char_utf8.rs.html b/target/doc/src/utf8_ranges/char_utf8.rs.html new file mode 100644 index 0000000..147b1fe --- /dev/null +++ b/target/doc/src/utf8_ranges/char_utf8.rs.html @@ -0,0 +1,75 @@ +char_utf8.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+
+// Pulled from std::char until encode_utf8 stabilizes. ---AG
+
+// UTF-8 ranges and tags for encoding characters
+const TAG_CONT: u8    = 0b1000_0000;
+const TAG_TWO_B: u8   = 0b1100_0000;
+const TAG_THREE_B: u8 = 0b1110_0000;
+const TAG_FOUR_B: u8  = 0b1111_0000;
+const MAX_ONE_B: u32   =     0x80;
+const MAX_TWO_B: u32   =    0x800;
+const MAX_THREE_B: u32 =  0x10000;
+
+#[inline]
+pub fn encode_utf8(character: char, dst: &mut [u8]) -> Option<usize> {
+    let code = character as u32;
+    if code < MAX_ONE_B && !dst.is_empty() {
+        dst[0] = code as u8;
+        Some(1)
+    } else if code < MAX_TWO_B && dst.len() >= 2 {
+        dst[0] = (code >> 6 & 0x1F) as u8 | TAG_TWO_B;
+        dst[1] = (code & 0x3F) as u8 | TAG_CONT;
+        Some(2)
+    } else if code < MAX_THREE_B && dst.len() >= 3  {
+        dst[0] = (code >> 12 & 0x0F) as u8 | TAG_THREE_B;
+        dst[1] = (code >>  6 & 0x3F) as u8 | TAG_CONT;
+        dst[2] = (code & 0x3F) as u8 | TAG_CONT;
+        Some(3)
+    } else if dst.len() >= 4 {
+        dst[0] = (code >> 18 & 0x07) as u8 | TAG_FOUR_B;
+        dst[1] = (code >> 12 & 0x3F) as u8 | TAG_CONT;
+        dst[2] = (code >>  6 & 0x3F) as u8 | TAG_CONT;
+        dst[3] = (code & 0x3F) as u8 | TAG_CONT;
+        Some(4)
+    } else {
+        None
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/src/utf8_ranges/lib.rs.html b/target/doc/src/utf8_ranges/lib.rs.html new file mode 100644 index 0000000..a1f789f --- /dev/null +++ b/target/doc/src/utf8_ranges/lib.rs.html @@ -0,0 +1,1071 @@ +lib.rs.html -- source
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+
+/*!
+Crate `utf8-ranges` converts ranges of Unicode scalar values to equivalent
+ranges of UTF-8 bytes. This is useful for constructing byte based automatons
+that need to embed UTF-8 decoding.
+
+See the documentation on the `Utf8Sequences` iterator for more details and
+an example.
+
+# Wait, what is this?
+
+This is simplest to explain with an example. Let's say you wanted to test
+whether a particular byte sequence was a Cyrillic character. One possible
+scalar value range is `[0400-04FF]`. The set of allowed bytes for this
+range can be expressed as a sequence of byte ranges:
+
+```ignore
+[D0-D3][80-BF]
+```
+
+This is simple enough: simply encode the boundaries, `0400` encodes to
+`D0 80` and `04FF` encodes to `D3 BF`, and create ranges from each
+corresponding pair of bytes: `D0` to `D3` and `80` to `BF`.
+
+However, what if you wanted to add the Cyrillic Supplementary characters to
+your range? Your range might then become `[0400-052F]`. The same procedure
+as above doesn't quite work because `052F` encodes to `D4 AF`. The byte ranges
+you'd get from the previous transformation would be `[D0-D4][80-AF]`. However,
+this isn't quite correct because this range doesn't capture many characters,
+for example, `04FF` (because its last byte, `BF` isn't in the range `80-AF`).
+
+Instead, you need multiple sequences of byte ranges:
+
+```ignore
+[D0-D3][80-BF]  # matches codepoints 0400-04FF
+[D4][80-AF]     # matches codepoints 0500-052F
+```
+
+This gets even more complicated if you want bigger ranges, particularly if
+they naively contain surrogate codepoints. For example, the sequence of byte
+ranges for the basic multilingual plane (`[0000-FFFF]`) look like this:
+
+```ignore
+[0-7F]
+[C2-DF][80-BF]
+[E0][A0-BF][80-BF]
+[E1-EC][80-BF][80-BF]
+[ED][80-9F][80-BF]
+[EE-EF][80-BF][80-BF]
+```
+
+Note that the byte ranges above will *not* match any erroneous encoding of
+UTF-8, including encodings of surrogate codepoints.
+
+And, of course, for all of Unicode (`[000000-10FFFF]`):
+
+```ignore
+[0-7F]
+[C2-DF][80-BF]
+[E0][A0-BF][80-BF]
+[E1-EC][80-BF][80-BF]
+[ED][80-9F][80-BF]
+[EE-EF][80-BF][80-BF]
+[F0][90-BF][80-BF][80-BF]
+[F1-F3][80-BF][80-BF][80-BF]
+[F4][80-8F][80-BF][80-BF]
+```
+
+This crate automates the process of creating these byte ranges from ranges of
+Unicode scalar values.
+
+# Why would I ever use this?
+
+You probably won't ever need this. In 99% of cases, you just decode the byte
+sequence into a Unicode scalar value and compare scalar values directly.
+However, this explicit decoding step isn't always possible. For example, the
+construction of some finite state machines may benefit from converting ranges
+of scalar values into UTF-8 decoder automata (e.g., for character classes in
+regular expressions).
+
+# Lineage
+
+I got the idea and general implementation strategy from Russ Cox in his
+[article on regexps](https://web.archive.org/web/20160404141123/https://swtch.com/~rsc/regexp/regexp3.html) and RE2.
+Russ Cox got it from Ken Thompson's `grep` (no source, folk lore?).
+I also got the idea from
+[Lucene](https://github.com/apache/lucene-solr/blob/ae93f4e7ac6a3908046391de35d4f50a0d3c59ca/lucene/core/src/java/org/apache/lucene/util/automaton/UTF32ToUTF8.java),
+which uses it for executing automata on their term index.
+*/
+
+#![deny(missing_docs)]
+
+#[cfg(test)]
+extern crate quickcheck;
+#[cfg(test)]
+#[macro_use]
+extern crate doc_comment;
+
+#[cfg(test)]
+doctest!("../README.md");
+
+use std::char;
+use std::fmt;
+use std::slice;
+
+use char_utf8::encode_utf8;
+
+const MAX_UTF8_BYTES: usize = 4;
+
+mod char_utf8;
+
+/// Utf8Sequence represents a sequence of byte ranges.
+///
+/// To match a Utf8Sequence, a candidate byte sequence must match each
+/// successive range.
+///
+/// For example, if there are two ranges, `[C2-DF][80-BF]`, then the byte
+/// sequence `\xDD\x61` would not match because `0x61 < 0x80`.
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub enum Utf8Sequence {
+    /// One byte range.
+    One(Utf8Range),
+    /// Two successive byte ranges.
+    Two([Utf8Range; 2]),
+    /// Three successive byte ranges.
+    Three([Utf8Range; 3]),
+    /// Four successive byte ranges.
+    Four([Utf8Range; 4]),
+}
+
+impl Utf8Sequence {
+    /// Creates a new UTF-8 sequence from the encoded bytes of a scalar value
+    /// range.
+    ///
+    /// This assumes that `start` and `end` have the same length.
+    fn from_encoded_range(start: &[u8], end: &[u8]) -> Self {
+        assert_eq!(start.len(), end.len());
+        match start.len() {
+            2 => Utf8Sequence::Two([
+                Utf8Range::new(start[0], end[0]),
+                Utf8Range::new(start[1], end[1]),
+            ]),
+            3 => Utf8Sequence::Three([
+                Utf8Range::new(start[0], end[0]),
+                Utf8Range::new(start[1], end[1]),
+                Utf8Range::new(start[2], end[2]),
+            ]),
+            4 => Utf8Sequence::Four([
+                Utf8Range::new(start[0], end[0]),
+                Utf8Range::new(start[1], end[1]),
+                Utf8Range::new(start[2], end[2]),
+                Utf8Range::new(start[3], end[3]),
+            ]),
+            n => unreachable!("invalid encoded length: {}", n),
+        }
+    }
+
+    /// Returns the underlying sequence of byte ranges as a slice.
+    pub fn as_slice(&self) -> &[Utf8Range] {
+        use self::Utf8Sequence::*;
+        match *self {
+            One(ref r) => unsafe { slice::from_raw_parts(r, 1) },
+            Two(ref r) => &r[..],
+            Three(ref r) => &r[..],
+            Four(ref r) => &r[..],
+        }
+    }
+
+    /// Returns the number of byte ranges in this sequence.
+    ///
+    /// The length is guaranteed to be in the closed interval `[1, 4]`.
+    pub fn len(&self) -> usize {
+        self.as_slice().len()
+    }
+
+    /// Returns true if and only if a prefix of `bytes` matches this sequence
+    /// of byte ranges.
+    pub fn matches(&self, bytes: &[u8]) -> bool {
+        if bytes.len() < self.len() {
+            return false;
+        }
+        for (&b, r) in bytes.iter().zip(self) {
+            if !r.matches(b) {
+                return false;
+            }
+        }
+        true
+    }
+}
+
+impl<'a> IntoIterator for &'a Utf8Sequence {
+    type IntoIter = slice::Iter<'a, Utf8Range>;
+    type Item = &'a Utf8Range;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.as_slice().into_iter()
+    }
+}
+
+impl fmt::Debug for Utf8Sequence {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        use self::Utf8Sequence::*;
+        match *self {
+            One(ref r) => write!(f, "{:?}", r),
+            Two(ref r) => write!(f, "{:?}{:?}", r[0], r[1]),
+            Three(ref r) => write!(f, "{:?}{:?}{:?}", r[0], r[1], r[2]),
+            Four(ref r) => write!(f, "{:?}{:?}{:?}{:?}",
+                                  r[0], r[1], r[2], r[3]),
+        }
+    }
+}
+
+/// A single inclusive range of UTF-8 bytes.
+#[derive(Clone, Copy, PartialEq, Eq)]
+pub struct Utf8Range {
+    /// Start of byte range (inclusive).
+    pub start: u8,
+    /// End of byte range (inclusive).
+    pub end: u8,
+}
+
+impl Utf8Range {
+    fn new(start: u8, end: u8) -> Self {
+        Utf8Range { start: start, end: end }
+    }
+
+    /// Returns true if and only if the given byte is in this range.
+    pub fn matches(&self, b: u8) -> bool {
+        self.start <= b && b <= self.end
+    }
+}
+
+impl fmt::Debug for Utf8Range {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        if self.start == self.end {
+            write!(f, "[{:X}]", self.start)
+        } else {
+            write!(f, "[{:X}-{:X}]", self.start, self.end)
+        }
+    }
+}
+
+/// An iterator over ranges of matching UTF-8 byte sequences.
+///
+/// The iteration represents an alternation of comprehensive byte sequences
+/// that match precisely the set of UTF-8 encoded scalar values.
+///
+/// A byte sequence corresponds to one of the scalar values in the range given
+/// if and only if it completely matches exactly one of the sequences of byte
+/// ranges produced by this iterator.
+///
+/// Each sequence of byte ranges matches a unique set of bytes. That is, no two
+/// sequences will match the same bytes.
+///
+/// # Example
+///
+/// This shows how to match an arbitrary byte sequence against a range of
+/// scalar values.
+///
+/// ```rust
+/// use utf8_ranges::{Utf8Sequences, Utf8Sequence};
+///
+/// fn matches(seqs: &[Utf8Sequence], bytes: &[u8]) -> bool {
+///     for range in seqs {
+///         if range.matches(bytes) {
+///             return true;
+///         }
+///     }
+///     false
+/// }
+///
+/// // Test the basic multilingual plane.
+/// let seqs: Vec<_> = Utf8Sequences::new('\u{0}', '\u{FFFF}').collect();
+///
+/// // UTF-8 encoding of 'a'.
+/// assert!(matches(&seqs, &[0x61]));
+/// // UTF-8 encoding of '☃' (`\u{2603}`).
+/// assert!(matches(&seqs, &[0xE2, 0x98, 0x83]));
+/// // UTF-8 encoding of `\u{10348}` (outside the BMP).
+/// assert!(!matches(&seqs, &[0xF0, 0x90, 0x8D, 0x88]));
+/// // Tries to match against a UTF-8 encoding of a surrogate codepoint,
+/// // which is invalid UTF-8, and therefore fails, despite the fact that
+/// // the corresponding codepoint (0xD800) falls in the range given.
+/// assert!(!matches(&seqs, &[0xED, 0xA0, 0x80]));
+/// // And fails against plain old invalid UTF-8.
+/// assert!(!matches(&seqs, &[0xFF, 0xFF]));
+/// ```
+///
+/// If this example seems circuitous, that's because it is! It's meant to be
+/// illustrative. In practice, you could just try to decode your byte sequence
+/// and compare it with the scalar value range directly. However, this is not
+/// always possible (for example, in a byte based automaton).
+pub struct Utf8Sequences {
+    range_stack: Vec<ScalarRange>,
+}
+
+impl Utf8Sequences {
+    /// Create a new iterator over UTF-8 byte ranges for the scalar value range
+    /// given.
+    pub fn new(start: char, end: char) -> Self {
+        let mut it = Utf8Sequences { range_stack: vec![] };
+        it.push(start as u32, end as u32);
+        it
+    }
+
+    /// reset resets the scalar value range.
+    /// Any existing state is cleared, but resources may be reused.
+    ///
+    /// N.B. Benchmarks say that this method is dubious.
+    #[doc(hidden)]
+    pub fn reset(&mut self, start: char, end: char) {
+        self.range_stack.clear();
+        self.push(start as u32, end as u32);
+    }
+
+    fn push(&mut self, start: u32, end: u32) {
+        self.range_stack.push(ScalarRange { start: start, end: end });
+    }
+}
+
+struct ScalarRange {
+    start: u32,
+    end: u32,
+}
+
+impl fmt::Debug for ScalarRange {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "ScalarRange({:X}, {:X})", self.start, self.end)
+    }
+}
+
+impl Iterator for Utf8Sequences {
+    type Item = Utf8Sequence;
+
+    fn next(&mut self) -> Option<Self::Item> {
+    'TOP:
+        while let Some(mut r) = self.range_stack.pop() {
+        'INNER:
+            loop {
+                if let Some((r1, r2)) = r.split() {
+                    self.push(r2.start, r2.end);
+                    r.start = r1.start;
+                    r.end = r1.end;
+                    continue 'INNER;
+                }
+                if !r.is_valid() {
+                    continue 'TOP;
+                }
+                for i in 1..MAX_UTF8_BYTES {
+                    let max = max_scalar_value(i);
+                    if r.start <= max && max < r.end {
+                        self.push(max + 1, r.end);
+                        r.end = max;
+                        continue 'INNER;
+                    }
+                }
+                if let Some(ascii_range) = r.as_ascii() {
+                    return Some(Utf8Sequence::One(ascii_range));
+                }
+                for i in 1..MAX_UTF8_BYTES {
+                    let m = (1 << (6 * i)) - 1;
+                    if (r.start & !m) != (r.end & !m) {
+                        if (r.start & m) != 0 {
+                            self.push((r.start | m) + 1, r.end);
+                            r.end = r.start | m;
+                            continue 'INNER;
+                        }
+                        if (r.end & m) != m {
+                            self.push(r.end & !m, r.end);
+                            r.end = (r.end & !m) - 1;
+                            continue 'INNER;
+                        }
+                    }
+                }
+                let mut start = [0; MAX_UTF8_BYTES];
+                let mut end = [0; MAX_UTF8_BYTES];
+                let n = r.encode(&mut start, &mut end);
+                return Some(Utf8Sequence::from_encoded_range(
+                    &start[0..n], &end[0..n]));
+            }
+        }
+        None
+    }
+}
+
+impl ScalarRange {
+    /// split splits this range if it overlaps with a surrogate codepoint.
+    ///
+    /// Either or both ranges may be invalid.
+    fn split(&self) -> Option<(ScalarRange, ScalarRange)> {
+        if self.start < 0xE000 && self.end > 0xD7FF {
+            Some((ScalarRange {
+                start: self.start,
+                end: 0xD7FF,
+            }, ScalarRange {
+                start: 0xE000,
+                end: self.end,
+            }))
+        } else {
+            None
+        }
+    }
+
+    /// is_valid returns true if and only if start <= end.
+    fn is_valid(&self) -> bool {
+        self.start <= self.end
+    }
+
+    /// as_ascii returns this range as a Utf8Range if and only if all scalar
+    /// values in this range can be encoded as a single byte.
+    fn as_ascii(&self) -> Option<Utf8Range> {
+        if self.is_ascii() {
+            Some(Utf8Range::new(self.start as u8, self.end as u8))
+        } else {
+            None
+        }
+    }
+
+    /// is_ascii returns true if the range is ASCII only (i.e., takes a single
+    /// byte to encode any scalar value).
+    fn is_ascii(&self) -> bool {
+        self.is_valid() && self.end <= 0x7f
+    }
+
+    /// encode writes the UTF-8 encoding of the start and end of this range
+    /// to the corresponding destination slices.
+    ///
+    /// The slices should have room for at least `MAX_UTF8_BYTES`.
+    fn encode(&self, start: &mut [u8], end: &mut [u8]) -> usize {
+        let cs = char::from_u32(self.start).unwrap();
+        let ce = char::from_u32(self.end).unwrap();
+        let n = encode_utf8(cs, start).unwrap();
+        let m = encode_utf8(ce, end).unwrap();
+        assert_eq!(n, m);
+        n
+    }
+}
+
+fn max_scalar_value(nbytes: usize) -> u32 {
+    match nbytes {
+        1 => 0x007F,
+        2 => 0x07FF,
+        3 => 0xFFFF,
+        4 => 0x10FFFF,
+        _ => unreachable!("invalid UTF-8 byte sequence size"),
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::char;
+
+    use quickcheck::{TestResult, quickcheck};
+
+    use char_utf8::encode_utf8;
+    use {MAX_UTF8_BYTES, Utf8Range, Utf8Sequences};
+
+    fn rutf8(s: u8, e: u8) -> Utf8Range {
+        Utf8Range::new(s, e)
+    }
+
+    fn never_accepts_surrogate_codepoints(start: char, end: char) {
+        let mut buf = [0; MAX_UTF8_BYTES];
+        for cp in 0xD800..0xE000 {
+            let c = unsafe { ::std::mem::transmute(cp) };
+            let n = encode_utf8(c, &mut buf).unwrap();
+            for r in Utf8Sequences::new(start, end) {
+                if r.matches(&buf[0..n]) {
+                    panic!("Sequence ({:X}, {:X}) contains range {:?}, \
+                            which matches surrogate code point {:X} \
+                            with encoded bytes {:?}",
+                           start as u32, end as u32, r, cp, &buf[0..n]);
+                }
+            }
+        }
+    }
+
+    #[test]
+    fn codepoints_no_surrogates() {
+        never_accepts_surrogate_codepoints('\u{0}', '\u{FFFF}');
+        never_accepts_surrogate_codepoints('\u{0}', '\u{10FFFF}');
+        never_accepts_surrogate_codepoints('\u{0}', '\u{10FFFE}');
+        never_accepts_surrogate_codepoints('\u{80}', '\u{10FFFF}');
+        never_accepts_surrogate_codepoints('\u{D7FF}', '\u{E000}');
+    }
+
+    #[test]
+    fn single_codepoint_one_sequence() {
+        // Tests that every range of scalar values that contains a single
+        // scalar value is recognized by one sequence of byte ranges.
+        for i in 0x0..(0x10FFFF + 1) {
+            let c = match char::from_u32(i) {
+                None => continue,
+                Some(c) => c,
+            };
+            let seqs: Vec<_> = Utf8Sequences::new(c, c).collect();
+            assert_eq!(seqs.len(), 1);
+        }
+    }
+
+    #[test]
+    fn qc_codepoints_no_surrogate() {
+        fn p(s: char, e: char) -> TestResult {
+            if s > e {
+                return TestResult::discard();
+            }
+            never_accepts_surrogate_codepoints(s, e);
+            TestResult::passed()
+        }
+        quickcheck(p as fn(char, char) -> TestResult);
+    }
+
+    #[test]
+    fn bmp() {
+        use Utf8Sequence::*;
+
+        let seqs = Utf8Sequences::new('\u{0}', '\u{FFFF}')
+                                 .collect::<Vec<_>>();
+        assert_eq!(seqs, vec![
+            One(rutf8(0x0, 0x7F)),
+            Two([rutf8(0xC2, 0xDF), rutf8(0x80, 0xBF)]),
+            Three([rutf8(0xE0, 0xE0), rutf8(0xA0, 0xBF), rutf8(0x80, 0xBF)]),
+            Three([rutf8(0xE1, 0xEC), rutf8(0x80, 0xBF), rutf8(0x80, 0xBF)]),
+            Three([rutf8(0xED, 0xED), rutf8(0x80, 0x9F), rutf8(0x80, 0xBF)]),
+            Three([rutf8(0xEE, 0xEF), rutf8(0x80, 0xBF), rutf8(0x80, 0xBF)]),
+        ]);
+    }
+
+    #[test]
+    fn scratch() {
+        for range in Utf8Sequences::new('\u{0}', '\u{FFFF}') {
+            println!("{:?}", range);
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/target/doc/storage.js b/target/doc/storage.js new file mode 100644 index 0000000..33632ba --- /dev/null +++ b/target/doc/storage.js @@ -0,0 +1 @@ +var resourcesSuffix="";var currentTheme=document.getElementById("themeStyle");var mainTheme=document.getElementById("mainThemeStyle");var savedHref=[];function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className);}function addClass(elem,className){if(!elem||!elem.classList){return;}elem.classList.add(className);}function removeClass(elem,className){if(!elem||!elem.classList){return;}elem.classList.remove(className);}function isHidden(elem){return elem.offsetParent===null;}function onEach(arr,func,reversed){if(arr&&arr.length>0&&func){var length=arr.length;if(reversed!==true){for(var i=0;i=0;--i){if(func(arr[i])===true){return true;}}}}return false;}function onEachLazy(lazyArray,func,reversed){return onEach(Array.prototype.slice.call(lazyArray),func,reversed);}function usableLocalStorage(){if(typeof(Storage)==="undefined"){return false;}try{window.localStorage;}catch(err){return false;}return true;}function updateLocalStorage(name,value){if(usableLocalStorage()){localStorage[name]=value;}else{}}function getCurrentValue(name){if(usableLocalStorage()&&localStorage[name]!==undefined){return localStorage[name];}return null;}function switchTheme(styleElem,mainStyleElem,newTheme){var fullBasicCss="rustdoc"+resourcesSuffix+".css";var fullNewTheme=newTheme+resourcesSuffix+".css";var newHref=mainStyleElem.href.replace(fullBasicCss,fullNewTheme);if(styleElem.href===newHref){return;}var found=false;if(savedHref.length===0){onEachLazy(document.getElementsByTagName("link"),function(el){savedHref.push(el.href);});}onEach(savedHref,function(el){if(el===newHref){found=true;return true;}});if(found===true){styleElem.href=newHref;updateLocalStorage("rustdoc-theme",newTheme);}}switchTheme(currentTheme,mainTheme,getCurrentValue("rustdoc-theme")||"light"); \ No newline at end of file diff --git a/target/doc/theme.js b/target/doc/theme.js new file mode 100644 index 0000000..f3a6a82 --- /dev/null +++ b/target/doc/theme.js @@ -0,0 +1,39 @@ +var themes = document.getElementById("theme-choices"); +var themePicker = document.getElementById("theme-picker"); + +function switchThemeButtonState() { + if (themes.style.display === "block") { + themes.style.display = "none"; + themePicker.style.borderBottomRightRadius = "3px"; + themePicker.style.borderBottomLeftRadius = "3px"; + } else { + themes.style.display = "block"; + themePicker.style.borderBottomRightRadius = "0"; + themePicker.style.borderBottomLeftRadius = "0"; + } +}; + +function handleThemeButtonsBlur(e) { + var active = document.activeElement; + var related = e.relatedTarget; + + if (active.id !== "themePicker" && + (!active.parentNode || active.parentNode.id !== "theme-choices") && + (!related || + (related.id !== "themePicker" && + (!related.parentNode || related.parentNode.id !== "theme-choices")))) { + switchThemeButtonState(); + } +} + +themePicker.onclick = switchThemeButtonState; +themePicker.onblur = handleThemeButtonsBlur; +["dark","light"].forEach(function(item) { + var but = document.createElement('button'); + but.innerHTML = item; + but.onclick = function(el) { + switchTheme(currentTheme, mainTheme, item); + }; + but.onblur = handleThemeButtonsBlur; + themes.appendChild(but); +}); \ No newline at end of file diff --git a/target/doc/thread_local/all.html b/target/doc/thread_local/all.html new file mode 100644 index 0000000..9f6a59d --- /dev/null +++ b/target/doc/thread_local/all.html @@ -0,0 +1,3 @@ +List of all items in this crate

[] + + List of all items

Structs

Typedefs

\ No newline at end of file diff --git a/target/doc/thread_local/index.html b/target/doc/thread_local/index.html new file mode 100644 index 0000000..5ed7aaa --- /dev/null +++ b/target/doc/thread_local/index.html @@ -0,0 +1,61 @@ +thread_local - Rust

[][src]Crate thread_local

Per-object thread-local storage

+

This library provides the ThreadLocal type which allows a separate copy of +an object to be used for each thread. This allows for per-object +thread-local storage, unlike the standard library's thread_local! macro +which only allows static thread-local storage.

+

Per-thread objects are not destroyed when a thread exits. Instead, objects +are only destroyed when the ThreadLocal containing them is destroyed.

+

You can also iterate over the thread-local values of all thread in a +ThreadLocal object using the iter_mut and into_iter methods. This can +only be done if you have mutable access to the ThreadLocal object, which +guarantees that you are the only thread currently accessing it.

+

A CachedThreadLocal type is also provided which wraps a ThreadLocal but +also uses a special fast path for the first thread that writes into it. The +fast path has very low overhead (<1ns per access) while keeping the same +performance as ThreadLocal for other threads.

+

Note that since thread IDs are recycled when a thread exits, it is possible +for one thread to retrieve the object of another thread. Since this can only +occur after a thread has exited this does not lead to any race conditions.

+

Examples

+

Basic usage of ThreadLocal:

+ +
+use thread_local::ThreadLocal;
+let tls: ThreadLocal<u32> = ThreadLocal::new();
+assert_eq!(tls.get(), None);
+assert_eq!(tls.get_or(|| Box::new(5)), &5);
+assert_eq!(tls.get(), Some(&5));
+

Combining thread-local values into a single result:

+ +
+use thread_local::ThreadLocal;
+use std::sync::Arc;
+use std::cell::Cell;
+use std::thread;
+
+let tls = Arc::new(ThreadLocal::new());
+
+// Create a bunch of threads to do stuff
+for _ in 0..5 {
+    let tls2 = tls.clone();
+    thread::spawn(move || {
+        // Increment a counter to count some event...
+        let cell = tls2.get_or(|| Box::new(Cell::new(0)));
+        cell.set(cell.get() + 1);
+    }).join().unwrap();
+}
+
+// Once all threads are done, collect the counter values and return the
+// sum of all thread-local counter values.
+let tls = Arc::try_unwrap(tls).unwrap();
+let total = tls.into_iter().fold(0, |x, y| x + y.get());
+assert_eq!(total, 5);
+

Structs

+
CachedThreadLocal

Wrapper around ThreadLocal which adds a fast path for a single thread.

+
IntoIter

An iterator that moves out of a ThreadLocal.

+
IterMut

Mutable iterator over the contents of a ThreadLocal.

+
ThreadLocal

Thread-local variable wrapper

+

Type Definitions

+
CachedIntoIter

An iterator that moves out of a CachedThreadLocal.

+
CachedIterMut

Mutable iterator over the contents of a CachedThreadLocal.

+
\ No newline at end of file diff --git a/target/doc/thread_local/sidebar-items.js b/target/doc/thread_local/sidebar-items.js new file mode 100644 index 0000000..4eb2ae2 --- /dev/null +++ b/target/doc/thread_local/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["CachedThreadLocal","Wrapper around `ThreadLocal` which adds a fast path for a single thread."],["IntoIter","An iterator that moves out of a `ThreadLocal`."],["IterMut","Mutable iterator over the contents of a `ThreadLocal`."],["ThreadLocal","Thread-local variable wrapper"]],"type":[["CachedIntoIter","An iterator that moves out of a `CachedThreadLocal`."],["CachedIterMut","Mutable iterator over the contents of a `CachedThreadLocal`."]]}); \ No newline at end of file diff --git a/target/doc/thread_local/struct.CachedThreadLocal.html b/target/doc/thread_local/struct.CachedThreadLocal.html new file mode 100644 index 0000000..3758bc9 --- /dev/null +++ b/target/doc/thread_local/struct.CachedThreadLocal.html @@ -0,0 +1,43 @@ +thread_local::CachedThreadLocal - Rust

[][src]Struct thread_local::CachedThreadLocal

pub struct CachedThreadLocal<T: ?Sized + Send> { /* fields omitted */ }

Wrapper around ThreadLocal which adds a fast path for a single thread.

+

This has the same API as ThreadLocal, but will register the first thread +that sets a value as its owner. All accesses by the owner will go through +a special fast path which is much faster than the normal ThreadLocal path.

+

Methods

impl<T: ?Sized + Send> CachedThreadLocal<T>[src]

pub fn new() -> CachedThreadLocal<T>[src]

Creates a new empty CachedThreadLocal.

+

pub fn get(&self) -> Option<&T>[src]

Returns the element for the current thread, if it exists.

+

pub fn get_or<F>(&self, create: F) -> &T where
    F: FnOnce() -> Box<T>, 
[src]

Returns the element for the current thread, or creates it if it doesn't +exist.

+

pub fn get_or_try<F, E>(&self, create: F) -> Result<&T, E> where
    F: FnOnce() -> Result<Box<T>, E>, 
[src]

Returns the element for the current thread, or creates it if it doesn't +exist. If create fails, that error is returned and no element is +added.

+

pub fn iter_mut(&mut self) -> CachedIterMut<T>[src]

Returns a mutable iterator over the local values of all threads.

+

Since this call borrows the ThreadLocal mutably, this operation can +be done safely---the mutable borrow statically guarantees no other +threads are currently accessing their associated values.

+

pub fn clear(&mut self)[src]

Removes all thread-specific values from the ThreadLocal, effectively +reseting it to its original state.

+

Since this call borrows the ThreadLocal mutably, this operation can +be done safely---the mutable borrow statically guarantees no other +threads are currently accessing their associated values.

+

impl<T: Send + Default> CachedThreadLocal<T>[src]

pub fn get_default(&self) -> &T[src]

Returns the element for the current thread, or creates a default one if +it doesn't exist.

+

Trait Implementations

impl<T: ?Sized + Send> Sync for CachedThreadLocal<T>[src]

impl<T: ?Sized + Send> Default for CachedThreadLocal<T>[src]

impl<T: ?Sized + Send> IntoIterator for CachedThreadLocal<T>[src]

type Item = Box<T>

The type of the elements being iterated over.

+

type IntoIter = CachedIntoIter<T>

Which kind of iterator are we turning this into?

+

impl<'a, T: ?Sized + Send + 'a> IntoIterator for &'a mut CachedThreadLocal<T>[src]

type Item = &'a mut Box<T>

The type of the elements being iterated over.

+

type IntoIter = CachedIterMut<'a, T>

Which kind of iterator are we turning this into?

+

impl<T: ?Sized + Send + Debug> Debug for CachedThreadLocal<T>[src]

impl<T: ?Sized + Send + UnwindSafe> UnwindSafe for CachedThreadLocal<T>[src]

Auto Trait Implementations

impl<T: ?Sized> Send for CachedThreadLocal<T>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/thread_local/struct.IntoIter.html b/target/doc/thread_local/struct.IntoIter.html new file mode 100644 index 0000000..1857407 --- /dev/null +++ b/target/doc/thread_local/struct.IntoIter.html @@ -0,0 +1,80 @@ +thread_local::IntoIter - Rust

[][src]Struct thread_local::IntoIter

pub struct IntoIter<T: ?Sized + Send> { /* fields omitted */ }

An iterator that moves out of a ThreadLocal.

+

Trait Implementations

impl<T: ?Sized + Send> Iterator for IntoIter<T>[src]

type Item = Box<T>

The type of the elements being iterated over.

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

impl<T: ?Sized + Send> ExactSizeIterator for IntoIter<T>[src]

fn len(&self) -> usize1.0.0[src]

Returns the exact number of times the iterator will iterate. Read more

+

fn is_empty(&self) -> bool[src]

🔬 This is a nightly-only experimental API. (exact_size_is_empty)

Returns true if the iterator is empty. Read more

+

Auto Trait Implementations

impl<T> !Send for IntoIter<T>

impl<T> !Sync for IntoIter<T>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/thread_local/struct.IterMut.html b/target/doc/thread_local/struct.IterMut.html new file mode 100644 index 0000000..300d6dd --- /dev/null +++ b/target/doc/thread_local/struct.IterMut.html @@ -0,0 +1,80 @@ +thread_local::IterMut - Rust

[][src]Struct thread_local::IterMut

pub struct IterMut<'a, T: ?Sized + Send + 'a> { /* fields omitted */ }

Mutable iterator over the contents of a ThreadLocal.

+

Trait Implementations

impl<'a, T: ?Sized + Send + 'a> Iterator for IterMut<'a, T>[src]

type Item = &'a mut Box<T>

The type of the elements being iterated over.

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

impl<'a, T: ?Sized + Send + 'a> ExactSizeIterator for IterMut<'a, T>[src]

fn len(&self) -> usize1.0.0[src]

Returns the exact number of times the iterator will iterate. Read more

+

fn is_empty(&self) -> bool[src]

🔬 This is a nightly-only experimental API. (exact_size_is_empty)

Returns true if the iterator is empty. Read more

+

Auto Trait Implementations

impl<'a, T> !Send for IterMut<'a, T>

impl<'a, T> !Sync for IterMut<'a, T>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/thread_local/struct.ThreadLocal.html b/target/doc/thread_local/struct.ThreadLocal.html new file mode 100644 index 0000000..ca98d06 --- /dev/null +++ b/target/doc/thread_local/struct.ThreadLocal.html @@ -0,0 +1,42 @@ +thread_local::ThreadLocal - Rust

[][src]Struct thread_local::ThreadLocal

pub struct ThreadLocal<T: ?Sized + Send> { /* fields omitted */ }

Thread-local variable wrapper

+

See the module-level documentation for more.

+

Methods

impl<T: ?Sized + Send> ThreadLocal<T>[src]

pub fn new() -> ThreadLocal<T>[src]

Creates a new empty ThreadLocal.

+

pub fn get(&self) -> Option<&T>[src]

Returns the element for the current thread, if it exists.

+

pub fn get_or<F>(&self, create: F) -> &T where
    F: FnOnce() -> Box<T>, 
[src]

Returns the element for the current thread, or creates it if it doesn't +exist.

+

pub fn get_or_try<F, E>(&self, create: F) -> Result<&T, E> where
    F: FnOnce() -> Result<Box<T>, E>, 
[src]

Returns the element for the current thread, or creates it if it doesn't +exist. If create fails, that error is returned and no element is +added.

+

Important traits for IterMut<'a, T>
pub fn iter_mut(&mut self) -> IterMut<T>[src]

Returns a mutable iterator over the local values of all threads.

+

Since this call borrows the ThreadLocal mutably, this operation can +be done safely---the mutable borrow statically guarantees no other +threads are currently accessing their associated values.

+

pub fn clear(&mut self)[src]

Removes all thread-specific values from the ThreadLocal, effectively +reseting it to its original state.

+

Since this call borrows the ThreadLocal mutably, this operation can +be done safely---the mutable borrow statically guarantees no other +threads are currently accessing their associated values.

+

impl<T: Send + Default> ThreadLocal<T>[src]

pub fn get_default(&self) -> &T[src]

Returns the element for the current thread, or creates a default one if +it doesn't exist.

+

Trait Implementations

impl<T: ?Sized + Send> Sync for ThreadLocal<T>[src]

impl<T: ?Sized + Send> Default for ThreadLocal<T>[src]

impl<T: ?Sized + Send> IntoIterator for ThreadLocal<T>[src]

type Item = Box<T>

The type of the elements being iterated over.

+

type IntoIter = IntoIter<T>

Which kind of iterator are we turning this into?

+

impl<'a, T: ?Sized + Send + 'a> IntoIterator for &'a mut ThreadLocal<T>[src]

type Item = &'a mut Box<T>

The type of the elements being iterated over.

+

type IntoIter = IterMut<'a, T>

Which kind of iterator are we turning this into?

+

impl<T: ?Sized + Send> Drop for ThreadLocal<T>[src]

impl<T: ?Sized + Send + Debug> Debug for ThreadLocal<T>[src]

impl<T: ?Sized + Send + UnwindSafe> UnwindSafe for ThreadLocal<T>[src]

Auto Trait Implementations

impl<T: ?Sized> Send for ThreadLocal<T>

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/thread_local/type.CachedIntoIter.html b/target/doc/thread_local/type.CachedIntoIter.html new file mode 100644 index 0000000..7611049 --- /dev/null +++ b/target/doc/thread_local/type.CachedIntoIter.html @@ -0,0 +1,2 @@ +thread_local::CachedIntoIter - Rust

[][src]Type Definition thread_local::CachedIntoIter

type CachedIntoIter<T> = Chain<OptionIter<Box<T>>, IntoIter<T>>;

An iterator that moves out of a CachedThreadLocal.

+
\ No newline at end of file diff --git a/target/doc/thread_local/type.CachedIterMut.html b/target/doc/thread_local/type.CachedIterMut.html new file mode 100644 index 0000000..c75497c --- /dev/null +++ b/target/doc/thread_local/type.CachedIterMut.html @@ -0,0 +1,2 @@ +thread_local::CachedIterMut - Rust

[][src]Type Definition thread_local::CachedIterMut

type CachedIterMut<'a, T> = Chain<OptionIter<&'a mut Box<T>>, IterMut<'a, T>>;

Mutable iterator over the contents of a CachedThreadLocal.

+
\ No newline at end of file diff --git a/target/doc/ucd_util/all.html b/target/doc/ucd_util/all.html new file mode 100644 index 0000000..9f5dd61 --- /dev/null +++ b/target/doc/ucd_util/all.html @@ -0,0 +1,3 @@ +List of all items in this crate

[] + + List of all items

Functions

Typedefs

Constants

\ No newline at end of file diff --git a/target/doc/ucd_util/constant.RANGE_HANGUL_SYLLABLE.html b/target/doc/ucd_util/constant.RANGE_HANGUL_SYLLABLE.html new file mode 100644 index 0000000..2b7bb63 --- /dev/null +++ b/target/doc/ucd_util/constant.RANGE_HANGUL_SYLLABLE.html @@ -0,0 +1,4 @@ +ucd_util::RANGE_HANGUL_SYLLABLE - Rust

[][src]Constant ucd_util::RANGE_HANGUL_SYLLABLE

pub const RANGE_HANGUL_SYLLABLE: &'static [(u32, u32)]

A set of ranges that corresponds to the set of all Hangul syllable +codepoints.

+

These ranges are defined in Unicode 4.8 Table 4-13.

+
\ No newline at end of file diff --git a/target/doc/ucd_util/constant.RANGE_IDEOGRAPH.html b/target/doc/ucd_util/constant.RANGE_IDEOGRAPH.html new file mode 100644 index 0000000..3948224 --- /dev/null +++ b/target/doc/ucd_util/constant.RANGE_IDEOGRAPH.html @@ -0,0 +1,3 @@ +ucd_util::RANGE_IDEOGRAPH - Rust

[][src]Constant ucd_util::RANGE_IDEOGRAPH

pub const RANGE_IDEOGRAPH: &'static [(u32, u32)]

A set of ranges that corresponds to the set of all ideograph codepoints.

+

These ranges are defined in Unicode 4.8 Table 4-13.

+
\ No newline at end of file diff --git a/target/doc/ucd_util/fn.canonical_property_name.html b/target/doc/ucd_util/fn.canonical_property_name.html new file mode 100644 index 0000000..4bc38a7 --- /dev/null +++ b/target/doc/ucd_util/fn.canonical_property_name.html @@ -0,0 +1,5 @@ +ucd_util::canonical_property_name - Rust

[][src]Function ucd_util::canonical_property_name

pub fn canonical_property_name(
    property_table: PropertyTable,
    normalized_property_name: &str
) -> Option<&'static str>

Find the canonical property name for the given normalized property name.

+

If no such property exists, then None is returned.

+

The normalized property name must have been normalized according to +UAX44 LM3, which can be done using symbolic_name_normalize.

+
\ No newline at end of file diff --git a/target/doc/ucd_util/fn.canonical_property_value.html b/target/doc/ucd_util/fn.canonical_property_value.html new file mode 100644 index 0000000..d19ba98 --- /dev/null +++ b/target/doc/ucd_util/fn.canonical_property_value.html @@ -0,0 +1,8 @@ +ucd_util::canonical_property_value - Rust

[][src]Function ucd_util::canonical_property_value

pub fn canonical_property_value(
    property_values: PropertyValues,
    normalized_property_value: &str
) -> Option<&'static str>

Find the canonical property value for the given normalized property +value.

+

The given property values should correspond to the values for the property +under question, which can be found using property_values.

+

If no such property value exists, then None is returned.

+

The normalized property value must have been normalized according to +UAX44 LM3, which can be done using symbolic_name_normalize.

+
\ No newline at end of file diff --git a/target/doc/ucd_util/fn.character_name_normalize.html b/target/doc/ucd_util/fn.character_name_normalize.html new file mode 100644 index 0000000..dd0ec6a --- /dev/null +++ b/target/doc/ucd_util/fn.character_name_normalize.html @@ -0,0 +1,3 @@ +ucd_util::character_name_normalize - Rust

[][src]Function ucd_util::character_name_normalize

pub fn character_name_normalize(string: &mut String)

Normalize the given character name in place according to UAX44-LM2.

+

See: http://unicode.org/reports/tr44/#UAX44-LM2

+
\ No newline at end of file diff --git a/target/doc/ucd_util/fn.hangul_full_canonical_decomposition.html b/target/doc/ucd_util/fn.hangul_full_canonical_decomposition.html new file mode 100644 index 0000000..295bea6 --- /dev/null +++ b/target/doc/ucd_util/fn.hangul_full_canonical_decomposition.html @@ -0,0 +1,8 @@ +ucd_util::hangul_full_canonical_decomposition - Rust

[][src]Function ucd_util::hangul_full_canonical_decomposition

pub fn hangul_full_canonical_decomposition(
    cp: u32
) -> Option<(u32, u32, Option<u32>)>

Return the full canonical decomposition of the given precomposed Hangul +codepoint.

+

If the decomposition does not have any trailing consonant, then the third +part of the tuple returned is None.

+

If the given codepoint does not correspond to a precomposed Hangul +codepoint in the inclusive range AC00..D7A3, then this returns None.

+

This implements the algorithms described in Unicode 3.12 and Unicode 4.8.

+
\ No newline at end of file diff --git a/target/doc/ucd_util/fn.hangul_name.html b/target/doc/ucd_util/fn.hangul_name.html new file mode 100644 index 0000000..f34d612 --- /dev/null +++ b/target/doc/ucd_util/fn.hangul_name.html @@ -0,0 +1,5 @@ +ucd_util::hangul_name - Rust

[][src]Function ucd_util::hangul_name

pub fn hangul_name(cp: u32) -> Option<String>

Return the character name of the given precomposed Hangul codepoint.

+

If the given codepoint does not correspond to a precomposed Hangul +codepoint in the inclusive range AC00..D7A3, then this returns None.

+

This implements the algorithms described in Unicode 3.12 and Unicode 4.8.

+
\ No newline at end of file diff --git a/target/doc/ucd_util/fn.ideograph_name.html b/target/doc/ucd_util/fn.ideograph_name.html new file mode 100644 index 0000000..81b493b --- /dev/null +++ b/target/doc/ucd_util/fn.ideograph_name.html @@ -0,0 +1,19 @@ +ucd_util::ideograph_name - Rust

[][src]Function ucd_util::ideograph_name

pub fn ideograph_name(cp: u32) -> Option<String>

Return the character name of the given ideograph codepoint.

+

This operation is only defined on ideographic codepoints. This includes +precisely the following inclusive ranges:

+
    +
  • 3400..4DB5
  • +
  • 4E00..9FD5
  • +
  • 20000..2A6D6
  • +
  • 2A700..2B734
  • +
  • 2B740..2B81D
  • +
  • 2B820..2CEA1
  • +
  • 17000..187EC
  • +
  • F900..FA6D
  • +
  • FA70..FAD9
  • +
  • 2F800..2FA1D
  • +
+

If the given codepoint is not in any of the above ranges, then None is +returned.

+

This implements the algorithm described in Unicode 4.8.

+
\ No newline at end of file diff --git a/target/doc/ucd_util/fn.property_values.html b/target/doc/ucd_util/fn.property_values.html new file mode 100644 index 0000000..d8e22a6 --- /dev/null +++ b/target/doc/ucd_util/fn.property_values.html @@ -0,0 +1,9 @@ +ucd_util::property_values - Rust

[][src]Function ucd_util::property_values

pub fn property_values(
    property_value_table: PropertyValueTable,
    canonical_property_name: &str
) -> Option<PropertyValues>

Find the set of possible property values for a given property.

+

The set returned is a mapping expressed as a sorted list of tuples. +The first element of each tuple is a normalized property value while the +second element of each tuple is the corresponding canonical property +value.

+

If no such property exists, then None is returned.

+

The given property name must be in its canonical form, which can be +found using canonical_property_name.

+
\ No newline at end of file diff --git a/target/doc/ucd_util/fn.symbolic_name_normalize.html b/target/doc/ucd_util/fn.symbolic_name_normalize.html new file mode 100644 index 0000000..1030d12 --- /dev/null +++ b/target/doc/ucd_util/fn.symbolic_name_normalize.html @@ -0,0 +1,6 @@ +ucd_util::symbolic_name_normalize - Rust

[][src]Function ucd_util::symbolic_name_normalize

pub fn symbolic_name_normalize(string: &mut String)

Normalize the given symbolic name in place according to UAX44-LM3.

+

A "symbolic name" typically corresponds to property names and property +value aliases. Note, though, that it should not be applied to property +string values.

+

See: http://unicode.org/reports/tr44/#UAX44-LM2

+
\ No newline at end of file diff --git a/target/doc/ucd_util/hangul/constant.RANGE_HANGUL_SYLLABLE.html b/target/doc/ucd_util/hangul/constant.RANGE_HANGUL_SYLLABLE.html new file mode 100644 index 0000000..eb24d42 --- /dev/null +++ b/target/doc/ucd_util/hangul/constant.RANGE_HANGUL_SYLLABLE.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ucd_util/constant.RANGE_HANGUL_SYLLABLE.html...

+ + + \ No newline at end of file diff --git a/target/doc/ucd_util/hangul/fn.hangul_full_canonical_decomposition.html b/target/doc/ucd_util/hangul/fn.hangul_full_canonical_decomposition.html new file mode 100644 index 0000000..b218761 --- /dev/null +++ b/target/doc/ucd_util/hangul/fn.hangul_full_canonical_decomposition.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ucd_util/fn.hangul_full_canonical_decomposition.html...

+ + + \ No newline at end of file diff --git a/target/doc/ucd_util/hangul/fn.hangul_name.html b/target/doc/ucd_util/hangul/fn.hangul_name.html new file mode 100644 index 0000000..fdca137 --- /dev/null +++ b/target/doc/ucd_util/hangul/fn.hangul_name.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ucd_util/fn.hangul_name.html...

+ + + \ No newline at end of file diff --git a/target/doc/ucd_util/ideograph/constant.RANGE_IDEOGRAPH.html b/target/doc/ucd_util/ideograph/constant.RANGE_IDEOGRAPH.html new file mode 100644 index 0000000..e4b14cf --- /dev/null +++ b/target/doc/ucd_util/ideograph/constant.RANGE_IDEOGRAPH.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ucd_util/constant.RANGE_IDEOGRAPH.html...

+ + + \ No newline at end of file diff --git a/target/doc/ucd_util/ideograph/fn.ideograph_name.html b/target/doc/ucd_util/ideograph/fn.ideograph_name.html new file mode 100644 index 0000000..70542fb --- /dev/null +++ b/target/doc/ucd_util/ideograph/fn.ideograph_name.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ucd_util/fn.ideograph_name.html...

+ + + \ No newline at end of file diff --git a/target/doc/ucd_util/index.html b/target/doc/ucd_util/index.html new file mode 100644 index 0000000..509423f --- /dev/null +++ b/target/doc/ucd_util/index.html @@ -0,0 +1,27 @@ +ucd_util - Rust

[][src]Crate ucd_util

The ucd-util crate contains a smattering of utility functions that implement +various algorithms specified by Unicode. There is no specific goal for +exhaustiveness. Instead, implementations should be added on an as-needed basis.

+

A current design constraint of this crate is that it should not bring in any +large Unicode tables. For example, to use the various property name and value +canonicalization functions, you'll need to supply your own table, which can +be generated using ucd-generate.

+

Constants

+
RANGE_HANGUL_SYLLABLE

A set of ranges that corresponds to the set of all Hangul syllable +codepoints.

+
RANGE_IDEOGRAPH

A set of ranges that corresponds to the set of all ideograph codepoints.

+

Functions

+
canonical_property_name

Find the canonical property name for the given normalized property name.

+
canonical_property_value

Find the canonical property value for the given normalized property +value.

+
character_name_normalize

Normalize the given character name in place according to UAX44-LM2.

+
hangul_full_canonical_decomposition

Return the full canonical decomposition of the given precomposed Hangul +codepoint.

+
hangul_name

Return the character name of the given precomposed Hangul codepoint.

+
ideograph_name

Return the character name of the given ideograph codepoint.

+
property_values

Find the set of possible property values for a given property.

+
symbolic_name_normalize

Normalize the given symbolic name in place according to UAX44-LM3.

+

Type Definitions

+
PropertyTable

The type of a property name table.

+
PropertyValueTable

Type of a property value table.

+
PropertyValues

A mapping of property values for a specific property.

+
\ No newline at end of file diff --git a/target/doc/ucd_util/name/fn.character_name_normalize.html b/target/doc/ucd_util/name/fn.character_name_normalize.html new file mode 100644 index 0000000..b676228 --- /dev/null +++ b/target/doc/ucd_util/name/fn.character_name_normalize.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ucd_util/fn.character_name_normalize.html...

+ + + \ No newline at end of file diff --git a/target/doc/ucd_util/name/fn.symbolic_name_normalize.html b/target/doc/ucd_util/name/fn.symbolic_name_normalize.html new file mode 100644 index 0000000..8af5710 --- /dev/null +++ b/target/doc/ucd_util/name/fn.symbolic_name_normalize.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ucd_util/fn.symbolic_name_normalize.html...

+ + + \ No newline at end of file diff --git a/target/doc/ucd_util/property/fn.canonical_property_name.html b/target/doc/ucd_util/property/fn.canonical_property_name.html new file mode 100644 index 0000000..4f4843e --- /dev/null +++ b/target/doc/ucd_util/property/fn.canonical_property_name.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ucd_util/fn.canonical_property_name.html...

+ + + \ No newline at end of file diff --git a/target/doc/ucd_util/property/fn.canonical_property_value.html b/target/doc/ucd_util/property/fn.canonical_property_value.html new file mode 100644 index 0000000..d59e8dd --- /dev/null +++ b/target/doc/ucd_util/property/fn.canonical_property_value.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ucd_util/fn.canonical_property_value.html...

+ + + \ No newline at end of file diff --git a/target/doc/ucd_util/property/fn.property_values.html b/target/doc/ucd_util/property/fn.property_values.html new file mode 100644 index 0000000..1bc10dd --- /dev/null +++ b/target/doc/ucd_util/property/fn.property_values.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ucd_util/fn.property_values.html...

+ + + \ No newline at end of file diff --git a/target/doc/ucd_util/property/type.PropertyTable.html b/target/doc/ucd_util/property/type.PropertyTable.html new file mode 100644 index 0000000..3b108ba --- /dev/null +++ b/target/doc/ucd_util/property/type.PropertyTable.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ucd_util/type.PropertyTable.html...

+ + + \ No newline at end of file diff --git a/target/doc/ucd_util/property/type.PropertyValueTable.html b/target/doc/ucd_util/property/type.PropertyValueTable.html new file mode 100644 index 0000000..ad0258f --- /dev/null +++ b/target/doc/ucd_util/property/type.PropertyValueTable.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ucd_util/type.PropertyValueTable.html...

+ + + \ No newline at end of file diff --git a/target/doc/ucd_util/property/type.PropertyValues.html b/target/doc/ucd_util/property/type.PropertyValues.html new file mode 100644 index 0000000..2803ed2 --- /dev/null +++ b/target/doc/ucd_util/property/type.PropertyValues.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../ucd_util/type.PropertyValues.html...

+ + + \ No newline at end of file diff --git a/target/doc/ucd_util/sidebar-items.js b/target/doc/ucd_util/sidebar-items.js new file mode 100644 index 0000000..e8a583b --- /dev/null +++ b/target/doc/ucd_util/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"constant":[["RANGE_HANGUL_SYLLABLE","A set of ranges that corresponds to the set of all Hangul syllable codepoints."],["RANGE_IDEOGRAPH","A set of ranges that corresponds to the set of all ideograph codepoints."]],"fn":[["canonical_property_name","Find the canonical property name for the given normalized property name."],["canonical_property_value","Find the canonical property value for the given normalized property value."],["character_name_normalize","Normalize the given character name in place according to UAX44-LM2."],["hangul_full_canonical_decomposition","Return the full canonical decomposition of the given precomposed Hangul codepoint."],["hangul_name","Return the character name of the given precomposed Hangul codepoint."],["ideograph_name","Return the character name of the given ideograph codepoint."],["property_values","Find the set of possible property values for a given property."],["symbolic_name_normalize","Normalize the given symbolic name in place according to UAX44-LM3."]],"type":[["PropertyTable","The type of a property name table."],["PropertyValueTable","Type of a property value table."],["PropertyValues","A mapping of property values for a specific property."]]}); \ No newline at end of file diff --git a/target/doc/ucd_util/type.PropertyTable.html b/target/doc/ucd_util/type.PropertyTable.html new file mode 100644 index 0000000..1a37539 --- /dev/null +++ b/target/doc/ucd_util/type.PropertyTable.html @@ -0,0 +1,5 @@ +ucd_util::PropertyTable - Rust

[][src]Type Definition ucd_util::PropertyTable

type PropertyTable = &'static [(&'static str, &'static str)];

The type of a property name table.

+

A property name table is a sequence of sorted tuples, where the first +value in each tuple is a normalized property name and the second value of +each tuple is the corresponding canonical property name.

+
\ No newline at end of file diff --git a/target/doc/ucd_util/type.PropertyValueTable.html b/target/doc/ucd_util/type.PropertyValueTable.html new file mode 100644 index 0000000..ba38a27 --- /dev/null +++ b/target/doc/ucd_util/type.PropertyValueTable.html @@ -0,0 +1,11 @@ +ucd_util::PropertyValueTable - Rust

[][src]Type Definition ucd_util::PropertyValueTable

type PropertyValueTable = &'static [(&'static str, PropertyValues)];

Type of a property value table.

+

A property value table maps property names to a mapping of property values, +where the mapping of property values is represented by a sequence of +tuples. The first element of each tuple is a normalized property value +while the second element of each tuple is the corresponding canonical +property value.

+

Note that a property value table only includes values for properties that +are catalogs, enumerations or binary properties. Properties that have +string values (such as case or decomposition mappings), numeric values +or are miscellaneous are not represented in this table.

+
\ No newline at end of file diff --git a/target/doc/ucd_util/type.PropertyValues.html b/target/doc/ucd_util/type.PropertyValues.html new file mode 100644 index 0000000..ec61a33 --- /dev/null +++ b/target/doc/ucd_util/type.PropertyValues.html @@ -0,0 +1,5 @@ +ucd_util::PropertyValues - Rust

[][src]Type Definition ucd_util::PropertyValues

type PropertyValues = &'static [(&'static str, &'static str)];

A mapping of property values for a specific property.

+

The first element of each tuple is a normalized property value while the +second element of each tuple is the corresponding canonical property +value.

+
\ No newline at end of file diff --git a/target/doc/utf8_ranges/all.html b/target/doc/utf8_ranges/all.html new file mode 100644 index 0000000..1d9ace3 --- /dev/null +++ b/target/doc/utf8_ranges/all.html @@ -0,0 +1,3 @@ +List of all items in this crate

[] + + List of all items

Structs

Enums

\ No newline at end of file diff --git a/target/doc/utf8_ranges/enum.Utf8Sequence.html b/target/doc/utf8_ranges/enum.Utf8Sequence.html new file mode 100644 index 0000000..8c714c3 --- /dev/null +++ b/target/doc/utf8_ranges/enum.Utf8Sequence.html @@ -0,0 +1,43 @@ +utf8_ranges::Utf8Sequence - Rust

[][src]Enum utf8_ranges::Utf8Sequence

pub enum Utf8Sequence {
+    One(Utf8Range),
+    Two([Utf8Range; 2]),
+    Three([Utf8Range; 3]),
+    Four([Utf8Range; 4]),
+}

Utf8Sequence represents a sequence of byte ranges.

+

To match a Utf8Sequence, a candidate byte sequence must match each +successive range.

+

For example, if there are two ranges, [C2-DF][80-BF], then the byte +sequence \xDD\x61 would not match because 0x61 < 0x80.

+

+ Variants

+One(Utf8Range)

One byte range.

+
Two([Utf8Range; 2])

Two successive byte ranges.

+
Three([Utf8Range; 3])

Three successive byte ranges.

+
Four([Utf8Range; 4])

Four successive byte ranges.

+

Methods

impl Utf8Sequence[src]

pub fn as_slice(&self) -> &[Utf8Range][src]

Returns the underlying sequence of byte ranges as a slice.

+

pub fn len(&self) -> usize[src]

Returns the number of byte ranges in this sequence.

+

The length is guaranteed to be in the closed interval [1, 4].

+

pub fn matches(&self, bytes: &[u8]) -> bool[src]

Returns true if and only if a prefix of bytes matches this sequence +of byte ranges.

+

Trait Implementations

impl PartialEq<Utf8Sequence> for Utf8Sequence[src]

impl Clone for Utf8Sequence[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl<'a> IntoIterator for &'a Utf8Sequence[src]

type IntoIter = Iter<'a, Utf8Range>

Which kind of iterator are we turning this into?

+

type Item = &'a Utf8Range

The type of the elements being iterated over.

+

impl Eq for Utf8Sequence[src]

impl Copy for Utf8Sequence[src]

impl Debug for Utf8Sequence[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/utf8_ranges/index.html b/target/doc/utf8_ranges/index.html new file mode 100644 index 0000000..9a82218 --- /dev/null +++ b/target/doc/utf8_ranges/index.html @@ -0,0 +1,74 @@ +utf8_ranges - Rust

[][src]Crate utf8_ranges

Crate utf8-ranges converts ranges of Unicode scalar values to equivalent +ranges of UTF-8 bytes. This is useful for constructing byte based automatons +that need to embed UTF-8 decoding.

+

See the documentation on the Utf8Sequences iterator for more details and +an example.

+

Wait, what is this?

+

This is simplest to explain with an example. Let's say you wanted to test +whether a particular byte sequence was a Cyrillic character. One possible +scalar value range is [0400-04FF]. The set of allowed bytes for this +range can be expressed as a sequence of byte ranges:

+ +
This example is not tested
+[D0-D3][80-BF]
+

This is simple enough: simply encode the boundaries, 0400 encodes to +D0 80 and 04FF encodes to D3 BF, and create ranges from each +corresponding pair of bytes: D0 to D3 and 80 to BF.

+

However, what if you wanted to add the Cyrillic Supplementary characters to +your range? Your range might then become [0400-052F]. The same procedure +as above doesn't quite work because 052F encodes to D4 AF. The byte ranges +you'd get from the previous transformation would be [D0-D4][80-AF]. However, +this isn't quite correct because this range doesn't capture many characters, +for example, 04FF (because its last byte, BF isn't in the range 80-AF).

+

Instead, you need multiple sequences of byte ranges:

+ +
This example is not tested
+[D0-D3][80-BF]  # matches codepoints 0400-04FF
+[D4][80-AF]     # matches codepoints 0500-052F
+

This gets even more complicated if you want bigger ranges, particularly if +they naively contain surrogate codepoints. For example, the sequence of byte +ranges for the basic multilingual plane ([0000-FFFF]) look like this:

+ +
This example is not tested
+[0-7F]
+[C2-DF][80-BF]
+[E0][A0-BF][80-BF]
+[E1-EC][80-BF][80-BF]
+[ED][80-9F][80-BF]
+[EE-EF][80-BF][80-BF]
+

Note that the byte ranges above will not match any erroneous encoding of +UTF-8, including encodings of surrogate codepoints.

+

And, of course, for all of Unicode ([000000-10FFFF]):

+ +
This example is not tested
+[0-7F]
+[C2-DF][80-BF]
+[E0][A0-BF][80-BF]
+[E1-EC][80-BF][80-BF]
+[ED][80-9F][80-BF]
+[EE-EF][80-BF][80-BF]
+[F0][90-BF][80-BF][80-BF]
+[F1-F3][80-BF][80-BF][80-BF]
+[F4][80-8F][80-BF][80-BF]
+

This crate automates the process of creating these byte ranges from ranges of +Unicode scalar values.

+

Why would I ever use this?

+

You probably won't ever need this. In 99% of cases, you just decode the byte +sequence into a Unicode scalar value and compare scalar values directly. +However, this explicit decoding step isn't always possible. For example, the +construction of some finite state machines may benefit from converting ranges +of scalar values into UTF-8 decoder automata (e.g., for character classes in +regular expressions).

+

Lineage

+

I got the idea and general implementation strategy from Russ Cox in his +article on regexps and RE2. +Russ Cox got it from Ken Thompson's grep (no source, folk lore?). +I also got the idea from +Lucene, +which uses it for executing automata on their term index.

+

Structs

+
Utf8Range

A single inclusive range of UTF-8 bytes.

+
Utf8Sequences

An iterator over ranges of matching UTF-8 byte sequences.

+

Enums

+
Utf8Sequence

Utf8Sequence represents a sequence of byte ranges.

+
\ No newline at end of file diff --git a/target/doc/utf8_ranges/sidebar-items.js b/target/doc/utf8_ranges/sidebar-items.js new file mode 100644 index 0000000..e3c4fa4 --- /dev/null +++ b/target/doc/utf8_ranges/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"enum":[["Utf8Sequence","Utf8Sequence represents a sequence of byte ranges."]],"struct":[["Utf8Range","A single inclusive range of UTF-8 bytes."],["Utf8Sequences","An iterator over ranges of matching UTF-8 byte sequences."]]}); \ No newline at end of file diff --git a/target/doc/utf8_ranges/struct.Utf8Range.html b/target/doc/utf8_ranges/struct.Utf8Range.html new file mode 100644 index 0000000..e0f95f4 --- /dev/null +++ b/target/doc/utf8_ranges/struct.Utf8Range.html @@ -0,0 +1,27 @@ +utf8_ranges::Utf8Range - Rust

[][src]Struct utf8_ranges::Utf8Range

pub struct Utf8Range {
+    pub start: u8,
+    pub end: u8,
+}

A single inclusive range of UTF-8 bytes.

+

+ Fields

start: u8

Start of byte range (inclusive).

+
end: u8

End of byte range (inclusive).

+

Methods

impl Utf8Range[src]

pub fn matches(&self, b: u8) -> bool[src]

Returns true if and only if the given byte is in this range.

+

Trait Implementations

impl PartialEq<Utf8Range> for Utf8Range[src]

impl Clone for Utf8Range[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

+

impl Eq for Utf8Range[src]

impl Copy for Utf8Range[src]

impl Debug for Utf8Range[src]

Auto Trait Implementations

impl Send for Utf8Range

impl Sync for Utf8Range

Blanket Implementations

impl<T> From<T> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/utf8_ranges/struct.Utf8Sequences.html b/target/doc/utf8_ranges/struct.Utf8Sequences.html new file mode 100644 index 0000000..2cc6bda --- /dev/null +++ b/target/doc/utf8_ranges/struct.Utf8Sequences.html @@ -0,0 +1,122 @@ +utf8_ranges::Utf8Sequences - Rust

[][src]Struct utf8_ranges::Utf8Sequences

pub struct Utf8Sequences { /* fields omitted */ }

An iterator over ranges of matching UTF-8 byte sequences.

+

The iteration represents an alternation of comprehensive byte sequences +that match precisely the set of UTF-8 encoded scalar values.

+

A byte sequence corresponds to one of the scalar values in the range given +if and only if it completely matches exactly one of the sequences of byte +ranges produced by this iterator.

+

Each sequence of byte ranges matches a unique set of bytes. That is, no two +sequences will match the same bytes.

+

Example

+

This shows how to match an arbitrary byte sequence against a range of +scalar values.

+ +
+use utf8_ranges::{Utf8Sequences, Utf8Sequence};
+
+fn matches(seqs: &[Utf8Sequence], bytes: &[u8]) -> bool {
+    for range in seqs {
+        if range.matches(bytes) {
+            return true;
+        }
+    }
+    false
+}
+
+// Test the basic multilingual plane.
+let seqs: Vec<_> = Utf8Sequences::new('\u{0}', '\u{FFFF}').collect();
+
+// UTF-8 encoding of 'a'.
+assert!(matches(&seqs, &[0x61]));
+// UTF-8 encoding of '☃' (`\u{2603}`).
+assert!(matches(&seqs, &[0xE2, 0x98, 0x83]));
+// UTF-8 encoding of `\u{10348}` (outside the BMP).
+assert!(!matches(&seqs, &[0xF0, 0x90, 0x8D, 0x88]));
+// Tries to match against a UTF-8 encoding of a surrogate codepoint,
+// which is invalid UTF-8, and therefore fails, despite the fact that
+// the corresponding codepoint (0xD800) falls in the range given.
+assert!(!matches(&seqs, &[0xED, 0xA0, 0x80]));
+// And fails against plain old invalid UTF-8.
+assert!(!matches(&seqs, &[0xFF, 0xFF]));
+

If this example seems circuitous, that's because it is! It's meant to be +illustrative. In practice, you could just try to decode your byte sequence +and compare it with the scalar value range directly. However, this is not +always possible (for example, in a byte based automaton).

+

Methods

impl Utf8Sequences[src]

pub fn new(start: char, end: char) -> Self[src]

Create a new iterator over UTF-8 byte ranges for the scalar value range +given.

+

Trait Implementations

impl Iterator for Utf8Sequences[src]

type Item = Utf8Sequence

The type of the elements being iterated over.

+

fn size_hint(&self) -> (usize, Option<usize>)1.0.0[src]

Returns the bounds on the remaining length of the iterator. Read more

+

fn count(self) -> usize1.0.0[src]

Consumes the iterator, counting the number of iterations and returning it. Read more

+

fn last(self) -> Option<Self::Item>1.0.0[src]

Consumes the iterator, returning the last element. Read more

+

fn nth(&mut self, n: usize) -> Option<Self::Item>1.0.0[src]

Returns the nth element of the iterator. Read more

+

fn step_by(self, step: usize) -> StepBy<Self>1.28.0[src]

Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more

+

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator<Item = Self::Item>, 
1.0.0[src]

Takes two iterators and creates a new iterator over both in sequence. Read more

+

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
    U: IntoIterator
1.0.0[src]

'Zips up' two iterators into a single iterator of pairs. Read more

+

fn map<B, F>(self, f: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> B, 
1.0.0[src]

Takes a closure and creates an iterator which calls that closure on each element. Read more

+

fn for_each<F>(self, f: F) where
    F: FnMut(Self::Item), 
1.21.0[src]

Calls a closure on each element of an iterator. Read more

+

fn filter<P>(self, predicate: P) -> Filter<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator which uses a closure to determine if an element should be yielded. Read more

+

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
    F: FnMut(Self::Item) -> Option<B>, 
1.0.0[src]

Creates an iterator that both filters and maps. Read more

+

fn enumerate(self) -> Enumerate<Self>1.0.0[src]

Creates an iterator which gives the current iteration count as well as the next value. Read more

+

fn peekable(self) -> Peekable<Self>1.0.0[src]

Creates an iterator which can use peek to look at the next element of the iterator without consuming it. Read more

+

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that [skip]s elements based on a predicate. Read more

+

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Creates an iterator that yields elements based on a predicate. Read more

+

fn skip(self, n: usize) -> Skip<Self>1.0.0[src]

Creates an iterator that skips the first n elements. Read more

+

fn take(self, n: usize) -> Take<Self>1.0.0[src]

Creates an iterator that yields its first n elements. Read more

+

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
    F: FnMut(&mut St, Self::Item) -> Option<B>, 
1.0.0[src]

An iterator adaptor similar to [fold] that holds internal state and produces a new iterator. Read more

+

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
    F: FnMut(Self::Item) -> U,
    U: IntoIterator
1.0.0[src]

Creates an iterator that works like map, but flattens nested structure. Read more

+

fn flatten(self) -> Flatten<Self> where
    Self::Item: IntoIterator
1.29.0[src]

Creates an iterator that flattens nested structure. Read more

+

fn fuse(self) -> Fuse<Self>1.0.0[src]

Creates an iterator which ends after the first [None]. Read more

+

fn inspect<F>(self, f: F) -> Inspect<Self, F> where
    F: FnMut(&Self::Item), 
1.0.0[src]

Do something with each element of an iterator, passing the value on. Read more

+

fn by_ref(&mut self) -> &mut Self1.0.0[src]

Borrows an iterator, rather than consuming it. Read more

+

#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] +
fn collect<B>(self) -> B where
    B: FromIterator<Self::Item>, 
1.0.0[src]

Transforms an iterator into a collection. Read more

+

fn partition<B, F>(self, f: F) -> (B, B) where
    B: Default + Extend<Self::Item>,
    F: FnMut(&Self::Item) -> bool
1.0.0[src]

Consumes an iterator, creating two collections from it. Read more

+

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
    F: FnMut(B, Self::Item) -> R,
    R: Try<Ok = B>, 
1.27.0[src]

An iterator method that applies a function as long as it returns successfully, producing a single, final value. Read more

+

fn try_for_each<F, R>(&mut self, f: F) -> R where
    F: FnMut(Self::Item) -> R,
    R: Try<Ok = ()>, 
1.27.0[src]

An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error. Read more

+

fn fold<B, F>(self, init: B, f: F) -> B where
    F: FnMut(B, Self::Item) -> B, 
1.0.0[src]

An iterator method that applies a function, producing a single, final value. Read more

+

fn all<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if every element of the iterator matches a predicate. Read more

+

fn any<F>(&mut self, f: F) -> bool where
    F: FnMut(Self::Item) -> bool
1.0.0[src]

Tests if any element of the iterator matches a predicate. Read more

+

fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
    P: FnMut(&Self::Item) -> bool
1.0.0[src]

Searches for an element of an iterator that satisfies a predicate. Read more

+

fn find_map<B, F>(&mut self, f: F) -> Option<B> where
    F: FnMut(Self::Item) -> Option<B>, 
1.30.0[src]

Applies function to the elements of iterator and returns the first non-none result. Read more

+

fn position<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool
1.0.0[src]

Searches for an element in an iterator, returning its index. Read more

+

fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
    P: FnMut(Self::Item) -> bool,
    Self: ExactSizeIterator + DoubleEndedIterator
1.0.0[src]

Searches for an element in an iterator from the right, returning its index. Read more

+

fn max(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the maximum element of an iterator. Read more

+

fn min(self) -> Option<Self::Item> where
    Self::Item: Ord
1.0.0[src]

Returns the minimum element of an iterator. Read more

+

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the maximum value from the specified function. Read more

+

fn max_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the maximum value with respect to the specified comparison function. Read more

+

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
    B: Ord,
    F: FnMut(&Self::Item) -> B, 
1.6.0[src]

Returns the element that gives the minimum value from the specified function. Read more

+

fn min_by<F>(self, compare: F) -> Option<Self::Item> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering
1.15.0[src]

Returns the element that gives the minimum value with respect to the specified comparison function. Read more

+

fn rev(self) -> Rev<Self> where
    Self: DoubleEndedIterator
1.0.0[src]

Reverses an iterator's direction. Read more

+

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 
1.0.0[src]

Converts an iterator of pairs into a pair of containers. Read more

+

fn copied<'a, T>(self) -> Copied<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Copy
1.36.0[src]

Creates an iterator which copies all of its elements. Read more

+

fn cloned<'a, T>(self) -> Cloned<Self> where
    Self: Iterator<Item = &'a T>,
    T: 'a + Clone
1.0.0[src]

Creates an iterator which [clone]s all of its elements. Read more

+

fn cycle(self) -> Cycle<Self> where
    Self: Clone
1.0.0[src]

Repeats an iterator endlessly. Read more

+

fn sum<S>(self) -> S where
    S: Sum<Self::Item>, 
1.11.0[src]

Sums the elements of an iterator. Read more

+

fn product<P>(self) -> P where
    P: Product<Self::Item>, 
1.11.0[src]

Iterates over the entire iterator, multiplying all the elements Read more

+

fn cmp<I>(self, other: I) -> Ordering where
    I: IntoIterator<Item = Self::Item>,
    Self::Item: Ord
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Lexicographically compares the elements of this Iterator with those of another. Read more

+

fn eq<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are equal to those of another. Read more

+

fn ne<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialEq<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are unequal to those of another. Read more

+

fn lt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less than those of another. Read more

+

fn le<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically less or equal to those of another. Read more

+

fn gt<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than those of another. Read more

+

fn ge<I>(self, other: I) -> bool where
    I: IntoIterator,
    Self::Item: PartialOrd<<I as IntoIterator>::Item>, 
1.5.0[src]

Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more

+

fn is_sorted(self) -> bool where
    Self::Item: PartialOrd<Self::Item>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted. Read more

+

fn is_sorted_by<F>(self, compare: F) -> bool where
    F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given comparator function. Read more

+

fn is_sorted_by_key<F, K>(self, f: F) -> bool where
    F: FnMut(&Self::Item) -> K,
    K: PartialOrd<K>, 
[src]

🔬 This is a nightly-only experimental API. (is_sorted)

new API

+

Checks if the elements of this iterator are sorted using the given key extraction function. Read more

+

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

+

type IntoIter = I

Which kind of iterator are we turning this into?

+

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

\ No newline at end of file diff --git a/target/doc/wheel.svg b/target/doc/wheel.svg new file mode 100644 index 0000000..44381a4 --- /dev/null +++ b/target/doc/wheel.svg @@ -0,0 +1 @@ + \ No newline at end of file