]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #26058 - Kimundi:issue15609, r=nikomatsakis
authorbors <bors@rust-lang.org>
Wed, 10 Jun 2015 03:15:16 +0000 (03:15 +0000)
committerbors <bors@rust-lang.org>
Wed, 10 Jun 2015 03:15:16 +0000 (03:15 +0000)
Closes #15609

137 files changed:
mk/cfg/x86_64-pc-windows-msvc.mk
mk/docs.mk
src/compiletest/runtest.rs
src/doc/not_found.md
src/doc/reference.md
src/doc/trpl/closures.md
src/doc/trpl/comments.md
src/doc/trpl/const-and-static.md
src/doc/trpl/dining-philosophers.md
src/doc/trpl/error-handling.md
src/doc/trpl/ffi.md
src/doc/trpl/generics.md
src/doc/trpl/hello-cargo.md
src/doc/trpl/method-syntax.md
src/doc/trpl/ownership.md
src/doc/trpl/patterns.md
src/doc/trpl/references-and-borrowing.md
src/doc/trpl/trait-objects.md
src/doc/trpl/traits.md
src/etc/unicode.py
src/grammar/verify.rs
src/liballoc/arc.rs
src/liballoc/boxed.rs
src/libcollections/binary_heap.rs
src/libcollections/bit.rs
src/libcollections/btree/map.rs
src/libcollections/btree/set.rs
src/libcollections/enum_set.rs
src/libcollections/linked_list.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcollections/vec.rs
src/libcollections/vec_deque.rs
src/libcollections/vec_map.rs
src/libcollectionstest/binary_heap.rs
src/libcollectionstest/bit/set.rs
src/libcollectionstest/bit/vec.rs
src/libcollectionstest/btree/map.rs
src/libcollectionstest/btree/set.rs
src/libcollectionstest/enum_set.rs
src/libcollectionstest/linked_list.rs
src/libcollectionstest/str.rs
src/libcollectionstest/string.rs
src/libcollectionstest/vec.rs
src/libcollectionstest/vec_deque.rs
src/libcollectionstest/vec_map.rs
src/libcore/intrinsics.rs
src/libcore/iter.rs
src/libcore/macros.rs
src/libcore/num/flt2dec/strategy/dragon.rs
src/libcore/num/flt2dec/strategy/grisu.rs
src/libcore/option.rs
src/libcoretest/char.rs
src/liblog/directive.rs
src/librand/distributions/ziggurat_tables.rs
src/librustc/diagnostics.rs
src/librustc/lint/mod.rs
src/librustc/metadata/loader.rs
src/librustc/metadata/tydecode.rs
src/librustc/middle/astencode.rs
src/librustc/middle/infer/error_reporting.rs
src/librustc/middle/infer/freshen.rs
src/librustc/middle/infer/higher_ranked/mod.rs
src/librustc/middle/infer/mod.rs
src/librustc/middle/traits/README.md
src/librustc/middle/traits/select.rs
src/librustc/middle/ty.rs
src/librustc/middle/ty_fold.rs
src/librustc/util/ppaux.rs
src/librustc_back/target/mod.rs
src/librustc_lint/lib.rs
src/librustc_llvm/lib.rs
src/librustc_resolve/lib.rs
src/librustc_trans/back/link.rs
src/librustc_trans/save/dump_csv.rs
src/librustc_trans/save/mod.rs
src/librustc_trans/save/recorder.rs
src/librustc_trans/save/span_utils.rs
src/librustc_trans/trans/builder.rs
src/librustc_trans/trans/callee.rs
src/librustc_trans/trans/closure.rs
src/librustc_trans/trans/common.rs
src/librustc_trans/trans/consts.rs
src/librustc_trans/trans/context.rs
src/librustc_trans/trans/controlflow.rs
src/librustc_trans/trans/debuginfo/mod.rs
src/librustc_trans/trans/debuginfo/namespace.rs
src/librustc_trans/trans/expr.rs
src/librustc_trans/trans/inline.rs
src/librustc_trans/trans/meth.rs
src/librustc_trans/trans/monomorphize.rs
src/librustc_typeck/check/coercion.rs
src/librustc_typeck/check/method/README.md
src/librustc_typeck/check/mod.rs
src/librustc_unicode/char.rs
src/librustc_unicode/lib.rs
src/librustc_unicode/tables.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/format.rs
src/librustdoc/html/render.rs
src/librustdoc/html/toc.rs
src/librustdoc/plugins.rs
src/libserialize/json.rs
src/libstd/error.rs
src/libstd/net/tcp.rs
src/libstd/process.rs
src/libstd/sys/common/backtrace.rs
src/libstd/sys/common/remutex.rs
src/libstd/sys/common/wtf8.rs
src/libstd/sys/windows/ext/fs.rs
src/libstd/sys/windows/fs.rs
src/libsyntax/diagnostics/plugin.rs
src/libsyntax/ext/format.rs
src/libsyntax/parse/parser.rs
src/libtest/lib.rs
src/rustbook/build.rs
src/rustllvm/ExecutionEngineWrapper.cpp
src/rustllvm/RustWrapper.cpp
src/rustllvm/rustllvm.h
src/test/compile-fail/bad-expr-path.rs
src/test/compile-fail/bad-expr-path2.rs
src/test/compile-fail/pub-struct-field-span-26083.rs [new file with mode: 0644]
src/test/compile-fail/typo-suggestion.rs [new file with mode: 0644]
src/test/debuginfo/gdb-pretty-struct-and-enums.rs
src/test/run-make/execution-engine/Makefile [new file with mode: 0644]
src/test/run-make/execution-engine/test.rs [new file with mode: 0644]
src/test/run-make/issue-26006/Makefile [new file with mode: 0644]
src/test/run-make/issue-26006/in/libc/lib.rs [new file with mode: 0644]
src/test/run-make/issue-26006/in/time/lib.rs [new file with mode: 0644]
src/test/run-pass/dst-coerce-rc.rs
src/test/run-pass/issue-19811-escape-unicode.rs
src/test/run-pass/issue-24779.rs [new file with mode: 0644]
src/test/run-pass/istr.rs
src/test/run-pass/new-unicode-escapes.rs
src/test/run-pass/overloaded-autoderef.rs
src/test/run-pass/overloaded-deref.rs
src/test/run-pass/while-prelude-drop.rs

index 1e1906a298084dce9f7efc0690efb37ace352903..c718c19d366cea67f4a37f4894b1f492f18e9659 100644 (file)
@@ -9,8 +9,8 @@ CFG_STATIC_LIB_NAME_x86_64-pc-windows-msvc=$(1).lib
 CFG_LIB_GLOB_x86_64-pc-windows-msvc=$(1)-*.dll
 CFG_LIB_DSYM_GLOB_x86_64-pc-windows-msvc=$(1)-*.dylib.dSYM
 CFG_JEMALLOC_CFLAGS_x86_64-pc-windows-msvc :=
-CFG_GCCISH_CFLAGS_x86_64-pc-windows-msvc :=
-CFG_GCCISH_CXXFLAGS_x86_64-pc-windows-msvc :=
+CFG_GCCISH_CFLAGS_x86_64-pc-windows-msvc := -MD
+CFG_GCCISH_CXXFLAGS_x86_64-pc-windows-msvc := -MD
 CFG_GCCISH_LINK_FLAGS_x86_64-pc-windows-msvc :=
 CFG_GCCISH_DEF_FLAG_x86_64-pc-windows-msvc :=
 CFG_LLC_FLAGS_x86_64-pc-windows-msvc :=
index 922b67d7cc9c44fc5ea1632908ea57ddfa5ef8e3..0f3d84cf6317c58f0d2e494382093f8f22c25b28 100644 (file)
@@ -169,6 +169,7 @@ DOC_TARGETS += doc/not_found.html
 doc/not_found.html: $(D)/not_found.md $(HTML_DEPS) | doc/
        @$(call E, rustdoc: $@)
        $(Q)$(RUSTDOC) $(RUSTDOC_HTML_OPTS_NO_CSS) \
+               --markdown-no-toc \
                --markdown-css http://doc.rust-lang.org/rust.css $<
 
 define DEF_DOC
index 87b6f8f0df6b34ab604428d33124fa23b8d50366..185a969cbc6270d1497532a8a38eda43ef6ba869 100644 (file)
@@ -651,7 +651,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
 
     // Write debugger script:
     // We don't want to hang when calling `quit` while the process is still running
-    let mut script_str = String::from_str("settings set auto-confirm true\n");
+    let mut script_str = String::from("settings set auto-confirm true\n");
 
     // Make LLDB emit its version, so we have it documented in the test output
     script_str.push_str("version\n");
index e740bf3c223aef1a34278be7c5811df77d63ff78..0efdf45c640cba9307c1f99cff0539c66b8ebb0c 100644 (file)
@@ -11,7 +11,7 @@ Looks like you've taken a wrong turn.
 
 Some things that might be helpful to you though:
 
-## Search
+# Search
 
 * <form action="https://duckduckgo.com/">
     <input type="text" id="site-search" name="q" size="80"></input>
@@ -19,12 +19,12 @@ Some things that might be helpful to you though:
 </form>
 * Rust doc search: <span id="core-search"></span>
 
-## Reference
+# Reference
 
 * [The Rust official site](http://rust-lang.org)
 * [The Rust reference](http://doc.rust-lang.org/reference.html)
 
-## Docs
+# Docs
 
 * [The standard library](http://doc.rust-lang.org/std/)
 
index d56ecb360cfed3ccd675813feaee24f0b7547518..8d57238dc175d4c99d63449e2c00e93d9df5e83d 100644 (file)
@@ -1038,7 +1038,7 @@ be undesired.
 
 * Deadlocks
 * Reading data from private fields (`std::repr`)
-* Leaks due to reference count cycles, even in the global heap
+* Leaks of memory and other resources
 * Exiting without calling destructors
 * Sending signals
 * Accessing/modifying the file system
@@ -1367,7 +1367,6 @@ Traits can include default implementations of methods, as in:
 ```
 trait Foo {
     fn bar(&self);
-
     fn baz(&self) { println!("We called baz."); }
 }
 ```
@@ -1418,9 +1417,13 @@ impl<T> Container for Vec<T> {
 ```
 
 Generic functions may use traits as _bounds_ on their type parameters. This
-will have two effects: only types that have the trait may instantiate the
-parameter, and within the generic function, the methods of the trait can be
-called on values that have the parameter's type. For example:
+will have two effects:
+
+- Only types that have the trait may instantiate the parameter.
+- Within the generic function, the methods of the trait can be
+  called on values that have the parameter's type.
+
+For example:
 
 ```
 # type Surface = i32;
@@ -2831,13 +2834,13 @@ on the right-hand side.
 An example of an `as` expression:
 
 ```
-# fn sum(v: &[f64]) -> f64 { 0.0 }
-# fn len(v: &[f64]) -> i32 { 0 }
+# fn sum(values: &[f64]) -> f64 { 0.0 }
+# fn len(values: &[f64]) -> i32 { 0 }
 
-fn avg(v: &[f64]) -> f64 {
-  let sum: f64 = sum(v);
-  let sz: f64 = len(v) as f64;
-  return sum / sz;
+fn average(values: &[f64]) -> f64 {
+  let sum: f64 = sum(values);
+  let size: f64 = len(values) as f64;
+  sum / size
 }
 ```
 
index d2fe9c6e550c90cf73a1baef1cff6b4e9f746629..4479fdb7baae5dcedf5f2f3c487b64550df0cd6e 100644 (file)
@@ -33,8 +33,8 @@ let plus_two = |x| {
 assert_eq!(4, plus_two(2));
 ```
 
-You’ll notice a few things about closures that are a bit different than regular
-functions defined with `fn`. The first of which is that we did not need to
+You’ll notice a few things about closures that are a bit different from regular
+functions defined with `fn`. The first is that we did not need to
 annotate the types of arguments the closure takes or the values it returns. We
 can:
 
@@ -48,10 +48,10 @@ But we don’t have to. Why is this? Basically, it was chosen for ergonomic reas
 While specifying the full type for named functions is helpful with things like
 documentation and type inference, the types of closures are rarely documented
 since they’re anonymous, and they don’t cause the kinds of error-at-a-distance
-that inferring named function types can.
+problems that inferring named function types can.
 
 The second is that the syntax is similar, but a bit different. I’ve added spaces
-here to make them look a little closer:
+here for easier comparison:
 
 ```rust
 fn  plus_one_v1   (x: i32) -> i32 { x + 1 }
@@ -59,7 +59,7 @@ let plus_one_v2 = |x: i32| -> i32 { x + 1 };
 let plus_one_v3 = |x: i32|          x + 1  ;
 ```
 
-Small differences, but they’re similar in ways.
+Small differences, but they’re similar.
 
 # Closures and their environment
 
@@ -99,7 +99,7 @@ note: previous borrow ends here
 fn main() {
     let mut num = 5;
     let plus_num = |x| x + num;
-    
+
     let y = &mut num;
 }
 ^
@@ -161,7 +161,7 @@ of `num`. So what’s the difference?
 ```rust
 let mut num = 5;
 
-{ 
+{
     let mut add_num = |x: i32| num += x;
 
     add_num(5);
@@ -180,7 +180,7 @@ If we change to a `move` closure, it’s different:
 ```rust
 let mut num = 5;
 
-{ 
+{
     let mut add_num = move |x: i32| num += x;
 
     add_num(5);
index fa27d1c226cc494cdf06bc9ce24b2a71d7d1d3fc..7687d2a57da9238de0900ee3e2ffda6f1d95cf25 100644 (file)
@@ -29,6 +29,9 @@ The other kind of comment is a doc comment. Doc comments use `///` instead of
 /// let five = 5;
 ///
 /// assert_eq!(6, add_one(5));
+/// # fn add_one(x: i32) -> i32 {
+/// #     x + 1
+/// # }
 /// ```
 fn add_one(x: i32) -> i32 {
     x + 1
index f309dd0fad6d93e3cd2937f1d349d854183b72a2..7d555b52a986df0329f7f1d42877ddc85aa15089 100644 (file)
@@ -64,7 +64,10 @@ unsafe {
 
 [unsafe]: unsafe.html
 
-Furthermore, any type stored in a `static` must be `Sync`.
+Furthermore, any type stored in a `static` must be `Sync`, and may not have
+a [`Drop`][drop] implementation.
+
+[drop]: drop.html
 
 # Initializing
 
@@ -78,7 +81,3 @@ Almost always, if you can choose between the two, choose `const`. It’s pretty
 rare that you actually want a memory location associated with your constant,
 and using a const allows for optimizations like constant propagation not only
 in your crate but downstream crates.
-
-A const can be thought of as a `#define` in C: it has metadata overhead but it
-has no runtime overhead. “Should I use a #define or a static in C,” is largely
-the same question as whether you should use a const or a static in Rust.
index 7e37473ac8feaf1aeb2eb0c943d0593f6689753c..b24d50c890da4a259c95d12adf9f80724601892e 100644 (file)
@@ -432,7 +432,9 @@ an extra annotation, `move`, to indicate that the closure is going to take
 ownership of the values it’s capturing. Primarily, the `p` variable of the
 `map` function.
 
-Inside the thread, all we do is call `eat()` on `p`.
+Inside the thread, all we do is call `eat()` on `p`. Also note that the call to `thread::spawn` lacks a trailing semicolon, making this an expression. This distinction is important, yielding the correct return value. For more details, read [Expressions vs. Statements][es].
+
+[es]: functions.html#expressions-vs.-statements
 
 ```rust,ignore
 }).collect();
@@ -672,9 +674,13 @@ let handles: Vec<_> = philosophers.into_iter().map(|p| {
 
 Finally, inside of our `map()`/`collect()` loop, we call `table.clone()`. The
 `clone()` method on `Arc<T>` is what bumps up the reference count, and when it
-goes out of scope, it decrements the count. You’ll notice we can introduce a
-new binding to `table` here, and it will shadow the old one. This is often used
-so that you don’t need to come up with two unique names.
+goes out of scope, it decrements the count. This is needed so that we know how
+many references to `table` exist across our threads. If we didn’t have a count,
+we wouldn’t know how to deallocate it.
+
+You’ll notice we can introduce a new binding to `table` here, and it will
+shadow the old one. This is often used so that you don’t need to come up with
+two unique names.
 
 With this, our program works! Only two philosophers can eat at any one time,
 and so you’ll get some output like this:
index 7b47559e0fce05f51b6dfd4d79bab2357d74843a..2a0e8ed16436e08a2380286db3225fdbac67658f 100644 (file)
@@ -284,7 +284,7 @@ struct Info {
 }
 
 fn write_info(info: &Info) -> io::Result<()> {
-    let mut file = try!(File::create("my_best_friends.txt"));
+    let mut file = File::create("my_best_friends.txt").unwrap();
 
     try!(writeln!(&mut file, "name: {}", info.name));
     try!(writeln!(&mut file, "age: {}", info.age));
index 9ede835e521c9a7e26212cec3c96392f537269be..8077f04ed60842b49aba8b7080b7eb5539a1201c 100644 (file)
@@ -342,8 +342,10 @@ Note that frameworks are only available on OSX targets.
 The different `kind` values are meant to differentiate how the native library
 participates in linkage. From a linkage perspective, the rust compiler creates
 two flavors of artifacts: partial (rlib/staticlib) and final (dylib/binary).
-Native dynamic libraries and frameworks are propagated to the final artifact
-boundary, while static libraries are not propagated at all.
+Native dynamic library and framework dependencies are propagated to the final
+artifact boundary, while static library dependencies are not propagated at
+all, because the static libraries are integrated directly into the subsequent
+artifact.
 
 A few examples of how this model can be used are:
 
index f8f1962e0cf5565bb6342f1bf538b39b7229186b..c28d7c71608bbf82e754daae4bd1560e26efc7c6 100644 (file)
@@ -1,8 +1,8 @@
 % Generics
 
 Sometimes, when writing a function or data type, we may want it to work for
-multiple types of arguments. Luckily, Rust has a feature that gives us a better
-way: generics. Generics are called ‘parametric polymorphism’ in type theory,
+multiple types of arguments. In Rust, we can do this with generics.
+Generics are called ‘parametric polymorphism’ in type theory,
 which means that they are types or functions that have multiple forms (‘poly’
 is multiple, ‘morph’ is form) over a given parameter (‘parametric’).
 
index 32002ebd1ec2a7178541906d591bfa0264e1acf1..9920e8e00685bf43640d8906bac7d3d218561552 100644 (file)
@@ -36,7 +36,7 @@ Note that since we're creating an executable, we used `main.rs`. If we
 want to make a library instead, we should use `lib.rs`. This convention is required
 for Cargo to successfully compile our projects, but it can be overridden if we wish. 
 Custom file locations for the entry point can be specified
-with a [`[[lib]]` or `[[bin]]`][crates-custom] key in the TOML file described below.
+with a [`[lib]` or `[[bin]]`][crates-custom] key in the TOML file.
 
 [crates-custom]: http://doc.crates.io/manifest.html#configuring-a-target
 
@@ -170,7 +170,7 @@ This is all we need to get started. First, let’s check out `Cargo.toml`:
 [package]
 
 name = "hello_world"
-version = "0.0.1"
+version = "0.1.0"
 authors = ["Your Name <you@example.com>"]
 ```
 
index 1f694f71a883f761e7ac5a947379cbbcf18a6698..1afa622db7dd39a75d9c93957acca2b4d4da6180 100644 (file)
@@ -86,8 +86,8 @@ impl Circle {
 # Chaining method calls
 
 So, now we know how to call a method, such as `foo.bar()`. But what about our
-original example, `foo.bar().baz()`? This is called ‘method chaining’, and we
-can do it by returning `self`.
+original example, `foo.bar().baz()`? This is called ‘method chaining’. Let’s
+look at an example:
 
 ```rust
 struct Circle {
index 0ba2b33759cd518cde8964bcc2bc335f5705dde0..46af311acf31547332961f38c2a980bbf260ee06 100644 (file)
@@ -156,6 +156,46 @@ that, just like a move, when we assign `v` to `v2`, a copy of the data is made.
 But, unlike a move, we can still use `v` afterward. This is because an `i32`
 has no pointers to data somewhere else, copying it is a full copy.
 
+All primitive types implement the `Copy` trait and their ownership is
+therefore not moved like one would assume, following the ´ownership rules´.
+To give an example, the two following snippets of code only compile because the 
+`i32` and `bool` types implement the `Copy` trait. 
+
+```rust
+fn main() {
+    let a = 5;
+
+    let _y = double(a);
+    println!("{}", a);
+}
+
+fn double(x: i32) -> i32 {
+    x * 2
+}
+```
+
+```rust
+fn main() {
+    let a = true;
+
+    let _y = change_truth(a);
+    println!("{}", a);
+}
+
+fn change_truth(x: bool) -> bool {
+    !x
+}
+```
+
+If we would have used types that do not implement the `Copy` trait,
+we would have gotten a compile error because we tried to use a moved value.
+
+```text
+error: use of moved value: `a`
+println!("{}", a);
+               ^
+```
+
 We will discuss how to make your own types `Copy` in the [traits][traits]
 section.
 
index 93df0f19e8eeb087283649842bcb5f64273c3247..0f356d75abc86d45fa7f67db1966c5c4a3499bba 100644 (file)
@@ -154,6 +154,31 @@ match x {
 
 This prints `Got an int!`.
 
+If you’re using `if` with multiple patterns, the `if` applies to both sides:
+
+```rust
+let x = 4;
+let y = false;
+
+match x {
+    4 | 5 if y => println!("yes"),
+    _ => println!("no"),
+}
+```
+
+This prints `no`, because the `if` applies to the whole of `4 | 5`, and not to
+just the `5`, In other words, the the precedence of `if` behaves like this:
+
+```text
+(4 | 5) if y => ...
+```
+
+not this:
+
+```text
+4 | (5 if y) => ...
+```
+
 # ref and ref mut
 
 If you want to get a [reference][ref], use the `ref` keyword:
index 775a6fbd293589337529cad99097d18e00bd2b7f..b27db2ab7bea8c0ac120f59b9d3540ee05269159 100644 (file)
@@ -151,9 +151,9 @@ As it turns out, there are rules.
 
 Here’s the rules about borrowing in Rust:
 
-First, any borrow must last for a smaller scope than the owner. Second, you may
-have one or the other of these two kinds of borrows, but not both at the same
-time:
+First, any borrow must last for a scope no greater than that of the owner.
+Second, you may have one or the other of these two kinds of borrows, but not
+both at the same time:
 
 * one or more references (`&T`) to a resource.
 * exactly one mutable reference (`&mut T`)
index c01129057418cf1af9db4d73fb37ed52d4133f19..3da29c9b817d2da9ce261b52d7329fb54b20aa46 100644 (file)
@@ -261,7 +261,7 @@ static Foo_for_String_vtable: FooVtable = FooVtable {
 ```
 
 The `destructor` field in each vtable points to a function that will clean up
-any resources of the vtable’s type, for `u8` it is trivial, but for `String` it
+any resources of the vtable’s type: for `u8` it is trivial, but for `String` it
 will free the memory. This is necessary for owning trait objects like
 `Box<Foo>`, which need to clean-up both the `Box` allocation as well as the
 internal type when they go out of scope. The `size` and `align` fields store
@@ -270,7 +270,7 @@ essentially unused at the moment since the information is embedded in the
 destructor, but will be used in the future, as trait objects are progressively
 made more flexible.
 
-Suppose we’ve got some values that implement `Foo`, then the explicit form of
+Suppose we’ve got some values that implement `Foo`. The explicit form of
 construction and use of `Foo` trait objects might look a bit like (ignoring the
 type mismatches: they’re all just pointers anyway):
 
index 2ef9e7ca22e60a655b30ea6b037855f09c5d6889..162a2db1ec7548216333d02e5907b6913e956175 100644 (file)
@@ -45,7 +45,7 @@ but we don’t define a body, just a type signature. When we `impl` a trait,
 we use `impl Trait for Item`, rather than just `impl Item`.
 
 We can use traits to constrain our generics. Consider this function, which
-does not compile, and gives us a similar error:
+does not compile:
 
 ```rust,ignore
 fn print_area<T>(shape: T) {
@@ -56,7 +56,7 @@ fn print_area<T>(shape: T) {
 Rust complains:
 
 ```text
-error: type `T` does not implement any method in scope named `area`
+error: no method named `area` found for type `T` in the current scope
 ```
 
 Because `T` can be any type, we can’t be sure that it implements the `area`
@@ -212,10 +212,10 @@ This will compile without error.
 This means that even if someone does something bad like add methods to `i32`,
 it won’t affect you, unless you `use` that trait.
 
-There’s one more restriction on implementing traits. Either the trait or the
-type you’re writing the `impl` for must be defined by you. So, we could
+There’s one more restriction on implementing traits: either the trait, or the
+type you’re writing the `impl` for, must be defined by you. So, we could
 implement the `HasArea` type for `i32`, because `HasArea` is in our code. But
-if we tried to implement `Float`, a trait provided by Rust, for `i32`, we could
+if we tried to implement `ToString`, a trait provided by Rust, for `i32`, we could
 not, because neither the trait nor the type are in our code.
 
 One last thing about traits: generic functions with a trait bound use
index 038a0806fd9fffcdcf79c9356b692da733f14015..f580127cddaf8386515919b10902772a45aacbcf 100755 (executable)
@@ -72,8 +72,9 @@ def is_surrogate(n):
 def load_unicode_data(f):
     fetch(f)
     gencats = {}
-    upperlower = {}
-    lowerupper = {}
+    to_lower = {}
+    to_upper = {}
+    to_title = {}
     combines = {}
     canon_decomp = {}
     compat_decomp = {}
@@ -103,12 +104,16 @@ def load_unicode_data(f):
 
         # generate char to char direct common and simple conversions
         # uppercase to lowercase
-        if gencat == "Lu" and lowcase != "" and code_org != lowcase:
-            upperlower[code] = int(lowcase, 16)
+        if lowcase != "" and code_org != lowcase:
+            to_lower[code] = (int(lowcase, 16), 0, 0)
 
         # lowercase to uppercase
-        if gencat == "Ll" and upcase != "" and code_org != upcase:
-            lowerupper[code] = int(upcase, 16)
+        if upcase != "" and code_org != upcase:
+            to_upper[code] = (int(upcase, 16), 0, 0)
+
+        # title case
+        if titlecase.strip() != "" and code_org != titlecase:
+            to_title[code] = (int(titlecase, 16), 0, 0)
 
         # store decomposition, if given
         if decomp != "":
@@ -144,7 +149,32 @@ def load_unicode_data(f):
     gencats = group_cats(gencats)
     combines = to_combines(group_cats(combines))
 
-    return (canon_decomp, compat_decomp, gencats, combines, lowerupper, upperlower)
+    return (canon_decomp, compat_decomp, gencats, combines, to_upper, to_lower, to_title)
+
+def load_special_casing(f, to_upper, to_lower, to_title):
+    fetch(f)
+    for line in fileinput.input(f):
+        data = line.split('#')[0].split(';')
+        if len(data) == 5:
+            code, lower, title, upper, _comment = data
+        elif len(data) == 6:
+            code, lower, title, upper, condition, _comment = data
+            if condition.strip():  # Only keep unconditional mappins
+                continue
+        else:
+            continue
+        code = code.strip()
+        lower = lower.strip()
+        title = title.strip()
+        upper = upper.strip()
+        key = int(code, 16)
+        for (map_, values) in [(to_lower, lower), (to_upper, upper), (to_title, title)]:
+            if values != code:
+                values = [int(i, 16) for i in values.split()]
+                for _ in range(len(values), 3):
+                    values.append(0)
+                assert len(values) == 3
+                map_[key] = values
 
 def group_cats(cats):
     cats_out = {}
@@ -279,7 +309,7 @@ def load_east_asian_width(want_widths, except_cats):
     return widths
 
 def escape_char(c):
-    return "'\\u{%x}'" % c
+    return "'\\u{%x}'" % c if c != 0 else "'\\0'"
 
 def emit_bsearch_range_table(f):
     f.write("""
@@ -319,7 +349,7 @@ def emit_property_module(f, mod, tbl, emit):
         f.write("    }\n\n")
     f.write("}\n\n")
 
-def emit_conversions_module(f, lowerupper, upperlower):
+def emit_conversions_module(f, to_upper, to_lower, to_title):
     f.write("pub mod conversions {")
     f.write("""
     use core::cmp::Ordering::{Equal, Less, Greater};
@@ -328,21 +358,28 @@ def emit_conversions_module(f, lowerupper, upperlower):
     use core::option::Option::{Some, None};
     use core::result::Result::{Ok, Err};
 
-    pub fn to_lower(c: char) -> char {
-        match bsearch_case_table(c, LuLl_table) {
-          None        => c,
-          Some(index) => LuLl_table[index].1
+    pub fn to_lower(c: char) -> [char; 3] {
+        match bsearch_case_table(c, to_lowercase_table) {
+          None        => [c, '\\0', '\\0'],
+          Some(index) => to_lowercase_table[index].1
+        }
+    }
+
+    pub fn to_upper(c: char) -> [char; 3] {
+        match bsearch_case_table(c, to_uppercase_table) {
+            None        => [c, '\\0', '\\0'],
+            Some(index) => to_uppercase_table[index].1
         }
     }
 
-    pub fn to_upper(c: char) -> char {
-        match bsearch_case_table(c, LlLu_table) {
-            None        => c,
-            Some(index) => LlLu_table[index].1
+    pub fn to_title(c: char) -> [char; 3] {
+        match bsearch_case_table(c, to_titlecase_table) {
+            None        => [c, '\\0', '\\0'],
+            Some(index) => to_titlecase_table[index].1
         }
     }
 
-    fn bsearch_case_table(c: char, table: &'static [(char, char)]) -> Option<usize> {
+    fn bsearch_case_table(c: char, table: &'static [(char, [char; 3])]) -> Option<usize> {
         match table.binary_search_by(|&(key, _)| {
             if c == key { Equal }
             else if key < c { Less }
@@ -354,10 +391,18 @@ def emit_conversions_module(f, lowerupper, upperlower):
     }
 
 """)
-    emit_table(f, "LuLl_table",
-        sorted(upperlower.iteritems(), key=operator.itemgetter(0)), is_pub=False)
-    emit_table(f, "LlLu_table",
-        sorted(lowerupper.iteritems(), key=operator.itemgetter(0)), is_pub=False)
+    t_type = "&'static [(char, [char; 3])]"
+    pfun = lambda x: "(%s,[%s,%s,%s])" % (
+        escape_char(x[0]), escape_char(x[1][0]), escape_char(x[1][1]), escape_char(x[1][2]))
+    emit_table(f, "to_lowercase_table",
+        sorted(to_lower.iteritems(), key=operator.itemgetter(0)),
+        is_pub=False, t_type = t_type, pfun=pfun)
+    emit_table(f, "to_uppercase_table",
+        sorted(to_upper.iteritems(), key=operator.itemgetter(0)),
+        is_pub=False, t_type = t_type, pfun=pfun)
+    emit_table(f, "to_titlecase_table",
+        sorted(to_title.iteritems(), key=operator.itemgetter(0)),
+        is_pub=False, t_type = t_type, pfun=pfun)
     f.write("}\n\n")
 
 def emit_grapheme_module(f, grapheme_table, grapheme_cats):
@@ -591,8 +636,10 @@ if __name__ == "__main__":
 pub const UNICODE_VERSION: (u64, u64, u64) = (%s, %s, %s);
 """ % unicode_version)
         (canon_decomp, compat_decomp, gencats, combines,
-                lowerupper, upperlower) = load_unicode_data("UnicodeData.txt")
-        want_derived = ["XID_Start", "XID_Continue", "Alphabetic", "Lowercase", "Uppercase"]
+                to_upper, to_lower, to_title) = load_unicode_data("UnicodeData.txt")
+        load_special_casing("SpecialCasing.txt", to_upper, to_lower, to_title)
+        want_derived = ["XID_Start", "XID_Continue", "Alphabetic", "Lowercase", "Uppercase",
+                        "Cased", "Case_Ignorable"]
         derived = load_properties("DerivedCoreProperties.txt", want_derived)
         scripts = load_properties("Scripts.txt", [])
         props = load_properties("PropList.txt",
@@ -611,7 +658,7 @@ pub const UNICODE_VERSION: (u64, u64, u64) = (%s, %s, %s);
 
         # normalizations and conversions module
         emit_norm_module(rf, canon_decomp, compat_decomp, combines, norm_props)
-        emit_conversions_module(rf, lowerupper, upperlower)
+        emit_conversions_module(rf, to_upper, to_lower, to_title)
 
         ### character width module
         width_table = []
index 0d8fb312d11315c3a52d0e4fe6d7075a126c11f1..3235389f1d19309bf83d68418185ef987a36b18f 100644 (file)
@@ -287,7 +287,7 @@ fn next(r: &mut lexer::StringReader) -> TokenAndSpan {
     let options = config::basic_options();
     let session = session::build_session(options, None,
                                          syntax::diagnostics::registry::Registry::new(&[]));
-    let filemap = session.parse_sess.codemap().new_filemap(String::from_str("<n/a>"), code);
+    let filemap = session.parse_sess.codemap().new_filemap(String::from("<n/a>"), code);
     let mut lexer = lexer::StringReader::new(session.diagnostic(), filemap);
     let cm = session.codemap();
 
index d12d28335dde606917bd6ab8cccec2389ce40f90..990a73c53ae966b417dff746909575492fc7810f 100644 (file)
@@ -98,7 +98,6 @@
 /// increase the reference counter.
 ///
 /// ```
-/// # #![feature(alloc, core)]
 /// use std::sync::Arc;
 /// use std::thread;
 ///
@@ -297,7 +296,6 @@ impl<T: ?Sized> Clone for Arc<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(alloc)]
     /// use std::sync::Arc;
     ///
     /// let five = Arc::new(5);
@@ -392,7 +390,6 @@ impl<T: ?Sized> Drop for Arc<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(alloc)]
     /// use std::sync::Arc;
     ///
     /// {
index 12eadcc145d5244b0154ad457a409da6092e1035..4ee500faa22c49ed5ec31321db7e2c0e4507df7c 100644 (file)
@@ -81,7 +81,7 @@
 #[lang = "exchange_heap"]
 #[unstable(feature = "alloc",
            reason = "may be renamed; uncertain about custom allocator design")]
-pub static HEAP: () = ();
+pub const HEAP: () = ();
 
 /// A pointer type for heap allocation.
 ///
index 00e4002f82f4f296bd5ec30b321baf068d4db10f..97bdd8e6a6ef5a6cdf0903bc41461af91b092c47 100644 (file)
@@ -760,3 +760,10 @@ fn extend<I: IntoIterator<Item=T>>(&mut self, iterable: I) {
         }
     }
 }
+
+#[stable(feature = "extend_ref", since = "1.2.0")]
+impl<'a, T: 'a + Ord + Copy> Extend<&'a T> for BinaryHeap<T> {
+    fn extend<I: IntoIterator<Item=&'a T>>(&mut self, iter: I) {
+        self.extend(iter.into_iter().cloned());
+    }
+}
index c06cbdb4179d5a799d254fdcdef41e5f46611c30..6a7a2197e2b4bbfec89b83f437b40787f5f1f215 100644 (file)
@@ -125,8 +125,8 @@ fn match_words <'a,'b>(a: &'a BitVec, b: &'b BitVec) -> (MatchWords<'a>, MatchWo
     }
 }
 
-static TRUE: bool = true;
-static FALSE: bool = false;
+const TRUE: &'static bool = &true;
+const FALSE: &'static bool = &false;
 
 /// The bitvector type.
 ///
@@ -172,9 +172,9 @@ impl Index<usize> for BitVec {
     #[inline]
     fn index(&self, i: usize) -> &bool {
         if self.get(i).expect("index out of bounds") {
-            &TRUE
+            TRUE
         } else {
-            &FALSE
+            FALSE
         }
     }
 }
@@ -1070,6 +1070,13 @@ fn extend<I: IntoIterator<Item=bool>>(&mut self, iterable: I) {
     }
 }
 
+#[stable(feature = "extend_ref", since = "1.2.0")]
+impl<'a> Extend<&'a bool> for BitVec {
+    fn extend<I: IntoIterator<Item=&'a bool>>(&mut self, iter: I) {
+        self.extend(iter.into_iter().cloned());
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Clone for BitVec {
     #[inline]
@@ -1278,6 +1285,13 @@ fn extend<I: IntoIterator<Item=usize>>(&mut self, iter: I) {
     }
 }
 
+#[stable(feature = "extend_ref", since = "1.2.0")]
+impl<'a> Extend<&'a usize> for BitSet {
+    fn extend<I: IntoIterator<Item=&'a usize>>(&mut self, iter: I) {
+        self.extend(iter.into_iter().cloned());
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl PartialOrd for BitSet {
     #[inline]
index 11f16e2f400b4892959c8ff7c93c92a2d884dd9d..c7c336e38a1c84cf8151c82376b297a0872b3f51 100644 (file)
@@ -879,6 +879,13 @@ fn extend<T: IntoIterator<Item=(K, V)>>(&mut self, iter: T) {
     }
 }
 
+#[stable(feature = "extend_ref", since = "1.2.0")]
+impl<'a, K: Ord + Copy, V: Copy> Extend<(&'a K, &'a V)> for BTreeMap<K, V> {
+    fn extend<I: IntoIterator<Item=(&'a K, &'a V)>>(&mut self, iter: I) {
+        self.extend(iter.into_iter().map(|(&key, &value)| (key, value)));
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: Hash, V: Hash> Hash for BTreeMap<K, V> {
     fn hash<H: Hasher>(&self, state: &mut H) {
index a3b9320e2b521221d3a16557e0903acbe5c3f81d..ec6c5e63e2daf37fec2e0f2075ff9163871b6447 100644 (file)
@@ -509,6 +509,13 @@ fn extend<Iter: IntoIterator<Item=T>>(&mut self, iter: Iter) {
     }
 }
 
+#[stable(feature = "extend_ref", since = "1.2.0")]
+impl<'a, T: 'a + Ord + Copy> Extend<&'a T> for BTreeSet<T> {
+    fn extend<I: IntoIterator<Item=&'a T>>(&mut self, iter: I) {
+        self.extend(iter.into_iter().cloned());
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Ord> Default for BTreeSet<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
index e6cdb88d3e1746eb90872a1fb7a2a896a06b4e4f..ad90f9f1caa9c532182f7b73f5604f63b60024be 100644 (file)
@@ -288,3 +288,10 @@ fn extend<I: IntoIterator<Item=E>>(&mut self, iter: I) {
         }
     }
 }
+
+#[stable(feature = "extend_ref", since = "1.2.0")]
+impl<'a, E: 'a + CLike + Copy> Extend<&'a E> for EnumSet<E> {
+    fn extend<I: IntoIterator<Item=&'a E>>(&mut self, iter: I) {
+        self.extend(iter.into_iter().cloned());
+    }
+}
index 0bfbfd7337713f2c908a9a70a1f8590fb0e47583..9ed129ccbe97b310e485be2daf1a6c8d1d41b7e4 100644 (file)
@@ -104,17 +104,23 @@ fn some(n: &mut T) -> Rawlink<T> {
     }
 
     /// Convert the `Rawlink` into an Option value
-    fn resolve_immut<'a>(&self) -> Option<&'a T> {
-        unsafe {
-            self.p.as_ref()
-        }
+    ///
+    /// **unsafe** because:
+    ///
+    /// - Dereference of raw pointer.
+    /// - Returns reference of arbitrary lifetime.
+    unsafe fn resolve<'a>(&self) -> Option<&'a T> {
+        self.p.as_ref()
     }
 
     /// Convert the `Rawlink` into an Option value
-    fn resolve<'a>(&mut self) -> Option<&'a mut T> {
-        unsafe {
-            self.p.as_mut()
-        }
+    ///
+    /// **unsafe** because:
+    ///
+    /// - Dereference of raw pointer.
+    /// - Returns reference of arbitrary lifetime.
+    unsafe fn resolve_mut<'a>(&mut self) -> Option<&'a mut T> {
+        self.p.as_mut()
     }
 
     /// Return the `Rawlink` and replace with `Rawlink::none()`
@@ -123,6 +129,15 @@ fn take(&mut self) -> Rawlink<T> {
     }
 }
 
+impl<'a, T> From<&'a mut Link<T>> for Rawlink<Node<T>> {
+    fn from(node: &'a mut Link<T>) -> Self {
+        match node.as_mut() {
+            None => Rawlink::none(),
+            Some(ptr) => Rawlink::some(ptr),
+        }
+    }
+}
+
 impl<T> Clone for Rawlink<T> {
     #[inline]
     fn clone(&self) -> Rawlink<T> {
@@ -134,12 +149,21 @@ impl<T> Node<T> {
     fn new(v: T) -> Node<T> {
         Node{value: v, next: None, prev: Rawlink::none()}
     }
+
+    /// Update the `prev` link on `next`, then set self's next pointer.
+    ///
+    /// `self.next` should be `None` when you call this
+    /// (otherwise a Node is probably being dropped by mistake).
+    fn set_next(&mut self, mut next: Box<Node<T>>) {
+        debug_assert!(self.next.is_none());
+        next.prev = Rawlink::some(self);
+        self.next = Some(next);
+    }
 }
 
-/// Set the .prev field on `next`, then return `Some(next)`
-fn link_with_prev<T>(mut next: Box<Node<T>>, prev: Rawlink<Node<T>>)
-                  -> Link<T> {
-    next.prev = prev;
+/// Clear the .prev field on `next`, then return `Some(next)`
+fn link_no_prev<T>(mut next: Box<Node<T>>) -> Link<T> {
+    next.prev = Rawlink::none();
     Some(next)
 }
 
@@ -150,8 +174,8 @@ impl<T> LinkedList<T> {
     fn push_front_node(&mut self, mut new_head: Box<Node<T>>) {
         match self.list_head {
             None => {
-                self.list_tail = Rawlink::some(&mut *new_head);
-                self.list_head = link_with_prev(new_head, Rawlink::none());
+                self.list_head = link_no_prev(new_head);
+                self.list_tail = Rawlink::from(&mut self.list_head);
             }
             Some(ref mut head) => {
                 new_head.prev = Rawlink::none();
@@ -169,7 +193,7 @@ fn pop_front_node(&mut self) -> Option<Box<Node<T>>> {
         self.list_head.take().map(|mut front_node| {
             self.length -= 1;
             match front_node.next.take() {
-                Some(node) => self.list_head = link_with_prev(node, Rawlink::none()),
+                Some(node) => self.list_head = link_no_prev(node),
                 None => self.list_tail = Rawlink::none()
             }
             front_node
@@ -178,12 +202,12 @@ fn pop_front_node(&mut self) -> Option<Box<Node<T>>> {
 
     /// Add a Node last in the list
     #[inline]
-    fn push_back_node(&mut self, mut new_tail: Box<Node<T>>) {
-        match self.list_tail.resolve() {
+    fn push_back_node(&mut self, new_tail: Box<Node<T>>) {
+        match unsafe { self.list_tail.resolve_mut() } {
             None => return self.push_front_node(new_tail),
             Some(tail) => {
-                self.list_tail = Rawlink::some(&mut *new_tail);
-                tail.next = link_with_prev(new_tail, Rawlink::some(tail));
+                tail.set_next(new_tail);
+                self.list_tail = Rawlink::from(&mut tail.next);
             }
         }
         self.length += 1;
@@ -192,14 +216,16 @@ fn push_back_node(&mut self, mut new_tail: Box<Node<T>>) {
     /// Remove the last Node and return it, or None if the list is empty
     #[inline]
     fn pop_back_node(&mut self) -> Option<Box<Node<T>>> {
-        self.list_tail.resolve().map_or(None, |tail| {
-            self.length -= 1;
-            self.list_tail = tail.prev;
-            match tail.prev.resolve() {
-                None => self.list_head.take(),
-                Some(tail_prev) => tail_prev.next.take()
-            }
-        })
+        unsafe {
+            self.list_tail.resolve_mut().and_then(|tail| {
+                self.length -= 1;
+                self.list_tail = tail.prev;
+                match tail.prev.resolve_mut() {
+                    None => self.list_head.take(),
+                    Some(tail_prev) => tail_prev.next.take()
+                }
+            })
+        }
     }
 }
 
@@ -246,7 +272,7 @@ pub fn new() -> LinkedList<T> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn append(&mut self, other: &mut LinkedList<T>) {
-        match self.list_tail.resolve() {
+        match unsafe { self.list_tail.resolve_mut() } {
             None => {
                 self.length = other.length;
                 self.list_head = other.list_head.take();
@@ -259,7 +285,7 @@ pub fn append(&mut self, other: &mut LinkedList<T>) {
                 match other.list_head.take() {
                     None => return,
                     Some(node) => {
-                        tail.next = link_with_prev(node, self.list_tail);
+                        tail.set_next(node);
                         self.list_tail = o_tail;
                         self.length += o_length;
                     }
@@ -280,13 +306,9 @@ pub fn iter(&self) -> Iter<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn iter_mut(&mut self) -> IterMut<T> {
-        let head_raw = match self.list_head {
-            Some(ref mut h) => Rawlink::some(&mut **h),
-            None => Rawlink::none(),
-        };
-        IterMut{
+        IterMut {
             nelem: self.len(),
-            head: head_raw,
+            head: Rawlink::from(&mut self.list_head),
             tail: self.list_tail,
             list: self
         }
@@ -433,7 +455,9 @@ pub fn front_mut(&mut self) -> Option<&mut T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn back(&self) -> Option<&T> {
-        self.list_tail.resolve_immut().as_ref().map(|tail| &tail.value)
+        unsafe {
+            self.list_tail.resolve().map(|tail| &tail.value)
+        }
     }
 
     /// Provides a mutable reference to the back element, or `None` if the list
@@ -460,7 +484,9 @@ pub fn back(&self) -> Option<&T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn back_mut(&mut self) -> Option<&mut T> {
-        self.list_tail.resolve().map(|tail| &mut tail.value)
+        unsafe {
+            self.list_tail.resolve_mut().map(|tail| &mut tail.value)
+        }
     }
 
     /// Adds an element first in the list.
@@ -603,44 +629,42 @@ pub fn split_off(&mut self, at: usize) -> LinkedList<T> {
             iter.tail
         };
 
-        let mut splitted_list = LinkedList {
-            list_head: None,
+        // The split node is the new tail node of the first part and owns
+        // the head of the second part.
+        let mut second_part_head;
+
+        unsafe {
+            second_part_head = split_node.resolve_mut().unwrap().next.take();
+            match second_part_head {
+                None => {}
+                Some(ref mut head) => head.prev = Rawlink::none(),
+            }
+        }
+
+        let second_part = LinkedList {
+            list_head: second_part_head,
             list_tail: self.list_tail,
             length: len - at
         };
 
-        // Swap split_node.next with list_head (which is None), nulling out split_node.next,
-        // as it is the new tail.
-        mem::swap(&mut split_node.resolve().unwrap().next, &mut splitted_list.list_head);
-        // Null out list_head.prev. Note this `unwrap` won't fail because if at == len
-        // we already branched out at the top of the fn to return the empty list.
-        splitted_list.list_head.as_mut().unwrap().prev = Rawlink::none();
-        // Fix the tail ptr
+        // Fix the tail ptr of the first part
         self.list_tail = split_node;
         self.length = at;
 
-        splitted_list
+        second_part
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Drop for LinkedList<T> {
     fn drop(&mut self) {
-        // Dissolve the linked_list in backwards direction
+        // Dissolve the linked_list in a loop.
         // Just dropping the list_head can lead to stack exhaustion
         // when length is >> 1_000_000
-        let mut tail = self.list_tail;
-        loop {
-            match tail.resolve() {
-                None => break,
-                Some(prev) => {
-                    prev.next.take(); // release Box<Node<T>>
-                    tail = prev.prev;
-                }
-            }
+        while let Some(mut head_) = self.list_head.take() {
+            self.list_head = head_.next.take();
         }
         self.length = 0;
-        self.list_head = None;
         self.list_tail = Rawlink::none();
     }
 }
@@ -674,11 +698,13 @@ fn next_back(&mut self) -> Option<&'a A> {
         if self.nelem == 0 {
             return None;
         }
-        self.tail.resolve_immut().as_ref().map(|prev| {
-            self.nelem -= 1;
-            self.tail = prev.prev;
-            &prev.value
-        })
+        unsafe {
+            self.tail.resolve().map(|prev| {
+                self.nelem -= 1;
+                self.tail = prev.prev;
+                &prev.value
+            })
+        }
     }
 }
 
@@ -693,14 +719,13 @@ fn next(&mut self) -> Option<&'a mut A> {
         if self.nelem == 0 {
             return None;
         }
-        self.head.resolve().map(|next| {
-            self.nelem -= 1;
-            self.head = match next.next {
-                Some(ref mut node) => Rawlink::some(&mut **node),
-                None => Rawlink::none(),
-            };
-            &mut next.value
-        })
+        unsafe {
+            self.head.resolve_mut().map(|next| {
+                self.nelem -= 1;
+                self.head = Rawlink::from(&mut next.next);
+                &mut next.value
+            })
+        }
     }
 
     #[inline]
@@ -716,11 +741,13 @@ fn next_back(&mut self) -> Option<&'a mut A> {
         if self.nelem == 0 {
             return None;
         }
-        self.tail.resolve().map(|prev| {
-            self.nelem -= 1;
-            self.tail = prev.prev;
-            &mut prev.value
-        })
+        unsafe {
+            self.tail.resolve_mut().map(|prev| {
+                self.nelem -= 1;
+                self.tail = prev.prev;
+                &mut prev.value
+            })
+        }
     }
 }
 
@@ -734,16 +761,16 @@ fn insert_next_node(&mut self, mut ins_node: Box<Node<A>>) {
         // previously yielded element and self.head.
         //
         // The inserted node will not appear in further iteration.
-        match self.head.resolve() {
+        match unsafe { self.head.resolve_mut() } {
             None => { self.list.push_back_node(ins_node); }
             Some(node) => {
-                let prev_node = match node.prev.resolve() {
+                let prev_node = match unsafe { node.prev.resolve_mut() } {
                     None => return self.list.push_front_node(ins_node),
                     Some(prev) => prev,
                 };
                 let node_own = prev_node.next.take().unwrap();
-                ins_node.next = link_with_prev(node_own, Rawlink::some(&mut *ins_node));
-                prev_node.next = link_with_prev(ins_node, Rawlink::some(prev_node));
+                ins_node.set_next(node_own);
+                prev_node.set_next(ins_node);
                 self.list.length += 1;
             }
         }
@@ -803,7 +830,9 @@ pub fn peek_next(&mut self) -> Option<&mut A> {
         if self.nelem == 0 {
             return None
         }
-        self.head.resolve().map(|head| &mut head.value)
+        unsafe {
+            self.head.resolve_mut().map(|head| &mut head.value)
+        }
     }
 }
 
@@ -875,6 +904,13 @@ fn extend<T: IntoIterator<Item=A>>(&mut self, iter: T) {
     }
 }
 
+#[stable(feature = "extend_ref", since = "1.2.0")]
+impl<'a, T: 'a + Copy> Extend<&'a T> for LinkedList<T> {
+    fn extend<I: IntoIterator<Item=&'a T>>(&mut self, iter: I) {
+        self.extend(iter.into_iter().cloned());
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<A: PartialEq> PartialEq for LinkedList<A> {
     fn eq(&self, other: &LinkedList<A>) -> bool {
@@ -933,7 +969,7 @@ fn hash<H: Hasher>(&self, state: &mut H) {
 #[cfg(test)]
 mod tests {
     use std::clone::Clone;
-    use std::iter::{Iterator, IntoIterator};
+    use std::iter::{Iterator, IntoIterator, Extend};
     use std::option::Option::{Some, None, self};
     use std::__rand::{thread_rng, Rng};
     use std::thread;
@@ -955,7 +991,7 @@ pub fn check_links<T>(list: &LinkedList<T>) {
             Some(ref node) => node_ptr = &**node,
         }
         loop {
-            match (last_ptr, node_ptr.prev.resolve_immut()) {
+            match unsafe { (last_ptr, node_ptr.prev.resolve()) } {
                 (None   , None      ) => {}
                 (None   , _         ) => panic!("prev link for list_head"),
                 (Some(p), Some(pptr)) => {
@@ -1101,6 +1137,26 @@ fn test_26021() {
         assert_eq!(v1.iter().collect::<Vec<_>>().len(), 3);
     }
 
+    #[test]
+    fn test_split_off() {
+        let mut v1 = LinkedList::new();
+        v1.push_front(1u8);
+        v1.push_front(1u8);
+        v1.push_front(1u8);
+        v1.push_front(1u8);
+
+        // test all splits
+        for ix in 0..1 + v1.len() {
+            let mut a = v1.clone();
+            let b = a.split_off(ix);
+            check_links(&a);
+            check_links(&b);
+            a.extend(b);
+            assert_eq!(v1, a);
+        }
+    }
+
+
     #[cfg(test)]
     fn fuzz_test(sz: i32) {
         let mut m: LinkedList<_> = LinkedList::new();
index 95bf6d0a9cd609c3f6abb297dcf04050ceaed8f1..ef8039c565ad24a3d286510f7a61b601e67a1607 100644 (file)
@@ -428,631 +428,436 @@ fn to_owned(&self) -> String {
 #[cfg(not(test))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl str {
-    /// Escapes each char in `s` with `char::escape_default`.
-    #[unstable(feature = "collections",
-               reason = "return type may change to be an iterator")]
-    pub fn escape_default(&self) -> String {
-        self.chars().flat_map(|c| c.escape_default()).collect()
-    }
-
-    /// Escapes each char in `s` with `char::escape_unicode`.
-    #[unstable(feature = "collections",
-               reason = "return type may change to be an iterator")]
-    pub fn escape_unicode(&self) -> String {
-        self.chars().flat_map(|c| c.escape_unicode()).collect()
-    }
-
-    /// Replaces all occurrences of one string with another.
-    ///
-    /// `replace` takes two arguments, a sub-`&str` to find in `self`, and a
-    /// second `&str` to
-    /// replace it with. If the original `&str` isn't found, no change occurs.
+    /// Returns the length of `self` in bytes.
     ///
     /// # Examples
     ///
     /// ```
-    /// let s = "this is old";
-    ///
-    /// assert_eq!(s.replace("old", "new"), "this is new");
-    /// ```
-    ///
-    /// When a `&str` isn't found:
-    ///
-    /// ```
-    /// let s = "this is old";
-    /// assert_eq!(s.replace("cookie monster", "little lamb"), s);
+    /// assert_eq!("foo".len(), 3);
+    /// assert_eq!("ƒoo".len(), 4); // fancy f!
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn replace(&self, from: &str, to: &str) -> String {
-        let mut result = String::new();
-        let mut last_end = 0;
-        for (start, end) in self.match_indices(from) {
-            result.push_str(unsafe { self.slice_unchecked(last_end, start) });
-            result.push_str(to);
-            last_end = end;
-        }
-        result.push_str(unsafe { self.slice_unchecked(last_end, self.len()) });
-        result
-    }
-
-    /// Returns an iterator over the string in Unicode Normalization Form D
-    /// (canonical decomposition).
-    #[allow(deprecated)]
-    #[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
-             since = "1.0.0")]
-    #[inline]
-    #[unstable(feature = "unicode",
-               reason = "this functionality may be replaced with a more generic \
-                         unicode crate on crates.io")]
-    pub fn nfd_chars(&self) -> Decompositions {
-        Decompositions {
-            iter: self[..].chars(),
-            buffer: Vec::new(),
-            sorted: false,
-            kind: Canonical
-        }
-    }
-
-    /// Returns an iterator over the string in Unicode Normalization Form KD
-    /// (compatibility decomposition).
-    #[allow(deprecated)]
-    #[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
-             since = "1.0.0")]
     #[inline]
-    #[unstable(feature = "unicode",
-               reason = "this functionality may be replaced with a more generic \
-                         unicode crate on crates.io")]
-    pub fn nfkd_chars(&self) -> Decompositions {
-        Decompositions {
-            iter: self[..].chars(),
-            buffer: Vec::new(),
-            sorted: false,
-            kind: Compatible
-        }
+    pub fn len(&self) -> usize {
+        core_str::StrExt::len(&self[..])
     }
 
-    /// An Iterator over the string in Unicode Normalization Form C
-    /// (canonical decomposition followed by canonical composition).
-    #[allow(deprecated)]
-    #[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
-             since = "1.0.0")]
+    /// Returns true if this slice has a length of zero bytes.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert!("".is_empty());
+    /// ```
     #[inline]
-    #[unstable(feature = "unicode",
-               reason = "this functionality may be replaced with a more generic \
-                         unicode crate on crates.io")]
-    pub fn nfc_chars(&self) -> Recompositions {
-        Recompositions {
-            iter: self.nfd_chars(),
-            state: Composing,
-            buffer: VecDeque::new(),
-            composee: None,
-            last_ccc: None
-        }
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn is_empty(&self) -> bool {
+        core_str::StrExt::is_empty(&self[..])
     }
 
-    /// An Iterator over the string in Unicode Normalization Form KC
-    /// (compatibility decomposition followed by canonical composition).
-    #[allow(deprecated)]
-    #[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
-             since = "1.0.0")]
-    #[inline]
+    /// Returns a string's displayed width in columns.
+    ///
+    /// Control characters have zero width.
+    ///
+    /// `is_cjk` determines behavior for characters in the Ambiguous category:
+    /// if `is_cjk` is
+    /// `true`, these are 2 columns wide; otherwise, they are 1.
+    /// In CJK locales, `is_cjk` should be
+    /// `true`, else it should be `false`.
+    /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/)
+    /// recommends that these
+    /// characters be treated as 1 column (i.e., `is_cjk = false`) if the
+    /// locale is unknown.
+    #[deprecated(reason = "use the crates.io `unicode-width` library instead",
+                 since = "1.0.0")]
     #[unstable(feature = "unicode",
-               reason = "this functionality may be replaced with a more generic \
-                         unicode crate on crates.io")]
-    pub fn nfkc_chars(&self) -> Recompositions {
-        Recompositions {
-            iter: self.nfkd_chars(),
-            state: Composing,
-            buffer: VecDeque::new(),
-            composee: None,
-            last_ccc: None
-        }
+               reason = "this functionality may only be provided by libunicode")]
+    pub fn width(&self, is_cjk: bool) -> usize {
+        UnicodeStr::width(&self[..], is_cjk)
     }
 
-    /// Returns `true` if `self` contains another `&str`.
+    /// Checks that `index`-th byte lies at the start and/or end of a
+    /// UTF-8 code point sequence.
+    ///
+    /// The start and end of the string (when `index == self.len()`) are
+    /// considered to be
+    /// boundaries.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `index` is greater than `self.len()`.
     ///
     /// # Examples
     ///
     /// ```
-    /// assert!("bananas".contains("nana"));
+    /// # #![feature(str_char)]
+    /// let s = "Löwe 老虎 Léopard";
+    /// assert!(s.is_char_boundary(0));
+    /// // start of `老`
+    /// assert!(s.is_char_boundary(6));
+    /// assert!(s.is_char_boundary(s.len()));
     ///
-    /// assert!(!"bananas".contains("foobar"));
+    /// // second byte of `ö`
+    /// assert!(!s.is_char_boundary(2));
+    ///
+    /// // third byte of `老`
+    /// assert!(!s.is_char_boundary(8));
     /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
-        core_str::StrExt::contains(&self[..], pat)
+    #[unstable(feature = "str_char",
+               reason = "it is unclear whether this method pulls its weight \
+                         with the existence of the char_indices iterator or \
+                         this method may want to be replaced with checked \
+                         slicing")]
+    pub fn is_char_boundary(&self, index: usize) -> bool {
+        core_str::StrExt::is_char_boundary(&self[..], index)
     }
 
-    /// An iterator over the codepoints of `self`.
+    /// Converts `self` to a byte slice.
     ///
     /// # Examples
     ///
     /// ```
-    /// let v: Vec<char> = "abc åäö".chars().collect();
-    ///
-    /// assert_eq!(v, ['a', 'b', 'c', ' ', 'å', 'ä', 'ö']);
+    /// assert_eq!("bors".as_bytes(), b"bors");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn chars(&self) -> Chars {
-        core_str::StrExt::chars(&self[..])
+    #[inline(always)]
+    pub fn as_bytes(&self) -> &[u8] {
+        core_str::StrExt::as_bytes(&self[..])
     }
 
-    /// An iterator over the bytes of `self`.
+    /// Returns an unsafe pointer to the `&str`'s buffer.
+    ///
+    /// The caller must ensure that the string outlives this pointer, and
+    /// that it is not
+    /// reallocated (e.g. by pushing to the string).
     ///
     /// # Examples
     ///
     /// ```
-    /// let v: Vec<u8> = "bors".bytes().collect();
-    ///
-    /// assert_eq!(v, b"bors".to_vec());
+    /// let s = "Hello";
+    /// let p = s.as_ptr();
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn bytes(&self) -> Bytes {
-        core_str::StrExt::bytes(&self[..])
+    #[inline]
+    pub fn as_ptr(&self) -> *const u8 {
+        core_str::StrExt::as_ptr(&self[..])
     }
 
-    /// An iterator over the characters of `self` and their byte offsets.
+    /// Takes a bytewise slice from a string.
+    ///
+    /// Returns the substring from [`begin`..`end`).
+    ///
+    /// # Unsafety
+    ///
+    /// Caller must check both UTF-8 character boundaries and the boundaries
+    /// of the entire slice as
+    /// well.
     ///
     /// # Examples
     ///
     /// ```
-    /// let v: Vec<(usize, char)> = "abc".char_indices().collect();
-    /// let b = vec![(0, 'a'), (1, 'b'), (2, 'c')];
+    /// let s = "Löwe 老虎 Léopard";
     ///
-    /// assert_eq!(v, b);
+    /// unsafe {
+    ///     assert_eq!(s.slice_unchecked(0, 21), "Löwe 老虎 Léopard");
+    /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn char_indices(&self) -> CharIndices {
-        core_str::StrExt::char_indices(&self[..])
+    pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
+        core_str::StrExt::slice_unchecked(&self[..], begin, end)
     }
 
-    /// An iterator over substrings of `self`, separated by characters
-    /// matched by a pattern.
+    /// Returns a slice of the string from the character range [`begin`..`end`).
     ///
-    /// The pattern can be a simple `&str`, `char`, or a closure that
-    /// determines the split.
-    /// Additional libraries might provide more complex patterns like
-    /// regular expressions.
+    /// That is, start at the `begin`-th code point of the string and continue
+    /// to the `end`-th code point. This does not detect or handle edge cases
+    /// such as leaving a combining character as the first code point of the
+    /// string.
     ///
-    /// # Iterator behavior
+    /// Due to the design of UTF-8, this operation is `O(end)`. Use slicing
+    /// syntax if you want to use byte indices rather than codepoint indices.
     ///
-    /// The returned iterator will be double ended if the pattern allows a
-    /// reverse search and forward/reverse search yields the same elements.
-    /// This is true for, eg, `char` but not
-    /// for `&str`.
+    /// # Panics
     ///
-    /// If the pattern allows a reverse search but its results might differ
-    /// from a forward search, `rsplit()` can be used.
+    /// Panics if `begin` > `end` or the either `begin` or `end` are beyond the
+    /// last character of the string.
     ///
     /// # Examples
     ///
-    /// Simple patterns:
-    ///
     /// ```
-    /// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
-    /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
-    ///
-    /// let v: Vec<&str> = "".split('X').collect();
-    /// assert_eq!(v, [""]);
-    ///
-    /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect();
-    /// assert_eq!(v, ["lion", "", "tiger", "leopard"]);
+    /// # #![feature(collections)]
+    /// let s = "Löwe 老虎 Léopard";
     ///
-    /// let v: Vec<&str> = "lion::tiger::leopard".split("::").collect();
-    /// assert_eq!(v, ["lion", "tiger", "leopard"]);
-    /// ```
-    ///
-    /// More complex patterns with closures:
-    ///
-    /// ```
-    /// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect();
-    /// assert_eq!(v, ["abc", "def", "ghi"]);
-    ///
-    /// let v: Vec<&str> = "lionXtigerXleopard".split(char::is_uppercase).collect();
-    /// assert_eq!(v, ["lion", "tiger", "leopard"]);
+    /// assert_eq!(s.slice_chars(0, 4), "Löwe");
+    /// assert_eq!(s.slice_chars(5, 7), "老虎");
     /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
-        core_str::StrExt::split(&self[..], pat)
+    #[unstable(feature = "collections",
+               reason = "may have yet to prove its worth")]
+    pub fn slice_chars(&self, begin: usize, end: usize) -> &str {
+        core_str::StrExt::slice_chars(&self[..], begin, end)
     }
 
-    /// An iterator over substrings of `self`, separated by characters
-    /// matched by a pattern and yielded in reverse order.
-    ///
-    /// The pattern can be a simple `&str`, `char`, or a closure that
-    /// determines the split.
-    /// Additional libraries might provide more complex patterns like
-    /// regular expressions.
+    /// Given a byte position, return the next char and its index.
     ///
-    /// # Iterator behavior
+    /// This can be used to iterate over the Unicode characters of a string.
     ///
-    /// The returned iterator requires that the pattern supports a
-    /// reverse search,
-    /// and it will be double ended if a forward/reverse search yields
-    /// the same elements.
+    /// # Panics
     ///
-    /// For iterating from the front, `split()` can be used.
+    /// If `i` is greater than or equal to the length of the string.
+    /// If `i` is not the index of the beginning of a valid UTF-8 character.
     ///
     /// # Examples
     ///
-    /// Simple patterns:
-    ///
-    /// ```rust
-    /// let v: Vec<&str> = "Mary had a little lamb".rsplit(' ').collect();
-    /// assert_eq!(v, ["lamb", "little", "a", "had", "Mary"]);
-    ///
-    /// let v: Vec<&str> = "".rsplit('X').collect();
-    /// assert_eq!(v, [""]);
-    ///
-    /// let v: Vec<&str> = "lionXXtigerXleopard".rsplit('X').collect();
-    /// assert_eq!(v, ["leopard", "tiger", "", "lion"]);
+    /// This example manually iterates through the characters of a string;
+    /// this should normally be
+    /// done by `.chars()` or `.char_indices()`.
     ///
-    /// let v: Vec<&str> = "lion::tiger::leopard".rsplit("::").collect();
-    /// assert_eq!(v, ["leopard", "tiger", "lion"]);
     /// ```
+    /// # #![feature(str_char, core)]
+    /// use std::str::CharRange;
     ///
-    /// More complex patterns with closures:
+    /// let s = "中华Việt Nam";
+    /// let mut i = 0;
+    /// while i < s.len() {
+    ///     let CharRange {ch, next} = s.char_range_at(i);
+    ///     println!("{}: {}", i, ch);
+    ///     i = next;
+    /// }
+    /// ```
     ///
-    /// ```rust
-    /// let v: Vec<&str> = "abc1def2ghi".rsplit(|c: char| c.is_numeric()).collect();
-    /// assert_eq!(v, ["ghi", "def", "abc"]);
+    /// This outputs:
     ///
-    /// let v: Vec<&str> = "lionXtigerXleopard".rsplit(char::is_uppercase).collect();
-    /// assert_eq!(v, ["leopard", "tiger", "lion"]);
+    /// ```text
+    /// 0: 中
+    /// 3: 华
+    /// 6: V
+    /// 7: i
+    /// 8: ệ
+    /// 11: t
+    /// 12:
+    /// 13: N
+    /// 14: a
+    /// 15: m
     /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
-        where P::Searcher: ReverseSearcher<'a>
-    {
-        core_str::StrExt::rsplit(&self[..], pat)
+    #[unstable(feature = "str_char",
+               reason = "often replaced by char_indices, this method may \
+                         be removed in favor of just char_at() or eventually \
+                         removed altogether")]
+    pub fn char_range_at(&self, start: usize) -> CharRange {
+        core_str::StrExt::char_range_at(&self[..], start)
     }
 
-    /// An iterator over substrings of `self`, separated by characters
-    /// matched by a pattern.
-    ///
-    /// The pattern can be a simple `&str`, `char`, or a closure that
-    /// determines the split.
-    /// Additional libraries might provide more complex patterns
-    /// like regular expressions.
-    ///
-    /// Equivalent to `split`, except that the trailing substring
-    /// is skipped if empty.
+    /// Given a byte position, return the previous `char` and its position.
     ///
-    /// This method can be used for string data that is _terminated_,
-    /// rather than _separated_ by a pattern.
+    /// This function can be used to iterate over a Unicode string in reverse.
     ///
-    /// # Iterator behavior
+    /// Returns 0 for next index if called on start index 0.
     ///
-    /// The returned iterator will be double ended if the pattern allows a
-    /// reverse search
-    /// and forward/reverse search yields the same elements. This is true
-    /// for, eg, `char` but not for `&str`.
+    /// # Panics
     ///
-    /// If the pattern allows a reverse search but its results might differ
-    /// from a forward search, `rsplit_terminator()` can be used.
+    /// If `i` is greater than the length of the string.
+    /// If `i` is not an index following a valid UTF-8 character.
     ///
     /// # Examples
     ///
-    /// Simple patterns:
+    /// This example manually iterates through the characters of a string;
+    /// this should normally be
+    /// done by `.chars().rev()` or `.char_indices()`.
     ///
     /// ```
-    /// let v: Vec<&str> = "A.B.".split_terminator('.').collect();
-    /// assert_eq!(v, ["A", "B"]);
+    /// # #![feature(str_char, core)]
+    /// use std::str::CharRange;
     ///
-    /// let v: Vec<&str> = "A..B..".split_terminator(".").collect();
-    /// assert_eq!(v, ["A", "", "B", ""]);
+    /// let s = "中华Việt Nam";
+    /// let mut i = s.len();
+    /// while i > 0 {
+    ///     let CharRange {ch, next} = s.char_range_at_reverse(i);
+    ///     println!("{}: {}", i, ch);
+    ///     i = next;
+    /// }
     /// ```
     ///
-    /// More complex patterns with closures:
+    /// This outputs:
     ///
+    /// ```text
+    /// 16: m
+    /// 15: a
+    /// 14: N
+    /// 13:
+    /// 12: t
+    /// 11: ệ
+    /// 8: i
+    /// 7: V
+    /// 6: 华
+    /// 3: 中
     /// ```
-    /// let v: Vec<&str> = "abc1def2ghi3".split_terminator(|c: char| c.is_numeric()).collect();
-    /// assert_eq!(v, ["abc", "def", "ghi"]);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> {
-        core_str::StrExt::split_terminator(&self[..], pat)
+    #[unstable(feature = "str_char",
+               reason = "often replaced by char_indices, this method may \
+                         be removed in favor of just char_at_reverse() or \
+                         eventually removed altogether")]
+    pub fn char_range_at_reverse(&self, start: usize) -> CharRange {
+        core_str::StrExt::char_range_at_reverse(&self[..], start)
     }
 
-    /// An iterator over substrings of `self`, separated by characters
-    /// matched by a pattern and yielded in reverse order.
-    ///
-    /// The pattern can be a simple `&str`, `char`, or a closure that
-    /// determines the split.
-    /// Additional libraries might provide more complex patterns like
-    /// regular expressions.
-    ///
-    /// Equivalent to `split`, except that the trailing substring is
-    /// skipped if empty.
-    ///
-    /// This method can be used for string data that is _terminated_,
-    /// rather than _separated_ by a pattern.
-    ///
-    /// # Iterator behavior
+    /// Given a byte position, return the `char` at that position.
     ///
-    /// The returned iterator requires that the pattern supports a
-    /// reverse search, and it will be double ended if a forward/reverse
-    /// search yields the same elements.
+    /// # Panics
     ///
-    /// For iterating from the front, `split_terminator()` can be used.
+    /// If `i` is greater than or equal to the length of the string.
+    /// If `i` is not the index of the beginning of a valid UTF-8 character.
     ///
     /// # Examples
     ///
-    /// Simple patterns:
-    ///
-    /// ```
-    /// let v: Vec<&str> = "A.B.".rsplit_terminator('.').collect();
-    /// assert_eq!(v, ["B", "A"]);
-    ///
-    /// let v: Vec<&str> = "A..B..".rsplit_terminator(".").collect();
-    /// assert_eq!(v, ["", "B", "", "A"]);
     /// ```
-    ///
-    /// More complex patterns with closures:
-    ///
-    /// ```
-    /// let v: Vec<&str> = "abc1def2ghi3".rsplit_terminator(|c: char| c.is_numeric()).collect();
-    /// assert_eq!(v, ["ghi", "def", "abc"]);
+    /// # #![feature(str_char)]
+    /// let s = "abπc";
+    /// assert_eq!(s.char_at(1), 'b');
+    /// assert_eq!(s.char_at(2), 'π');
     /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
-        where P::Searcher: ReverseSearcher<'a>
-    {
-        core_str::StrExt::rsplit_terminator(&self[..], pat)
+    #[unstable(feature = "str_char",
+               reason = "frequently replaced by the chars() iterator, this \
+                         method may be removed or possibly renamed in the \
+                         future; it is normally replaced by chars/char_indices \
+                         iterators or by getting the first char from a \
+                         subslice")]
+    pub fn char_at(&self, i: usize) -> char {
+        core_str::StrExt::char_at(&self[..], i)
     }
 
-    /// An iterator over substrings of `self`, separated by a pattern,
-    /// restricted to returning
-    /// at most `count` items.
-    ///
-    /// The last element returned, if any, will contain the remainder of the
-    /// string.
-    /// The pattern can be a simple `&str`, `char`, or a closure that
-    /// determines the split.
-    /// Additional libraries might provide more complex patterns like
-    /// regular expressions.
-    ///
-    /// # Iterator behavior
+    /// Given a byte position, return the `char` at that position, counting
+    /// from the end.
     ///
-    /// The returned iterator will not be double ended, because it is
-    /// not efficient to support.
+    /// # Panics
     ///
-    /// If the pattern allows a reverse search, `rsplitn()` can be used.
+    /// If `i` is greater than the length of the string.
+    /// If `i` is not an index following a valid UTF-8 character.
     ///
     /// # Examples
     ///
-    /// Simple patterns:
-    ///
     /// ```
-    /// let v: Vec<&str> = "Mary had a little lambda".splitn(3, ' ').collect();
-    /// assert_eq!(v, ["Mary", "had", "a little lambda"]);
-    ///
-    /// let v: Vec<&str> = "lionXXtigerXleopard".splitn(3, "X").collect();
-    /// assert_eq!(v, ["lion", "", "tigerXleopard"]);
-    ///
-    /// let v: Vec<&str> = "abcXdef".splitn(1, 'X').collect();
-    /// assert_eq!(v, ["abcXdef"]);
-    ///
-    /// let v: Vec<&str> = "".splitn(1, 'X').collect();
-    /// assert_eq!(v, [""]);
-    /// ```
-    ///
-    /// More complex patterns with closures:
-    ///
-    /// ```
-    /// let v: Vec<&str> = "abc1def2ghi".splitn(2, |c: char| c.is_numeric()).collect();
-    /// assert_eq!(v, ["abc", "def2ghi"]);
+    /// # #![feature(str_char)]
+    /// let s = "abπc";
+    /// assert_eq!(s.char_at_reverse(1), 'a');
+    /// assert_eq!(s.char_at_reverse(2), 'b');
     /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P> {
-        core_str::StrExt::splitn(&self[..], count, pat)
+    #[unstable(feature = "str_char",
+               reason = "see char_at for more details, but reverse semantics \
+                         are also somewhat unclear, especially with which \
+                         cases generate panics")]
+    pub fn char_at_reverse(&self, i: usize) -> char {
+        core_str::StrExt::char_at_reverse(&self[..], i)
     }
 
-    /// An iterator over substrings of `self`, separated by a pattern,
-    /// starting from the end of the string, restricted to returning
-    /// at most `count` items.
-    ///
-    /// The last element returned, if any, will contain the remainder of the
-    /// string.
-    ///
-    /// The pattern can be a simple `&str`, `char`, or a closure that
-    /// determines the split.
-    /// Additional libraries might provide more complex patterns like
-    /// regular expressions.
-    ///
-    /// # Iterator behavior
+    /// Retrieves the first character from a `&str` and returns it.
     ///
-    /// The returned iterator will not be double ended, because it is not
-    /// efficient to support.
+    /// This does not allocate a new string; instead, it returns a slice that
+    /// points one character
+    /// beyond the character that was shifted.
     ///
-    /// `splitn()` can be used for splitting from the front.
+    /// If the slice does not contain any characters, None is returned instead.
     ///
     /// # Examples
     ///
-    /// Simple patterns:
-    ///
     /// ```
-    /// let v: Vec<&str> = "Mary had a little lamb".rsplitn(3, ' ').collect();
-    /// assert_eq!(v, ["lamb", "little", "Mary had a"]);
+    /// # #![feature(str_char)]
+    /// let s = "Löwe 老虎 Léopard";
+    /// let (c, s1) = s.slice_shift_char().unwrap();
     ///
-    /// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(3, 'X').collect();
-    /// assert_eq!(v, ["leopard", "tiger", "lionX"]);
+    /// assert_eq!(c, 'L');
+    /// assert_eq!(s1, "öwe 老虎 Léopard");
     ///
-    /// let v: Vec<&str> = "lion::tiger::leopard".rsplitn(2, "::").collect();
-    /// assert_eq!(v, ["leopard", "lion::tiger"]);
+    /// let (c, s2) = s1.slice_shift_char().unwrap();
+    ///
+    /// assert_eq!(c, 'ö');
+    /// assert_eq!(s2, "we 老虎 Léopard");
     /// ```
+    #[unstable(feature = "str_char",
+               reason = "awaiting conventions about shifting and slices and \
+                         may not be warranted with the existence of the chars \
+                         and/or char_indices iterators")]
+    pub fn slice_shift_char(&self) -> Option<(char, &str)> {
+        core_str::StrExt::slice_shift_char(&self[..])
+    }
+
+    /// An iterator over the codepoints of `self`.
     ///
-    /// More complex patterns with closures:
+    /// # Examples
     ///
     /// ```
-    /// let v: Vec<&str> = "abc1def2ghi".rsplitn(2, |c: char| c.is_numeric()).collect();
-    /// assert_eq!(v, ["ghi", "abc1def"]);
+    /// let v: Vec<char> = "abc åäö".chars().collect();
+    ///
+    /// assert_eq!(v, ['a', 'b', 'c', ' ', 'å', 'ä', 'ö']);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
-        where P::Searcher: ReverseSearcher<'a>
-    {
-        core_str::StrExt::rsplitn(&self[..], count, pat)
+    pub fn chars(&self) -> Chars {
+        core_str::StrExt::chars(&self[..])
     }
 
-    /// An iterator over the matches of a pattern within `self`.
-    ///
-    /// The pattern can be a simple `&str`, `char`, or a closure that
-    /// determines the split.
-    /// Additional libraries might provide more complex patterns like
-    /// regular expressions.
-    ///
-    /// # Iterator behavior
-    ///
-    /// The returned iterator will be double ended if the pattern allows
-    /// a reverse search
-    /// and forward/reverse search yields the same elements. This is true
-    /// for, eg, `char` but not
-    /// for `&str`.
-    ///
-    /// If the pattern allows a reverse search but its results might differ
-    /// from a forward search, `rmatches()` can be used.
+    /// An iterator over the characters of `self` and their byte offsets.
     ///
     /// # Examples
     ///
     /// ```
-    /// # #![feature(collections)]
-    /// let v: Vec<&str> = "abcXXXabcYYYabc".matches("abc").collect();
-    /// assert_eq!(v, ["abc", "abc", "abc"]);
+    /// let v: Vec<(usize, char)> = "abc".char_indices().collect();
+    /// let b = vec![(0, 'a'), (1, 'b'), (2, 'c')];
     ///
-    /// let v: Vec<&str> = "1abc2abc3".matches(|c: char| c.is_numeric()).collect();
-    /// assert_eq!(v, ["1", "2", "3"]);
+    /// assert_eq!(v, b);
     /// ```
-    #[unstable(feature = "collections",
-               reason = "method got recently added")]
-    pub fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> {
-        core_str::StrExt::matches(&self[..], pat)
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn char_indices(&self) -> CharIndices {
+        core_str::StrExt::char_indices(&self[..])
     }
 
-    /// An iterator over the matches of a pattern within `self`, yielded in
-    /// reverse order.
-    ///
-    /// The pattern can be a simple `&str`, `char`, or a closure that
-    /// determines the split.
-    /// Additional libraries might provide more complex patterns like
-    /// regular expressions.
-    ///
-    /// # Iterator behavior
-    ///
-    /// The returned iterator requires that the pattern supports a
-    /// reverse search,
-    /// and it will be double ended if a forward/reverse search yields
-    /// the same elements.
-    ///
-    /// For iterating from the front, `matches()` can be used.
+    /// An iterator over the bytes of `self`.
     ///
     /// # Examples
     ///
     /// ```
-    /// # #![feature(collections)]
-    /// let v: Vec<&str> = "abcXXXabcYYYabc".rmatches("abc").collect();
-    /// assert_eq!(v, ["abc", "abc", "abc"]);
+    /// let v: Vec<u8> = "bors".bytes().collect();
     ///
-    /// let v: Vec<&str> = "1abc2abc3".rmatches(|c: char| c.is_numeric()).collect();
-    /// assert_eq!(v, ["3", "2", "1"]);
+    /// assert_eq!(v, b"bors".to_vec());
     /// ```
-    #[unstable(feature = "collections",
-               reason = "method got recently added")]
-    pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
-        where P::Searcher: ReverseSearcher<'a>
-    {
-        core_str::StrExt::rmatches(&self[..], pat)
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn bytes(&self) -> Bytes {
+        core_str::StrExt::bytes(&self[..])
     }
 
-    /// An iterator over the start and end indices of the disjoint matches
-    /// of a pattern within `self`.
-    ///
-    /// For matches of `pat` within `self` that overlap, only the indices
-    /// corresponding to the first
-    /// match are returned.
-    ///
-    /// The pattern can be a simple `&str`, `char`, or a closure that
-    /// determines
-    /// the split.
-    /// Additional libraries might provide more complex patterns like
-    /// regular expressions.
-    ///
-    /// # Iterator behavior
-    ///
-    /// The returned iterator will be double ended if the pattern allows a
-    /// reverse search
-    /// and forward/reverse search yields the same elements. This is true for,
-    /// eg, `char` but not
-    /// for `&str`.
-    ///
-    /// If the pattern allows a reverse search but its results might differ
-    /// from a forward search, `rmatch_indices()` can be used.
+    /// An iterator over the non-empty substrings of `self` which contain no whitespace,
+    /// and which are separated by any amount of whitespace.
     ///
     /// # Examples
     ///
     /// ```
-    /// # #![feature(collections)]
-    /// let v: Vec<(usize, usize)> = "abcXXXabcYYYabc".match_indices("abc").collect();
-    /// assert_eq!(v, [(0, 3), (6, 9), (12, 15)]);
-    ///
-    /// let v: Vec<(usize, usize)> = "1abcabc2".match_indices("abc").collect();
-    /// assert_eq!(v, [(1, 4), (4, 7)]);
+    /// let some_words = " Mary   had\ta little  \n\t lamb";
+    /// let v: Vec<&str> = some_words.split_whitespace().collect();
     ///
-    /// let v: Vec<(usize, usize)> = "ababa".match_indices("aba").collect();
-    /// assert_eq!(v, [(0, 3)]); // only the first `aba`
+    /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
     /// ```
-    #[unstable(feature = "collections",
-               reason = "might have its iterator type changed")]
-    // NB: Right now MatchIndices yields `(usize, usize)`, but it would
-    // be more consistent with `matches` and `char_indices` to return `(usize, &str)`
-    pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
-        core_str::StrExt::match_indices(&self[..], pat)
+    #[stable(feature = "split_whitespace", since = "1.1.0")]
+    pub fn split_whitespace(&self) -> SplitWhitespace {
+        UnicodeStr::split_whitespace(&self[..])
     }
 
-    /// An iterator over the start and end indices of the disjoint matches of
-    /// a pattern within
-    /// `self`, yielded in reverse order.
-    ///
-    /// For matches of `pat` within `self` that overlap, only the indices
-    /// corresponding to the last
-    /// match are returned.
-    ///
-    /// The pattern can be a simple `&str`, `char`, or a closure that
-    /// determines
-    /// the split.
-    /// Additional libraries might provide more complex patterns like
-    /// regular expressions.
-    ///
-    /// # Iterator behavior
-    ///
-    /// The returned iterator requires that the pattern supports a
-    /// reverse search,
-    /// and it will be double ended if a forward/reverse search yields
-    /// the same elements.
-    ///
-    /// For iterating from the front, `match_indices()` can be used.
+    /// An iterator over the non-empty substrings of `self` which contain no whitespace,
+    /// and which are separated by any amount of whitespace.
     ///
     /// # Examples
     ///
     /// ```
-    /// # #![feature(collections)]
-    /// let v: Vec<(usize, usize)> = "abcXXXabcYYYabc".rmatch_indices("abc").collect();
-    /// assert_eq!(v, [(12, 15), (6, 9), (0, 3)]);
-    ///
-    /// let v: Vec<(usize, usize)> = "1abcabc2".rmatch_indices("abc").collect();
-    /// assert_eq!(v, [(4, 7), (1, 4)]);
+    /// # #![feature(str_words)]
+    /// # #![allow(deprecated)]
+    /// let some_words = " Mary   had\ta little  \n\t lamb";
+    /// let v: Vec<&str> = some_words.words().collect();
     ///
-    /// let v: Vec<(usize, usize)> = "ababa".rmatch_indices("aba").collect();
-    /// assert_eq!(v, [(2, 5)]); // only the last `aba`
+    /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
     /// ```
-    #[unstable(feature = "collections",
-               reason = "might have its iterator type changed")]
-    // NB: Right now RMatchIndices yields `(usize, usize)`, but it would
-    // be more consistent with `rmatches` and `char_indices` to return `(usize, &str)`
-    pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
-        where P::Searcher: ReverseSearcher<'a>
-    {
-        core_str::StrExt::rmatch_indices(&self[..], pat)
+    #[deprecated(reason = "words() will be removed. Use split_whitespace() instead",
+                 since = "1.1.0")]
+    #[unstable(feature = "str_words",
+               reason = "the precise algorithm to use is unclear")]
+    #[allow(deprecated)]
+    pub fn words(&self) -> Words {
+        UnicodeStr::words(&self[..])
     }
 
     /// An iterator over the lines of a string, separated by `\n`.
@@ -1107,58 +912,153 @@ pub fn lines(&self) -> Lines {
     pub fn lines_any(&self) -> LinesAny {
         core_str::StrExt::lines_any(&self[..])
     }
-    /// Returns a slice of the string from the character range [`begin`..`end`).
-    ///
-    /// That is, start at the `begin`-th code point of the string and continue
-    /// to the `end`-th code point. This does not detect or handle edge cases
-    /// such as leaving a combining character as the first code point of the
-    /// string.
-    ///
-    /// Due to the design of UTF-8, this operation is `O(end)`. Use slicing
-    /// syntax if you want to use byte indices rather than codepoint indices.
+
+    /// Returns an iterator over the string in Unicode Normalization Form D
+    /// (canonical decomposition).
+    #[allow(deprecated)]
+    #[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
+             since = "1.0.0")]
+    #[inline]
+    #[unstable(feature = "unicode",
+               reason = "this functionality may be replaced with a more generic \
+                         unicode crate on crates.io")]
+    pub fn nfd_chars(&self) -> Decompositions {
+        Decompositions {
+            iter: self[..].chars(),
+            buffer: Vec::new(),
+            sorted: false,
+            kind: Canonical
+        }
+    }
+
+    /// Returns an iterator over the string in Unicode Normalization Form KD
+    /// (compatibility decomposition).
+    #[allow(deprecated)]
+    #[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
+             since = "1.0.0")]
+    #[inline]
+    #[unstable(feature = "unicode",
+               reason = "this functionality may be replaced with a more generic \
+                         unicode crate on crates.io")]
+    pub fn nfkd_chars(&self) -> Decompositions {
+        Decompositions {
+            iter: self[..].chars(),
+            buffer: Vec::new(),
+            sorted: false,
+            kind: Compatible
+        }
+    }
+
+    /// An Iterator over the string in Unicode Normalization Form C
+    /// (canonical decomposition followed by canonical composition).
+    #[allow(deprecated)]
+    #[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
+             since = "1.0.0")]
+    #[inline]
+    #[unstable(feature = "unicode",
+               reason = "this functionality may be replaced with a more generic \
+                         unicode crate on crates.io")]
+    pub fn nfc_chars(&self) -> Recompositions {
+        Recompositions {
+            iter: self.nfd_chars(),
+            state: Composing,
+            buffer: VecDeque::new(),
+            composee: None,
+            last_ccc: None
+        }
+    }
+
+    /// An Iterator over the string in Unicode Normalization Form KC
+    /// (compatibility decomposition followed by canonical composition).
+    #[allow(deprecated)]
+    #[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
+             since = "1.0.0")]
+    #[inline]
+    #[unstable(feature = "unicode",
+               reason = "this functionality may be replaced with a more generic \
+                         unicode crate on crates.io")]
+    pub fn nfkc_chars(&self) -> Recompositions {
+        Recompositions {
+            iter: self.nfkd_chars(),
+            state: Composing,
+            buffer: VecDeque::new(),
+            composee: None,
+            last_ccc: None
+        }
+    }
+
+    /// Returns an iterator over the [grapheme clusters][graphemes] of `self`.
     ///
-    /// # Panics
+    /// [graphemes]: http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries
     ///
-    /// Panics if `begin` > `end` or the either `begin` or `end` are beyond the
-    /// last character of the string.
+    /// If `is_extended` is true, the iterator is over the
+    /// *extended grapheme clusters*;
+    /// otherwise, the iterator is over the *legacy grapheme clusters*.
+    /// [UAX#29](http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries)
+    /// recommends extended grapheme cluster boundaries for general processing.
     ///
     /// # Examples
     ///
     /// ```
-    /// # #![feature(collections)]
-    /// let s = "Löwe 老虎 Léopard";
+    /// # #![feature(unicode, core)]
+    /// let gr1 = "a\u{310}e\u{301}o\u{308}\u{332}".graphemes(true).collect::<Vec<&str>>();
+    /// let b: &[_] = &["a\u{310}", "e\u{301}", "o\u{308}\u{332}"];
     ///
-    /// assert_eq!(s.slice_chars(0, 4), "Löwe");
-    /// assert_eq!(s.slice_chars(5, 7), "老虎");
+    /// assert_eq!(&gr1[..], b);
+    ///
+    /// let gr2 = "a\r\nb🇷🇺🇸🇹".graphemes(true).collect::<Vec<&str>>();
+    /// let b: &[_] = &["a", "\r\n", "b", "🇷🇺🇸🇹"];
+    ///
+    /// assert_eq!(&gr2[..], b);
     /// ```
-    #[unstable(feature = "collections",
-               reason = "may have yet to prove its worth")]
-    pub fn slice_chars(&self, begin: usize, end: usize) -> &str {
-        core_str::StrExt::slice_chars(&self[..], begin, end)
+    #[deprecated(reason = "use the crates.io `unicode-segmentation` library instead",
+             since = "1.0.0")]
+    #[unstable(feature = "unicode",
+               reason = "this functionality may only be provided by libunicode")]
+    pub fn graphemes(&self, is_extended: bool) -> Graphemes {
+        UnicodeStr::graphemes(&self[..], is_extended)
     }
 
-    /// Takes a bytewise slice from a string.
+    /// Returns an iterator over the grapheme clusters of `self` and their
+    /// byte offsets. See
+    /// `graphemes()` for more information.
     ///
-    /// Returns the substring from [`begin`..`end`).
+    /// # Examples
     ///
-    /// # Unsafety
+    /// ```
+    /// # #![feature(unicode, core)]
+    /// let gr_inds = "a̐éö̲\r\n".grapheme_indices(true).collect::<Vec<(usize, &str)>>();
+    /// let b: &[_] = &[(0, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
     ///
-    /// Caller must check both UTF-8 character boundaries and the boundaries
-    /// of the entire slice as
-    /// well.
+    /// assert_eq!(&gr_inds[..], b);
+    /// ```
+    #[deprecated(reason = "use the crates.io `unicode-segmentation` library instead",
+             since = "1.0.0")]
+    #[unstable(feature = "unicode",
+               reason = "this functionality may only be provided by libunicode")]
+    pub fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices {
+        UnicodeStr::grapheme_indices(&self[..], is_extended)
+    }
+
+    /// Returns an iterator of `u16` over the string encoded as UTF-16.
+    #[unstable(feature = "collections",
+               reason = "this functionality may only be provided by libunicode")]
+    pub fn utf16_units(&self) -> Utf16Units {
+        Utf16Units { encoder: Utf16Encoder::new(self[..].chars()) }
+    }
+
+    /// Returns `true` if `self` contains another `&str`.
     ///
     /// # Examples
     ///
     /// ```
-    /// let s = "Löwe 老虎 Léopard";
+    /// assert!("bananas".contains("nana"));
     ///
-    /// unsafe {
-    ///     assert_eq!(s.slice_unchecked(0, 21), "Löwe 老虎 Léopard");
-    /// }
+    /// assert!(!"bananas".contains("foobar"));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
-        core_str::StrExt::slice_unchecked(&self[..], begin, end)
+    pub fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
+        core_str::StrExt::contains(&self[..], pat)
     }
 
     /// Returns `true` if the given `&str` is a prefix of the string.
@@ -1187,408 +1087,524 @@ pub fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
         core_str::StrExt::ends_with(&self[..], pat)
     }
 
-    /// Returns a string with all pre- and suffixes that match a pattern
-    /// repeatedly removed.
+    /// Returns the byte index of the first character of `self` that matches
+    /// the pattern, if it
+    /// exists.
     ///
-    /// The pattern can be a simple `char`, or a closure that determines
-    /// the split.
+    /// Returns `None` if it doesn't exist.
+    ///
+    /// The pattern can be a simple `&str`, `char`, or a closure that
+    /// determines the
+    /// split.
     ///
     /// # Examples
     ///
     /// Simple patterns:
     ///
     /// ```
-    /// assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
+    /// let s = "Löwe 老虎 Léopard";
+    ///
+    /// assert_eq!(s.find('L'), Some(0));
+    /// assert_eq!(s.find('é'), Some(14));
+    /// assert_eq!(s.find("Léopard"), Some(13));
+    ///
+    /// ```
+    ///
+    /// More complex patterns with closures:
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
+    ///
+    /// assert_eq!(s.find(char::is_whitespace), Some(5));
+    /// assert_eq!(s.find(char::is_lowercase), Some(1));
+    /// ```
+    ///
+    /// Not finding the pattern:
     ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
     /// let x: &[_] = &['1', '2'];
-    /// assert_eq!("12foo1bar12".trim_matches(x), "foo1bar");
+    ///
+    /// assert_eq!(s.find(x), None);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
+        core_str::StrExt::find(&self[..], pat)
+    }
+
+    /// Returns the byte index of the last character of `self` that
+    /// matches the pattern, if it
+    /// exists.
+    ///
+    /// Returns `None` if it doesn't exist.
+    ///
+    /// The pattern can be a simple `&str`, `char`,
+    /// or a closure that determines the split.
+    ///
+    /// # Examples
+    ///
+    /// Simple patterns:
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
+    ///
+    /// assert_eq!(s.rfind('L'), Some(13));
+    /// assert_eq!(s.rfind('é'), Some(14));
     /// ```
     ///
     /// More complex patterns with closures:
     ///
     /// ```
-    /// assert_eq!("123foo1bar123".trim_matches(|c: char| c.is_numeric()), "foo1bar");
+    /// let s = "Löwe 老虎 Léopard";
+    ///
+    /// assert_eq!(s.rfind(char::is_whitespace), Some(12));
+    /// assert_eq!(s.rfind(char::is_lowercase), Some(20));
+    /// ```
+    ///
+    /// Not finding the pattern:
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
+    /// let x: &[_] = &['1', '2'];
+    ///
+    /// assert_eq!(s.rfind(x), None);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
-        where P::Searcher: DoubleEndedSearcher<'a>
+    pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
+        where P::Searcher: ReverseSearcher<'a>
     {
-        core_str::StrExt::trim_matches(&self[..], pat)
+        core_str::StrExt::rfind(&self[..], pat)
     }
 
-    /// Returns a string with all prefixes that match a pattern
-    /// repeatedly removed.
+    /// An iterator over substrings of `self`, separated by characters
+    /// matched by a pattern.
     ///
     /// The pattern can be a simple `&str`, `char`, or a closure that
     /// determines the split.
+    /// Additional libraries might provide more complex patterns like
+    /// regular expressions.
+    ///
+    /// # Iterator behavior
+    ///
+    /// The returned iterator will be double ended if the pattern allows a
+    /// reverse search and forward/reverse search yields the same elements.
+    /// This is true for, eg, `char` but not
+    /// for `&str`.
+    ///
+    /// If the pattern allows a reverse search but its results might differ
+    /// from a forward search, `rsplit()` can be used.
     ///
     /// # Examples
     ///
     /// Simple patterns:
     ///
     /// ```
-    /// assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
+    /// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
+    /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
     ///
-    /// let x: &[_] = &['1', '2'];
-    /// assert_eq!("12foo1bar12".trim_left_matches(x), "foo1bar12");
+    /// let v: Vec<&str> = "".split('X').collect();
+    /// assert_eq!(v, [""]);
+    ///
+    /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect();
+    /// assert_eq!(v, ["lion", "", "tiger", "leopard"]);
+    ///
+    /// let v: Vec<&str> = "lion::tiger::leopard".split("::").collect();
+    /// assert_eq!(v, ["lion", "tiger", "leopard"]);
+    ///
+    /// let v: Vec<&str> = "abc1def2ghi".split(char::is_numeric).collect();
+    /// assert_eq!(v, ["abc", "def", "ghi"]);
+    ///
+    /// let v: Vec<&str> = "lionXtigerXleopard".split(char::is_uppercase).collect();
+    /// assert_eq!(v, ["lion", "tiger", "leopard"]);
     /// ```
     ///
-    /// More complex patterns with closures:
+    /// A more complex pattern, using a closure:
     ///
     /// ```
-    /// assert_eq!("123foo1bar123".trim_left_matches(|c: char| c.is_numeric()), "foo1bar123");
+    /// let v: Vec<&str> = "abc1defXghi".split(|c| c == '1' || c == 'X').collect();
+    /// assert_eq!(v, ["abc", "def", "ghi"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
-        core_str::StrExt::trim_left_matches(&self[..], pat)
+    pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
+        core_str::StrExt::split(&self[..], pat)
     }
 
-    /// Returns a string with all suffixes that match a pattern
-    /// repeatedly removed.
+    /// An iterator over substrings of `self`, separated by characters
+    /// matched by a pattern and yielded in reverse order.
     ///
     /// The pattern can be a simple `&str`, `char`, or a closure that
     /// determines the split.
+    /// Additional libraries might provide more complex patterns like
+    /// regular expressions.
+    ///
+    /// # Iterator behavior
+    ///
+    /// The returned iterator requires that the pattern supports a
+    /// reverse search,
+    /// and it will be double ended if a forward/reverse search yields
+    /// the same elements.
+    ///
+    /// For iterating from the front, `split()` can be used.
     ///
     /// # Examples
     ///
     /// Simple patterns:
     ///
-    /// ```
-    /// assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
-    /// let x: &[_] = &['1', '2'];
-    /// assert_eq!("12foo1bar12".trim_right_matches(x), "12foo1bar");
+    /// ```rust
+    /// let v: Vec<&str> = "Mary had a little lamb".rsplit(' ').collect();
+    /// assert_eq!(v, ["lamb", "little", "a", "had", "Mary"]);
+    ///
+    /// let v: Vec<&str> = "".rsplit('X').collect();
+    /// assert_eq!(v, [""]);
+    ///
+    /// let v: Vec<&str> = "lionXXtigerXleopard".rsplit('X').collect();
+    /// assert_eq!(v, ["leopard", "tiger", "", "lion"]);
+    ///
+    /// let v: Vec<&str> = "lion::tiger::leopard".rsplit("::").collect();
+    /// assert_eq!(v, ["leopard", "tiger", "lion"]);
     /// ```
     ///
-    /// More complex patterns with closures:
+    /// A more complex pattern, using a closure:
     ///
     /// ```
-    /// assert_eq!("123foo1bar123".trim_right_matches(|c: char| c.is_numeric()), "123foo1bar");
+    /// let v: Vec<&str> = "abc1defXghi".rsplit(|c| c == '1' || c == 'X').collect();
+    /// assert_eq!(v, ["ghi", "def", "abc"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
+    pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
         where P::Searcher: ReverseSearcher<'a>
     {
-        core_str::StrExt::trim_right_matches(&self[..], pat)
+        core_str::StrExt::rsplit(&self[..], pat)
     }
 
-    /// Checks that `index`-th byte lies at the start and/or end of a
-    /// UTF-8 code point sequence.
-    ///
-    /// The start and end of the string (when `index == self.len()`) are
-    /// considered to be
-    /// boundaries.
-    ///
-    /// # Panics
-    ///
-    /// Panics if `index` is greater than `self.len()`.
-    ///
-    /// # Examples
+    /// An iterator over substrings of `self`, separated by characters
+    /// matched by a pattern.
     ///
-    /// ```
-    /// # #![feature(str_char)]
-    /// let s = "Löwe 老虎 Léopard";
-    /// assert!(s.is_char_boundary(0));
-    /// // start of `老`
-    /// assert!(s.is_char_boundary(6));
-    /// assert!(s.is_char_boundary(s.len()));
+    /// The pattern can be a simple `&str`, `char`, or a closure that
+    /// determines the split.
+    /// Additional libraries might provide more complex patterns
+    /// like regular expressions.
     ///
-    /// // second byte of `ö`
-    /// assert!(!s.is_char_boundary(2));
+    /// Equivalent to `split`, except that the trailing substring
+    /// is skipped if empty.
     ///
-    /// // third byte of `老`
-    /// assert!(!s.is_char_boundary(8));
-    /// ```
-    #[unstable(feature = "str_char",
-               reason = "it is unclear whether this method pulls its weight \
-                         with the existence of the char_indices iterator or \
-                         this method may want to be replaced with checked \
-                         slicing")]
-    pub fn is_char_boundary(&self, index: usize) -> bool {
-        core_str::StrExt::is_char_boundary(&self[..], index)
-    }
-
-    /// Given a byte position, return the next char and its index.
+    /// This method can be used for string data that is _terminated_,
+    /// rather than _separated_ by a pattern.
     ///
-    /// This can be used to iterate over the Unicode characters of a string.
+    /// # Iterator behavior
     ///
-    /// # Panics
+    /// The returned iterator will be double ended if the pattern allows a
+    /// reverse search
+    /// and forward/reverse search yields the same elements. This is true
+    /// for, eg, `char` but not for `&str`.
     ///
-    /// If `i` is greater than or equal to the length of the string.
-    /// If `i` is not the index of the beginning of a valid UTF-8 character.
+    /// If the pattern allows a reverse search but its results might differ
+    /// from a forward search, `rsplit_terminator()` can be used.
     ///
     /// # Examples
     ///
-    /// This example manually iterates through the characters of a string;
-    /// this should normally be
-    /// done by `.chars()` or `.char_indices()`.
-    ///
-    /// ```
-    /// # #![feature(str_char, core)]
-    /// use std::str::CharRange;
-    ///
-    /// let s = "中华Việt Nam";
-    /// let mut i = 0;
-    /// while i < s.len() {
-    ///     let CharRange {ch, next} = s.char_range_at(i);
-    ///     println!("{}: {}", i, ch);
-    ///     i = next;
-    /// }
     /// ```
+    /// let v: Vec<&str> = "A.B.".split_terminator('.').collect();
+    /// assert_eq!(v, ["A", "B"]);
     ///
-    /// This outputs:
-    ///
-    /// ```text
-    /// 0: 中
-    /// 3: 华
-    /// 6: V
-    /// 7: i
-    /// 8: ệ
-    /// 11: t
-    /// 12:
-    /// 13: N
-    /// 14: a
-    /// 15: m
+    /// let v: Vec<&str> = "A..B..".split_terminator(".").collect();
+    /// assert_eq!(v, ["A", "", "B", ""]);
     /// ```
-    #[unstable(feature = "str_char",
-               reason = "often replaced by char_indices, this method may \
-                         be removed in favor of just char_at() or eventually \
-                         removed altogether")]
-    pub fn char_range_at(&self, start: usize) -> CharRange {
-        core_str::StrExt::char_range_at(&self[..], start)
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> {
+        core_str::StrExt::split_terminator(&self[..], pat)
     }
 
-    /// Given a byte position, return the previous `char` and its position.
+    /// An iterator over substrings of `self`, separated by characters
+    /// matched by a pattern and yielded in reverse order.
     ///
-    /// This function can be used to iterate over a Unicode string in reverse.
+    /// The pattern can be a simple `&str`, `char`, or a closure that
+    /// determines the split.
+    /// Additional libraries might provide more complex patterns like
+    /// regular expressions.
     ///
-    /// Returns 0 for next index if called on start index 0.
+    /// Equivalent to `split`, except that the trailing substring is
+    /// skipped if empty.
     ///
-    /// # Panics
+    /// This method can be used for string data that is _terminated_,
+    /// rather than _separated_ by a pattern.
     ///
-    /// If `i` is greater than the length of the string.
-    /// If `i` is not an index following a valid UTF-8 character.
+    /// # Iterator behavior
     ///
-    /// # Examples
+    /// The returned iterator requires that the pattern supports a
+    /// reverse search, and it will be double ended if a forward/reverse
+    /// search yields the same elements.
     ///
-    /// This example manually iterates through the characters of a string;
-    /// this should normally be
-    /// done by `.chars().rev()` or `.char_indices()`.
+    /// For iterating from the front, `split_terminator()` can be used.
     ///
-    /// ```
-    /// # #![feature(str_char, core)]
-    /// use std::str::CharRange;
+    /// # Examples
     ///
-    /// let s = "中华Việt Nam";
-    /// let mut i = s.len();
-    /// while i > 0 {
-    ///     let CharRange {ch, next} = s.char_range_at_reverse(i);
-    ///     println!("{}: {}", i, ch);
-    ///     i = next;
-    /// }
     /// ```
+    /// let v: Vec<&str> = "A.B.".rsplit_terminator('.').collect();
+    /// assert_eq!(v, ["B", "A"]);
     ///
-    /// This outputs:
-    ///
-    /// ```text
-    /// 16: m
-    /// 15: a
-    /// 14: N
-    /// 13:
-    /// 12: t
-    /// 11: ệ
-    /// 8: i
-    /// 7: V
-    /// 6: 华
-    /// 3: 中
+    /// let v: Vec<&str> = "A..B..".rsplit_terminator(".").collect();
+    /// assert_eq!(v, ["", "B", "", "A"]);
     /// ```
-    #[unstable(feature = "str_char",
-               reason = "often replaced by char_indices, this method may \
-                         be removed in favor of just char_at_reverse() or \
-                         eventually removed altogether")]
-    pub fn char_range_at_reverse(&self, start: usize) -> CharRange {
-        core_str::StrExt::char_range_at_reverse(&self[..], start)
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
+        where P::Searcher: ReverseSearcher<'a>
+    {
+        core_str::StrExt::rsplit_terminator(&self[..], pat)
     }
 
-    /// Given a byte position, return the `char` at that position.
-    ///
-    /// # Panics
-    ///
-    /// If `i` is greater than or equal to the length of the string.
-    /// If `i` is not the index of the beginning of a valid UTF-8 character.
-    ///
-    /// # Examples
+    /// An iterator over substrings of `self`, separated by a pattern,
+    /// restricted to returning
+    /// at most `count` items.
     ///
-    /// ```
-    /// # #![feature(str_char)]
-    /// let s = "abπc";
-    /// assert_eq!(s.char_at(1), 'b');
-    /// assert_eq!(s.char_at(2), 'π');
-    /// ```
-    #[unstable(feature = "str_char",
-               reason = "frequently replaced by the chars() iterator, this \
-                         method may be removed or possibly renamed in the \
-                         future; it is normally replaced by chars/char_indices \
-                         iterators or by getting the first char from a \
-                         subslice")]
-    pub fn char_at(&self, i: usize) -> char {
-        core_str::StrExt::char_at(&self[..], i)
-    }
-
-    /// Given a byte position, return the `char` at that position, counting
-    /// from the end.
+    /// The last element returned, if any, will contain the remainder of the
+    /// string.
+    /// The pattern can be a simple `&str`, `char`, or a closure that
+    /// determines the split.
+    /// Additional libraries might provide more complex patterns like
+    /// regular expressions.
     ///
-    /// # Panics
+    /// # Iterator behavior
     ///
-    /// If `i` is greater than the length of the string.
-    /// If `i` is not an index following a valid UTF-8 character.
+    /// The returned iterator will not be double ended, because it is
+    /// not efficient to support.
+    ///
+    /// If the pattern allows a reverse search, `rsplitn()` can be used.
     ///
     /// # Examples
     ///
+    /// Simple patterns:
+    ///
     /// ```
-    /// # #![feature(str_char)]
-    /// let s = "abπc";
-    /// assert_eq!(s.char_at_reverse(1), 'a');
-    /// assert_eq!(s.char_at_reverse(2), 'b');
+    /// let v: Vec<&str> = "Mary had a little lambda".splitn(3, ' ').collect();
+    /// assert_eq!(v, ["Mary", "had", "a little lambda"]);
+    ///
+    /// let v: Vec<&str> = "lionXXtigerXleopard".splitn(3, "X").collect();
+    /// assert_eq!(v, ["lion", "", "tigerXleopard"]);
+    ///
+    /// let v: Vec<&str> = "abcXdef".splitn(1, 'X').collect();
+    /// assert_eq!(v, ["abcXdef"]);
+    ///
+    /// let v: Vec<&str> = "".splitn(1, 'X').collect();
+    /// assert_eq!(v, [""]);
     /// ```
-    #[unstable(feature = "str_char",
-               reason = "see char_at for more details, but reverse semantics \
-                         are also somewhat unclear, especially with which \
-                         cases generate panics")]
-    pub fn char_at_reverse(&self, i: usize) -> char {
-        core_str::StrExt::char_at_reverse(&self[..], i)
-    }
-
-    /// Converts `self` to a byte slice.
     ///
-    /// # Examples
+    /// A more complex pattern, using a closure:
     ///
     /// ```
-    /// assert_eq!("bors".as_bytes(), b"bors");
+    /// let v: Vec<&str> = "abc1defXghi".splitn(2, |c| c == '1' || c == 'X').collect();
+    /// assert_eq!(v, ["abc", "defXghi"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[inline(always)]
-    pub fn as_bytes(&self) -> &[u8] {
-        core_str::StrExt::as_bytes(&self[..])
+    pub fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P> {
+        core_str::StrExt::splitn(&self[..], count, pat)
     }
 
-    /// Returns the byte index of the first character of `self` that matches
-    /// the pattern, if it
-    /// exists.
+    /// An iterator over substrings of `self`, separated by a pattern,
+    /// starting from the end of the string, restricted to returning
+    /// at most `count` items.
     ///
-    /// Returns `None` if it doesn't exist.
+    /// The last element returned, if any, will contain the remainder of the
+    /// string.
     ///
     /// The pattern can be a simple `&str`, `char`, or a closure that
-    /// determines the
-    /// split.
+    /// determines the split.
+    /// Additional libraries might provide more complex patterns like
+    /// regular expressions.
+    ///
+    /// # Iterator behavior
+    ///
+    /// The returned iterator will not be double ended, because it is not
+    /// efficient to support.
+    ///
+    /// `splitn()` can be used for splitting from the front.
     ///
     /// # Examples
     ///
     /// Simple patterns:
     ///
     /// ```
-    /// let s = "Löwe 老虎 Léopard";
+    /// let v: Vec<&str> = "Mary had a little lamb".rsplitn(3, ' ').collect();
+    /// assert_eq!(v, ["lamb", "little", "Mary had a"]);
     ///
-    /// assert_eq!(s.find('L'), Some(0));
-    /// assert_eq!(s.find('é'), Some(14));
-    /// assert_eq!(s.find("Léopard"), Some(13));
+    /// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(3, 'X').collect();
+    /// assert_eq!(v, ["leopard", "tiger", "lionX"]);
     ///
+    /// let v: Vec<&str> = "lion::tiger::leopard".rsplitn(2, "::").collect();
+    /// assert_eq!(v, ["leopard", "lion::tiger"]);
     /// ```
     ///
-    /// More complex patterns with closures:
+    /// A more complex pattern, using a closure:
     ///
     /// ```
-    /// let s = "Löwe 老虎 Léopard";
-    ///
-    /// assert_eq!(s.find(|c: char| c.is_whitespace()), Some(5));
-    /// assert_eq!(s.find(char::is_lowercase), Some(1));
+    /// let v: Vec<&str> = "abc1defXghi".rsplitn(2, |c| c == '1' || c == 'X').collect();
+    /// assert_eq!(v, ["ghi", "abc1def"]);
     /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
+        where P::Searcher: ReverseSearcher<'a>
+    {
+        core_str::StrExt::rsplitn(&self[..], count, pat)
+    }
+
+    /// An iterator over the matches of a pattern within `self`.
     ///
-    /// Not finding the pattern:
+    /// The pattern can be a simple `&str`, `char`, or a closure that
+    /// determines the split.
+    /// Additional libraries might provide more complex patterns like
+    /// regular expressions.
+    ///
+    /// # Iterator behavior
+    ///
+    /// The returned iterator will be double ended if the pattern allows
+    /// a reverse search
+    /// and forward/reverse search yields the same elements. This is true
+    /// for, eg, `char` but not
+    /// for `&str`.
+    ///
+    /// If the pattern allows a reverse search but its results might differ
+    /// from a forward search, `rmatches()` can be used.
+    ///
+    /// # Examples
     ///
     /// ```
-    /// let s = "Löwe 老虎 Léopard";
-    /// let x: &[_] = &['1', '2'];
+    /// # #![feature(collections)]
+    /// let v: Vec<&str> = "abcXXXabcYYYabc".matches("abc").collect();
+    /// assert_eq!(v, ["abc", "abc", "abc"]);
     ///
-    /// assert_eq!(s.find(x), None);
+    /// let v: Vec<&str> = "1abc2abc3".matches(char::is_numeric).collect();
+    /// assert_eq!(v, ["1", "2", "3"]);
     /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
-        core_str::StrExt::find(&self[..], pat)
+    #[unstable(feature = "collections",
+               reason = "method got recently added")]
+    pub fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> {
+        core_str::StrExt::matches(&self[..], pat)
     }
 
-    /// Returns the byte index of the last character of `self` that
-    /// matches the pattern, if it
-    /// exists.
+    /// An iterator over the matches of a pattern within `self`, yielded in
+    /// reverse order.
     ///
-    /// Returns `None` if it doesn't exist.
+    /// The pattern can be a simple `&str`, `char`, or a closure that
+    /// determines the split.
+    /// Additional libraries might provide more complex patterns like
+    /// regular expressions.
     ///
-    /// The pattern can be a simple `&str`, `char`,
-    /// or a closure that determines the split.
+    /// # Iterator behavior
     ///
-    /// # Examples
+    /// The returned iterator requires that the pattern supports a
+    /// reverse search,
+    /// and it will be double ended if a forward/reverse search yields
+    /// the same elements.
     ///
-    /// Simple patterns:
+    /// For iterating from the front, `matches()` can be used.
+    ///
+    /// # Examples
     ///
     /// ```
-    /// let s = "Löwe 老虎 Léopard";
+    /// # #![feature(collections)]
+    /// let v: Vec<&str> = "abcXXXabcYYYabc".rmatches("abc").collect();
+    /// assert_eq!(v, ["abc", "abc", "abc"]);
     ///
-    /// assert_eq!(s.rfind('L'), Some(13));
-    /// assert_eq!(s.rfind('é'), Some(14));
+    /// let v: Vec<&str> = "1abc2abc3".rmatches(char::is_numeric).collect();
+    /// assert_eq!(v, ["3", "2", "1"]);
     /// ```
+    #[unstable(feature = "collections",
+               reason = "method got recently added")]
+    pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
+        where P::Searcher: ReverseSearcher<'a>
+    {
+        core_str::StrExt::rmatches(&self[..], pat)
+    }
+
+    /// An iterator over the start and end indices of the disjoint matches
+    /// of a pattern within `self`.
     ///
-    /// More complex patterns with closures:
+    /// For matches of `pat` within `self` that overlap, only the indices
+    /// corresponding to the first
+    /// match are returned.
     ///
-    /// ```
-    /// let s = "Löwe 老虎 Léopard";
+    /// The pattern can be a simple `&str`, `char`, or a closure that
+    /// determines
+    /// the split.
+    /// Additional libraries might provide more complex patterns like
+    /// regular expressions.
     ///
-    /// assert_eq!(s.rfind(|c: char| c.is_whitespace()), Some(12));
-    /// assert_eq!(s.rfind(char::is_lowercase), Some(20));
-    /// ```
+    /// # Iterator behavior
     ///
-    /// Not finding the pattern:
+    /// The returned iterator will be double ended if the pattern allows a
+    /// reverse search
+    /// and forward/reverse search yields the same elements. This is true for,
+    /// eg, `char` but not
+    /// for `&str`.
+    ///
+    /// If the pattern allows a reverse search but its results might differ
+    /// from a forward search, `rmatch_indices()` can be used.
+    ///
+    /// # Examples
     ///
     /// ```
-    /// let s = "Löwe 老虎 Léopard";
-    /// let x: &[_] = &['1', '2'];
+    /// # #![feature(collections)]
+    /// let v: Vec<(usize, usize)> = "abcXXXabcYYYabc".match_indices("abc").collect();
+    /// assert_eq!(v, [(0, 3), (6, 9), (12, 15)]);
     ///
-    /// assert_eq!(s.rfind(x), None);
+    /// let v: Vec<(usize, usize)> = "1abcabc2".match_indices("abc").collect();
+    /// assert_eq!(v, [(1, 4), (4, 7)]);
+    ///
+    /// let v: Vec<(usize, usize)> = "ababa".match_indices("aba").collect();
+    /// assert_eq!(v, [(0, 3)]); // only the first `aba`
     /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
-        where P::Searcher: ReverseSearcher<'a>
-    {
-        core_str::StrExt::rfind(&self[..], pat)
+    #[unstable(feature = "collections",
+               reason = "might have its iterator type changed")]
+    // NB: Right now MatchIndices yields `(usize, usize)`, but it would
+    // be more consistent with `matches` and `char_indices` to return `(usize, &str)`
+    pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
+        core_str::StrExt::match_indices(&self[..], pat)
     }
 
-    /// Retrieves the first character from a `&str` and returns it.
+    /// An iterator over the start and end indices of the disjoint matches of
+    /// a pattern within
+    /// `self`, yielded in reverse order.
     ///
-    /// This does not allocate a new string; instead, it returns a slice that
-    /// points one character
-    /// beyond the character that was shifted.
+    /// For matches of `pat` within `self` that overlap, only the indices
+    /// corresponding to the last
+    /// match are returned.
     ///
-    /// If the slice does not contain any characters, None is returned instead.
+    /// The pattern can be a simple `&str`, `char`, or a closure that
+    /// determines
+    /// the split.
+    /// Additional libraries might provide more complex patterns like
+    /// regular expressions.
+    ///
+    /// # Iterator behavior
+    ///
+    /// The returned iterator requires that the pattern supports a
+    /// reverse search,
+    /// and it will be double ended if a forward/reverse search yields
+    /// the same elements.
+    ///
+    /// For iterating from the front, `match_indices()` can be used.
     ///
     /// # Examples
     ///
     /// ```
-    /// # #![feature(str_char)]
-    /// let s = "Löwe 老虎 Léopard";
-    /// let (c, s1) = s.slice_shift_char().unwrap();
-    ///
-    /// assert_eq!(c, 'L');
-    /// assert_eq!(s1, "öwe 老虎 Léopard");
+    /// # #![feature(collections)]
+    /// let v: Vec<(usize, usize)> = "abcXXXabcYYYabc".rmatch_indices("abc").collect();
+    /// assert_eq!(v, [(12, 15), (6, 9), (0, 3)]);
     ///
-    /// let (c, s2) = s1.slice_shift_char().unwrap();
+    /// let v: Vec<(usize, usize)> = "1abcabc2".rmatch_indices("abc").collect();
+    /// assert_eq!(v, [(4, 7), (1, 4)]);
     ///
-    /// assert_eq!(c, 'ö');
-    /// assert_eq!(s2, "we 老虎 Léopard");
+    /// let v: Vec<(usize, usize)> = "ababa".rmatch_indices("aba").collect();
+    /// assert_eq!(v, [(2, 5)]); // only the last `aba`
     /// ```
-    #[unstable(feature = "str_char",
-               reason = "awaiting conventions about shifting and slices and \
-                         may not be warranted with the existence of the chars \
-                         and/or char_indices iterators")]
-    pub fn slice_shift_char(&self) -> Option<(char, &str)> {
-        core_str::StrExt::slice_shift_char(&self[..])
+    #[unstable(feature = "collections",
+               reason = "might have its iterator type changed")]
+    // NB: Right now RMatchIndices yields `(usize, usize)`, but it would
+    // be more consistent with `rmatches` and `char_indices` to return `(usize, &str)`
+    pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
+        where P::Searcher: ReverseSearcher<'a>
+    {
+        core_str::StrExt::rmatch_indices(&self[..], pat)
     }
 
     /// Returns the byte offset of an inner slice relative to an enclosing
@@ -1615,230 +1631,179 @@ pub fn subslice_offset(&self, inner: &str) -> usize {
         core_str::StrExt::subslice_offset(&self[..], inner)
     }
 
-    /// Returns an unsafe pointer to the `&str`'s buffer.
-    ///
-    /// The caller must ensure that the string outlives this pointer, and
-    /// that it is not
-    /// reallocated (e.g. by pushing to the string).
+    /// Returns a `&str` with leading and trailing whitespace removed.
     ///
     /// # Examples
     ///
     /// ```
-    /// let s = "Hello";
-    /// let p = s.as_ptr();
+    /// let s = " Hello\tworld\t";
+    /// assert_eq!(s.trim(), "Hello\tworld");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[inline]
-    pub fn as_ptr(&self) -> *const u8 {
-        core_str::StrExt::as_ptr(&self[..])
-    }
-
-    /// Returns an iterator of `u16` over the string encoded as UTF-16.
-    #[unstable(feature = "collections",
-               reason = "this functionality may only be provided by libunicode")]
-    pub fn utf16_units(&self) -> Utf16Units {
-        Utf16Units { encoder: Utf16Encoder::new(self[..].chars()) }
+    pub fn trim(&self) -> &str {
+        UnicodeStr::trim(&self[..])
     }
 
-    /// Returns the length of `self` in bytes.
+    /// Returns a `&str` with leading whitespace removed.
     ///
     /// # Examples
     ///
     /// ```
-    /// assert_eq!("foo".len(), 3);
-    /// assert_eq!("ƒoo".len(), 4); // fancy f!
+    /// let s = " Hello\tworld\t";
+    /// assert_eq!(s.trim_left(), "Hello\tworld\t");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[inline]
-    pub fn len(&self) -> usize {
-        core_str::StrExt::len(&self[..])
+    pub fn trim_left(&self) -> &str {
+        UnicodeStr::trim_left(&self[..])
     }
 
-    /// Returns true if this slice has a length of zero bytes.
+    /// Returns a `&str` with trailing whitespace removed.
     ///
     /// # Examples
     ///
     /// ```
-    /// assert!("".is_empty());
+    /// let s = " Hello\tworld\t";
+    /// assert_eq!(s.trim_right(), " Hello\tworld");
     /// ```
-    #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn is_empty(&self) -> bool {
-        core_str::StrExt::is_empty(&self[..])
+    pub fn trim_right(&self) -> &str {
+        UnicodeStr::trim_right(&self[..])
     }
 
-    /// Parses `self` into the specified type.
+    /// Returns a string with all pre- and suffixes that match a pattern
+    /// repeatedly removed.
     ///
-    /// # Failure
+    /// The pattern can be a simple `char`, or a closure that determines
+    /// the split.
     ///
-    /// Will return `Err` if it's not possible to parse `self` into the type.
+    /// # Examples
     ///
-    /// # Example
+    /// Simple patterns:
     ///
     /// ```
-    /// assert_eq!("4".parse::<u32>(), Ok(4));
+    /// assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
+    /// assert_eq!("123foo1bar123".trim_matches(char::is_numeric), "foo1bar");
+    ///
+    /// let x: &[_] = &['1', '2'];
+    /// assert_eq!("12foo1bar12".trim_matches(x), "foo1bar");
     /// ```
     ///
-    /// Failing:
+    /// A more complex pattern, using a closure:
     ///
     /// ```
-    /// assert!("j".parse::<u32>().is_err());
+    /// assert_eq!("1foo1barXX".trim_matches(|c| c == '1' || c == 'X'), "foo1bar");
     /// ```
-    #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
-        core_str::StrExt::parse(&self[..])
+    pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
+        where P::Searcher: DoubleEndedSearcher<'a>
+    {
+        core_str::StrExt::trim_matches(&self[..], pat)
     }
 
-    /// Returns an iterator over the [grapheme clusters][graphemes] of `self`.
-    ///
-    /// [graphemes]: http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries
+    /// Returns a string with all prefixes that match a pattern
+    /// repeatedly removed.
     ///
-    /// If `is_extended` is true, the iterator is over the
-    /// *extended grapheme clusters*;
-    /// otherwise, the iterator is over the *legacy grapheme clusters*.
-    /// [UAX#29](http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries)
-    /// recommends extended grapheme cluster boundaries for general processing.
+    /// The pattern can be a simple `&str`, `char`, or a closure that
+    /// determines the split.
     ///
     /// # Examples
     ///
     /// ```
-    /// # #![feature(unicode, core)]
-    /// let gr1 = "a\u{310}e\u{301}o\u{308}\u{332}".graphemes(true).collect::<Vec<&str>>();
-    /// let b: &[_] = &["a\u{310}", "e\u{301}", "o\u{308}\u{332}"];
-    ///
-    /// assert_eq!(&gr1[..], b);
-    ///
-    /// let gr2 = "a\r\nb🇷🇺🇸🇹".graphemes(true).collect::<Vec<&str>>();
-    /// let b: &[_] = &["a", "\r\n", "b", "🇷🇺🇸🇹"];
+    /// assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
+    /// assert_eq!("123foo1bar123".trim_left_matches(char::is_numeric), "foo1bar123");
     ///
-    /// assert_eq!(&gr2[..], b);
+    /// let x: &[_] = &['1', '2'];
+    /// assert_eq!("12foo1bar12".trim_left_matches(x), "foo1bar12");
     /// ```
-    #[deprecated(reason = "use the crates.io `unicode-segmentation` library instead",
-             since = "1.0.0")]
-    #[unstable(feature = "unicode",
-               reason = "this functionality may only be provided by libunicode")]
-    pub fn graphemes(&self, is_extended: bool) -> Graphemes {
-        UnicodeStr::graphemes(&self[..], is_extended)
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
+        core_str::StrExt::trim_left_matches(&self[..], pat)
     }
 
-    /// Returns an iterator over the grapheme clusters of `self` and their
-    /// byte offsets. See
-    /// `graphemes()` for more information.
+    /// Returns a string with all suffixes that match a pattern
+    /// repeatedly removed.
+    ///
+    /// The pattern can be a simple `&str`, `char`, or a closure that
+    /// determines the split.
     ///
     /// # Examples
     ///
+    /// Simple patterns:
+    ///
     /// ```
-    /// # #![feature(unicode, core)]
-    /// let gr_inds = "a̐éö̲\r\n".grapheme_indices(true).collect::<Vec<(usize, &str)>>();
-    /// let b: &[_] = &[(0, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
+    /// assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
+    /// assert_eq!("123foo1bar123".trim_right_matches(char::is_numeric), "123foo1bar");
     ///
-    /// assert_eq!(&gr_inds[..], b);
+    /// let x: &[_] = &['1', '2'];
+    /// assert_eq!("12foo1bar12".trim_right_matches(x), "12foo1bar");
     /// ```
-    #[deprecated(reason = "use the crates.io `unicode-segmentation` library instead",
-             since = "1.0.0")]
-    #[unstable(feature = "unicode",
-               reason = "this functionality may only be provided by libunicode")]
-    pub fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices {
-        UnicodeStr::grapheme_indices(&self[..], is_extended)
-    }
-
-    /// An iterator over the non-empty substrings of `self` which contain no whitespace,
-    /// and which are separated by any amount of whitespace.
     ///
-    /// # Examples
+    /// A more complex pattern, using a closure:
     ///
     /// ```
-    /// # #![feature(str_words)]
-    /// # #![allow(deprecated)]
-    /// let some_words = " Mary   had\ta little  \n\t lamb";
-    /// let v: Vec<&str> = some_words.words().collect();
-    ///
-    /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
+    /// assert_eq!("1fooX".trim_left_matches(|c| c == '1' || c == 'X'), "fooX");
     /// ```
-    #[deprecated(reason = "words() will be removed. Use split_whitespace() instead",
-                 since = "1.1.0")]
-    #[unstable(feature = "str_words",
-               reason = "the precise algorithm to use is unclear")]
-    #[allow(deprecated)]
-    pub fn words(&self) -> Words {
-        UnicodeStr::words(&self[..])
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
+        where P::Searcher: ReverseSearcher<'a>
+    {
+        core_str::StrExt::trim_right_matches(&self[..], pat)
     }
 
-    /// An iterator over the non-empty substrings of `self` which contain no whitespace,
-    /// and which are separated by any amount of whitespace.
-    ///
-    /// # Examples
+    /// Parses `self` into the specified type.
     ///
-    /// ```
-    /// let some_words = " Mary   had\ta little  \n\t lamb";
-    /// let v: Vec<&str> = some_words.split_whitespace().collect();
+    /// # Failure
     ///
-    /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
-    /// ```
-    #[stable(feature = "split_whitespace", since = "1.1.0")]
-    pub fn split_whitespace(&self) -> SplitWhitespace {
-        UnicodeStr::split_whitespace(&self[..])
-    }
-
-    /// Returns a string's displayed width in columns.
+    /// Will return `Err` if it's not possible to parse `self` into the type.
     ///
-    /// Control characters have zero width.
+    /// # Example
     ///
-    /// `is_cjk` determines behavior for characters in the Ambiguous category:
-    /// if `is_cjk` is
-    /// `true`, these are 2 columns wide; otherwise, they are 1.
-    /// In CJK locales, `is_cjk` should be
-    /// `true`, else it should be `false`.
-    /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/)
-    /// recommends that these
-    /// characters be treated as 1 column (i.e., `is_cjk = false`) if the
-    /// locale is unknown.
-    #[deprecated(reason = "use the crates.io `unicode-width` library instead",
-                 since = "1.0.0")]
-    #[unstable(feature = "unicode",
-               reason = "this functionality may only be provided by libunicode")]
-    pub fn width(&self, is_cjk: bool) -> usize {
-        UnicodeStr::width(&self[..], is_cjk)
-    }
-
-    /// Returns a `&str` with leading and trailing whitespace removed.
+    /// ```
+    /// assert_eq!("4".parse::<u32>(), Ok(4));
+    /// ```
     ///
-    /// # Examples
+    /// Failing:
     ///
     /// ```
-    /// let s = " Hello\tworld\t";
-    /// assert_eq!(s.trim(), "Hello\tworld");
+    /// assert!("j".parse::<u32>().is_err());
     /// ```
+    #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn trim(&self) -> &str {
-        UnicodeStr::trim(&self[..])
+    pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
+        core_str::StrExt::parse(&self[..])
     }
 
-    /// Returns a `&str` with leading whitespace removed.
+    /// Replaces all occurrences of one string with another.
+    ///
+    /// `replace` takes two arguments, a sub-`&str` to find in `self`, and a
+    /// second `&str` to
+    /// replace it with. If the original `&str` isn't found, no change occurs.
     ///
     /// # Examples
     ///
     /// ```
-    /// let s = " Hello\tworld\t";
-    /// assert_eq!(s.trim_left(), "Hello\tworld\t");
+    /// let s = "this is old";
+    ///
+    /// assert_eq!(s.replace("old", "new"), "this is new");
     /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn trim_left(&self) -> &str {
-        UnicodeStr::trim_left(&self[..])
-    }
-
-    /// Returns a `&str` with trailing whitespace removed.
     ///
-    /// # Examples
+    /// When a `&str` isn't found:
     ///
     /// ```
-    /// let s = " Hello\tworld\t";
-    /// assert_eq!(s.trim_right(), " Hello\tworld");
+    /// let s = "this is old";
+    /// assert_eq!(s.replace("cookie monster", "little lamb"), s);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn trim_right(&self) -> &str {
-        UnicodeStr::trim_right(&self[..])
+    pub fn replace(&self, from: &str, to: &str) -> String {
+        let mut result = String::new();
+        let mut last_end = 0;
+        for (start, end) in self.match_indices(from) {
+            result.push_str(unsafe { self.slice_unchecked(last_end, start) });
+            result.push_str(to);
+            last_end = end;
+        }
+        result.push_str(unsafe { self.slice_unchecked(last_end, self.len()) });
+        result
     }
 
     /// Returns the lowercase equivalent of this string.
@@ -1851,11 +1816,40 @@ pub fn trim_right(&self) -> &str {
     /// let s = "HELLO";
     /// assert_eq!(s.to_lowercase(), "hello");
     /// ```
-    #[unstable(feature = "collections")]
+    #[stable(feature = "unicode_case_mapping", since = "1.2.0")]
     pub fn to_lowercase(&self) -> String {
         let mut s = String::with_capacity(self.len());
-        s.extend(self[..].chars().flat_map(|c| c.to_lowercase()));
+        for (i, c) in self[..].char_indices() {
+            if c == 'Σ' {
+                // Σ maps to σ, except at the end of a word where it maps to ς.
+                // This is the only conditional (contextual) but language-independent mapping
+                // in `SpecialCasing.txt`,
+                // so hard-code it rather than have a generic "condition" mechanim.
+                // See https://github.com/rust-lang/rust/issues/26035
+                map_uppercase_sigma(self, i, &mut s)
+            } else {
+                s.extend(c.to_lowercase());
+            }
+        }
         return s;
+
+        fn map_uppercase_sigma(from: &str, i: usize, to: &mut String) {
+            // See http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992
+            // for the definition of `Final_Sigma`.
+            debug_assert!('Σ'.len_utf8() == 2);
+            let is_word_final =
+                case_ignoreable_then_cased(from[..i].chars().rev()) &&
+                !case_ignoreable_then_cased(from[i + 2..].chars());
+            to.push_str(if is_word_final { "ς" } else { "σ" });
+        }
+
+        fn case_ignoreable_then_cased<I: Iterator<Item=char>>(iter: I) -> bool {
+            use rustc_unicode::derived_property::{Cased, Case_Ignorable};
+            match iter.skip_while(|&c| Case_Ignorable(c)).next() {
+                Some(c) => Cased(c),
+                None => false,
+            }
+        }
     }
 
     /// Returns the uppercase equivalent of this string.
@@ -1868,10 +1862,24 @@ pub fn to_lowercase(&self) -> String {
     /// let s = "hello";
     /// assert_eq!(s.to_uppercase(), "HELLO");
     /// ```
-    #[unstable(feature = "collections")]
+    #[stable(feature = "unicode_case_mapping", since = "1.2.0")]
     pub fn to_uppercase(&self) -> String {
         let mut s = String::with_capacity(self.len());
         s.extend(self[..].chars().flat_map(|c| c.to_uppercase()));
         return s;
     }
+
+    /// Escapes each char in `s` with `char::escape_default`.
+    #[unstable(feature = "collections",
+               reason = "return type may change to be an iterator")]
+    pub fn escape_default(&self) -> String {
+        self.chars().flat_map(|c| c.escape_default()).collect()
+    }
+
+    /// Escapes each char in `s` with `char::escape_unicode`.
+    #[unstable(feature = "collections",
+               reason = "return type may change to be an iterator")]
+    pub fn escape_unicode(&self) -> String {
+        self.chars().flat_map(|c| c.escape_unicode()).collect()
+    }
 }
index c328a58f0770efcf7f97021857cdcd33f14c17df..7ede6545b9fb214be464bd734756cdd6b9a79a94 100644 (file)
@@ -88,13 +88,13 @@ pub fn with_capacity(capacity: usize) -> String {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(collections, core)]
-    /// let s = String::from_str("hello");
+    /// # #![feature(collections)]
+    /// let s = String::from("hello");
     /// assert_eq!(&s[..], "hello");
     /// ```
     #[inline]
-    #[unstable(feature = "collections",
-               reason = "needs investigation to see if to_string() can match perf")]
+    #[unstable(feature = "collections", reason = "use `String::from` instead")]
+    #[deprecated(since = "1.2.0", reason = "use `String::from` instead")]
     #[cfg(not(test))]
     pub fn from_str(string: &str) -> String {
         String { vec: <[_]>::to_vec(string.as_bytes()) }
@@ -793,6 +793,13 @@ fn extend<I: IntoIterator<Item=char>>(&mut self, iterable: I) {
     }
 }
 
+#[stable(feature = "extend_ref", since = "1.2.0")]
+impl<'a> Extend<&'a char> for String {
+    fn extend<I: IntoIterator<Item=&'a char>>(&mut self, iter: I) {
+        self.extend(iter.into_iter().cloned());
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Extend<&'a str> for String {
     fn extend<I: IntoIterator<Item=&'a str>>(&mut self, iterable: I) {
@@ -1002,7 +1009,7 @@ pub fn as_string<'a>(x: &'a str) -> DerefString<'a> {
     DerefString { x: as_vec(x.as_bytes()) }
 }
 
-/// Error returned from `String::from_str`
+/// Error returned from `String::from`
 #[unstable(feature = "str_parse_error", reason = "may want to be replaced with \
                                                   Void if it ever exists")]
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
@@ -1013,7 +1020,7 @@ impl FromStr for String {
     type Err = ParseError;
     #[inline]
     fn from_str(s: &str) -> Result<String, ParseError> {
-        Ok(String::from_str(s))
+        Ok(String::from(s))
     }
 }
 
index 8dacfa53bc9807588c2b33815189a74937cc33d2..0cc0108fd0116bf788c8fa1d1f20a4eb031362f7 100644 (file)
@@ -83,7 +83,7 @@
 use super::range::RangeArgument;
 
 // FIXME- fix places which assume the max vector allowed has memory usize::MAX.
-static MAX_MEMORY_SIZE: usize = isize::MAX as usize;
+const MAX_MEMORY_SIZE: usize = isize::MAX as usize;
 
 /// A growable list type, written `Vec<T>` but pronounced 'vector.'
 ///
@@ -840,7 +840,7 @@ pub fn is_empty(&self) -> bool { self.len() == 0 }
     /// # Examples
     ///
     /// ```
-    /// # #![feature(collections, core)]
+    /// # #![feature(collections)]
     /// let v = vec![0, 1, 2];
     /// let w = v.map_in_place(|i| i + 3);
     /// assert_eq!(&w[..], &[3, 4, 5]);
@@ -1578,6 +1578,13 @@ fn extend<I: IntoIterator<Item=T>>(&mut self, iterable: I) {
     }
 }
 
+#[stable(feature = "extend_ref", since = "1.2.0")]
+impl<'a, T: 'a + Copy> Extend<&'a T> for Vec<T> {
+    fn extend<I: IntoIterator<Item=&'a T>>(&mut self, iter: I) {
+        self.extend(iter.into_iter().cloned());
+    }
+}
+
 __impl_slice_eq1! { Vec<A>, Vec<B> }
 __impl_slice_eq1! { Vec<A>, &'b [B] }
 __impl_slice_eq1! { Vec<A>, &'b mut [B] }
index 0bc42bd2c7e020578e5935ad60565fc4cfd3fb30..88d0a96b78cc7f0494bd812f817330f52ce1a241 100644 (file)
@@ -1785,6 +1785,13 @@ fn extend<T: IntoIterator<Item=A>>(&mut self, iter: T) {
     }
 }
 
+#[stable(feature = "extend_ref", since = "1.2.0")]
+impl<'a, T: 'a + Copy> Extend<&'a T> for VecDeque<T> {
+    fn extend<I: IntoIterator<Item=&'a T>>(&mut self, iter: I) {
+        self.extend(iter.into_iter().cloned());
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: fmt::Debug> fmt::Debug for VecDeque<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
index aa0ab41b7455b05d4bba2192a4525a5d58af9f8a..8180f1d56df1205d1e6743a1cbc6354cd3b1ccf6 100644 (file)
@@ -828,6 +828,13 @@ fn extend<I: IntoIterator<Item=(usize, V)>>(&mut self, iter: I) {
     }
 }
 
+#[stable(feature = "extend_ref", since = "1.2.0")]
+impl<'a, V: Copy> Extend<(usize, &'a V)> for VecMap<V> {
+    fn extend<I: IntoIterator<Item=(usize, &'a V)>>(&mut self, iter: I) {
+        self.extend(iter.into_iter().map(|(key, &value)| (key, value)));
+    }
+}
+
 impl<V> Index<usize> for VecMap<V> {
     type Output = V;
 
index 47a366bb1e2e0dd937eac062be37bfd06c208391..303a0ce811df6f825d60eed5d87d763ea0937e2b 100644 (file)
@@ -217,3 +217,28 @@ fn test_drain() {
 
     assert!(q.is_empty());
 }
+
+#[test]
+fn test_extend_ref() {
+    let mut a = BinaryHeap::new();
+    a.push(1);
+    a.push(2);
+
+    a.extend(&[3, 4, 5]);
+
+    assert_eq!(a.len(), 5);
+    assert_eq!(a.into_sorted_vec(), [1, 2, 3, 4, 5]);
+
+    let mut a = BinaryHeap::new();
+    a.push(1);
+    a.push(2);
+    let mut b = BinaryHeap::new();
+    b.push(3);
+    b.push(4);
+    b.push(5);
+
+    a.extend(&b);
+
+    assert_eq!(a.len(), 5);
+    assert_eq!(a.into_sorted_vec(), [1, 2, 3, 4, 5]);
+}
index e6aa15608f03eb0297afcae622927e105a55c92d..8ab3eff0f4f6425e490adf4c09b6da257867e527 100644 (file)
@@ -448,6 +448,26 @@ fn test_bit_set_split_off() {
                                                             0b00101011, 0b10101101])));
 }
 
+#[test]
+fn test_bit_set_extend_ref() {
+    let mut a = BitSet::new();
+    a.insert(3);
+
+    a.extend(&[5, 7, 10]);
+
+    assert_eq!(a.len(), 4);
+    assert_eq!(a, BitSet::from_bit_vec(BitVec::from_bytes(&[0b00010101,0b00100000])));
+
+    let mut b = BitSet::new();
+    b.insert(11);
+    b.insert(15);
+
+    a.extend(&b);
+
+    assert_eq!(a.len(), 6);
+    assert_eq!(a, BitSet::from_bit_vec(BitVec::from_bytes(&[0b00010101,0b00110001])));
+}
+
 mod bench {
     use std::collections::{BitSet, BitVec};
     use std::__rand::{Rng, thread_rng, ThreadRng};
index a1d2eed0a8b5f13089c7923193a2fbdd2ca4d272..696ae8aa7b68e87aeb1219a7b15e0519f6ca9f9d 100644 (file)
@@ -630,6 +630,24 @@ fn test_bit_vec_extend() {
                                  0b01001001, 0b10010010, 0b10111101]));
 }
 
+#[test]
+fn test_bit_vecextend_ref() {
+    let mut bv = BitVec::from_bytes(&[0b10100011]);
+    bv.extend(&[true, false, true]);
+
+    assert_eq!(bv.len(), 11);
+    assert!(bv.eq_vec(&[true, false, true, false, false, false, true, true,
+                        true, false, true]));
+
+    let bw = BitVec::from_bytes(&[0b00010001]);
+    bv.extend(&bw);
+
+    assert_eq!(bv.len(), 19);
+    assert!(bv.eq_vec(&[true, false, true, false, false, false, true, true,
+                        true, false, true, false, false, false, true, false,
+                        false, false, true]));
+}
+
 #[test]
 fn test_bit_vec_append() {
     // Append to BitVec that holds a multiple of u32::BITS bits
index a29968ae8a2fc5f03eb01fbd2872ca1b5307e6da..e617e194d300a6d348581e86cbf78d89f7c5d9be 100644 (file)
@@ -249,6 +249,22 @@ fn test_entry(){
     assert_eq!(map.len(), 6);
 }
 
+#[test]
+fn test_extend_ref() {
+    let mut a = BTreeMap::new();
+    a.insert(1, "one");
+    let mut b = BTreeMap::new();
+    b.insert(2, "two");
+    b.insert(3, "three");
+
+    a.extend(&b);
+
+    assert_eq!(a.len(), 3);
+    assert_eq!(a[&1], "one");
+    assert_eq!(a[&2], "two");
+    assert_eq!(a[&3], "three");
+}
+
 mod bench {
     use std::collections::BTreeMap;
     use std::__rand::{Rng, thread_rng};
index 234cd6e0fd21ec23994810de197661005891dc0a..97fb4b6b15fd63d94e6d6c9623bda7f0e54f12ef 100644 (file)
@@ -184,3 +184,31 @@ fn test_show() {
     assert_eq!(set_str, "{1, 2}");
     assert_eq!(format!("{:?}", empty), "{}");
 }
+
+#[test]
+fn test_extend_ref() {
+    let mut a = BTreeSet::new();
+    a.insert(1);
+
+    a.extend(&[2, 3, 4]);
+
+    assert_eq!(a.len(), 4);
+    assert!(a.contains(&1));
+    assert!(a.contains(&2));
+    assert!(a.contains(&3));
+    assert!(a.contains(&4));
+
+    let mut b = BTreeSet::new();
+    b.insert(5);
+    b.insert(6);
+
+    a.extend(&b);
+
+    assert_eq!(a.len(), 6);
+    assert!(a.contains(&1));
+    assert!(a.contains(&2));
+    assert!(a.contains(&3));
+    assert!(a.contains(&4));
+    assert!(a.contains(&5));
+    assert!(a.contains(&6));
+}
index 0a1eb0bcfa8879cb801191d5e6532f65fda60f40..b073c2f3ae4dd307d99ef5e79a1b3e74c8044b32 100644 (file)
@@ -242,3 +242,25 @@ fn from_usize(v: usize) -> Bar {
     let mut set = EnumSet::new();
     set.insert(Bar::V64);
 }
+
+#[test]
+fn test_extend_ref() {
+    let mut a = EnumSet::new();
+    a.insert(A);
+
+    a.extend(&[A, C]);
+
+    assert_eq!(a.len(), 2);
+    assert!(a.contains(&A));
+    assert!(a.contains(&C));
+
+    let mut b = EnumSet::new();
+    b.insert(B);
+
+    a.extend(&b);
+
+    assert_eq!(a.len(), 3);
+    assert!(a.contains(&A));
+    assert!(a.contains(&B));
+    assert!(a.contains(&C));
+}
index fd73938095f09e4338679c1612ff19e101cbe537..d04ce574ed0a5ace60e5ba3a9575655fd7601f85 100644 (file)
@@ -321,6 +321,25 @@ fn test_show() {
     assert_eq!(format!("{:?}", list), "[\"just\", \"one\", \"test\", \"more\"]");
 }
 
+#[test]
+fn test_extend_ref() {
+    let mut a = LinkedList::new();
+    a.push_back(1);
+
+    a.extend(&[2, 3, 4]);
+
+    assert_eq!(a.len(), 4);
+    assert_eq!(a, list_from(&[1, 2, 3, 4]));
+
+    let mut b = LinkedList::new();
+    b.push_back(5);
+    b.push_back(6);
+    a.extend(&b);
+
+    assert_eq!(a.len(), 6);
+    assert_eq!(a, list_from(&[1, 2, 3, 4, 5, 6]));
+}
+
 #[bench]
 fn bench_collect_into(b: &mut test::Bencher) {
     let v = &[0; 64];
index 170f49ab15be553d5177122d4033da1e65bbaf85..ae525459189520d526c956709b32dc01762a2054 100644 (file)
@@ -71,17 +71,17 @@ fn test_rfind() {
 
 #[test]
 fn test_collect() {
-    let empty = String::from_str("");
+    let empty = String::from("");
     let s: String = empty.chars().collect();
     assert_eq!(empty, s);
-    let data = String::from_str("ประเทศไทย中");
+    let data = String::from("ประเทศไทย中");
     let s: String = data.chars().collect();
     assert_eq!(data, s);
 }
 
 #[test]
 fn test_into_bytes() {
-    let data = String::from_str("asdf");
+    let data = String::from("asdf");
     let buf = data.into_bytes();
     assert_eq!(buf, b"asdf");
 }
@@ -98,7 +98,7 @@ fn test_find_str() {
     assert!(data[2..4].find("ab").is_none());
 
     let string = "ประเทศไทย中华Việt Nam";
-    let mut data = String::from_str(string);
+    let mut data = String::from(string);
     data.push_str(string);
     assert!(data.find("ไท华").is_none());
     assert_eq!(data[0..43].find(""), Some(0));
@@ -211,7 +211,7 @@ fn half_a_million_letter_a() -> String {
     }
     let letters = a_million_letter_a();
     assert!(half_a_million_letter_a() ==
-        unsafe {String::from_str(letters.slice_unchecked(
+        unsafe {String::from(letters.slice_unchecked(
                                  0,
                                  500000))});
 }
@@ -247,13 +247,13 @@ fn test_is_empty() {
 #[test]
 fn test_replace() {
     let a = "a";
-    assert_eq!("".replace(a, "b"), String::from_str(""));
-    assert_eq!("a".replace(a, "b"), String::from_str("b"));
-    assert_eq!("ab".replace(a, "b"), String::from_str("bb"));
+    assert_eq!("".replace(a, "b"), String::from(""));
+    assert_eq!("a".replace(a, "b"), String::from("b"));
+    assert_eq!("ab".replace(a, "b"), String::from("bb"));
     let test = "test";
     assert!(" test test ".replace(test, "toast") ==
-        String::from_str(" toast toast "));
-    assert_eq!(" test test ".replace(test, ""), String::from_str("   "));
+        String::from(" toast toast "));
+    assert_eq!(" test test ".replace(test, ""), String::from("   "));
 }
 
 #[test]
@@ -328,7 +328,7 @@ fn half_a_million_letter_x() -> String {
     }
     let letters = a_million_letter_x();
     assert!(half_a_million_letter_x() ==
-        String::from_str(&letters[0..3 * 500000]));
+        String::from(&letters[0..3 * 500000]));
 }
 
 #[test]
@@ -581,7 +581,7 @@ fn test_as_bytes() {
 fn test_as_bytes_fail() {
     // Don't double free. (I'm not sure if this exercises the
     // original problem code path anymore.)
-    let s = String::from_str("");
+    let s = String::from("");
     let _bytes = s.as_bytes();
     panic!();
 }
@@ -623,10 +623,10 @@ fn test_subslice_offset_2() {
 
 #[test]
 fn vec_str_conversions() {
-    let s1: String = String::from_str("All mimsy were the borogoves");
+    let s1: String = String::from("All mimsy were the borogoves");
 
     let v: Vec<u8> = s1.as_bytes().to_vec();
-    let s2: String = String::from_str(from_utf8(&v).unwrap());
+    let s2: String = String::from(from_utf8(&v).unwrap());
     let mut i = 0;
     let n1 = s1.len();
     let n2 = v.len();
@@ -691,39 +691,39 @@ fn test_char_at_reverse() {
 #[test]
 fn test_escape_unicode() {
     assert_eq!("abc".escape_unicode(),
-               String::from_str("\\u{61}\\u{62}\\u{63}"));
+               String::from("\\u{61}\\u{62}\\u{63}"));
     assert_eq!("a c".escape_unicode(),
-               String::from_str("\\u{61}\\u{20}\\u{63}"));
+               String::from("\\u{61}\\u{20}\\u{63}"));
     assert_eq!("\r\n\t".escape_unicode(),
-               String::from_str("\\u{d}\\u{a}\\u{9}"));
+               String::from("\\u{d}\\u{a}\\u{9}"));
     assert_eq!("'\"\\".escape_unicode(),
-               String::from_str("\\u{27}\\u{22}\\u{5c}"));
+               String::from("\\u{27}\\u{22}\\u{5c}"));
     assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode(),
-               String::from_str("\\u{0}\\u{1}\\u{fe}\\u{ff}"));
+               String::from("\\u{0}\\u{1}\\u{fe}\\u{ff}"));
     assert_eq!("\u{100}\u{ffff}".escape_unicode(),
-               String::from_str("\\u{100}\\u{ffff}"));
+               String::from("\\u{100}\\u{ffff}"));
     assert_eq!("\u{10000}\u{10ffff}".escape_unicode(),
-               String::from_str("\\u{10000}\\u{10ffff}"));
+               String::from("\\u{10000}\\u{10ffff}"));
     assert_eq!("ab\u{fb00}".escape_unicode(),
-               String::from_str("\\u{61}\\u{62}\\u{fb00}"));
+               String::from("\\u{61}\\u{62}\\u{fb00}"));
     assert_eq!("\u{1d4ea}\r".escape_unicode(),
-               String::from_str("\\u{1d4ea}\\u{d}"));
+               String::from("\\u{1d4ea}\\u{d}"));
 }
 
 #[test]
 fn test_escape_default() {
-    assert_eq!("abc".escape_default(), String::from_str("abc"));
-    assert_eq!("a c".escape_default(), String::from_str("a c"));
-    assert_eq!("\r\n\t".escape_default(), String::from_str("\\r\\n\\t"));
-    assert_eq!("'\"\\".escape_default(), String::from_str("\\'\\\"\\\\"));
+    assert_eq!("abc".escape_default(), String::from("abc"));
+    assert_eq!("a c".escape_default(), String::from("a c"));
+    assert_eq!("\r\n\t".escape_default(), String::from("\\r\\n\\t"));
+    assert_eq!("'\"\\".escape_default(), String::from("\\'\\\"\\\\"));
     assert_eq!("\u{100}\u{ffff}".escape_default(),
-               String::from_str("\\u{100}\\u{ffff}"));
+               String::from("\\u{100}\\u{ffff}"));
     assert_eq!("\u{10000}\u{10ffff}".escape_default(),
-               String::from_str("\\u{10000}\\u{10ffff}"));
+               String::from("\\u{10000}\\u{10ffff}"));
     assert_eq!("ab\u{fb00}".escape_default(),
-               String::from_str("ab\\u{fb00}"));
+               String::from("ab\\u{fb00}"));
     assert_eq!("\u{1d4ea}\r".escape_default(),
-               String::from_str("\\u{1d4ea}\\r"));
+               String::from("\\u{1d4ea}\\r"));
 }
 
 #[test]
@@ -1490,12 +1490,12 @@ fn sum_len(v: &[&str]) -> usize {
         v.iter().map(|x| x.len()).sum()
     }
 
-    let s = String::from_str("01234");
+    let s = String::from("01234");
     assert_eq!(5, sum_len(&["012", "", "34"]));
-    assert_eq!(5, sum_len(&[&String::from_str("01"),
-                            &String::from_str("2"),
-                            &String::from_str("34"),
-                            &String::from_str("")]));
+    assert_eq!(5, sum_len(&[&String::from("01"),
+                            &String::from("2"),
+                            &String::from("34"),
+                            &String::from("")]));
     assert_eq!(5, sum_len(&[&s]));
 }
 
@@ -1687,6 +1687,45 @@ fn trim_ws() {
                "");
 }
 
+#[test]
+fn to_lowercase() {
+    assert_eq!("".to_lowercase(), "");
+    assert_eq!("AÉDžaé ".to_lowercase(), "aédžaé ");
+
+    // https://github.com/rust-lang/rust/issues/26035
+    assert_eq!("ΑΣ".to_lowercase(), "ας");
+    assert_eq!("Α'Σ".to_lowercase(), "α'ς");
+    assert_eq!("Α''Σ".to_lowercase(), "α''ς");
+
+    assert_eq!("ΑΣ Α".to_lowercase(), "ας α");
+    assert_eq!("Α'Σ Α".to_lowercase(), "α'ς α");
+    assert_eq!("Α''Σ Α".to_lowercase(), "α''ς α");
+
+    assert_eq!("ΑΣ' Α".to_lowercase(), "ας' α");
+    assert_eq!("ΑΣ'' Α".to_lowercase(), "ας'' α");
+
+    assert_eq!("Α'Σ' Α".to_lowercase(), "α'ς' α");
+    assert_eq!("Α''Σ'' Α".to_lowercase(), "α''ς'' α");
+
+    assert_eq!("Α Σ".to_lowercase(), "α σ");
+    assert_eq!("Α 'Σ".to_lowercase(), "α 'σ");
+    assert_eq!("Α ''Σ".to_lowercase(), "α ''σ");
+
+    assert_eq!("Σ".to_lowercase(), "σ");
+    assert_eq!("'Σ".to_lowercase(), "'σ");
+    assert_eq!("''Σ".to_lowercase(), "''σ");
+
+    assert_eq!("ΑΣΑ".to_lowercase(), "ασα");
+    assert_eq!("ΑΣ'Α".to_lowercase(), "ασ'α");
+    assert_eq!("ΑΣ''Α".to_lowercase(), "ασ''α");
+}
+
+#[test]
+fn to_uppercase() {
+    assert_eq!("".to_uppercase(), "");
+    assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
+}
+
 mod pattern {
     use std::str::pattern::Pattern;
     use std::str::pattern::{Searcher, ReverseSearcher};
index d4e2ebf4fd137e31a49fb1caa967bae1347f1d8c..a1c7209f23b443c55fd2eaf9f3a2c2c2367d6d70 100644 (file)
@@ -37,11 +37,11 @@ fn test_unsized_to_string() {
 fn test_from_utf8() {
     let xs = b"hello".to_vec();
     assert_eq!(String::from_utf8(xs).unwrap(),
-               String::from_str("hello"));
+               String::from("hello"));
 
     let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
     assert_eq!(String::from_utf8(xs).unwrap(),
-               String::from_str("ศไทย中华Việt Nam"));
+               String::from("ศไทย中华Việt Nam"));
 
     let xs = b"hello\xFF".to_vec();
     let err = String::from_utf8(xs).err().unwrap();
@@ -60,44 +60,44 @@ fn test_from_utf8_lossy() {
 
     let xs = b"Hello\xC2 There\xFF Goodbye";
     assert_eq!(String::from_utf8_lossy(xs),
-               String::from_str("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow());
+               String::from("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow());
 
     let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
     assert_eq!(String::from_utf8_lossy(xs),
-               String::from_str("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow());
+               String::from("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow());
 
     let xs = b"\xF5foo\xF5\x80bar";
     assert_eq!(String::from_utf8_lossy(xs),
-               String::from_str("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow());
+               String::from("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow());
 
     let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
     assert_eq!(String::from_utf8_lossy(xs),
-               String::from_str("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow());
+               String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow());
 
     let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
     assert_eq!(String::from_utf8_lossy(xs),
-               String::from_str("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow());
+               String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow());
 
     let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
-    assert_eq!(String::from_utf8_lossy(xs), String::from_str("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}\
+    assert_eq!(String::from_utf8_lossy(xs), String::from("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}\
                                            foo\u{10000}bar").into_cow());
 
     // surrogates
     let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
-    assert_eq!(String::from_utf8_lossy(xs), String::from_str("\u{FFFD}\u{FFFD}\u{FFFD}foo\
+    assert_eq!(String::from_utf8_lossy(xs), String::from("\u{FFFD}\u{FFFD}\u{FFFD}foo\
                                            \u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow());
 }
 
 #[test]
 fn test_from_utf16() {
     let pairs =
-        [(String::from_str("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
+        [(String::from("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
           vec![0xd800, 0xdf45, 0xd800, 0xdf3f,
             0xd800, 0xdf3b, 0xd800, 0xdf46,
             0xd800, 0xdf39, 0xd800, 0xdf3b,
             0xd800, 0xdf30, 0x000a]),
 
-         (String::from_str("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
+         (String::from("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
           vec![0xd801, 0xdc12, 0xd801,
             0xdc49, 0xd801, 0xdc2e, 0xd801,
             0xdc40, 0xd801, 0xdc32, 0xd801,
@@ -105,7 +105,7 @@ fn test_from_utf16() {
             0xd801, 0xdc32, 0xd801, 0xdc4d,
             0x000a]),
 
-         (String::from_str("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
+         (String::from("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
           vec![0xd800, 0xdf00, 0xd800, 0xdf16,
             0xd800, 0xdf0b, 0xd800, 0xdf04,
             0xd800, 0xdf11, 0xd800, 0xdf09,
@@ -114,7 +114,7 @@ fn test_from_utf16() {
             0xdf04, 0xd800, 0xdf0b, 0xd800,
             0xdf09, 0xd800, 0xdf11, 0x000a ]),
 
-         (String::from_str("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
+         (String::from("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
           vec![0xd801, 0xdc8b, 0xd801, 0xdc98,
             0xd801, 0xdc88, 0xd801, 0xdc91,
             0xd801, 0xdc9b, 0xd801, 0xdc92,
@@ -127,7 +127,7 @@ fn test_from_utf16() {
             0xd801, 0xdc95, 0xd801, 0xdc86,
             0x000a ]),
          // Issue #12318, even-numbered non-BMP planes
-         (String::from_str("\u{20000}"),
+         (String::from("\u{20000}"),
           vec![0xD840, 0xDC00])];
 
     for p in &pairs {
@@ -165,22 +165,22 @@ fn test_utf16_invalid() {
 fn test_from_utf16_lossy() {
     // completely positive cases tested above.
     // lead + eof
-    assert_eq!(String::from_utf16_lossy(&[0xD800]), String::from_str("\u{FFFD}"));
+    assert_eq!(String::from_utf16_lossy(&[0xD800]), String::from("\u{FFFD}"));
     // lead + lead
     assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]),
-               String::from_str("\u{FFFD}\u{FFFD}"));
+               String::from("\u{FFFD}\u{FFFD}"));
 
     // isolated trail
-    assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]), String::from_str("a\u{FFFD}"));
+    assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]), String::from("a\u{FFFD}"));
 
     // general
     assert_eq!(String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
-               String::from_str("\u{FFFD}𐒋\u{FFFD}"));
+               String::from("\u{FFFD}𐒋\u{FFFD}"));
 }
 
 #[test]
 fn test_push_bytes() {
-    let mut s = String::from_str("ABC");
+    let mut s = String::from("ABC");
     unsafe {
         let mv = s.as_mut_vec();
         mv.push_all(&[b'D']);
@@ -201,7 +201,7 @@ fn test_push_str() {
 
 #[test]
 fn test_push() {
-    let mut data = String::from_str("ประเทศไทย中");
+    let mut data = String::from("ประเทศไทย中");
     data.push('华');
     data.push('b'); // 1 byte
     data.push('¢'); // 2 byte
@@ -212,7 +212,7 @@ fn test_push() {
 
 #[test]
 fn test_pop() {
-    let mut data = String::from_str("ประเทศไทย中华b¢€𤭢");
+    let mut data = String::from("ประเทศไทย中华b¢€𤭢");
     assert_eq!(data.pop().unwrap(), '𤭢'); // 4 bytes
     assert_eq!(data.pop().unwrap(), '€'); // 3 bytes
     assert_eq!(data.pop().unwrap(), '¢'); // 2 bytes
@@ -223,7 +223,7 @@ fn test_pop() {
 
 #[test]
 fn test_str_truncate() {
-    let mut s = String::from_str("12345");
+    let mut s = String::from("12345");
     s.truncate(5);
     assert_eq!(s, "12345");
     s.truncate(3);
@@ -231,7 +231,7 @@ fn test_str_truncate() {
     s.truncate(0);
     assert_eq!(s, "");
 
-    let mut s = String::from_str("12345");
+    let mut s = String::from("12345");
     let p = s.as_ptr();
     s.truncate(3);
     s.push_str("6");
@@ -242,20 +242,20 @@ fn test_str_truncate() {
 #[test]
 #[should_panic]
 fn test_str_truncate_invalid_len() {
-    let mut s = String::from_str("12345");
+    let mut s = String::from("12345");
     s.truncate(6);
 }
 
 #[test]
 #[should_panic]
 fn test_str_truncate_split_codepoint() {
-    let mut s = String::from_str("\u{FC}"); // ü
+    let mut s = String::from("\u{FC}"); // ü
     s.truncate(1);
 }
 
 #[test]
 fn test_str_clear() {
-    let mut s = String::from_str("12345");
+    let mut s = String::from("12345");
     s.clear();
     assert_eq!(s.len(), 0);
     assert_eq!(s, "");
@@ -263,7 +263,7 @@ fn test_str_clear() {
 
 #[test]
 fn test_str_add() {
-    let a = String::from_str("12345");
+    let a = String::from("12345");
     let b = a + "2";
     let b = b + "2";
     assert_eq!(b.len(), 7);
@@ -365,6 +365,14 @@ fn test_drain() {
     assert_eq!(t, "");
 }
 
+#[test]
+fn test_extend_ref() {
+    let mut a = "foo".to_string();
+    a.extend(&['b', 'a', 'r']);
+
+    assert_eq!(&a, "foobar");
+}
+
 #[bench]
 fn bench_with_capacity(b: &mut Bencher) {
     b.iter(|| {
@@ -473,7 +481,7 @@ fn bench_from_str(b: &mut Bencher) {
     let s = "Hello there, the quick brown fox jumped over the lazy dog! \
              Lorem ipsum dolor sit amet, consectetur. ";
     b.iter(|| {
-        String::from_str(s)
+        String::from(s)
     })
 }
 
index b4d3d0b1a22815d75000a21ceeff7ee5ac45ad58..8df2398c97e0d9d72f72d47df5d820e0017a6242 100644 (file)
@@ -112,6 +112,21 @@ fn test_extend() {
     assert_eq!(v, w);
 }
 
+#[test]
+fn test_extend_ref() {
+    let mut v = vec![1, 2];
+    v.extend(&[3, 4, 5]);
+
+    assert_eq!(v.len(), 5);
+    assert_eq!(v, [1, 2, 3, 4, 5]);
+
+    let w = vec![6, 7];
+    v.extend(&w);
+
+    assert_eq!(v.len(), 7);
+    assert_eq!(v, [1, 2, 3, 4, 5, 6, 7]);
+}
+
 #[test]
 fn test_slice_from_mut() {
     let mut values = vec![1, 2, 3, 4, 5];
index 7870447281bc1335fc48b1c9e3c3b255f5488753..14a36b7c4db791ae3b2259a90c77515e603aa8a5 100644 (file)
@@ -894,3 +894,29 @@ fn test_retain() {
     let v: Vec<_> = buf.into_iter().collect();
     assert_eq!(&v[..], &[2, 4]);
 }
+
+#[test]
+fn test_extend_ref() {
+    let mut v = VecDeque::new();
+    v.push_back(1);
+    v.extend(&[2, 3, 4]);
+
+    assert_eq!(v.len(), 4);
+    assert_eq!(v[0], 1);
+    assert_eq!(v[1], 2);
+    assert_eq!(v[2], 3);
+    assert_eq!(v[3], 4);
+
+    let mut w = VecDeque::new();
+    w.push_back(5);
+    w.push_back(6);
+    v.extend(&w);
+
+    assert_eq!(v.len(), 6);
+    assert_eq!(v[0], 1);
+    assert_eq!(v[1], 2);
+    assert_eq!(v[2], 3);
+    assert_eq!(v[3], 4);
+    assert_eq!(v[4], 5);
+    assert_eq!(v[5], 6);
+}
index 112b4c03e20e5c354b335d50e8fab0879c842a23..3ab32323603ca1bd096d9e2e9fdc4115b6187457 100644 (file)
@@ -493,6 +493,22 @@ fn test_entry(){
     assert_eq!(map.len(), 6);
 }
 
+#[test]
+fn test_extend_ref() {
+    let mut a = VecMap::new();
+    a.insert(1, "one");
+    let mut b = VecMap::new();
+    b.insert(2, "two");
+    b.insert(3, "three");
+
+    a.extend(&b);
+
+    assert_eq!(a.len(), 3);
+    assert_eq!(a[&1], "one");
+    assert_eq!(a[&2], "two");
+    assert_eq!(a[&3], "three");
+}
+
 mod bench {
     use std::collections::VecMap;
 
index 88a686ec255f34732454abed6f2a643df9c30226..16094f2e6cc3c11078fe9552236824a894497b9e 100644 (file)
     /// A safe swap function:
     ///
     /// ```
-    /// # #![feature(core)]
     /// use std::mem;
     /// use std::ptr;
     ///
     /// Efficiently create a Rust vector from an unsafe buffer:
     ///
     /// ```
-    /// # #![feature(core)]
     /// use std::ptr;
     ///
     /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
index 9337c501a3a68d71953e4d3212427a0c3a4e1a86..b12a1c1ed96bd42e759241224e8d4a20bfd4dd6f 100644 (file)
@@ -326,7 +326,6 @@ fn enumerate(self) -> Enumerate<Self> where Self: Sized {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(core)]
     /// let xs = [100, 200, 300];
     /// let mut it = xs.iter().cloned().peekable();
     /// assert_eq!(*it.peek().unwrap(), 100);
@@ -514,15 +513,13 @@ fn fuse(self) -> Fuse<Self> where Self: Sized {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(core)]
-    ///
     /// let a = [1, 4, 2, 3, 8, 9, 6];
     /// let sum: i32 = a.iter()
     ///                 .map(|x| *x)
     ///                 .inspect(|&x| println!("filtering {}", x))
     ///                 .filter(|&x| x % 2 == 0)
     ///                 .inspect(|&x| println!("{} made it through", x))
-    ///                 .sum();
+    ///                 .fold(0, |sum, i| sum + i);
     /// println!("{}", sum);
     /// ```
     #[inline]
@@ -572,7 +569,6 @@ fn collect<B: FromIterator<Self::Item>>(self) -> B where Self: Sized {
     /// do not.
     ///
     /// ```
-    /// # #![feature(core)]
     /// let vec = vec![1, 2, 3, 4];
     /// let (even, odd): (Vec<_>, Vec<_>) = vec.into_iter().partition(|&n| n % 2 == 0);
     /// assert_eq!(even, [2, 4]);
@@ -897,7 +893,6 @@ fn min_max(mut self) -> MinMaxResult<Self::Item> where Self: Sized, Self::Item:
     ///
     /// ```
     /// # #![feature(core)]
-    ///
     /// let a = [-3_i32, 0, 1, 5, -10];
     /// assert_eq!(*a.iter().max_by(|x| x.abs()).unwrap(), -10);
     /// ```
@@ -926,7 +921,6 @@ fn max_by<B: Ord, F>(self, f: F) -> Option<Self::Item> where
     ///
     /// ```
     /// # #![feature(core)]
-    ///
     /// let a = [-3_i32, 0, 1, 5, -10];
     /// assert_eq!(*a.iter().min_by(|x| x.abs()).unwrap(), 0);
     /// ```
@@ -971,7 +965,6 @@ fn rev(self) -> Rev<Self> where Self: Sized + DoubleEndedIterator {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(core)]
     /// let a = [(1, 2), (3, 4)];
     /// let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip();
     /// assert_eq!(left, [1, 3]);
@@ -1065,7 +1058,6 @@ fn reverse_in_place<'a, T: 'a>(&mut self) where
     ///
     /// ```
     /// # #![feature(core)]
-    ///
     /// let a = [1, 2, 3, 4, 5];
     /// let it = a.iter();
     /// assert_eq!(it.sum::<i32>(), 15);
@@ -1084,7 +1076,6 @@ fn sum<S=<Self as Iterator>::Item>(self) -> S where
     ///
     /// ```
     /// # #![feature(core)]
-    ///
     /// fn factorial(n: u32) -> u32 {
     ///     (1..).take_while(|&i| i <= n).product()
     /// }
@@ -2730,7 +2721,7 @@ impl<A: Step> ops::Range<A> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(step_by, core)]
+    /// # #![feature(step_by)]
     /// for i in (0..10).step_by(2) {
     ///     println!("{}", i);
     /// }
index 64eb75ea530f10f7f5d349a5660c764c4ef9e4b4..b5555fa51197c190444f63e51be7184275c671ab 100644 (file)
@@ -173,12 +173,11 @@ macro_rules! try {
 /// # Examples
 ///
 /// ```
-/// # #![allow(unused_must_use)]
 /// use std::io::Write;
 ///
 /// let mut w = Vec::new();
-/// write!(&mut w, "test");
-/// write!(&mut w, "formatted {}", "arguments");
+/// write!(&mut w, "test").unwrap();
+/// write!(&mut w, "formatted {}", "arguments").unwrap();
 /// ```
 #[macro_export]
 macro_rules! write {
index a819932525bd14259559a5c8fb407fbfa9d1bb42..a11377893713d02a0610645beee045bbd4d0c1a3 100644 (file)
@@ -24,7 +24,6 @@
 use num::flt2dec::bignum::Digit32 as Digit;
 use num::flt2dec::bignum::Big32x36 as Big;
 
-// FIXME(#22540) const ref to static array seems to ICE
 static POW10: [Digit; 10] = [1, 10, 100, 1000, 10000, 100000,
                              1000000, 10000000, 100000000, 1000000000];
 static TWOPOW10: [Digit; 10] = [2, 20, 200, 2000, 20000, 200000,
@@ -328,4 +327,3 @@ pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usi
 
     (len, k)
 }
-
index 220811e9985c33c8843e3ed78e41c450538ef04f..54d3c92eca4666cd6334f4fffcc3a148266e80bf 100644 (file)
@@ -87,7 +87,7 @@ fn normalize_to(&self, e: i16) -> Fp {
     f = ((f << 64 >> (l-1)) + 1) >> 1; e += l - 64
     print '    (%#018x, %5d, %4d),' % (f, e, i)
 */
-// FIXME(#22540) const ref to static array seems to ICE
+
 #[doc(hidden)]
 pub static CACHED_POW10: [(u64, i16, i16); 81] = [ // (f, e, k)
     (0xe61acf033d1a45df, -1087, -308),
@@ -746,4 +746,3 @@ pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usi
         None => fallback(d, buf, limit),
     }
 }
-
index 8d2d725251220d5ee55721256785e198e990aa71..872186c09e255cdd97485fe7e9db9e5c498f3849 100644 (file)
@@ -474,7 +474,6 @@ pub fn map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f:
     /// # Examples
     ///
     /// ```
-    /// # #![feature(core)]
     /// let x = Some("foo");
     /// assert_eq!(x.ok_or(0), Ok("foo"));
     ///
@@ -496,7 +495,6 @@ pub fn ok_or<E>(self, err: E) -> Result<T, E> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(core)]
     /// let x = Some("foo");
     /// assert_eq!(x.ok_or_else(|| 0), Ok("foo"));
     ///
@@ -538,7 +536,6 @@ pub fn iter(&self) -> Iter<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(core)]
     /// let mut x = Some(4);
     /// match x.iter_mut().next() {
     ///     Some(&mut ref mut v) => *v = 42,
index b73807aa317588a7500309bc87b2d8912990875a..1506982586a00a55f819084d2e9f6b5a33b8e849 100644 (file)
@@ -58,6 +58,8 @@ fn test_to_lowercase() {
     fn lower(c: char) -> char {
         let mut it = c.to_lowercase();
         let c = it.next().unwrap();
+        // As of Unicode version 7.0.0, `SpecialCasing.txt` has no lower-case mapping
+        // to multiple code points.
         assert!(it.next().is_none());
         c
     }
@@ -73,29 +75,54 @@ fn lower(c: char) -> char {
     assert_eq!(lower('Μ'), 'μ');
     assert_eq!(lower('Α'), 'α');
     assert_eq!(lower('Σ'), 'σ');
+    assert_eq!(lower('Dž'), 'dž');
+    assert_eq!(lower('fi'), 'fi');
 }
 
 #[test]
 fn test_to_uppercase() {
-    fn upper(c: char) -> char {
-        let mut it = c.to_uppercase();
-        let c = it.next().unwrap();
-        assert!(it.next().is_none());
-        c
+    fn upper(c: char) -> Vec<char> {
+        c.to_uppercase().collect()
     }
-    assert_eq!(upper('a'), 'A');
-    assert_eq!(upper('ö'), 'Ö');
-    assert_eq!(upper('ß'), 'ß'); // not ẞ: Latin capital letter sharp s
-    assert_eq!(upper('ü'), 'Ü');
-    assert_eq!(upper('💩'), '💩');
-
-    assert_eq!(upper('σ'), 'Σ');
-    assert_eq!(upper('τ'), 'Τ');
-    assert_eq!(upper('ι'), 'Ι');
-    assert_eq!(upper('γ'), 'Γ');
-    assert_eq!(upper('μ'), 'Μ');
-    assert_eq!(upper('α'), 'Α');
-    assert_eq!(upper('ς'), 'Σ');
+    assert_eq!(upper('a'), ['A']);
+    assert_eq!(upper('ö'), ['Ö']);
+    assert_eq!(upper('ß'), ['S', 'S']); // not ẞ: Latin capital letter sharp s
+    assert_eq!(upper('ü'), ['Ü']);
+    assert_eq!(upper('💩'), ['💩']);
+
+    assert_eq!(upper('σ'), ['Σ']);
+    assert_eq!(upper('τ'), ['Τ']);
+    assert_eq!(upper('ι'), ['Ι']);
+    assert_eq!(upper('γ'), ['Γ']);
+    assert_eq!(upper('μ'), ['Μ']);
+    assert_eq!(upper('α'), ['Α']);
+    assert_eq!(upper('ς'), ['Σ']);
+    assert_eq!(upper('Dž'), ['DŽ']);
+    assert_eq!(upper('fi'), ['F', 'I']);
+    assert_eq!(upper('ᾀ'), ['Ἀ', 'Ι']);
+}
+
+#[test]
+fn test_to_titlecase() {
+    fn title(c: char) -> Vec<char> {
+        c.to_titlecase().collect()
+    }
+    assert_eq!(title('a'), ['A']);
+    assert_eq!(title('ö'), ['Ö']);
+    assert_eq!(title('ß'), ['S', 's']); // not ẞ: Latin capital letter sharp s
+    assert_eq!(title('ü'), ['Ü']);
+    assert_eq!(title('💩'), ['💩']);
+
+    assert_eq!(title('σ'), ['Σ']);
+    assert_eq!(title('τ'), ['Τ']);
+    assert_eq!(title('ι'), ['Ι']);
+    assert_eq!(title('γ'), ['Γ']);
+    assert_eq!(title('μ'), ['Μ']);
+    assert_eq!(title('α'), ['Α']);
+    assert_eq!(title('ς'), ['Σ']);
+    assert_eq!(title('DŽ'), ['Dž']);
+    assert_eq!(title('fi'), ['F', 'i']);
+    assert_eq!(title('ᾀ'), ['ᾈ']);
 }
 
 #[test]
index 9ea680c7efe7643c8bab6a4717333931bb3d49bd..5d38a381e6b7e878dbc464ae3acd8e265599c86c 100644 (file)
@@ -17,7 +17,7 @@ pub struct LogDirective {
     pub level: u32,
 }
 
-pub static LOG_LEVEL_NAMES: [&'static str; 4] = ["ERROR", "WARN", "INFO",
+pub const LOG_LEVEL_NAMES: [&'static str; 4] = ["ERROR", "WARN", "INFO",
                                                "DEBUG"];
 
 /// Parse an individual log level that is either a number or a symbolic log level
index a108fd70d1ca9d6410eb60bc1f048dbacf68b211..b6de4bf892cdfb658def734e365de8eaf9aa0bea 100644 (file)
@@ -12,7 +12,7 @@
 // algorithm. Autogenerated by `ziggurat_tables.py`.
 
 pub type ZigTable = &'static [f64; 257];
-pub static ZIG_NORM_R: f64 = 3.654152885361008796;
+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,
      0.887984660763399880, 0.898095921906304051, 0.908726440060562912, 0.919991505048360247,
      0.932060075968990209, 0.945198953453078028, 0.959879091812415930, 0.977101701282731328,
      1.000000000000000000];
-pub static ZIG_EXP_R: f64 = 7.697117470131050077;
+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,
index 5e79e5a5a4ed2edf6b1a7623d4ab8bc5b9faf75a..9a60e2378cca62976c9e8b85d917d4ecc8896e83 100644 (file)
@@ -227,6 +227,25 @@ fn index<'a>(&'a self, idx: u8) -> &'a u8 { &self.a }
 ```
 "##,
 
+E0014: r##"
+Constants can only be initialized by a constant value or, in a future
+version of Rust, a call to a const function. This error indicates the use
+of a path (like a::b, or x) denoting something other than one of these
+allowed items. Example:
+
+```
+const FOO: i32 = { let x = 0; x }; // 'x' isn't a constant nor a function!
+```
+
+To avoid it, you have to replace the non-constant value:
+
+```
+const FOO: i32 = { const X : i32 = 0; X };
+// or even:
+const FOO: i32 = { 0 }; // but brackets are useless here
+```
+"##,
+
 E0015: r##"
 The only functions that can be called in static or constant expressions are
 `const` functions. Rust currently does not support more general compile-time
@@ -559,7 +578,7 @@ fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
 
 foo(3_i8);
 // Here, we invoke `foo` with an `i8`, which does not satisfy
-// the constraint `<i8 as Trait>::AssociatedType=32`, and
+// the constraint `<i8 as Trait>::AssociatedType=u32`, and
 // therefore the type-checker complains with this error code.
 ```
 
@@ -931,7 +950,6 @@ fn bar(&self) -> i32 { self.0 }
 
 
 register_diagnostics! {
-    E0014,
     E0016,
     E0017,
     E0019,
index 498b2ce518c16dc6055166053e19ed7ac5cb8b20..62dc8f77693987d17e10c0961129b281a8f04388 100644 (file)
@@ -101,9 +101,8 @@ macro_rules! declare_lint {
 #[macro_export]
 macro_rules! lint_array { ($( $lint:expr ),*) => (
     {
-        #[allow(non_upper_case_globals)]
-        static array: LintArray = &[ $( &$lint ),* ];
-        array
+        static ARRAY: LintArray = &[ $( &$lint ),* ];
+        ARRAY
     }
 ) }
 
index f96094d3d090db01b058d3c7861801c0172211b2..5f1e30ae63a1920b84488e83224938490c31a1ca 100644 (file)
@@ -429,13 +429,14 @@ fn find_library_crate(&mut self) -> Option<Library> {
             let slot = candidates.entry(hash_str)
                                  .or_insert_with(|| (HashMap::new(), HashMap::new()));
             let (ref mut rlibs, ref mut dylibs) = *slot;
-            if rlib {
-                rlibs.insert(fs::canonicalize(path).unwrap(), kind);
-            } else {
-                dylibs.insert(fs::canonicalize(path).unwrap(), kind);
-            }
-
-            FileMatches
+            fs::canonicalize(path).map(|p| {
+                if rlib {
+                    rlibs.insert(p, kind);
+                } else {
+                    dylibs.insert(p, kind);
+                }
+                FileMatches
+            }).unwrap_or(FileDoesntMatch)
         });
         self.rejected_via_kind.extend(staticlibs.into_iter());
 
index 223a5eef614c1acc4aacf62e4369be359f7e36cc..6d83ab152d5bcb576146e647cb1bf5442b0dbe8c 100644 (file)
@@ -50,9 +50,6 @@ pub enum DefIdSource {
     // Identifies a type alias (`type X = ...`).
     TypeWithId,
 
-    // Identifies a type parameter (`fn foo<X>() { ... }`).
-    TypeParameter,
-
     // Identifies a region parameter (`fn foo<'X>() { ... }`).
     RegionParameter,
 
@@ -193,7 +190,7 @@ pub fn parse_substs_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: us
                                   tcx: &ty::ctxt<'tcx>, conv: F) -> subst::Substs<'tcx> where
     F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
 {
-    debug!("parse_substs_data {}", data_log_string(data, pos));
+    debug!("parse_substs_data{}", data_log_string(data, pos));
     let mut st = parse_state_from_data(data, crate_num, pos, tcx);
     parse_substs(&mut st, conv)
 }
@@ -542,7 +539,14 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w
                                          len: len };
 
         match tcx.rcache.borrow().get(&key).cloned() {
-          Some(tt) => return tt,
+          Some(tt) => {
+            // If there is a closure buried in the type some where, then we
+            // need to re-convert any def ids (see case 'k', below). That means
+            // we can't reuse the cached version.
+            if !ty::type_has_ty_closure(tt) {
+                return tt;
+            }
+          }
           None => {}
         }
         let mut ps = PState {
index fda57c9dc610a5a222bc6faba121920b5ce07b77..3242dafbd1cc14975b3c44afafa7c3cbb7c8f2d9 100644 (file)
@@ -20,7 +20,7 @@
 use metadata::encoder as e;
 use middle::region;
 use metadata::tydecode;
-use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter};
+use metadata::tydecode::{DefIdSource, NominalType, TypeWithId};
 use metadata::tydecode::{RegionParameter, ClosureSource};
 use metadata::tyencode;
 use middle::cast;
@@ -346,13 +346,6 @@ fn read_def_id_nodcx(&mut self,
 // ______________________________________________________________________
 // Encoding and decoding the AST itself
 //
-// The hard work is done by an autogenerated module astencode_gen.  To
-// regenerate astencode_gen, run src/etc/gen-astencode.  It will
-// replace astencode_gen with a dummy file and regenerate its
-// contents.  If you get compile errors, the dummy file
-// remains---resolve the errors and then rerun astencode_gen.
-// Annoying, I know, but hopefully only temporary.
-//
 // When decoding, we have to renumber the AST so that the node ids that
 // appear within are disjoint from the node ids in our existing ASTs.
 // We also have to adjust the spans: for now we just insert a dummy span,
@@ -656,35 +649,6 @@ fn read_method_callee<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
     }
 }
 
-impl<'tcx> tr for MethodOrigin<'tcx> {
-    fn tr(&self, dcx: &DecodeContext) -> MethodOrigin<'tcx> {
-        match *self {
-            ty::MethodStatic(did) => ty::MethodStatic(did.tr(dcx)),
-            ty::MethodStaticClosure(did) => {
-                ty::MethodStaticClosure(did.tr(dcx))
-            }
-            ty::MethodTypeParam(ref mp) => {
-                ty::MethodTypeParam(
-                    ty::MethodParam {
-                        // def-id is already translated when we read it out
-                        trait_ref: mp.trait_ref.clone(),
-                        method_num: mp.method_num,
-                        impl_def_id: mp.impl_def_id.tr(dcx),
-                    }
-                )
-            }
-            ty::MethodTraitObject(ref mo) => {
-                ty::MethodTraitObject(
-                    ty::MethodObject {
-                        trait_ref: mo.trait_ref.clone(),
-                        .. *mo
-                    }
-                )
-            }
-        }
-    }
-}
-
 pub fn encode_closure_kind(ebml_w: &mut Encoder, kind: ty::ClosureKind) {
     kind.encode(ebml_w).unwrap();
 }
@@ -1473,10 +1437,10 @@ fn read_substs<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
                            -> subst::Substs<'tcx> {
         self.read_opaque(|this, doc| {
             Ok(tydecode::parse_substs_data(doc.data,
-                                        dcx.cdata.cnum,
-                                        doc.start,
-                                        dcx.tcx,
-                                        |s, a| this.convert_def_id(dcx, s, a)))
+                                           dcx.cdata.cnum,
+                                           doc.start,
+                                           dcx.tcx,
+                                           |s, a| this.convert_def_id(dcx, s, a)))
         }).unwrap()
     }
 
@@ -1617,7 +1581,7 @@ fn convert_def_id(&mut self,
                       -> ast::DefId {
         let r = match source {
             NominalType | TypeWithId | RegionParameter => dcx.tr_def_id(did),
-            TypeParameter | ClosureSource => dcx.tr_intern_def_id(did)
+            ClosureSource => dcx.tr_intern_def_id(did)
         };
         debug!("convert_def_id(source={:?}, did={:?})={:?}", source, did, r);
         return r;
index 4ec5cf03364973d241a6c1a19242dc62a522f617..c9a863c096352a944a26f9f8b3e9b490ae80666e 100644 (file)
@@ -1783,7 +1783,7 @@ fn inc_counter(&self) {
     fn give_lifetime(&self) -> ast::Lifetime {
         let mut lifetime;
         loop {
-            let mut s = String::from_str("'");
+            let mut s = String::from("'");
             s.push_str(&num_to_string(self.counter.get()));
             if !self.taken.contains(&s) {
                 lifetime = name_to_dummy_lifetime(
index 111cf68726c61b61d47ee21222dda8ab0adab60e..8783577945ce470ccb938b8c8fce61bf2b249135 100644 (file)
@@ -104,6 +104,10 @@ fn fold_region(&mut self, r: ty::Region) -> ty::Region {
     }
 
     fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
+        if !ty::type_needs_infer(t) && !ty::type_has_erasable_regions(t) {
+            return t;
+        }
+
         let tcx = self.infcx.tcx;
 
         match t.sty {
index b0940aa7ec0ac823afccc51d440547dacd80c898..7fd4a14b25b453c947a32fa4ebfb53a3b012acfd 100644 (file)
@@ -530,7 +530,7 @@ pub fn skolemize_late_bound_regions<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
      * details.
      */
 
-    let (result, map) = ty::replace_late_bound_regions(infcx.tcx, binder, |br| {
+    let (result, map) = ty_fold::replace_late_bound_regions(infcx.tcx, binder, |br| {
         infcx.region_vars.new_skolemized(br, &snapshot.region_vars_snapshot)
     });
 
index b802f46e28594184eeb8c51853e5d880902dead1..b3c4dd68dbaf7675dda65770401534c11a85fa98 100644 (file)
@@ -26,9 +26,8 @@
 use middle::subst;
 use middle::subst::Substs;
 use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric};
-use middle::ty::replace_late_bound_regions;
 use middle::ty::{self, Ty};
-use middle::ty_fold::{TypeFolder, TypeFoldable};
+use middle::ty_fold::{self, TypeFolder, TypeFoldable};
 use middle::ty_relate::{Relate, RelateResult, TypeRelation};
 use rustc_data_structures::unify::{self, UnificationTable};
 use std::cell::{RefCell};
@@ -1038,7 +1037,7 @@ pub fn replace_late_bound_regions_with_fresh_var<T>(
         -> (T, FnvHashMap<ty::BoundRegion,ty::Region>)
         where T : TypeFoldable<'tcx> + Repr<'tcx>
     {
-        ty::replace_late_bound_regions(
+        ty_fold::replace_late_bound_regions(
             self.tcx,
             value,
             |br| self.next_region_var(LateBoundRegion(span, br, lbrct)))
index 9c47d7f217aac183d663e3bc3b65b86aa740bc22..853d12172af5ef67010e6db28f4f987958d099c0 100644 (file)
@@ -120,7 +120,7 @@ implement `Convert` like so:
 
 ```rust
 impl Convert<uint> for int { ... } // int -> uint
-impl Convert<int> for uint { ... } // uint -> uint
+impl Convert<int> for uint { ... } // uint -> int
 ```
 
 Now imagine there is some code like the following:
index b568d40ba1c99d5890422affcae0861cce228054..789d4f8b9d31096c5f457decce6925afac512eb4 100644 (file)
@@ -1663,11 +1663,11 @@ fn builtin_bound(&mut self,
             }
 
             ty::ty_vec(element_ty, ref len) => {
-                // [T, ..n] and [T]
+                // [Tn] and [T]
                 match bound {
                     ty::BoundCopy => {
                         match *len {
-                            // [T, ..n] is copy iff T is copy
+                            // [Tn] is copy iff T is copy
                             Some(_) => ok_if(vec![element_ty]),
 
                             // [T] is unsized and hence affine
@@ -2523,41 +2523,57 @@ fn confirm_builtin_unsize_candidate(&mut self,
                     ty::lookup_field_type_unsubstituted(tcx, def_id, f.id)
                 }).collect::<Vec<_>>();
 
-                // FIXME(#25351) The last field of the structure has to exist and be a
-                // type parameter (for now, to avoid tracking edge cases).
-                let i = if let Some(&ty::ty_param(p)) = fields.last().map(|ty| &ty.sty) {
-                    assert!(p.space == TypeSpace);
-                    p.idx as usize
+                // The last field of the structure has to exist and contain type parameters.
+                let field = if let Some(&field) = fields.last() {
+                    field
                 } else {
                     return Err(Unimplemented);
                 };
+                let mut ty_params = vec![];
+                ty::walk_ty(field, |ty| {
+                    if let ty::ty_param(p) = ty.sty {
+                        assert!(p.space == TypeSpace);
+                        let idx = p.idx as usize;
+                        if !ty_params.contains(&idx) {
+                            ty_params.push(idx);
+                        }
+                    }
+                });
+                if ty_params.is_empty() {
+                    return Err(Unimplemented);
+                }
 
-                // Replace the type parameter chosen for unsizing with
-                // ty_err and ensure it does not affect any other fields.
+                // Replace type parameters used in unsizing with
+                // ty_err and ensure they do not affect any other fields.
                 // This could be checked after type collection for any struct
                 // with a potentially unsized trailing field.
                 let mut new_substs = substs_a.clone();
-                new_substs.types.get_mut_slice(TypeSpace)[i] = tcx.types.err;
+                for &i in &ty_params {
+                    new_substs.types.get_mut_slice(TypeSpace)[i] = tcx.types.err;
+                }
                 for &ty in fields.init() {
                     if ty::type_is_error(ty.subst(tcx, &new_substs)) {
                         return Err(Unimplemented);
                     }
                 }
 
-                // Extract T and U from Struct<T> and Struct<U>.
-                let inner_source = *substs_a.types.get(TypeSpace, i);
-                let inner_target = *substs_b.types.get(TypeSpace, i);
+                // Extract Field<T> and Field<U> from Struct<T> and Struct<U>.
+                let inner_source = field.subst(tcx, substs_a);
+                let inner_target = field.subst(tcx, substs_b);
 
-                // Check that all the source structure with the unsized
-                // type parameter is a subtype of the target.
-                new_substs.types.get_mut_slice(TypeSpace)[i] = inner_target;
+                // Check that the source structure with the target's
+                // type parameters is a subtype of the target.
+                for &i in &ty_params {
+                    let param_b = *substs_b.types.get(TypeSpace, i);
+                    new_substs.types.get_mut_slice(TypeSpace)[i] = param_b;
+                }
                 let new_struct = ty::mk_struct(tcx, def_id, tcx.mk_substs(new_substs));
                 let origin = infer::Misc(obligation.cause.span);
                 if self.infcx.sub_types(false, origin, new_struct, target).is_err() {
                     return Err(Unimplemented);
                 }
 
-                // Construct the nested T: Unsize<U> predicate.
+                // Construct the nested Field<T>: Unsize<Field<U>> predicate.
                 nested.push(util::predicate_for_trait_def(tcx,
                     obligation.cause.clone(),
                     obligation.predicate.def_id(),
index ee2189c769aa0eae80c8e43aeb402d38e15b468e..2fd9dfb9d02362622d30e3e1ec9f59f3ed1dd723 100644 (file)
@@ -806,28 +806,31 @@ pub fn free_region_map(&self, id: NodeId) -> FreeRegionMap {
 // recursing over the type itself.
 bitflags! {
     flags TypeFlags: u32 {
-        const HAS_PARAMS        = 1 << 0,
-        const HAS_SELF          = 1 << 1,
-        const HAS_TY_INFER      = 1 << 2,
-        const HAS_RE_INFER      = 1 << 3,
-        const HAS_RE_LATE_BOUND = 1 << 4,
-        const HAS_REGIONS       = 1 << 5,
-        const HAS_TY_ERR        = 1 << 6,
-        const HAS_PROJECTION    = 1 << 7,
-        const NEEDS_SUBST       = TypeFlags::HAS_PARAMS.bits |
-                                  TypeFlags::HAS_SELF.bits |
-                                  TypeFlags::HAS_REGIONS.bits,
+        const HAS_PARAMS         = 1 << 0,
+        const HAS_SELF           = 1 << 1,
+        const HAS_TY_INFER       = 1 << 2,
+        const HAS_RE_INFER       = 1 << 3,
+        const HAS_RE_EARLY_BOUND = 1 << 4,
+        const HAS_FREE_REGIONS   = 1 << 5,
+        const HAS_TY_ERR         = 1 << 6,
+        const HAS_PROJECTION     = 1 << 7,
+        const HAS_TY_CLOSURE     = 1 << 8,
+        const NEEDS_SUBST        = TypeFlags::HAS_PARAMS.bits |
+                                   TypeFlags::HAS_SELF.bits |
+                                   TypeFlags::HAS_RE_EARLY_BOUND.bits,
 
         // Flags representing the nominal content of a type,
-        // computed by FlagsComputetion
+        // computed by FlagsComputation. If you add a new nominal
+        // flag, it should be added here too.
         const NOMINAL_FLAGS     = TypeFlags::HAS_PARAMS.bits |
                                   TypeFlags::HAS_SELF.bits |
                                   TypeFlags::HAS_TY_INFER.bits |
                                   TypeFlags::HAS_RE_INFER.bits |
-                                  TypeFlags::HAS_RE_LATE_BOUND.bits |
-                                  TypeFlags::HAS_REGIONS.bits |
+                                  TypeFlags::HAS_RE_EARLY_BOUND.bits |
+                                  TypeFlags::HAS_FREE_REGIONS.bits |
                                   TypeFlags::HAS_TY_ERR.bits |
-                                  TypeFlags::HAS_PROJECTION.bits,
+                                  TypeFlags::HAS_PROJECTION.bits |
+                                  TypeFlags::HAS_TY_CLOSURE.bits,
 
         // Caches for type_is_sized, type_moves_by_default
         const SIZEDNESS_CACHED  = 1 << 16,
@@ -985,9 +988,14 @@ pub fn type_needs_infer(ty: Ty) -> bool {
 pub fn type_has_projection(ty: Ty) -> bool {
     ty.flags.get().intersects(TypeFlags::HAS_PROJECTION)
 }
+pub fn type_has_ty_closure(ty: Ty) -> bool {
+    ty.flags.get().intersects(TypeFlags::HAS_TY_CLOSURE)
+}
 
-pub fn type_has_late_bound_regions(ty: Ty) -> bool {
-    ty.flags.get().intersects(TypeFlags::HAS_RE_LATE_BOUND)
+pub fn type_has_erasable_regions(ty: Ty) -> bool {
+    ty.flags.get().intersects(TypeFlags::HAS_RE_EARLY_BOUND |
+                              TypeFlags::HAS_RE_INFER |
+                              TypeFlags::HAS_FREE_REGIONS)
 }
 
 /// An "escaping region" is a bound region whose binder is not part of `t`.
@@ -2960,6 +2968,7 @@ fn add_sty(&mut self, st: &sty) {
             }
 
             &ty_closure(_, substs) => {
+                self.add_flags(TypeFlags::HAS_TY_CLOSURE);
                 self.add_substs(substs);
             }
 
@@ -2982,7 +2991,7 @@ fn add_sty(&mut self, st: &sty) {
                 for projection_bound in &bounds.projection_bounds {
                     let mut proj_computation = FlagComputation::new();
                     proj_computation.add_projection_predicate(&projection_bound.0);
-                    computation.add_bound_computation(&proj_computation);
+                    self.add_bound_computation(&proj_computation);
                 }
                 self.add_bound_computation(&computation);
 
@@ -3036,14 +3045,12 @@ fn add_fn_sig(&mut self, fn_sig: &PolyFnSig) {
     }
 
     fn add_region(&mut self, r: Region) {
-        self.add_flags(TypeFlags::HAS_REGIONS);
         match r {
             ty::ReInfer(_) => { self.add_flags(TypeFlags::HAS_RE_INFER); }
-            ty::ReLateBound(debruijn, _) => {
-                self.add_flags(TypeFlags::HAS_RE_LATE_BOUND);
-                self.add_depth(debruijn.depth);
-            }
-            _ => { }
+            ty::ReLateBound(debruijn, _) => { self.add_depth(debruijn.depth); }
+            ty::ReEarlyBound(..) => { self.add_flags(TypeFlags::HAS_RE_EARLY_BOUND); }
+            ty::ReStatic => {}
+            _ => { self.add_flags(TypeFlags::HAS_FREE_REGIONS); }
         }
     }
 
@@ -6989,7 +6996,7 @@ pub fn liberate_late_bound_regions<'tcx, T>(
     -> T
     where T : TypeFoldable<'tcx> + Repr<'tcx>
 {
-    replace_late_bound_regions(
+    ty_fold::replace_late_bound_regions(
         tcx, value,
         |br| ty::ReFree(ty::FreeRegion{scope: all_outlive_scope, bound_region: br})).0
 }
@@ -7000,7 +7007,7 @@ pub fn count_late_bound_regions<'tcx, T>(
     -> usize
     where T : TypeFoldable<'tcx> + Repr<'tcx>
 {
-    let (_, skol_map) = replace_late_bound_regions(tcx, value, |_| ty::ReStatic);
+    let (_, skol_map) = ty_fold::replace_late_bound_regions(tcx, value, |_| ty::ReStatic);
     skol_map.len()
 }
 
@@ -7058,7 +7065,7 @@ pub fn erase_late_bound_regions<'tcx, T>(
     -> T
     where T : TypeFoldable<'tcx> + Repr<'tcx>
 {
-    replace_late_bound_regions(tcx, value, |_| ty::ReStatic).0
+    ty_fold::replace_late_bound_regions(tcx, value, |_| ty::ReStatic).0
 }
 
 /// Rewrite any late-bound regions so that they are anonymous.  Region numbers are
@@ -7076,53 +7083,12 @@ pub fn anonymize_late_bound_regions<'tcx, T>(
     where T : TypeFoldable<'tcx> + Repr<'tcx>,
 {
     let mut counter = 0;
-    ty::Binder(replace_late_bound_regions(tcx, sig, |_| {
+    ty::Binder(ty_fold::replace_late_bound_regions(tcx, sig, |_| {
         counter += 1;
         ReLateBound(ty::DebruijnIndex::new(1), BrAnon(counter))
     }).0)
 }
 
-/// Replaces the late-bound-regions in `value` that are bound by `value`.
-pub fn replace_late_bound_regions<'tcx, T, F>(
-    tcx: &ty::ctxt<'tcx>,
-    binder: &Binder<T>,
-    mut mapf: F)
-    -> (T, FnvHashMap<ty::BoundRegion,ty::Region>)
-    where T : TypeFoldable<'tcx> + Repr<'tcx>,
-          F : FnMut(BoundRegion) -> ty::Region,
-{
-    debug!("replace_late_bound_regions({})", binder.repr(tcx));
-
-    let mut map = FnvHashMap();
-
-    // Note: fold the field `0`, not the binder, so that late-bound
-    // regions bound by `binder` are considered free.
-    let value = ty_fold::fold_regions(tcx, &binder.0, |region, current_depth| {
-        debug!("region={}", region.repr(tcx));
-        match region {
-            ty::ReLateBound(debruijn, br) if debruijn.depth == current_depth => {
-                let region = *map.entry(br).or_insert_with(|| mapf(br));
-
-                if let ty::ReLateBound(debruijn1, br) = region {
-                    // If the callback returns a late-bound region,
-                    // that region should always use depth 1. Then we
-                    // adjust it to the correct depth.
-                    assert_eq!(debruijn1.depth, 1);
-                    ty::ReLateBound(debruijn, br)
-                } else {
-                    region
-                }
-            }
-            _ => {
-                region
-            }
-        }
-    });
-
-    debug!("resulting map: {:?} value: {:?}", map, value.repr(tcx));
-    (value, map)
-}
-
 impl DebruijnIndex {
     pub fn new(depth: u32) -> DebruijnIndex {
         assert!(depth > 0);
index 6f098a53238b68ee2d7a122145564b68550910bf..884fc9571ce1f886854156516d815d09d1b91403 100644 (file)
@@ -42,6 +42,7 @@
 use syntax::abi;
 use syntax::ast;
 use syntax::owned_slice::OwnedSlice;
+use util::nodemap::FnvHashMap;
 use util::ppaux::Repr;
 
 ///////////////////////////////////////////////////////////////////////////
@@ -841,6 +842,86 @@ fn fold_region(&mut self, r: ty::Region) -> ty::Region {
     }
 }
 
+///////////////////////////////////////////////////////////////////////////
+// Late-bound region replacer
+
+// Replaces the escaping regions in a type.
+
+struct RegionReplacer<'a, 'tcx: 'a> {
+    tcx: &'a ty::ctxt<'tcx>,
+    current_depth: u32,
+    fld_r: &'a mut (FnMut(ty::BoundRegion) -> ty::Region + 'a),
+    map: FnvHashMap<ty::BoundRegion, ty::Region>
+}
+
+impl<'a, 'tcx> RegionReplacer<'a, 'tcx> {
+    fn new<F>(tcx: &'a ty::ctxt<'tcx>, fld_r: &'a mut F) -> RegionReplacer<'a, 'tcx>
+        where F : FnMut(ty::BoundRegion) -> ty::Region
+    {
+        RegionReplacer {
+            tcx: tcx,
+            current_depth: 1,
+            fld_r: fld_r,
+            map: FnvHashMap()
+        }
+    }
+}
+
+pub fn replace_late_bound_regions<'tcx,T,F>(tcx: &ty::ctxt<'tcx>,
+                                            value: &ty::Binder<T>,
+                                            mut f: F)
+                                            -> (T, FnvHashMap<ty::BoundRegion, ty::Region>)
+    where F : FnMut(ty::BoundRegion) -> ty::Region,
+          T : TypeFoldable<'tcx> + Repr<'tcx>,
+{
+    debug!("replace_late_bound_regions({})", value.repr(tcx));
+    let mut replacer = RegionReplacer::new(tcx, &mut f);
+    let result = value.skip_binder().fold_with(&mut replacer);
+    (result, replacer.map)
+}
+
+impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx>
+{
+    fn tcx(&self) -> &ty::ctxt<'tcx> { self.tcx }
+
+    fn enter_region_binder(&mut self) {
+        self.current_depth += 1;
+    }
+
+    fn exit_region_binder(&mut self) {
+        self.current_depth -= 1;
+    }
+
+    fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
+        if !ty::type_escapes_depth(t, self.current_depth-1) {
+            return t;
+        }
+
+        super_fold_ty(self, t)
+    }
+
+    fn fold_region(&mut self, r: ty::Region) -> ty::Region {
+        match r {
+            ty::ReLateBound(debruijn, br) if debruijn.depth == self.current_depth => {
+                debug!("RegionReplacer.fold_region({}) folding region (current_depth={})",
+                       r.repr(self.tcx()), self.current_depth);
+                let fld_r = &mut self.fld_r;
+                let region = *self.map.entry(br).or_insert_with(|| fld_r(br));
+                if let ty::ReLateBound(debruijn1, br) = region {
+                    // If the callback returns a late-bound region,
+                    // that region should always use depth 1. Then we
+                    // adjust it to the correct depth.
+                    assert_eq!(debruijn1.depth, 1);
+                    ty::ReLateBound(debruijn, br)
+                } else {
+                    region
+                }
+            }
+            r => r
+        }
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // Region eraser
 //
@@ -861,6 +942,14 @@ pub fn erase_regions<'tcx, T: TypeFoldable<'tcx>>(tcx: &ty::ctxt<'tcx>, t: T) ->
 impl<'a, 'tcx> TypeFolder<'tcx> for RegionEraser<'a, 'tcx> {
     fn tcx(&self) -> &ty::ctxt<'tcx> { self.tcx }
 
+    fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
+        if !ty::type_has_erasable_regions(t) {
+            return t;
+        }
+
+        super_fold_ty(self, t)
+    }
+
     fn fold_region(&mut self, r: ty::Region) -> ty::Region {
         // because whether or not a region is bound affects subtyping,
         // we can't erase the bound/free distinction, but we can
index 6f71def11886da32fed990dabdf87b97354164f1..3532bcdb279a92379f0922335de0b681ee69b8e8 100644 (file)
@@ -24,7 +24,7 @@
 use middle::ty::ty_closure;
 use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer};
 use middle::ty;
-use middle::ty_fold::TypeFoldable;
+use middle::ty_fold::{self, TypeFoldable};
 
 use std::collections::HashMap;
 use std::collections::hash_state::HashState;
@@ -304,11 +304,18 @@ fn bare_fn_to_string<'tcx>(cx: &ctxt<'tcx>,
         s
     }
 
-    fn closure_to_string<'tcx>(cx: &ctxt<'tcx>, cty: &ty::ClosureTy<'tcx>) -> String {
+    fn closure_to_string<'tcx>(cx: &ctxt<'tcx>,
+                               cty: &ty::ClosureTy<'tcx>,
+                               did: &ast::DefId)
+                               -> String {
         let mut s = String::new();
         s.push_str("[closure");
         push_sig_to_string(cx, &mut s, '(', ')', &cty.sig);
-        s.push(']');
+        if cx.sess.verbose() {
+            s.push_str(&format!(" id={:?}]", did));
+        } else {
+            s.push(']');
+        }
         s
     }
 
@@ -407,13 +414,20 @@ fn infer_ty_to_string(cx: &ctxt, ty: ty::InferTy) -> String {
         ty_closure(ref did, substs) => {
             let closure_tys = cx.closure_tys.borrow();
             closure_tys.get(did).map(|closure_type| {
-                closure_to_string(cx, &closure_type.subst(cx, substs))
+                closure_to_string(cx, &closure_type.subst(cx, substs), did)
             }).unwrap_or_else(|| {
+                let id_str = if cx.sess.verbose() {
+                    format!(" id={:?}", did)
+                } else {
+                    "".to_owned()
+                };
+
+
                 if did.krate == ast::LOCAL_CRATE {
                     let span = cx.map.span(did.node);
-                    format!("[closure {}]", span.repr(cx))
+                    format!("[closure {}{}]", span.repr(cx), id_str)
                 } else {
-                    format!("[closure]")
+                    format!("[closure{}]", id_str)
                 }
             })
         }
@@ -1287,7 +1301,7 @@ fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
         // the output. We'll probably want to tweak this over time to
         // decide just how much information to give.
         let mut names = Vec::new();
-        let (unbound_value, _) = ty::replace_late_bound_regions(tcx, self, |br| {
+        let (unbound_value, _) = ty_fold::replace_late_bound_regions(tcx, self, |br| {
             ty::ReLateBound(ty::DebruijnIndex::new(1), match br {
                 ty::BrNamed(_, name) => {
                     names.push(token::get_name(name));
index 22d966014da1c348b7048a731dff9ab5a2623858..402fbcd8d8d8e6ebf74007072b47f546314cb38b 100644 (file)
@@ -272,6 +272,7 @@ macro_rules! key {
         }
 
         key!(cpu);
+        key!(ar);
         key!(linker);
         key!(relocation_model);
         key!(code_model);
index 1343453d103ad148f09e1ca7fcdb8d31ab268feb..1737de827e3cead9414212814a613d4eeb0decc0 100644 (file)
@@ -32,7 +32,7 @@
 
 #![feature(box_patterns)]
 #![feature(box_syntax)]
-#![feature(collections)]
+#![cfg_attr(stage0, feature(collections))]
 #![feature(core)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
index a3b9a0e846700bf51d90b7a63c984b022a94d986..4d7f00e95230aa17a5b933217acf0f9dcfad0c1a 100644 (file)
@@ -478,9 +478,6 @@ pub enum Builder_opaque {}
 pub enum ExecutionEngine_opaque {}
 pub type ExecutionEngineRef = *mut ExecutionEngine_opaque;
 #[allow(missing_copy_implementations)]
-pub enum RustJITMemoryManager_opaque {}
-pub type RustJITMemoryManagerRef = *mut RustJITMemoryManager_opaque;
-#[allow(missing_copy_implementations)]
 pub enum MemoryBuffer_opaque {}
 pub type MemoryBufferRef = *mut MemoryBuffer_opaque;
 #[allow(missing_copy_implementations)]
@@ -1090,10 +1087,7 @@ pub fn LLVMInsertIntoBuilderWithName(Builder: BuilderRef,
     pub fn LLVMDisposeBuilder(Builder: BuilderRef);
 
     /* Execution engine */
-    pub fn LLVMRustCreateJITMemoryManager(morestack: *const ())
-                                          -> RustJITMemoryManagerRef;
-    pub fn LLVMBuildExecutionEngine(Mod: ModuleRef,
-                                    MM: RustJITMemoryManagerRef) -> ExecutionEngineRef;
+    pub fn LLVMBuildExecutionEngine(Mod: ModuleRef) -> ExecutionEngineRef;
     pub fn LLVMDisposeExecutionEngine(EE: ExecutionEngineRef);
     pub fn LLVMExecutionEngineFinalizeObject(EE: ExecutionEngineRef);
     pub fn LLVMRustLoadDynamicLibrary(path: *const c_char) -> Bool;
@@ -1772,6 +1766,8 @@ pub fn LLVMInlineAsm(Ty: TypeRef,
                          -> ValueRef;
 
     pub fn LLVMRustDebugMetadataVersion() -> u32;
+    pub fn LLVMVersionMajor() -> u32;
+    pub fn LLVMVersionMinor() -> u32;
 
     pub fn LLVMRustAddModuleFlag(M: ModuleRef,
                                  name: *const c_char,
index cae0c7c7f5792ac8322ea88104d9b68544700318..ba8680a35cb4be3d862d7bce5b495cedc3e6ac3e 100644 (file)
@@ -3206,14 +3206,11 @@ fn is_static_method(this: &Resolver, did: DefId) -> bool {
         NoSuggestion
     }
 
-    fn find_best_match_for_name(&mut self, name: &str, max_distance: usize)
-                                -> Option<String> {
-        let this = &mut *self;
-
+    fn find_best_match_for_name(&mut self, name: &str) -> Option<String> {
         let mut maybes: Vec<token::InternedString> = Vec::new();
         let mut values: Vec<usize> = Vec::new();
 
-        for rib in this.value_ribs.iter().rev() {
+        for rib in self.value_ribs.iter().rev() {
             for (&k, _) in &rib.bindings {
                 maybes.push(token::get_name(k));
                 values.push(usize::MAX);
@@ -3229,9 +3226,12 @@ fn find_best_match_for_name(&mut self, name: &str, max_distance: usize)
             }
         }
 
+        // As a loose rule to avoid obviously incorrect suggestions, clamp the
+        // maximum edit distance we will accept for a suggestion to one third of
+        // the typo'd name's length.
+        let max_distance = std::cmp::max(name.len(), 3) / 3;
+
         if !values.is_empty() &&
-            values[smallest] != usize::MAX &&
-            values[smallest] < name.len() + 2 &&
             values[smallest] <= max_distance &&
             name != &maybes[smallest][..] {
 
@@ -3357,7 +3357,7 @@ fn resolve_expr(&mut self, expr: &Expr) {
                                     NoSuggestion => {
                                         // limit search to 5 to reduce the number
                                         // of stupid suggestions
-                                        self.find_best_match_for_name(&path_name, 5)
+                                        self.find_best_match_for_name(&path_name)
                                                             .map_or("".to_string(),
                                                                     |x| format!("`{}`", x))
                                     }
index c416a9810eb0ebedee7b449dc3f3ef106ee2f856..3de91d58740b802fa2031b6cd59fd432463edacb 100644 (file)
@@ -210,7 +210,7 @@ fn symbol_hash<'tcx>(tcx: &ty::ctxt<'tcx>,
     symbol_hasher.input_str("-");
     symbol_hasher.input_str(&encoder::encoded_ty(tcx, t));
     // Prefix with 'h' so that it never blends into adjacent digits
-    let mut hash = String::from_str("h");
+    let mut hash = String::from("h");
     hash.push_str(&truncated_hash_result(symbol_hasher));
     hash
 }
@@ -294,7 +294,7 @@ pub fn mangle<PI: Iterator<Item=PathElem>>(path: PI,
     // To be able to work on all platforms and get *some* reasonable output, we
     // use C++ name-mangling.
 
-    let mut n = String::from_str("_ZN"); // _Z == Begin name-sequence, N == nested
+    let mut n = String::from("_ZN"); // _Z == Begin name-sequence, N == nested
 
     fn push(n: &mut String, s: &str) {
         let sani = sanitize(s);
index 0513653eb24f5d26bdbb5dbaae59cc58a0624e57..30c72d68fb0e8a690fac2a6ea508ad675de136de 100644 (file)
@@ -318,7 +318,7 @@ fn process_method(&mut self, sig: &ast::MethodSig,
                     scope_id = item.id;
                     match item.node {
                         ast::ItemImpl(_, _, _, _, ref ty, _) => {
-                            let mut result = String::from_str("<");
+                            let mut result = String::from("<");
                             result.push_str(&ty_to_string(&**ty));
 
                             match ty::trait_of_item(&self.analysis.ty_cx,
@@ -1341,7 +1341,7 @@ fn visit_expr(&mut self, ex: &ast::Expr) {
                     return
                 }
 
-                let mut id = String::from_str("$");
+                let mut id = String::from("$");
                 id.push_str(&ex.id.to_string());
                 self.process_formals(&decl.inputs, &id);
 
index c6dc1c9b7074eff3c8c1be70086f09c0445fae25..1249d22946f65b08f9c36af36fefab1a304be505 100644 (file)
@@ -152,7 +152,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Data {
 
                 // If the variable is immutable, save the initialising expression.
                 let (value, keyword) = match mt {
-                    ast::MutMutable => (String::from_str("<mutable>"), keywords::Mut),
+                    ast::MutMutable => (String::from("<mutable>"), keywords::Mut),
                     ast::MutImmutable => (self.span_utils.snippet(expr.span), keywords::Static),
                 };
 
@@ -326,7 +326,7 @@ pub fn process_crate(sess: &Session,
         Some(name) => name.to_string(),
         None => {
             info!("Could not find crate name, using 'unknown_crate'");
-            String::from_str("unknown_crate")
+            String::from("unknown_crate")
         },
     };
 
index 193902d981d690b30cf3795d6f58af419818038e..c7759f4266ba5901efc5f0f7f906ee9e09e224dd 100644 (file)
@@ -178,7 +178,7 @@ pub fn make_values_str(&self,
         });
 
         let pairs = fields.iter().zip(values);
-        let strs = pairs.map(|(f, v)| format!(",{},\"{}\"", f, escape(String::from_str(v))));
+        let strs = pairs.map(|(f, v)| format!(",{},\"{}\"", f, escape(String::from(v))));
         Some(strs.fold(String::new(), |mut s, ss| {
             s.push_str(&ss[..]);
             s
@@ -207,7 +207,7 @@ pub fn record_without_span(&mut self,
             None => return,
         };
 
-        let mut result = String::from_str(label);
+        let mut result = String::from(label);
         result.push_str(&values_str[..]);
         result.push_str("\n");
         self.recorder.record(&result[..]);
@@ -269,7 +269,7 @@ pub fn variable_str(&mut self,
         // the local case they can be overridden in one block and there is no nice way
         // to refer to such a scope in english, so we just hack it by appending the
         // variable def's node id
-        let mut qualname = String::from_str(name);
+        let mut qualname = String::from(name);
         qualname.push_str("$");
         qualname.push_str(&id.to_string());
         self.check_and_record(Variable,
@@ -286,7 +286,7 @@ pub fn formal_str(&mut self,
                       fn_name: &str,
                       name: &str,
                       typ: &str) {
-        let mut qualname = String::from_str(fn_name);
+        let mut qualname = String::from(fn_name);
         qualname.push_str("::");
         qualname.push_str(name);
         self.check_and_record(Variable,
index c3ac805af27ec1fcd6b5d684af0f353cb987b93d..08cbd777c095cdefc09644f86761b0c7b4ffb050 100644 (file)
@@ -83,7 +83,7 @@ pub fn retokenise_span(&self, span: Span) -> StringReader<'a> {
         // the codemap as a new filemap. This is mostly OK, but means we should
         // not iterate over the codemap. Also, any spans over the new filemap
         // are incompatible with spans over other filemaps.
-        let filemap = self.sess.codemap().new_filemap(String::from_str("<anon-dxr>"),
+        let filemap = self.sess.codemap().new_filemap(String::from("<anon-dxr>"),
                                                       self.snippet(span));
         let s = self.sess;
         lexer::StringReader::new(s.diagnostic(), filemap)
index 497e0ae422c1fa3659c17eadb3e0140b518f5956..9ba1f84407c51eb4327144db0fa9b55d65b022a5 100644 (file)
@@ -71,7 +71,7 @@ pub fn count_insn(&self, category: &str) {
                 // Pass 2: concat strings for each elt, skipping
                 // forwards over any cycles by advancing to rightmost
                 // occurrence of each element in path.
-                let mut s = String::from_str(".");
+                let mut s = String::from(".");
                 i = 0;
                 while i < len {
                     i = mm[v[i]];
index 027f2dbc717b5f1e77fad680efd0dac20414a196..31c9b60f478a28150268e7414a05c88df2286283 100644 (file)
@@ -117,9 +117,8 @@ fn datum_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
             _ => {
                 bcx.tcx().sess.span_bug(
                     expr.span,
-                    &format!("type of callee is neither bare-fn nor closure: \
-                             {}",
-                            bcx.ty_to_string(datum.ty)));
+                    &format!("type of callee is neither bare-fn nor closure: {}",
+                             bcx.ty_to_string(datum.ty)));
             }
         }
     }
@@ -506,6 +505,9 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
         false
     };
 
+    debug!("trans_fn_ref_with_substs({}) must_monomorphise: {}",
+           def_id.repr(tcx), must_monomorphise);
+
     // Create a monomorphic version of generic functions
     if must_monomorphise {
         // Should be either intra-crate or inlined.
index eb4acec25510ac7f28370210cfeced6fc5562f34..e046b5cb111935535f6d29c29d20009c066668da 100644 (file)
@@ -153,7 +153,8 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc
 
     match ccx.closure_vals().borrow().get(&mono_id) {
         Some(&llfn) => {
-            debug!("get_or_create_declaration_if_closure(): found closure");
+            debug!("get_or_create_declaration_if_closure(): found closure {:?}: {:?}",
+                   mono_id, ccx.tn().val_to_string(llfn));
             return Some(Datum::new(llfn, function_type, Rvalue::new(ByValue)))
         }
         None => {}
@@ -173,9 +174,10 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc
     attributes::inline(llfn, attributes::InlineAttr::Hint);
 
     debug!("get_or_create_declaration_if_closure(): inserting new \
-            closure {:?} (type {})",
+            closure {:?} (type {}): {:?}",
            mono_id,
-           ccx.tn().type_to_string(val_ty(llfn)));
+           ccx.tn().type_to_string(val_ty(llfn)),
+           ccx.tn().val_to_string(llfn));
     ccx.closure_vals().borrow_mut().insert(mono_id, llfn);
 
     Some(Datum::new(llfn, function_type, Rvalue::new(ByValue)))
@@ -198,9 +200,9 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
         Dest::Ignore(ccx) => ccx
     };
     let tcx = ccx.tcx();
-    let _icx = push_ctxt("closure::trans_closure");
+    let _icx = push_ctxt("closure::trans_closure_expr");
 
-    debug!("trans_closure()");
+    debug!("trans_closure_expr()");
 
     let closure_id = ast_util::local_def(id);
     let llfn = get_or_create_declaration_if_closure(
@@ -230,7 +232,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
                   &[],
                   sig.output,
                   function_type.abi,
-                  ClosureEnv::Closure(&freevars[..]));
+                  ClosureEnv::Closure(&freevars));
 
     // Don't hoist this to the top of the function. It's perfectly legitimate
     // to have a zero-size closure (in which case dest will be `Ignore`) and
@@ -238,7 +240,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
     let (mut bcx, dest_addr) = match dest {
         Dest::SaveIn(bcx, p) => (bcx, p),
         Dest::Ignore(_) => {
-            debug!("trans_closure() ignoring result");
+            debug!("trans_closure_expr() ignoring result");
             return None;
         }
     };
index a72bac3e3b2cd7b0b21761368afd5203dd758576..6259f8fe1cc2e4591f2d377d51c605cd8dcabaeb 100644 (file)
@@ -1000,7 +1000,8 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         None => { }
     }
 
-    debug!("trans fulfill_obligation: trait_ref={}", trait_ref.repr(ccx.tcx()));
+    debug!("trans fulfill_obligation: trait_ref={} def_id={:?}",
+           trait_ref.repr(ccx.tcx()), trait_ref.def_id());
 
     ty::populate_implementations_for_trait_if_necessary(tcx, trait_ref.def_id());
     let infcx = infer::new_infer_ctxt(tcx);
index 8ebda9a6678dfb29801a9fb1a104b3ae488f53ea..0afaf88aaad911c918d707cdf494579010020ba8 100644 (file)
@@ -221,6 +221,7 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                           qualif: check_const::ConstQualif,
                                           param_substs: &'tcx Substs<'tcx>)
                                           -> ValueRef {
+    debug!("get_const_expr_as_global: {:?}", expr.id);
     // Special-case constants to cache a common global for all uses.
     match expr.node {
         ast::ExprPath(..) => {
@@ -228,6 +229,8 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
             match def {
                 def::DefConst(def_id) | def::DefAssociatedConst(def_id, _) => {
                     if !ccx.tcx().adjustments.borrow().contains_key(&expr.id) {
+                        debug!("get_const_expr_as_global ({:?}): found const {:?}",
+                               expr.id, def_id);
                         return get_const_val(ccx, def_id, expr);
                     }
                 }
@@ -911,7 +914,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
           }
           ast::ExprClosure(_, ref decl, ref body) => {
             closure::trans_closure_expr(closure::Dest::Ignore(cx),
-                                        &**decl, &**body, e.id,
+                                        decl,
+                                        body,
+                                        e.id,
                                         param_substs);
             C_null(type_of::type_of(cx, ety))
           }
index 51db0adf5b77508a8235aafea96ab99a9fee37c4..663a01e19f342887faeb3ffe170ef2a92893a676 100644 (file)
@@ -73,7 +73,6 @@ pub struct SharedCrateContext<'tcx> {
     check_overflow: bool,
     check_drop_flag_for_sanity: bool,
 
-    available_monomorphizations: RefCell<FnvHashSet<String>>,
     available_drop_glues: RefCell<FnvHashMap<DropGlueKind<'tcx>, String>>,
     use_dll_storage_attrs: bool,
 }
@@ -100,6 +99,7 @@ pub struct LocalCrateContext<'tcx> {
     /// Cache instances of monomorphized functions
     monomorphized: RefCell<FnvHashMap<MonoId<'tcx>, ValueRef>>,
     monomorphizing: RefCell<DefIdMap<usize>>,
+    available_monomorphizations: RefCell<FnvHashSet<String>>,
     /// Cache generated vtables
     vtables: RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>, ValueRef>>,
     /// Cache of constant strings,
@@ -321,7 +321,6 @@ pub fn new(crate_name: &str,
             },
             check_overflow: check_overflow,
             check_drop_flag_for_sanity: check_drop_flag_for_sanity,
-            available_monomorphizations: RefCell::new(FnvHashSet()),
             available_drop_glues: RefCell::new(FnvHashMap()),
             use_dll_storage_attrs: use_dll_storage_attrs,
         };
@@ -452,6 +451,7 @@ fn new(shared: &SharedCrateContext<'tcx>,
                 external_srcs: RefCell::new(NodeMap()),
                 monomorphized: RefCell::new(FnvHashMap()),
                 monomorphizing: RefCell::new(DefIdMap()),
+                available_monomorphizations: RefCell::new(FnvHashSet()),
                 vtables: RefCell::new(FnvHashMap()),
                 const_cstr_cache: RefCell::new(FnvHashMap()),
                 const_unsized: RefCell::new(FnvHashMap()),
@@ -709,7 +709,7 @@ pub fn stats<'a>(&'a self) -> &'a Stats {
     }
 
     pub fn available_monomorphizations<'a>(&'a self) -> &'a RefCell<FnvHashSet<String>> {
-        &self.shared.available_monomorphizations
+        &self.local.available_monomorphizations
     }
 
     pub fn available_drop_glues(&self) -> &RefCell<FnvHashMap<DropGlueKind<'tcx>, String>> {
@@ -870,6 +870,11 @@ macro_rules! mk_struct {
     ifn!("llvm.trunc.f32", fn(t_f32) -> t_f32);
     ifn!("llvm.trunc.f64", fn(t_f64) -> t_f64);
 
+    ifn!("llvm.copysign.f32", fn(t_f32, t_f32) -> t_f32);
+    ifn!("llvm.copysign.f64", fn(t_f64, t_f64) -> t_f64);
+    ifn!("llvm.round.f32", fn(t_f32) -> t_f32);
+    ifn!("llvm.round.f64", fn(t_f64) -> t_f64);
+
     ifn!("llvm.rint.f32", fn(t_f32) -> t_f32);
     ifn!("llvm.rint.f64", fn(t_f64) -> t_f64);
     ifn!("llvm.nearbyint.f32", fn(t_f32) -> t_f32);
@@ -928,22 +933,48 @@ macro_rules! mk_struct {
     ifn!("llvm.lifetime.end", fn(t_i64, i8p) -> void);
 
     ifn!("llvm.expect.i1", fn(i1, i1) -> i1);
-    ifn!("llvm.assume", fn(i1) -> void);
 
     // Some intrinsics were introduced in later versions of LLVM, but they have
-    // fallbacks in libc or libm and such. Currently, all of these intrinsics
-    // were introduced in LLVM 3.4, so we case on that.
+    // fallbacks in libc or libm and such.
     macro_rules! compatible_ifn {
-        ($name:expr, $cname:ident ($($arg:expr),*) -> $ret:expr) => (
-            ifn!($name, fn($($arg),*) -> $ret);
+        ($name:expr, noop($cname:ident ($($arg:expr),*) -> void), $llvm_version:expr) => (
+            if unsafe { llvm::LLVMVersionMinor() >= $llvm_version } {
+                // The `if key == $name` is already in ifn!
+                ifn!($name, fn($($arg),*) -> void);
+            } else if *key == $name {
+                let f = declare::declare_cfn(ccx, stringify!($cname),
+                                             Type::func(&[$($arg),*], &void),
+                                             ty::mk_nil(ccx.tcx()));
+                llvm::SetLinkage(f, llvm::InternalLinkage);
+
+                let bld = ccx.builder();
+                let llbb = unsafe {
+                    llvm::LLVMAppendBasicBlockInContext(ccx.llcx(), f,
+                                                        "entry-block\0".as_ptr() as *const _)
+                };
+
+                bld.position_at_end(llbb);
+                bld.ret_void();
+
+                ccx.intrinsics().borrow_mut().insert($name, f.clone());
+                return Some(f);
+            }
+        );
+        ($name:expr, $cname:ident ($($arg:expr),*) -> $ret:expr, $llvm_version:expr) => (
+            if unsafe { llvm::LLVMVersionMinor() >= $llvm_version } {
+                // The `if key == $name` is already in ifn!
+                ifn!($name, fn($($arg),*) -> $ret);
+            } else if *key == $name {
+                let f = declare::declare_cfn(ccx, stringify!($cname),
+                                             Type::func(&[$($arg),*], &$ret),
+                                             ty::mk_nil(ccx.tcx()));
+                ccx.intrinsics().borrow_mut().insert($name, f.clone());
+                return Some(f);
+            }
         )
     }
 
-    compatible_ifn!("llvm.copysign.f32", copysignf(t_f32, t_f32) -> t_f32);
-    compatible_ifn!("llvm.copysign.f64", copysign(t_f64, t_f64) -> t_f64);
-    compatible_ifn!("llvm.round.f32", roundf(t_f32) -> t_f32);
-    compatible_ifn!("llvm.round.f64", round(t_f64) -> t_f64);
-
+    compatible_ifn!("llvm.assume", noop(llvmcompat_assume(i1) -> void), 6);
 
     if ccx.sess().opts.debuginfo != NoDebugInfo {
         ifn!("llvm.dbg.declare", fn(Type::metadata(ccx), Type::metadata(ccx)) -> void);
index ab8cfa0ce3b7eaa72508ab75824b002b2ceb3530..d203aeca0a757929bd270edcd65ce5bf063d3f46 100644 (file)
@@ -30,7 +30,6 @@
 use syntax::ast_util;
 use syntax::parse::token::InternedString;
 use syntax::parse::token;
-use syntax::visit::Visitor;
 
 pub fn trans_stmt<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                               s: &ast::Stmt)
@@ -171,16 +170,7 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             // if true { .. } [else { .. }]
             bcx = trans_block(bcx, &*thn, dest);
             trans::debuginfo::clear_source_location(bcx.fcx);
-
-            if let Some(elexpr) = els {
-                let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx };
-                trans.visit_expr(&*elexpr);
-            }
         } else {
-            // if false { .. } [else { .. }]
-            let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx };
-            trans.visit_block(&*thn);
-
             if let Some(elexpr) = els {
                 bcx = expr::trans_into(bcx, &*elexpr, dest);
                 trans::debuginfo::clear_source_location(bcx.fcx);
index f9ad3d1a857f11cd751f3e3977a2daa27b472a2e..71312bb60a2a59b4692e782278412b8c309f68d5 100644 (file)
@@ -331,7 +331,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     // Get_template_parameters() will append a `<...>` clause to the function
     // name if necessary.
-    let mut function_name = String::from_str(&token::get_name(name));
+    let mut function_name = String::from(&*token::get_name(name));
     let template_parameters = get_template_parameters(cx,
                                                       generics,
                                                       param_substs,
index 0aa0408c0ef33c31a89fd1566901207dfa7b56cb..a41a62dcd4cfafab3ef1bad2608e476119babb19 100644 (file)
@@ -41,7 +41,7 @@ fn fill_nested(node: &NamespaceTreeNode, output: &mut String) {
             output.push_str(&string);
         }
 
-        let mut name = String::from_str("_ZN");
+        let mut name = String::from("_ZN");
         fill_nested(self, &mut name);
         name.push_str(&format!("{}", item_name.len()));
         name.push_str(item_name);
index 63158cdee92471cd801a780204cc0615bc64988a..e9804a11f2c8cd7efc61718d8e5814fbeed44c75 100644 (file)
@@ -139,9 +139,12 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 // have different types.
                 let lldest = PointerCast(bcx, lldest, val_ty(global));
                 memcpy_ty(bcx, lldest, global, expr_ty_adjusted(bcx, expr));
+                return bcx;
             }
-            // Don't do anything in the Ignore case, consts don't need drop.
-            return bcx;
+            // Even if we don't have a value to emit, and the expression
+            // doesn't have any side-effects, we still have to translate the
+            // body of any closures.
+            // FIXME: Find a better way of handling this case.
         } else {
             // The only way we're going to see a `const` at this point is if
             // it prefers in-place instantiation, likely because it contains
@@ -1145,7 +1148,7 @@ fn make_field(field_name: &str, expr: P<ast::Expr>) -> ast::Field {
                 SaveIn(lldest) => closure::Dest::SaveIn(bcx, lldest),
                 Ignore => closure::Dest::Ignore(bcx.ccx())
             };
-            closure::trans_closure_expr(dest, &**decl, &**body, expr.id, bcx.fcx.param_substs)
+            closure::trans_closure_expr(dest, decl, body, expr.id, bcx.fcx.param_substs)
                 .unwrap_or(bcx)
         }
         ast::ExprCall(ref f, ref args) => {
@@ -1956,6 +1959,7 @@ fn trans_overloaded_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                                          args: &'a [P<ast::Expr>],
                                          dest: Option<Dest>)
                                          -> Block<'blk, 'tcx> {
+    debug!("trans_overloaded_call {}", expr.id);
     let method_call = MethodCall::expr(expr.id);
     let method_type = bcx.tcx()
                          .method_map
index 9a53c3f0bcdf588790a9c23493f4591af07454b3..f860fe44f28e78f073e6170c38731ab1db103801 100644 (file)
 
 fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
     -> Option<ast::DefId> {
-    let _icx = push_ctxt("maybe_instantiate_inline");
+    debug!("instantiate_inline({:?})", fn_id);
+    let _icx = push_ctxt("instantiate_inline");
+
     match ccx.external().borrow().get(&fn_id) {
         Some(&Some(node_id)) => {
             // Already inline
-            debug!("maybe_instantiate_inline({}): already inline as node id {}",
+            debug!("instantiate_inline({}): already inline as node id {}",
                    ty::item_path_str(ccx.tcx(), fn_id), node_id);
             return Some(local_def(node_id));
         }
@@ -52,7 +54,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
             ccx.external_srcs().borrow_mut().insert(item.id, fn_id);
 
             ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1);
-            trans_item(ccx, &**item);
+            trans_item(ccx, item);
 
             let linkage = match item.node {
                 ast::ItemFn(_, _, _, _, ref generics, _) => {
@@ -118,7 +120,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
                 }
               }
             }
-            _ => ccx.sess().bug("maybe_instantiate_inline: item has a \
+            _ => ccx.sess().bug("instantiate_inline: item has a \
                                  non-enum, non-struct parent")
           }
           trans_item(ccx, &**item);
@@ -126,7 +128,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
         }
         csearch::FoundAst::FoundParent(_, _) => {
             ccx.sess().bug("maybe_get_item_ast returned a FoundParent \
-             with a non-item parent");
+                            with a non-item parent");
         }
         csearch::FoundAst::Found(&ast::IITraitItem(_, ref trait_item)) => {
             ccx.external().borrow_mut().insert(fn_id, Some(trait_item.id));
@@ -167,8 +169,12 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
                              empty_substs,
                              impl_item.id,
                              &[]);
-                    // Use InternalLinkage so LLVM can optimize more aggressively.
-                    SetLinkage(llfn, InternalLinkage);
+                    // See linkage comments on items.
+                    if ccx.sess().opts.cg.codegen_units == 1 {
+                        SetLinkage(llfn, InternalLinkage);
+                    } else {
+                        SetLinkage(llfn, AvailableExternallyLinkage);
+                    }
                 }
             }
 
index 7039968b029ac776284dfcc55ec7449f0c5c884e..feb2b879183277ee2872c35cd4a00260468aff34 100644 (file)
@@ -118,6 +118,7 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     match origin {
         ty::MethodStatic(did) |
         ty::MethodStaticClosure(did) => {
+            debug!("trans_method_callee: static, {:?}", did);
             Callee {
                 bcx: bcx,
                 data: Fn(callee::trans_fn_ref(bcx.ccx(),
@@ -134,9 +135,11 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         }) => {
             let trait_ref = ty::Binder(bcx.monomorphize(trait_ref));
             let span = bcx.tcx().map.span(method_call.expr_id);
-            debug!("method_call={:?} trait_ref={}",
+            debug!("method_call={:?} trait_ref={} trait_ref id={:?} substs={:?}",
                    method_call,
-                   trait_ref.repr(bcx.tcx()));
+                   trait_ref.repr(bcx.tcx()),
+                   trait_ref.0.def_id,
+                   trait_ref.0.substs);
             let origin = fulfill_obligation(bcx.ccx(),
                                             span,
                                             trait_ref.clone());
index d086aa93a6f6b37d891427bd86e8df069b00d9e9..3d74cf46e6ec32b6809aad11fcac221a09095bda 100644 (file)
@@ -60,6 +60,8 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     };
 
     let item_ty = ty::lookup_item_type(ccx.tcx(), fn_id).ty;
+
+    debug!("monomorphic_fn about to subst into {}", item_ty.repr(ccx.tcx()));
     let mono_ty = item_ty.subst(ccx.tcx(), psubsts);
 
     match ccx.monomorphized().borrow().get(&hash_id) {
@@ -97,8 +99,6 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         }
     }
 
-    debug!("monomorphic_fn about to subst into {}", item_ty.repr(ccx.tcx()));
-
     debug!("mono_ty = {} (post-substitution)", mono_ty.repr(ccx.tcx()));
 
     let mono_ty = normalize_associated_type(ccx.tcx(), &mono_ty);
index 002bfd94a9860bb6906c6073f58cca3a27d37949..c33ed87a5c2a23a35c16a0e29d15d43a5da9d02a 100644 (file)
@@ -231,8 +231,8 @@ fn coerce_borrowed_pointer(&self,
     }
 
 
-    // &[T, ..n] or &mut [T, ..n] -> &[T]
-    // or &mut [T, ..n] -> &mut [T]
+    // &[T; n] or &mut [T; n] -> &[T]
+    // or &mut [Tn] -> &mut [T]
     // or &Concrete -> &Trait, etc.
     fn coerce_unsized(&self,
                       source: Ty<'tcx>,
index 367273dc635f47b003fed53abf9a7f001f5bb595..b5d317d602538f2cf83cfed10e18680e35c417c1 100644 (file)
@@ -18,7 +18,7 @@ into a more explicit UFCS form:
 Here `ADJ` is some kind of adjustment, which is typically a series of
 autoderefs and then possibly an autoref (e.g., `&**receiver`). However
 we sometimes do other adjustments and coercions along the way, in
-particular unsizing (e.g., converting from `[T, ..n]` to `[T]`).
+particular unsizing (e.g., converting from `[Tn]` to `[T]`).
 
 ## The Two Phases
 
index 33737f40e46f09504ff206f7eae83aa1f2d91c7f..314793e2097a33378a096f6c61635b77c43fb74a 100644 (file)
@@ -2094,7 +2094,7 @@ fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         return final_mt;
     }
 
-    // After we have fully autoderef'd, if the resulting type is [T, ..n], then
+    // After we have fully autoderef'd, if the resulting type is [Tn], then
     // do a final unsized coercion to yield [T].
     if let ty::ty_vec(element_ty, Some(_)) = ty.sty {
         let adjusted_ty = ty::mk_vec(fcx.tcx(), element_ty, None);
index 9dfd172707d7b15dd42b36588c3c0e317bb0d13a..5b1300b18b63bedd013d3999d4f4fd2032c12d27 100644 (file)
@@ -29,7 +29,7 @@
 #![doc(primitive = "char")]
 
 use core::char::CharExt as C;
-use core::option::Option::{self, Some};
+use core::option::Option::{self, Some, None};
 use core::iter::Iterator;
 use tables::{derived_property, property, general_category, conversions, charwidth};
 
 /// the [`to_lowercase` method](../primitive.char.html#method.to_lowercase) on
 /// characters.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct ToLowercase(Option<char>);
+pub struct ToLowercase(CaseMappingIter);
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Iterator for ToLowercase {
     type Item = char;
-    fn next(&mut self) -> Option<char> { self.0.take() }
+    fn next(&mut self) -> Option<char> { self.0.next() }
 }
 
 /// An iterator over the uppercase mapping of a given character, returned from
 /// the [`to_uppercase` method](../primitive.char.html#method.to_uppercase) on
 /// characters.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct ToUppercase(Option<char>);
+pub struct ToUppercase(CaseMappingIter);
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Iterator for ToUppercase {
     type Item = char;
-    fn next(&mut self) -> Option<char> { self.0.take() }
+    fn next(&mut self) -> Option<char> { self.0.next() }
+}
+
+/// An iterator over the titlecase mapping of a given character, returned from
+/// the [`to_titlecase` method](../primitive.char.html#method.to_titlecase) on
+/// characters.
+#[unstable(feature = "unicode", reason = "recently added")]
+pub struct ToTitlecase(CaseMappingIter);
+
+#[stable(feature = "unicode_case_mapping", since = "1.2.0")]
+impl Iterator for ToTitlecase {
+    type Item = char;
+    fn next(&mut self) -> Option<char> { self.0.next() }
+}
+
+
+enum CaseMappingIter {
+    Three(char, char, char),
+    Two(char, char),
+    One(char),
+    Zero
+}
+
+impl CaseMappingIter {
+    fn new(chars: [char; 3]) -> CaseMappingIter {
+        if chars[2] == '\0' {
+            if chars[1] == '\0' {
+                CaseMappingIter::One(chars[0])  // Including if chars[0] == '\0'
+            } else {
+                CaseMappingIter::Two(chars[0], chars[1])
+            }
+        } else {
+            CaseMappingIter::Three(chars[0], chars[1], chars[2])
+        }
+    }
+}
+
+impl Iterator for CaseMappingIter {
+    type Item = char;
+    fn next(&mut self) -> Option<char> {
+        match *self {
+            CaseMappingIter::Three(a, b, c) => {
+                *self = CaseMappingIter::Two(b, c);
+                Some(a)
+            }
+            CaseMappingIter::Two(b, c) => {
+                *self = CaseMappingIter::One(c);
+                Some(b)
+            }
+            CaseMappingIter::One(c) => {
+                *self = CaseMappingIter::Zero;
+                Some(c)
+            }
+            CaseMappingIter::Zero => None,
+        }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -397,27 +452,48 @@ pub fn is_numeric(self) -> bool {
 
     /// Converts a character to its lowercase equivalent.
     ///
-    /// The case-folding performed is the common or simple mapping. See
-    /// `to_uppercase()` for references and more information.
+    /// This performs complex unconditional mappings with no tailoring.
+    /// See `to_uppercase()` for references and more information.
     ///
     /// # Return value
     ///
     /// Returns an iterator which yields the characters corresponding to the
     /// lowercase equivalent of the character. If no conversion is possible then
-    /// the input character is returned.
+    /// an iterator with just the input character is returned.
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn to_lowercase(self) -> ToLowercase {
-        ToLowercase(Some(conversions::to_lower(self)))
+        ToLowercase(CaseMappingIter::new(conversions::to_lower(self)))
+    }
+
+    /// Converts a character to its titlecase equivalent.
+    ///
+    /// This performs complex unconditional mappings with no tailoring.
+    /// See `to_uppercase()` for references and more information.
+    ///
+    /// This differs from `to_uppercase()` since Unicode contains
+    /// digraphs and ligature characters.
+    /// For example, U+01F3 “dz” and U+FB01 “fi”
+    /// map to U+01F1 “DZ” and U+0046 U+0069 “Fi”, respectively.
+    ///
+    /// # Return value
+    ///
+    /// Returns an iterator which yields the characters corresponding to the
+    /// lowercase equivalent of the character. If no conversion is possible then
+    /// an iterator with just the input character is returned.
+    #[unstable(feature = "unicode", reason = "recently added")]
+    #[inline]
+    pub fn to_titlecase(self) -> ToTitlecase {
+        ToTitlecase(CaseMappingIter::new(conversions::to_title(self)))
     }
 
     /// Converts a character to its uppercase equivalent.
     ///
-    /// The case-folding performed is the common or simple mapping: it maps
-    /// one Unicode codepoint to its uppercase equivalent according to the
-    /// Unicode database [1]. The additional [`SpecialCasing.txt`] is not yet
-    /// considered here, but the iterator returned will soon support this form
-    /// of case folding.
+    /// This performs complex unconditional mappings with no tailoring:
+    /// it maps one Unicode character to its uppercase equivalent
+    /// according to the Unicode database [1]
+    /// and the additional complex mappings [`SpecialCasing.txt`].
+    /// Conditional mappings (based on context or language) are not considerd here.
     ///
     /// A full reference can be found here [2].
     ///
@@ -425,17 +501,17 @@ pub fn to_lowercase(self) -> ToLowercase {
     ///
     /// Returns an iterator which yields the characters corresponding to the
     /// uppercase equivalent of the character. If no conversion is possible then
-    /// the input character is returned.
+    /// an iterator with just the input character is returned.
     ///
     /// [1]: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
     ///
     /// [`SpecialCasing.txt`]: ftp://ftp.unicode.org/Public/UNIDATA/SpecialCasing.txt
     ///
-    /// [2]: http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf#G33992
+    /// [2]: http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn to_uppercase(self) -> ToUppercase {
-        ToUppercase(Some(conversions::to_upper(self)))
+        ToUppercase(CaseMappingIter::new(conversions::to_upper(self)))
     }
 
     /// Returns this character's displayed width in columns, or `None` if it is a
index 2f72b940e328383af0d6d518d91bf7ba372eb701..a9456cb487c6a71d199414dfd9e251575715ed9c 100644 (file)
@@ -49,3 +49,8 @@ pub mod str {
     pub use u_str::{utf8_char_width, is_utf16, Utf16Items, Utf16Item};
     pub use u_str::{utf16_items, Utf16Encoder};
 }
+
+// For use in libcollections, not re-exported in libstd.
+pub mod derived_property {
+    pub use tables::derived_property::{Cased, Case_Ignorable};
+}
index 3343bc401835c882780aee2c21f0be29c52172eb..4ebb6a70d291c300cc588ca9aadc7e111be598d2 100644 (file)
@@ -28,7 +28,7 @@ fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
 
 pub mod general_category {
     pub const Cc_table: &'static [(char, char)] = &[
-        ('\u{0}', '\u{1f}'), ('\u{7f}', '\u{9f}')
+        ('\0', '\u{1f}'), ('\u{7f}', '\u{9f}')
     ];
 
     pub fn Cc(c: char) -> bool {
@@ -251,6 +251,157 @@ pub fn Alphabetic(c: char) -> bool {
         super::bsearch_range_table(c, Alphabetic_table)
     }
 
+    pub const Case_Ignorable_table: &'static [(char, char)] = &[
+        ('\u{27}', '\u{27}'), ('\u{2e}', '\u{2e}'), ('\u{3a}', '\u{3a}'), ('\u{5e}', '\u{5e}'),
+        ('\u{60}', '\u{60}'), ('\u{a8}', '\u{a8}'), ('\u{ad}', '\u{ad}'), ('\u{af}', '\u{af}'),
+        ('\u{b4}', '\u{b4}'), ('\u{b7}', '\u{b8}'), ('\u{2b0}', '\u{36f}'), ('\u{374}', '\u{375}'),
+        ('\u{37a}', '\u{37a}'), ('\u{384}', '\u{385}'), ('\u{387}', '\u{387}'), ('\u{483}',
+        '\u{489}'), ('\u{559}', '\u{559}'), ('\u{591}', '\u{5bd}'), ('\u{5bf}', '\u{5bf}'),
+        ('\u{5c1}', '\u{5c2}'), ('\u{5c4}', '\u{5c5}'), ('\u{5c7}', '\u{5c7}'), ('\u{5f4}',
+        '\u{5f4}'), ('\u{600}', '\u{605}'), ('\u{610}', '\u{61a}'), ('\u{61c}', '\u{61c}'),
+        ('\u{640}', '\u{640}'), ('\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{7f5}'), ('\u{7fa}', '\u{7fa}'), ('\u{816}', '\u{82d}'), ('\u{859}', '\u{85b}'),
+        ('\u{8e4}', '\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{971}', '\u{971}'), ('\u{981}', '\u{981}'), ('\u{9bc}', '\u{9bc}'), ('\u{9c1}',
+        '\u{9c4}'), ('\u{9cd}', '\u{9cd}'), ('\u{9e2}', '\u{9e3}'), ('\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{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{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{d01}', '\u{d01}'), ('\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{e46}', '\u{e4e}'), ('\u{eb1}',
+        '\u{eb1}'), ('\u{eb4}', '\u{eb9}'), ('\u{ebb}', '\u{ebc}'), ('\u{ec6}', '\u{ec6}'),
+        ('\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{10fc}', '\u{10fc}'), ('\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{17d7}', '\u{17d7}'), ('\u{17dd}', '\u{17dd}'), ('\u{180b}', '\u{180e}'),
+        ('\u{1843}', '\u{1843}'), ('\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{1aa7}', '\u{1aa7}'), ('\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{1c78}', '\u{1c7d}'), ('\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{1d2c}', '\u{1d6a}'), ('\u{1d78}', '\u{1d78}'),
+        ('\u{1d9b}', '\u{1df5}'), ('\u{1dfc}', '\u{1dff}'), ('\u{1fbd}', '\u{1fbd}'), ('\u{1fbf}',
+        '\u{1fc1}'), ('\u{1fcd}', '\u{1fcf}'), ('\u{1fdd}', '\u{1fdf}'), ('\u{1fed}', '\u{1fef}'),
+        ('\u{1ffd}', '\u{1ffe}'), ('\u{200b}', '\u{200f}'), ('\u{2018}', '\u{2019}'), ('\u{2024}',
+        '\u{2024}'), ('\u{2027}', '\u{2027}'), ('\u{202a}', '\u{202e}'), ('\u{2060}', '\u{2064}'),
+        ('\u{2066}', '\u{206f}'), ('\u{2071}', '\u{2071}'), ('\u{207f}', '\u{207f}'), ('\u{2090}',
+        '\u{209c}'), ('\u{20d0}', '\u{20f0}'), ('\u{2c7c}', '\u{2c7d}'), ('\u{2cef}', '\u{2cf1}'),
+        ('\u{2d6f}', '\u{2d6f}'), ('\u{2d7f}', '\u{2d7f}'), ('\u{2de0}', '\u{2dff}'), ('\u{2e2f}',
+        '\u{2e2f}'), ('\u{3005}', '\u{3005}'), ('\u{302a}', '\u{302d}'), ('\u{3031}', '\u{3035}'),
+        ('\u{303b}', '\u{303b}'), ('\u{3099}', '\u{309e}'), ('\u{30fc}', '\u{30fe}'), ('\u{a015}',
+        '\u{a015}'), ('\u{a4f8}', '\u{a4fd}'), ('\u{a60c}', '\u{a60c}'), ('\u{a66f}', '\u{a672}'),
+        ('\u{a674}', '\u{a67d}'), ('\u{a67f}', '\u{a67f}'), ('\u{a69c}', '\u{a69d}'), ('\u{a69f}',
+        '\u{a69f}'), ('\u{a6f0}', '\u{a6f1}'), ('\u{a700}', '\u{a721}'), ('\u{a770}', '\u{a770}'),
+        ('\u{a788}', '\u{a78a}'), ('\u{a7f8}', '\u{a7f9}'), ('\u{a802}', '\u{a802}'), ('\u{a806}',
+        '\u{a806}'), ('\u{a80b}', '\u{a80b}'), ('\u{a825}', '\u{a826}'), ('\u{a8c4}', '\u{a8c4}'),
+        ('\u{a8e0}', '\u{a8f1}'), ('\u{a926}', '\u{a92d}'), ('\u{a947}', '\u{a951}'), ('\u{a980}',
+        '\u{a982}'), ('\u{a9b3}', '\u{a9b3}'), ('\u{a9b6}', '\u{a9b9}'), ('\u{a9bc}', '\u{a9bc}'),
+        ('\u{a9cf}', '\u{a9cf}'), ('\u{a9e5}', '\u{a9e6}'), ('\u{aa29}', '\u{aa2e}'), ('\u{aa31}',
+        '\u{aa32}'), ('\u{aa35}', '\u{aa36}'), ('\u{aa43}', '\u{aa43}'), ('\u{aa4c}', '\u{aa4c}'),
+        ('\u{aa70}', '\u{aa70}'), ('\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{aadd}', '\u{aadd}'), ('\u{aaec}', '\u{aaed}'), ('\u{aaf3}', '\u{aaf4}'), ('\u{aaf6}',
+        '\u{aaf6}'), ('\u{ab5b}', '\u{ab5f}'), ('\u{abe5}', '\u{abe5}'), ('\u{abe8}', '\u{abe8}'),
+        ('\u{abed}', '\u{abed}'), ('\u{fb1e}', '\u{fb1e}'), ('\u{fbb2}', '\u{fbc1}'), ('\u{fe00}',
+        '\u{fe0f}'), ('\u{fe13}', '\u{fe13}'), ('\u{fe20}', '\u{fe2d}'), ('\u{fe52}', '\u{fe52}'),
+        ('\u{fe55}', '\u{fe55}'), ('\u{feff}', '\u{feff}'), ('\u{ff07}', '\u{ff07}'), ('\u{ff0e}',
+        '\u{ff0e}'), ('\u{ff1a}', '\u{ff1a}'), ('\u{ff3e}', '\u{ff3e}'), ('\u{ff40}', '\u{ff40}'),
+        ('\u{ff70}', '\u{ff70}'), ('\u{ff9e}', '\u{ff9f}'), ('\u{ffe3}', '\u{ffe3}'), ('\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{11001}', '\u{11001}'), ('\u{11038}', '\u{11046}'), ('\u{1107f}',
+        '\u{11081}'), ('\u{110b3}', '\u{110b6}'), ('\u{110b9}', '\u{110ba}'), ('\u{110bd}',
+        '\u{110bd}'), ('\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{1122f}', '\u{11231}'), ('\u{11234}', '\u{11234}'), ('\u{11236}',
+        '\u{11237}'), ('\u{112df}', '\u{112df}'), ('\u{112e3}', '\u{112ea}'), ('\u{11301}',
+        '\u{11301}'), ('\u{1133c}', '\u{1133c}'), ('\u{11340}', '\u{11340}'), ('\u{11366}',
+        '\u{1136c}'), ('\u{11370}', '\u{11374}'), ('\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{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{16af0}', '\u{16af4}'), ('\u{16b30}', '\u{16b36}'), ('\u{16b40}',
+        '\u{16b43}'), ('\u{16f8f}', '\u{16f9f}'), ('\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{1e8d0}',
+        '\u{1e8d6}'), ('\u{e0001}', '\u{e0001}'), ('\u{e0020}', '\u{e007f}'), ('\u{e0100}',
+        '\u{e01ef}')
+    ];
+
+    pub fn Case_Ignorable(c: char) -> bool {
+        super::bsearch_range_table(c, Case_Ignorable_table)
+    }
+
+    pub const Cased_table: &'static [(char, char)] = &[
+        ('\u{41}', '\u{5a}'), ('\u{61}', '\u{7a}'), ('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'),
+        ('\u{ba}', '\u{ba}'), ('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{1ba}'),
+        ('\u{1bc}', '\u{1bf}'), ('\u{1c4}', '\u{293}'), ('\u{295}', '\u{2b8}'), ('\u{2c0}',
+        '\u{2c1}'), ('\u{2e0}', '\u{2e4}'), ('\u{345}', '\u{345}'), ('\u{370}', '\u{373}'),
+        ('\u{376}', '\u{377}'), ('\u{37a}', '\u{37d}'), ('\u{37f}', '\u{37f}'), ('\u{386}',
+        '\u{386}'), ('\u{388}', '\u{38a}'), ('\u{38c}', '\u{38c}'), ('\u{38e}', '\u{3a1}'),
+        ('\u{3a3}', '\u{3f5}'), ('\u{3f7}', '\u{481}'), ('\u{48a}', '\u{52f}'), ('\u{531}',
+        '\u{556}'), ('\u{561}', '\u{587}'), ('\u{10a0}', '\u{10c5}'), ('\u{10c7}', '\u{10c7}'),
+        ('\u{10cd}', '\u{10cd}'), ('\u{1d00}', '\u{1dbf}'), ('\u{1e00}', '\u{1f15}'), ('\u{1f18}',
+        '\u{1f1d}'), ('\u{1f20}', '\u{1f45}'), ('\u{1f48}', '\u{1f4d}'), ('\u{1f50}', '\u{1f57}'),
+        ('\u{1f59}', '\u{1f59}'), ('\u{1f5b}', '\u{1f5b}'), ('\u{1f5d}', '\u{1f5d}'), ('\u{1f5f}',
+        '\u{1f7d}'), ('\u{1f80}', '\u{1fb4}'), ('\u{1fb6}', '\u{1fbc}'), ('\u{1fbe}', '\u{1fbe}'),
+        ('\u{1fc2}', '\u{1fc4}'), ('\u{1fc6}', '\u{1fcc}'), ('\u{1fd0}', '\u{1fd3}'), ('\u{1fd6}',
+        '\u{1fdb}'), ('\u{1fe0}', '\u{1fec}'), ('\u{1ff2}', '\u{1ff4}'), ('\u{1ff6}', '\u{1ffc}'),
+        ('\u{2071}', '\u{2071}'), ('\u{207f}', '\u{207f}'), ('\u{2090}', '\u{209c}'), ('\u{2102}',
+        '\u{2102}'), ('\u{2107}', '\u{2107}'), ('\u{210a}', '\u{2113}'), ('\u{2115}', '\u{2115}'),
+        ('\u{2119}', '\u{211d}'), ('\u{2124}', '\u{2124}'), ('\u{2126}', '\u{2126}'), ('\u{2128}',
+        '\u{2128}'), ('\u{212a}', '\u{212d}'), ('\u{212f}', '\u{2134}'), ('\u{2139}', '\u{2139}'),
+        ('\u{213c}', '\u{213f}'), ('\u{2145}', '\u{2149}'), ('\u{214e}', '\u{214e}'), ('\u{2160}',
+        '\u{217f}'), ('\u{2183}', '\u{2184}'), ('\u{24b6}', '\u{24e9}'), ('\u{2c00}', '\u{2c2e}'),
+        ('\u{2c30}', '\u{2c5e}'), ('\u{2c60}', '\u{2ce4}'), ('\u{2ceb}', '\u{2cee}'), ('\u{2cf2}',
+        '\u{2cf3}'), ('\u{2d00}', '\u{2d25}'), ('\u{2d27}', '\u{2d27}'), ('\u{2d2d}', '\u{2d2d}'),
+        ('\u{a640}', '\u{a66d}'), ('\u{a680}', '\u{a69d}'), ('\u{a722}', '\u{a787}'), ('\u{a78b}',
+        '\u{a78e}'), ('\u{a790}', '\u{a7ad}'), ('\u{a7b0}', '\u{a7b1}'), ('\u{a7f8}', '\u{a7fa}'),
+        ('\u{ab30}', '\u{ab5a}'), ('\u{ab5c}', '\u{ab5f}'), ('\u{ab64}', '\u{ab65}'), ('\u{fb00}',
+        '\u{fb06}'), ('\u{fb13}', '\u{fb17}'), ('\u{ff21}', '\u{ff3a}'), ('\u{ff41}', '\u{ff5a}'),
+        ('\u{10400}', '\u{1044f}'), ('\u{118a0}', '\u{118df}'), ('\u{1d400}', '\u{1d454}'),
+        ('\u{1d456}', '\u{1d49c}'), ('\u{1d49e}', '\u{1d49f}'), ('\u{1d4a2}', '\u{1d4a2}'),
+        ('\u{1d4a5}', '\u{1d4a6}'), ('\u{1d4a9}', '\u{1d4ac}'), ('\u{1d4ae}', '\u{1d4b9}'),
+        ('\u{1d4bb}', '\u{1d4bb}'), ('\u{1d4bd}', '\u{1d4c3}'), ('\u{1d4c5}', '\u{1d505}'),
+        ('\u{1d507}', '\u{1d50a}'), ('\u{1d50d}', '\u{1d514}'), ('\u{1d516}', '\u{1d51c}'),
+        ('\u{1d51e}', '\u{1d539}'), ('\u{1d53b}', '\u{1d53e}'), ('\u{1d540}', '\u{1d544}'),
+        ('\u{1d546}', '\u{1d546}'), ('\u{1d54a}', '\u{1d550}'), ('\u{1d552}', '\u{1d6a5}'),
+        ('\u{1d6a8}', '\u{1d6c0}'), ('\u{1d6c2}', '\u{1d6da}'), ('\u{1d6dc}', '\u{1d6fa}'),
+        ('\u{1d6fc}', '\u{1d714}'), ('\u{1d716}', '\u{1d734}'), ('\u{1d736}', '\u{1d74e}'),
+        ('\u{1d750}', '\u{1d76e}'), ('\u{1d770}', '\u{1d788}'), ('\u{1d78a}', '\u{1d7a8}'),
+        ('\u{1d7aa}', '\u{1d7c2}'), ('\u{1d7c4}', '\u{1d7cb}'), ('\u{1f130}', '\u{1f149}'),
+        ('\u{1f150}', '\u{1f169}'), ('\u{1f170}', '\u{1f189}')
+    ];
+
+    pub fn Cased(c: char) -> bool {
+        super::bsearch_range_table(c, Cased_table)
+    }
+
     pub const Lowercase_table: &'static [(char, char)] = &[
         ('\u{61}', '\u{7a}'), ('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'), ('\u{ba}', '\u{ba}'),
         ('\u{df}', '\u{f6}'), ('\u{f8}', '\u{ff}'), ('\u{101}', '\u{101}'), ('\u{103}', '\u{103}'),
@@ -3726,21 +3877,28 @@ pub mod conversions {
     use core::option::Option::{Some, None};
     use core::result::Result::{Ok, Err};
 
-    pub fn to_lower(c: char) -> char {
-        match bsearch_case_table(c, LuLl_table) {
-          None        => c,
-          Some(index) => LuLl_table[index].1
+    pub fn to_lower(c: char) -> [char; 3] {
+        match bsearch_case_table(c, to_lowercase_table) {
+          None        => [c, '\0', '\0'],
+          Some(index) => to_lowercase_table[index].1
+        }
+    }
+
+    pub fn to_upper(c: char) -> [char; 3] {
+        match bsearch_case_table(c, to_uppercase_table) {
+            None        => [c, '\0', '\0'],
+            Some(index) => to_uppercase_table[index].1
         }
     }
 
-    pub fn to_upper(c: char) -> char {
-        match bsearch_case_table(c, LlLu_table) {
-            None        => c,
-            Some(index) => LlLu_table[index].1
+    pub fn to_title(c: char) -> [char; 3] {
+        match bsearch_case_table(c, to_titlecase_table) {
+            None        => [c, '\0', '\0'],
+            Some(index) => to_titlecase_table[index].1
         }
     }
 
-    fn bsearch_case_table(c: char, table: &'static [(char, char)]) -> Option<usize> {
+    fn bsearch_case_table(c: char, table: &'static [(char, [char; 3])]) -> Option<usize> {
         match table.binary_search_by(|&(key, _)| {
             if c == key { Equal }
             else if key < c { Less }
@@ -3751,606 +3909,1527 @@ fn bsearch_case_table(c: char, table: &'static [(char, char)]) -> Option<usize>
         }
     }
 
-    const LuLl_table: &'static [(char, char)] = &[
-        ('\u{41}', '\u{61}'), ('\u{42}', '\u{62}'), ('\u{43}', '\u{63}'), ('\u{44}', '\u{64}'),
-        ('\u{45}', '\u{65}'), ('\u{46}', '\u{66}'), ('\u{47}', '\u{67}'), ('\u{48}', '\u{68}'),
-        ('\u{49}', '\u{69}'), ('\u{4a}', '\u{6a}'), ('\u{4b}', '\u{6b}'), ('\u{4c}', '\u{6c}'),
-        ('\u{4d}', '\u{6d}'), ('\u{4e}', '\u{6e}'), ('\u{4f}', '\u{6f}'), ('\u{50}', '\u{70}'),
-        ('\u{51}', '\u{71}'), ('\u{52}', '\u{72}'), ('\u{53}', '\u{73}'), ('\u{54}', '\u{74}'),
-        ('\u{55}', '\u{75}'), ('\u{56}', '\u{76}'), ('\u{57}', '\u{77}'), ('\u{58}', '\u{78}'),
-        ('\u{59}', '\u{79}'), ('\u{5a}', '\u{7a}'), ('\u{c0}', '\u{e0}'), ('\u{c1}', '\u{e1}'),
-        ('\u{c2}', '\u{e2}'), ('\u{c3}', '\u{e3}'), ('\u{c4}', '\u{e4}'), ('\u{c5}', '\u{e5}'),
-        ('\u{c6}', '\u{e6}'), ('\u{c7}', '\u{e7}'), ('\u{c8}', '\u{e8}'), ('\u{c9}', '\u{e9}'),
-        ('\u{ca}', '\u{ea}'), ('\u{cb}', '\u{eb}'), ('\u{cc}', '\u{ec}'), ('\u{cd}', '\u{ed}'),
-        ('\u{ce}', '\u{ee}'), ('\u{cf}', '\u{ef}'), ('\u{d0}', '\u{f0}'), ('\u{d1}', '\u{f1}'),
-        ('\u{d2}', '\u{f2}'), ('\u{d3}', '\u{f3}'), ('\u{d4}', '\u{f4}'), ('\u{d5}', '\u{f5}'),
-        ('\u{d6}', '\u{f6}'), ('\u{d8}', '\u{f8}'), ('\u{d9}', '\u{f9}'), ('\u{da}', '\u{fa}'),
-        ('\u{db}', '\u{fb}'), ('\u{dc}', '\u{fc}'), ('\u{dd}', '\u{fd}'), ('\u{de}', '\u{fe}'),
-        ('\u{100}', '\u{101}'), ('\u{102}', '\u{103}'), ('\u{104}', '\u{105}'), ('\u{106}',
-        '\u{107}'), ('\u{108}', '\u{109}'), ('\u{10a}', '\u{10b}'), ('\u{10c}', '\u{10d}'),
-        ('\u{10e}', '\u{10f}'), ('\u{110}', '\u{111}'), ('\u{112}', '\u{113}'), ('\u{114}',
-        '\u{115}'), ('\u{116}', '\u{117}'), ('\u{118}', '\u{119}'), ('\u{11a}', '\u{11b}'),
-        ('\u{11c}', '\u{11d}'), ('\u{11e}', '\u{11f}'), ('\u{120}', '\u{121}'), ('\u{122}',
-        '\u{123}'), ('\u{124}', '\u{125}'), ('\u{126}', '\u{127}'), ('\u{128}', '\u{129}'),
-        ('\u{12a}', '\u{12b}'), ('\u{12c}', '\u{12d}'), ('\u{12e}', '\u{12f}'), ('\u{130}',
-        '\u{69}'), ('\u{132}', '\u{133}'), ('\u{134}', '\u{135}'), ('\u{136}', '\u{137}'),
-        ('\u{139}', '\u{13a}'), ('\u{13b}', '\u{13c}'), ('\u{13d}', '\u{13e}'), ('\u{13f}',
-        '\u{140}'), ('\u{141}', '\u{142}'), ('\u{143}', '\u{144}'), ('\u{145}', '\u{146}'),
-        ('\u{147}', '\u{148}'), ('\u{14a}', '\u{14b}'), ('\u{14c}', '\u{14d}'), ('\u{14e}',
-        '\u{14f}'), ('\u{150}', '\u{151}'), ('\u{152}', '\u{153}'), ('\u{154}', '\u{155}'),
-        ('\u{156}', '\u{157}'), ('\u{158}', '\u{159}'), ('\u{15a}', '\u{15b}'), ('\u{15c}',
-        '\u{15d}'), ('\u{15e}', '\u{15f}'), ('\u{160}', '\u{161}'), ('\u{162}', '\u{163}'),
-        ('\u{164}', '\u{165}'), ('\u{166}', '\u{167}'), ('\u{168}', '\u{169}'), ('\u{16a}',
-        '\u{16b}'), ('\u{16c}', '\u{16d}'), ('\u{16e}', '\u{16f}'), ('\u{170}', '\u{171}'),
-        ('\u{172}', '\u{173}'), ('\u{174}', '\u{175}'), ('\u{176}', '\u{177}'), ('\u{178}',
-        '\u{ff}'), ('\u{179}', '\u{17a}'), ('\u{17b}', '\u{17c}'), ('\u{17d}', '\u{17e}'),
-        ('\u{181}', '\u{253}'), ('\u{182}', '\u{183}'), ('\u{184}', '\u{185}'), ('\u{186}',
-        '\u{254}'), ('\u{187}', '\u{188}'), ('\u{189}', '\u{256}'), ('\u{18a}', '\u{257}'),
-        ('\u{18b}', '\u{18c}'), ('\u{18e}', '\u{1dd}'), ('\u{18f}', '\u{259}'), ('\u{190}',
-        '\u{25b}'), ('\u{191}', '\u{192}'), ('\u{193}', '\u{260}'), ('\u{194}', '\u{263}'),
-        ('\u{196}', '\u{269}'), ('\u{197}', '\u{268}'), ('\u{198}', '\u{199}'), ('\u{19c}',
-        '\u{26f}'), ('\u{19d}', '\u{272}'), ('\u{19f}', '\u{275}'), ('\u{1a0}', '\u{1a1}'),
-        ('\u{1a2}', '\u{1a3}'), ('\u{1a4}', '\u{1a5}'), ('\u{1a6}', '\u{280}'), ('\u{1a7}',
-        '\u{1a8}'), ('\u{1a9}', '\u{283}'), ('\u{1ac}', '\u{1ad}'), ('\u{1ae}', '\u{288}'),
-        ('\u{1af}', '\u{1b0}'), ('\u{1b1}', '\u{28a}'), ('\u{1b2}', '\u{28b}'), ('\u{1b3}',
-        '\u{1b4}'), ('\u{1b5}', '\u{1b6}'), ('\u{1b7}', '\u{292}'), ('\u{1b8}', '\u{1b9}'),
-        ('\u{1bc}', '\u{1bd}'), ('\u{1c4}', '\u{1c6}'), ('\u{1c7}', '\u{1c9}'), ('\u{1ca}',
-        '\u{1cc}'), ('\u{1cd}', '\u{1ce}'), ('\u{1cf}', '\u{1d0}'), ('\u{1d1}', '\u{1d2}'),
-        ('\u{1d3}', '\u{1d4}'), ('\u{1d5}', '\u{1d6}'), ('\u{1d7}', '\u{1d8}'), ('\u{1d9}',
-        '\u{1da}'), ('\u{1db}', '\u{1dc}'), ('\u{1de}', '\u{1df}'), ('\u{1e0}', '\u{1e1}'),
-        ('\u{1e2}', '\u{1e3}'), ('\u{1e4}', '\u{1e5}'), ('\u{1e6}', '\u{1e7}'), ('\u{1e8}',
-        '\u{1e9}'), ('\u{1ea}', '\u{1eb}'), ('\u{1ec}', '\u{1ed}'), ('\u{1ee}', '\u{1ef}'),
-        ('\u{1f1}', '\u{1f3}'), ('\u{1f4}', '\u{1f5}'), ('\u{1f6}', '\u{195}'), ('\u{1f7}',
-        '\u{1bf}'), ('\u{1f8}', '\u{1f9}'), ('\u{1fa}', '\u{1fb}'), ('\u{1fc}', '\u{1fd}'),
-        ('\u{1fe}', '\u{1ff}'), ('\u{200}', '\u{201}'), ('\u{202}', '\u{203}'), ('\u{204}',
-        '\u{205}'), ('\u{206}', '\u{207}'), ('\u{208}', '\u{209}'), ('\u{20a}', '\u{20b}'),
-        ('\u{20c}', '\u{20d}'), ('\u{20e}', '\u{20f}'), ('\u{210}', '\u{211}'), ('\u{212}',
-        '\u{213}'), ('\u{214}', '\u{215}'), ('\u{216}', '\u{217}'), ('\u{218}', '\u{219}'),
-        ('\u{21a}', '\u{21b}'), ('\u{21c}', '\u{21d}'), ('\u{21e}', '\u{21f}'), ('\u{220}',
-        '\u{19e}'), ('\u{222}', '\u{223}'), ('\u{224}', '\u{225}'), ('\u{226}', '\u{227}'),
-        ('\u{228}', '\u{229}'), ('\u{22a}', '\u{22b}'), ('\u{22c}', '\u{22d}'), ('\u{22e}',
-        '\u{22f}'), ('\u{230}', '\u{231}'), ('\u{232}', '\u{233}'), ('\u{23a}', '\u{2c65}'),
-        ('\u{23b}', '\u{23c}'), ('\u{23d}', '\u{19a}'), ('\u{23e}', '\u{2c66}'), ('\u{241}',
-        '\u{242}'), ('\u{243}', '\u{180}'), ('\u{244}', '\u{289}'), ('\u{245}', '\u{28c}'),
-        ('\u{246}', '\u{247}'), ('\u{248}', '\u{249}'), ('\u{24a}', '\u{24b}'), ('\u{24c}',
-        '\u{24d}'), ('\u{24e}', '\u{24f}'), ('\u{370}', '\u{371}'), ('\u{372}', '\u{373}'),
-        ('\u{376}', '\u{377}'), ('\u{37f}', '\u{3f3}'), ('\u{386}', '\u{3ac}'), ('\u{388}',
-        '\u{3ad}'), ('\u{389}', '\u{3ae}'), ('\u{38a}', '\u{3af}'), ('\u{38c}', '\u{3cc}'),
-        ('\u{38e}', '\u{3cd}'), ('\u{38f}', '\u{3ce}'), ('\u{391}', '\u{3b1}'), ('\u{392}',
-        '\u{3b2}'), ('\u{393}', '\u{3b3}'), ('\u{394}', '\u{3b4}'), ('\u{395}', '\u{3b5}'),
-        ('\u{396}', '\u{3b6}'), ('\u{397}', '\u{3b7}'), ('\u{398}', '\u{3b8}'), ('\u{399}',
-        '\u{3b9}'), ('\u{39a}', '\u{3ba}'), ('\u{39b}', '\u{3bb}'), ('\u{39c}', '\u{3bc}'),
-        ('\u{39d}', '\u{3bd}'), ('\u{39e}', '\u{3be}'), ('\u{39f}', '\u{3bf}'), ('\u{3a0}',
-        '\u{3c0}'), ('\u{3a1}', '\u{3c1}'), ('\u{3a3}', '\u{3c3}'), ('\u{3a4}', '\u{3c4}'),
-        ('\u{3a5}', '\u{3c5}'), ('\u{3a6}', '\u{3c6}'), ('\u{3a7}', '\u{3c7}'), ('\u{3a8}',
-        '\u{3c8}'), ('\u{3a9}', '\u{3c9}'), ('\u{3aa}', '\u{3ca}'), ('\u{3ab}', '\u{3cb}'),
-        ('\u{3cf}', '\u{3d7}'), ('\u{3d8}', '\u{3d9}'), ('\u{3da}', '\u{3db}'), ('\u{3dc}',
-        '\u{3dd}'), ('\u{3de}', '\u{3df}'), ('\u{3e0}', '\u{3e1}'), ('\u{3e2}', '\u{3e3}'),
-        ('\u{3e4}', '\u{3e5}'), ('\u{3e6}', '\u{3e7}'), ('\u{3e8}', '\u{3e9}'), ('\u{3ea}',
-        '\u{3eb}'), ('\u{3ec}', '\u{3ed}'), ('\u{3ee}', '\u{3ef}'), ('\u{3f4}', '\u{3b8}'),
-        ('\u{3f7}', '\u{3f8}'), ('\u{3f9}', '\u{3f2}'), ('\u{3fa}', '\u{3fb}'), ('\u{3fd}',
-        '\u{37b}'), ('\u{3fe}', '\u{37c}'), ('\u{3ff}', '\u{37d}'), ('\u{400}', '\u{450}'),
-        ('\u{401}', '\u{451}'), ('\u{402}', '\u{452}'), ('\u{403}', '\u{453}'), ('\u{404}',
-        '\u{454}'), ('\u{405}', '\u{455}'), ('\u{406}', '\u{456}'), ('\u{407}', '\u{457}'),
-        ('\u{408}', '\u{458}'), ('\u{409}', '\u{459}'), ('\u{40a}', '\u{45a}'), ('\u{40b}',
-        '\u{45b}'), ('\u{40c}', '\u{45c}'), ('\u{40d}', '\u{45d}'), ('\u{40e}', '\u{45e}'),
-        ('\u{40f}', '\u{45f}'), ('\u{410}', '\u{430}'), ('\u{411}', '\u{431}'), ('\u{412}',
-        '\u{432}'), ('\u{413}', '\u{433}'), ('\u{414}', '\u{434}'), ('\u{415}', '\u{435}'),
-        ('\u{416}', '\u{436}'), ('\u{417}', '\u{437}'), ('\u{418}', '\u{438}'), ('\u{419}',
-        '\u{439}'), ('\u{41a}', '\u{43a}'), ('\u{41b}', '\u{43b}'), ('\u{41c}', '\u{43c}'),
-        ('\u{41d}', '\u{43d}'), ('\u{41e}', '\u{43e}'), ('\u{41f}', '\u{43f}'), ('\u{420}',
-        '\u{440}'), ('\u{421}', '\u{441}'), ('\u{422}', '\u{442}'), ('\u{423}', '\u{443}'),
-        ('\u{424}', '\u{444}'), ('\u{425}', '\u{445}'), ('\u{426}', '\u{446}'), ('\u{427}',
-        '\u{447}'), ('\u{428}', '\u{448}'), ('\u{429}', '\u{449}'), ('\u{42a}', '\u{44a}'),
-        ('\u{42b}', '\u{44b}'), ('\u{42c}', '\u{44c}'), ('\u{42d}', '\u{44d}'), ('\u{42e}',
-        '\u{44e}'), ('\u{42f}', '\u{44f}'), ('\u{460}', '\u{461}'), ('\u{462}', '\u{463}'),
-        ('\u{464}', '\u{465}'), ('\u{466}', '\u{467}'), ('\u{468}', '\u{469}'), ('\u{46a}',
-        '\u{46b}'), ('\u{46c}', '\u{46d}'), ('\u{46e}', '\u{46f}'), ('\u{470}', '\u{471}'),
-        ('\u{472}', '\u{473}'), ('\u{474}', '\u{475}'), ('\u{476}', '\u{477}'), ('\u{478}',
-        '\u{479}'), ('\u{47a}', '\u{47b}'), ('\u{47c}', '\u{47d}'), ('\u{47e}', '\u{47f}'),
-        ('\u{480}', '\u{481}'), ('\u{48a}', '\u{48b}'), ('\u{48c}', '\u{48d}'), ('\u{48e}',
-        '\u{48f}'), ('\u{490}', '\u{491}'), ('\u{492}', '\u{493}'), ('\u{494}', '\u{495}'),
-        ('\u{496}', '\u{497}'), ('\u{498}', '\u{499}'), ('\u{49a}', '\u{49b}'), ('\u{49c}',
-        '\u{49d}'), ('\u{49e}', '\u{49f}'), ('\u{4a0}', '\u{4a1}'), ('\u{4a2}', '\u{4a3}'),
-        ('\u{4a4}', '\u{4a5}'), ('\u{4a6}', '\u{4a7}'), ('\u{4a8}', '\u{4a9}'), ('\u{4aa}',
-        '\u{4ab}'), ('\u{4ac}', '\u{4ad}'), ('\u{4ae}', '\u{4af}'), ('\u{4b0}', '\u{4b1}'),
-        ('\u{4b2}', '\u{4b3}'), ('\u{4b4}', '\u{4b5}'), ('\u{4b6}', '\u{4b7}'), ('\u{4b8}',
-        '\u{4b9}'), ('\u{4ba}', '\u{4bb}'), ('\u{4bc}', '\u{4bd}'), ('\u{4be}', '\u{4bf}'),
-        ('\u{4c0}', '\u{4cf}'), ('\u{4c1}', '\u{4c2}'), ('\u{4c3}', '\u{4c4}'), ('\u{4c5}',
-        '\u{4c6}'), ('\u{4c7}', '\u{4c8}'), ('\u{4c9}', '\u{4ca}'), ('\u{4cb}', '\u{4cc}'),
-        ('\u{4cd}', '\u{4ce}'), ('\u{4d0}', '\u{4d1}'), ('\u{4d2}', '\u{4d3}'), ('\u{4d4}',
-        '\u{4d5}'), ('\u{4d6}', '\u{4d7}'), ('\u{4d8}', '\u{4d9}'), ('\u{4da}', '\u{4db}'),
-        ('\u{4dc}', '\u{4dd}'), ('\u{4de}', '\u{4df}'), ('\u{4e0}', '\u{4e1}'), ('\u{4e2}',
-        '\u{4e3}'), ('\u{4e4}', '\u{4e5}'), ('\u{4e6}', '\u{4e7}'), ('\u{4e8}', '\u{4e9}'),
-        ('\u{4ea}', '\u{4eb}'), ('\u{4ec}', '\u{4ed}'), ('\u{4ee}', '\u{4ef}'), ('\u{4f0}',
-        '\u{4f1}'), ('\u{4f2}', '\u{4f3}'), ('\u{4f4}', '\u{4f5}'), ('\u{4f6}', '\u{4f7}'),
-        ('\u{4f8}', '\u{4f9}'), ('\u{4fa}', '\u{4fb}'), ('\u{4fc}', '\u{4fd}'), ('\u{4fe}',
-        '\u{4ff}'), ('\u{500}', '\u{501}'), ('\u{502}', '\u{503}'), ('\u{504}', '\u{505}'),
-        ('\u{506}', '\u{507}'), ('\u{508}', '\u{509}'), ('\u{50a}', '\u{50b}'), ('\u{50c}',
-        '\u{50d}'), ('\u{50e}', '\u{50f}'), ('\u{510}', '\u{511}'), ('\u{512}', '\u{513}'),
-        ('\u{514}', '\u{515}'), ('\u{516}', '\u{517}'), ('\u{518}', '\u{519}'), ('\u{51a}',
-        '\u{51b}'), ('\u{51c}', '\u{51d}'), ('\u{51e}', '\u{51f}'), ('\u{520}', '\u{521}'),
-        ('\u{522}', '\u{523}'), ('\u{524}', '\u{525}'), ('\u{526}', '\u{527}'), ('\u{528}',
-        '\u{529}'), ('\u{52a}', '\u{52b}'), ('\u{52c}', '\u{52d}'), ('\u{52e}', '\u{52f}'),
-        ('\u{531}', '\u{561}'), ('\u{532}', '\u{562}'), ('\u{533}', '\u{563}'), ('\u{534}',
-        '\u{564}'), ('\u{535}', '\u{565}'), ('\u{536}', '\u{566}'), ('\u{537}', '\u{567}'),
-        ('\u{538}', '\u{568}'), ('\u{539}', '\u{569}'), ('\u{53a}', '\u{56a}'), ('\u{53b}',
-        '\u{56b}'), ('\u{53c}', '\u{56c}'), ('\u{53d}', '\u{56d}'), ('\u{53e}', '\u{56e}'),
-        ('\u{53f}', '\u{56f}'), ('\u{540}', '\u{570}'), ('\u{541}', '\u{571}'), ('\u{542}',
-        '\u{572}'), ('\u{543}', '\u{573}'), ('\u{544}', '\u{574}'), ('\u{545}', '\u{575}'),
-        ('\u{546}', '\u{576}'), ('\u{547}', '\u{577}'), ('\u{548}', '\u{578}'), ('\u{549}',
-        '\u{579}'), ('\u{54a}', '\u{57a}'), ('\u{54b}', '\u{57b}'), ('\u{54c}', '\u{57c}'),
-        ('\u{54d}', '\u{57d}'), ('\u{54e}', '\u{57e}'), ('\u{54f}', '\u{57f}'), ('\u{550}',
-        '\u{580}'), ('\u{551}', '\u{581}'), ('\u{552}', '\u{582}'), ('\u{553}', '\u{583}'),
-        ('\u{554}', '\u{584}'), ('\u{555}', '\u{585}'), ('\u{556}', '\u{586}'), ('\u{10a0}',
-        '\u{2d00}'), ('\u{10a1}', '\u{2d01}'), ('\u{10a2}', '\u{2d02}'), ('\u{10a3}', '\u{2d03}'),
-        ('\u{10a4}', '\u{2d04}'), ('\u{10a5}', '\u{2d05}'), ('\u{10a6}', '\u{2d06}'), ('\u{10a7}',
-        '\u{2d07}'), ('\u{10a8}', '\u{2d08}'), ('\u{10a9}', '\u{2d09}'), ('\u{10aa}', '\u{2d0a}'),
-        ('\u{10ab}', '\u{2d0b}'), ('\u{10ac}', '\u{2d0c}'), ('\u{10ad}', '\u{2d0d}'), ('\u{10ae}',
-        '\u{2d0e}'), ('\u{10af}', '\u{2d0f}'), ('\u{10b0}', '\u{2d10}'), ('\u{10b1}', '\u{2d11}'),
-        ('\u{10b2}', '\u{2d12}'), ('\u{10b3}', '\u{2d13}'), ('\u{10b4}', '\u{2d14}'), ('\u{10b5}',
-        '\u{2d15}'), ('\u{10b6}', '\u{2d16}'), ('\u{10b7}', '\u{2d17}'), ('\u{10b8}', '\u{2d18}'),
-        ('\u{10b9}', '\u{2d19}'), ('\u{10ba}', '\u{2d1a}'), ('\u{10bb}', '\u{2d1b}'), ('\u{10bc}',
-        '\u{2d1c}'), ('\u{10bd}', '\u{2d1d}'), ('\u{10be}', '\u{2d1e}'), ('\u{10bf}', '\u{2d1f}'),
-        ('\u{10c0}', '\u{2d20}'), ('\u{10c1}', '\u{2d21}'), ('\u{10c2}', '\u{2d22}'), ('\u{10c3}',
-        '\u{2d23}'), ('\u{10c4}', '\u{2d24}'), ('\u{10c5}', '\u{2d25}'), ('\u{10c7}', '\u{2d27}'),
-        ('\u{10cd}', '\u{2d2d}'), ('\u{1e00}', '\u{1e01}'), ('\u{1e02}', '\u{1e03}'), ('\u{1e04}',
-        '\u{1e05}'), ('\u{1e06}', '\u{1e07}'), ('\u{1e08}', '\u{1e09}'), ('\u{1e0a}', '\u{1e0b}'),
-        ('\u{1e0c}', '\u{1e0d}'), ('\u{1e0e}', '\u{1e0f}'), ('\u{1e10}', '\u{1e11}'), ('\u{1e12}',
-        '\u{1e13}'), ('\u{1e14}', '\u{1e15}'), ('\u{1e16}', '\u{1e17}'), ('\u{1e18}', '\u{1e19}'),
-        ('\u{1e1a}', '\u{1e1b}'), ('\u{1e1c}', '\u{1e1d}'), ('\u{1e1e}', '\u{1e1f}'), ('\u{1e20}',
-        '\u{1e21}'), ('\u{1e22}', '\u{1e23}'), ('\u{1e24}', '\u{1e25}'), ('\u{1e26}', '\u{1e27}'),
-        ('\u{1e28}', '\u{1e29}'), ('\u{1e2a}', '\u{1e2b}'), ('\u{1e2c}', '\u{1e2d}'), ('\u{1e2e}',
-        '\u{1e2f}'), ('\u{1e30}', '\u{1e31}'), ('\u{1e32}', '\u{1e33}'), ('\u{1e34}', '\u{1e35}'),
-        ('\u{1e36}', '\u{1e37}'), ('\u{1e38}', '\u{1e39}'), ('\u{1e3a}', '\u{1e3b}'), ('\u{1e3c}',
-        '\u{1e3d}'), ('\u{1e3e}', '\u{1e3f}'), ('\u{1e40}', '\u{1e41}'), ('\u{1e42}', '\u{1e43}'),
-        ('\u{1e44}', '\u{1e45}'), ('\u{1e46}', '\u{1e47}'), ('\u{1e48}', '\u{1e49}'), ('\u{1e4a}',
-        '\u{1e4b}'), ('\u{1e4c}', '\u{1e4d}'), ('\u{1e4e}', '\u{1e4f}'), ('\u{1e50}', '\u{1e51}'),
-        ('\u{1e52}', '\u{1e53}'), ('\u{1e54}', '\u{1e55}'), ('\u{1e56}', '\u{1e57}'), ('\u{1e58}',
-        '\u{1e59}'), ('\u{1e5a}', '\u{1e5b}'), ('\u{1e5c}', '\u{1e5d}'), ('\u{1e5e}', '\u{1e5f}'),
-        ('\u{1e60}', '\u{1e61}'), ('\u{1e62}', '\u{1e63}'), ('\u{1e64}', '\u{1e65}'), ('\u{1e66}',
-        '\u{1e67}'), ('\u{1e68}', '\u{1e69}'), ('\u{1e6a}', '\u{1e6b}'), ('\u{1e6c}', '\u{1e6d}'),
-        ('\u{1e6e}', '\u{1e6f}'), ('\u{1e70}', '\u{1e71}'), ('\u{1e72}', '\u{1e73}'), ('\u{1e74}',
-        '\u{1e75}'), ('\u{1e76}', '\u{1e77}'), ('\u{1e78}', '\u{1e79}'), ('\u{1e7a}', '\u{1e7b}'),
-        ('\u{1e7c}', '\u{1e7d}'), ('\u{1e7e}', '\u{1e7f}'), ('\u{1e80}', '\u{1e81}'), ('\u{1e82}',
-        '\u{1e83}'), ('\u{1e84}', '\u{1e85}'), ('\u{1e86}', '\u{1e87}'), ('\u{1e88}', '\u{1e89}'),
-        ('\u{1e8a}', '\u{1e8b}'), ('\u{1e8c}', '\u{1e8d}'), ('\u{1e8e}', '\u{1e8f}'), ('\u{1e90}',
-        '\u{1e91}'), ('\u{1e92}', '\u{1e93}'), ('\u{1e94}', '\u{1e95}'), ('\u{1e9e}', '\u{df}'),
-        ('\u{1ea0}', '\u{1ea1}'), ('\u{1ea2}', '\u{1ea3}'), ('\u{1ea4}', '\u{1ea5}'), ('\u{1ea6}',
-        '\u{1ea7}'), ('\u{1ea8}', '\u{1ea9}'), ('\u{1eaa}', '\u{1eab}'), ('\u{1eac}', '\u{1ead}'),
-        ('\u{1eae}', '\u{1eaf}'), ('\u{1eb0}', '\u{1eb1}'), ('\u{1eb2}', '\u{1eb3}'), ('\u{1eb4}',
-        '\u{1eb5}'), ('\u{1eb6}', '\u{1eb7}'), ('\u{1eb8}', '\u{1eb9}'), ('\u{1eba}', '\u{1ebb}'),
-        ('\u{1ebc}', '\u{1ebd}'), ('\u{1ebe}', '\u{1ebf}'), ('\u{1ec0}', '\u{1ec1}'), ('\u{1ec2}',
-        '\u{1ec3}'), ('\u{1ec4}', '\u{1ec5}'), ('\u{1ec6}', '\u{1ec7}'), ('\u{1ec8}', '\u{1ec9}'),
-        ('\u{1eca}', '\u{1ecb}'), ('\u{1ecc}', '\u{1ecd}'), ('\u{1ece}', '\u{1ecf}'), ('\u{1ed0}',
-        '\u{1ed1}'), ('\u{1ed2}', '\u{1ed3}'), ('\u{1ed4}', '\u{1ed5}'), ('\u{1ed6}', '\u{1ed7}'),
-        ('\u{1ed8}', '\u{1ed9}'), ('\u{1eda}', '\u{1edb}'), ('\u{1edc}', '\u{1edd}'), ('\u{1ede}',
-        '\u{1edf}'), ('\u{1ee0}', '\u{1ee1}'), ('\u{1ee2}', '\u{1ee3}'), ('\u{1ee4}', '\u{1ee5}'),
-        ('\u{1ee6}', '\u{1ee7}'), ('\u{1ee8}', '\u{1ee9}'), ('\u{1eea}', '\u{1eeb}'), ('\u{1eec}',
-        '\u{1eed}'), ('\u{1eee}', '\u{1eef}'), ('\u{1ef0}', '\u{1ef1}'), ('\u{1ef2}', '\u{1ef3}'),
-        ('\u{1ef4}', '\u{1ef5}'), ('\u{1ef6}', '\u{1ef7}'), ('\u{1ef8}', '\u{1ef9}'), ('\u{1efa}',
-        '\u{1efb}'), ('\u{1efc}', '\u{1efd}'), ('\u{1efe}', '\u{1eff}'), ('\u{1f08}', '\u{1f00}'),
-        ('\u{1f09}', '\u{1f01}'), ('\u{1f0a}', '\u{1f02}'), ('\u{1f0b}', '\u{1f03}'), ('\u{1f0c}',
-        '\u{1f04}'), ('\u{1f0d}', '\u{1f05}'), ('\u{1f0e}', '\u{1f06}'), ('\u{1f0f}', '\u{1f07}'),
-        ('\u{1f18}', '\u{1f10}'), ('\u{1f19}', '\u{1f11}'), ('\u{1f1a}', '\u{1f12}'), ('\u{1f1b}',
-        '\u{1f13}'), ('\u{1f1c}', '\u{1f14}'), ('\u{1f1d}', '\u{1f15}'), ('\u{1f28}', '\u{1f20}'),
-        ('\u{1f29}', '\u{1f21}'), ('\u{1f2a}', '\u{1f22}'), ('\u{1f2b}', '\u{1f23}'), ('\u{1f2c}',
-        '\u{1f24}'), ('\u{1f2d}', '\u{1f25}'), ('\u{1f2e}', '\u{1f26}'), ('\u{1f2f}', '\u{1f27}'),
-        ('\u{1f38}', '\u{1f30}'), ('\u{1f39}', '\u{1f31}'), ('\u{1f3a}', '\u{1f32}'), ('\u{1f3b}',
-        '\u{1f33}'), ('\u{1f3c}', '\u{1f34}'), ('\u{1f3d}', '\u{1f35}'), ('\u{1f3e}', '\u{1f36}'),
-        ('\u{1f3f}', '\u{1f37}'), ('\u{1f48}', '\u{1f40}'), ('\u{1f49}', '\u{1f41}'), ('\u{1f4a}',
-        '\u{1f42}'), ('\u{1f4b}', '\u{1f43}'), ('\u{1f4c}', '\u{1f44}'), ('\u{1f4d}', '\u{1f45}'),
-        ('\u{1f59}', '\u{1f51}'), ('\u{1f5b}', '\u{1f53}'), ('\u{1f5d}', '\u{1f55}'), ('\u{1f5f}',
-        '\u{1f57}'), ('\u{1f68}', '\u{1f60}'), ('\u{1f69}', '\u{1f61}'), ('\u{1f6a}', '\u{1f62}'),
-        ('\u{1f6b}', '\u{1f63}'), ('\u{1f6c}', '\u{1f64}'), ('\u{1f6d}', '\u{1f65}'), ('\u{1f6e}',
-        '\u{1f66}'), ('\u{1f6f}', '\u{1f67}'), ('\u{1fb8}', '\u{1fb0}'), ('\u{1fb9}', '\u{1fb1}'),
-        ('\u{1fba}', '\u{1f70}'), ('\u{1fbb}', '\u{1f71}'), ('\u{1fc8}', '\u{1f72}'), ('\u{1fc9}',
-        '\u{1f73}'), ('\u{1fca}', '\u{1f74}'), ('\u{1fcb}', '\u{1f75}'), ('\u{1fd8}', '\u{1fd0}'),
-        ('\u{1fd9}', '\u{1fd1}'), ('\u{1fda}', '\u{1f76}'), ('\u{1fdb}', '\u{1f77}'), ('\u{1fe8}',
-        '\u{1fe0}'), ('\u{1fe9}', '\u{1fe1}'), ('\u{1fea}', '\u{1f7a}'), ('\u{1feb}', '\u{1f7b}'),
-        ('\u{1fec}', '\u{1fe5}'), ('\u{1ff8}', '\u{1f78}'), ('\u{1ff9}', '\u{1f79}'), ('\u{1ffa}',
-        '\u{1f7c}'), ('\u{1ffb}', '\u{1f7d}'), ('\u{2126}', '\u{3c9}'), ('\u{212a}', '\u{6b}'),
-        ('\u{212b}', '\u{e5}'), ('\u{2132}', '\u{214e}'), ('\u{2183}', '\u{2184}'), ('\u{2c00}',
-        '\u{2c30}'), ('\u{2c01}', '\u{2c31}'), ('\u{2c02}', '\u{2c32}'), ('\u{2c03}', '\u{2c33}'),
-        ('\u{2c04}', '\u{2c34}'), ('\u{2c05}', '\u{2c35}'), ('\u{2c06}', '\u{2c36}'), ('\u{2c07}',
-        '\u{2c37}'), ('\u{2c08}', '\u{2c38}'), ('\u{2c09}', '\u{2c39}'), ('\u{2c0a}', '\u{2c3a}'),
-        ('\u{2c0b}', '\u{2c3b}'), ('\u{2c0c}', '\u{2c3c}'), ('\u{2c0d}', '\u{2c3d}'), ('\u{2c0e}',
-        '\u{2c3e}'), ('\u{2c0f}', '\u{2c3f}'), ('\u{2c10}', '\u{2c40}'), ('\u{2c11}', '\u{2c41}'),
-        ('\u{2c12}', '\u{2c42}'), ('\u{2c13}', '\u{2c43}'), ('\u{2c14}', '\u{2c44}'), ('\u{2c15}',
-        '\u{2c45}'), ('\u{2c16}', '\u{2c46}'), ('\u{2c17}', '\u{2c47}'), ('\u{2c18}', '\u{2c48}'),
-        ('\u{2c19}', '\u{2c49}'), ('\u{2c1a}', '\u{2c4a}'), ('\u{2c1b}', '\u{2c4b}'), ('\u{2c1c}',
-        '\u{2c4c}'), ('\u{2c1d}', '\u{2c4d}'), ('\u{2c1e}', '\u{2c4e}'), ('\u{2c1f}', '\u{2c4f}'),
-        ('\u{2c20}', '\u{2c50}'), ('\u{2c21}', '\u{2c51}'), ('\u{2c22}', '\u{2c52}'), ('\u{2c23}',
-        '\u{2c53}'), ('\u{2c24}', '\u{2c54}'), ('\u{2c25}', '\u{2c55}'), ('\u{2c26}', '\u{2c56}'),
-        ('\u{2c27}', '\u{2c57}'), ('\u{2c28}', '\u{2c58}'), ('\u{2c29}', '\u{2c59}'), ('\u{2c2a}',
-        '\u{2c5a}'), ('\u{2c2b}', '\u{2c5b}'), ('\u{2c2c}', '\u{2c5c}'), ('\u{2c2d}', '\u{2c5d}'),
-        ('\u{2c2e}', '\u{2c5e}'), ('\u{2c60}', '\u{2c61}'), ('\u{2c62}', '\u{26b}'), ('\u{2c63}',
-        '\u{1d7d}'), ('\u{2c64}', '\u{27d}'), ('\u{2c67}', '\u{2c68}'), ('\u{2c69}', '\u{2c6a}'),
-        ('\u{2c6b}', '\u{2c6c}'), ('\u{2c6d}', '\u{251}'), ('\u{2c6e}', '\u{271}'), ('\u{2c6f}',
-        '\u{250}'), ('\u{2c70}', '\u{252}'), ('\u{2c72}', '\u{2c73}'), ('\u{2c75}', '\u{2c76}'),
-        ('\u{2c7e}', '\u{23f}'), ('\u{2c7f}', '\u{240}'), ('\u{2c80}', '\u{2c81}'), ('\u{2c82}',
-        '\u{2c83}'), ('\u{2c84}', '\u{2c85}'), ('\u{2c86}', '\u{2c87}'), ('\u{2c88}', '\u{2c89}'),
-        ('\u{2c8a}', '\u{2c8b}'), ('\u{2c8c}', '\u{2c8d}'), ('\u{2c8e}', '\u{2c8f}'), ('\u{2c90}',
-        '\u{2c91}'), ('\u{2c92}', '\u{2c93}'), ('\u{2c94}', '\u{2c95}'), ('\u{2c96}', '\u{2c97}'),
-        ('\u{2c98}', '\u{2c99}'), ('\u{2c9a}', '\u{2c9b}'), ('\u{2c9c}', '\u{2c9d}'), ('\u{2c9e}',
-        '\u{2c9f}'), ('\u{2ca0}', '\u{2ca1}'), ('\u{2ca2}', '\u{2ca3}'), ('\u{2ca4}', '\u{2ca5}'),
-        ('\u{2ca6}', '\u{2ca7}'), ('\u{2ca8}', '\u{2ca9}'), ('\u{2caa}', '\u{2cab}'), ('\u{2cac}',
-        '\u{2cad}'), ('\u{2cae}', '\u{2caf}'), ('\u{2cb0}', '\u{2cb1}'), ('\u{2cb2}', '\u{2cb3}'),
-        ('\u{2cb4}', '\u{2cb5}'), ('\u{2cb6}', '\u{2cb7}'), ('\u{2cb8}', '\u{2cb9}'), ('\u{2cba}',
-        '\u{2cbb}'), ('\u{2cbc}', '\u{2cbd}'), ('\u{2cbe}', '\u{2cbf}'), ('\u{2cc0}', '\u{2cc1}'),
-        ('\u{2cc2}', '\u{2cc3}'), ('\u{2cc4}', '\u{2cc5}'), ('\u{2cc6}', '\u{2cc7}'), ('\u{2cc8}',
-        '\u{2cc9}'), ('\u{2cca}', '\u{2ccb}'), ('\u{2ccc}', '\u{2ccd}'), ('\u{2cce}', '\u{2ccf}'),
-        ('\u{2cd0}', '\u{2cd1}'), ('\u{2cd2}', '\u{2cd3}'), ('\u{2cd4}', '\u{2cd5}'), ('\u{2cd6}',
-        '\u{2cd7}'), ('\u{2cd8}', '\u{2cd9}'), ('\u{2cda}', '\u{2cdb}'), ('\u{2cdc}', '\u{2cdd}'),
-        ('\u{2cde}', '\u{2cdf}'), ('\u{2ce0}', '\u{2ce1}'), ('\u{2ce2}', '\u{2ce3}'), ('\u{2ceb}',
-        '\u{2cec}'), ('\u{2ced}', '\u{2cee}'), ('\u{2cf2}', '\u{2cf3}'), ('\u{a640}', '\u{a641}'),
-        ('\u{a642}', '\u{a643}'), ('\u{a644}', '\u{a645}'), ('\u{a646}', '\u{a647}'), ('\u{a648}',
-        '\u{a649}'), ('\u{a64a}', '\u{a64b}'), ('\u{a64c}', '\u{a64d}'), ('\u{a64e}', '\u{a64f}'),
-        ('\u{a650}', '\u{a651}'), ('\u{a652}', '\u{a653}'), ('\u{a654}', '\u{a655}'), ('\u{a656}',
-        '\u{a657}'), ('\u{a658}', '\u{a659}'), ('\u{a65a}', '\u{a65b}'), ('\u{a65c}', '\u{a65d}'),
-        ('\u{a65e}', '\u{a65f}'), ('\u{a660}', '\u{a661}'), ('\u{a662}', '\u{a663}'), ('\u{a664}',
-        '\u{a665}'), ('\u{a666}', '\u{a667}'), ('\u{a668}', '\u{a669}'), ('\u{a66a}', '\u{a66b}'),
-        ('\u{a66c}', '\u{a66d}'), ('\u{a680}', '\u{a681}'), ('\u{a682}', '\u{a683}'), ('\u{a684}',
-        '\u{a685}'), ('\u{a686}', '\u{a687}'), ('\u{a688}', '\u{a689}'), ('\u{a68a}', '\u{a68b}'),
-        ('\u{a68c}', '\u{a68d}'), ('\u{a68e}', '\u{a68f}'), ('\u{a690}', '\u{a691}'), ('\u{a692}',
-        '\u{a693}'), ('\u{a694}', '\u{a695}'), ('\u{a696}', '\u{a697}'), ('\u{a698}', '\u{a699}'),
-        ('\u{a69a}', '\u{a69b}'), ('\u{a722}', '\u{a723}'), ('\u{a724}', '\u{a725}'), ('\u{a726}',
-        '\u{a727}'), ('\u{a728}', '\u{a729}'), ('\u{a72a}', '\u{a72b}'), ('\u{a72c}', '\u{a72d}'),
-        ('\u{a72e}', '\u{a72f}'), ('\u{a732}', '\u{a733}'), ('\u{a734}', '\u{a735}'), ('\u{a736}',
-        '\u{a737}'), ('\u{a738}', '\u{a739}'), ('\u{a73a}', '\u{a73b}'), ('\u{a73c}', '\u{a73d}'),
-        ('\u{a73e}', '\u{a73f}'), ('\u{a740}', '\u{a741}'), ('\u{a742}', '\u{a743}'), ('\u{a744}',
-        '\u{a745}'), ('\u{a746}', '\u{a747}'), ('\u{a748}', '\u{a749}'), ('\u{a74a}', '\u{a74b}'),
-        ('\u{a74c}', '\u{a74d}'), ('\u{a74e}', '\u{a74f}'), ('\u{a750}', '\u{a751}'), ('\u{a752}',
-        '\u{a753}'), ('\u{a754}', '\u{a755}'), ('\u{a756}', '\u{a757}'), ('\u{a758}', '\u{a759}'),
-        ('\u{a75a}', '\u{a75b}'), ('\u{a75c}', '\u{a75d}'), ('\u{a75e}', '\u{a75f}'), ('\u{a760}',
-        '\u{a761}'), ('\u{a762}', '\u{a763}'), ('\u{a764}', '\u{a765}'), ('\u{a766}', '\u{a767}'),
-        ('\u{a768}', '\u{a769}'), ('\u{a76a}', '\u{a76b}'), ('\u{a76c}', '\u{a76d}'), ('\u{a76e}',
-        '\u{a76f}'), ('\u{a779}', '\u{a77a}'), ('\u{a77b}', '\u{a77c}'), ('\u{a77d}', '\u{1d79}'),
-        ('\u{a77e}', '\u{a77f}'), ('\u{a780}', '\u{a781}'), ('\u{a782}', '\u{a783}'), ('\u{a784}',
-        '\u{a785}'), ('\u{a786}', '\u{a787}'), ('\u{a78b}', '\u{a78c}'), ('\u{a78d}', '\u{265}'),
-        ('\u{a790}', '\u{a791}'), ('\u{a792}', '\u{a793}'), ('\u{a796}', '\u{a797}'), ('\u{a798}',
-        '\u{a799}'), ('\u{a79a}', '\u{a79b}'), ('\u{a79c}', '\u{a79d}'), ('\u{a79e}', '\u{a79f}'),
-        ('\u{a7a0}', '\u{a7a1}'), ('\u{a7a2}', '\u{a7a3}'), ('\u{a7a4}', '\u{a7a5}'), ('\u{a7a6}',
-        '\u{a7a7}'), ('\u{a7a8}', '\u{a7a9}'), ('\u{a7aa}', '\u{266}'), ('\u{a7ab}', '\u{25c}'),
-        ('\u{a7ac}', '\u{261}'), ('\u{a7ad}', '\u{26c}'), ('\u{a7b0}', '\u{29e}'), ('\u{a7b1}',
-        '\u{287}'), ('\u{ff21}', '\u{ff41}'), ('\u{ff22}', '\u{ff42}'), ('\u{ff23}', '\u{ff43}'),
-        ('\u{ff24}', '\u{ff44}'), ('\u{ff25}', '\u{ff45}'), ('\u{ff26}', '\u{ff46}'), ('\u{ff27}',
-        '\u{ff47}'), ('\u{ff28}', '\u{ff48}'), ('\u{ff29}', '\u{ff49}'), ('\u{ff2a}', '\u{ff4a}'),
-        ('\u{ff2b}', '\u{ff4b}'), ('\u{ff2c}', '\u{ff4c}'), ('\u{ff2d}', '\u{ff4d}'), ('\u{ff2e}',
-        '\u{ff4e}'), ('\u{ff2f}', '\u{ff4f}'), ('\u{ff30}', '\u{ff50}'), ('\u{ff31}', '\u{ff51}'),
-        ('\u{ff32}', '\u{ff52}'), ('\u{ff33}', '\u{ff53}'), ('\u{ff34}', '\u{ff54}'), ('\u{ff35}',
-        '\u{ff55}'), ('\u{ff36}', '\u{ff56}'), ('\u{ff37}', '\u{ff57}'), ('\u{ff38}', '\u{ff58}'),
-        ('\u{ff39}', '\u{ff59}'), ('\u{ff3a}', '\u{ff5a}'), ('\u{10400}', '\u{10428}'),
-        ('\u{10401}', '\u{10429}'), ('\u{10402}', '\u{1042a}'), ('\u{10403}', '\u{1042b}'),
-        ('\u{10404}', '\u{1042c}'), ('\u{10405}', '\u{1042d}'), ('\u{10406}', '\u{1042e}'),
-        ('\u{10407}', '\u{1042f}'), ('\u{10408}', '\u{10430}'), ('\u{10409}', '\u{10431}'),
-        ('\u{1040a}', '\u{10432}'), ('\u{1040b}', '\u{10433}'), ('\u{1040c}', '\u{10434}'),
-        ('\u{1040d}', '\u{10435}'), ('\u{1040e}', '\u{10436}'), ('\u{1040f}', '\u{10437}'),
-        ('\u{10410}', '\u{10438}'), ('\u{10411}', '\u{10439}'), ('\u{10412}', '\u{1043a}'),
-        ('\u{10413}', '\u{1043b}'), ('\u{10414}', '\u{1043c}'), ('\u{10415}', '\u{1043d}'),
-        ('\u{10416}', '\u{1043e}'), ('\u{10417}', '\u{1043f}'), ('\u{10418}', '\u{10440}'),
-        ('\u{10419}', '\u{10441}'), ('\u{1041a}', '\u{10442}'), ('\u{1041b}', '\u{10443}'),
-        ('\u{1041c}', '\u{10444}'), ('\u{1041d}', '\u{10445}'), ('\u{1041e}', '\u{10446}'),
-        ('\u{1041f}', '\u{10447}'), ('\u{10420}', '\u{10448}'), ('\u{10421}', '\u{10449}'),
-        ('\u{10422}', '\u{1044a}'), ('\u{10423}', '\u{1044b}'), ('\u{10424}', '\u{1044c}'),
-        ('\u{10425}', '\u{1044d}'), ('\u{10426}', '\u{1044e}'), ('\u{10427}', '\u{1044f}'),
-        ('\u{118a0}', '\u{118c0}'), ('\u{118a1}', '\u{118c1}'), ('\u{118a2}', '\u{118c2}'),
-        ('\u{118a3}', '\u{118c3}'), ('\u{118a4}', '\u{118c4}'), ('\u{118a5}', '\u{118c5}'),
-        ('\u{118a6}', '\u{118c6}'), ('\u{118a7}', '\u{118c7}'), ('\u{118a8}', '\u{118c8}'),
-        ('\u{118a9}', '\u{118c9}'), ('\u{118aa}', '\u{118ca}'), ('\u{118ab}', '\u{118cb}'),
-        ('\u{118ac}', '\u{118cc}'), ('\u{118ad}', '\u{118cd}'), ('\u{118ae}', '\u{118ce}'),
-        ('\u{118af}', '\u{118cf}'), ('\u{118b0}', '\u{118d0}'), ('\u{118b1}', '\u{118d1}'),
-        ('\u{118b2}', '\u{118d2}'), ('\u{118b3}', '\u{118d3}'), ('\u{118b4}', '\u{118d4}'),
-        ('\u{118b5}', '\u{118d5}'), ('\u{118b6}', '\u{118d6}'), ('\u{118b7}', '\u{118d7}'),
-        ('\u{118b8}', '\u{118d8}'), ('\u{118b9}', '\u{118d9}'), ('\u{118ba}', '\u{118da}'),
-        ('\u{118bb}', '\u{118db}'), ('\u{118bc}', '\u{118dc}'), ('\u{118bd}', '\u{118dd}'),
-        ('\u{118be}', '\u{118de}'), ('\u{118bf}', '\u{118df}')
+    const to_lowercase_table: &'static [(char, [char; 3])] = &[
+        ('\u{41}', ['\u{61}', '\0', '\0']), ('\u{42}', ['\u{62}', '\0', '\0']), ('\u{43}',
+        ['\u{63}', '\0', '\0']), ('\u{44}', ['\u{64}', '\0', '\0']), ('\u{45}', ['\u{65}', '\0',
+        '\0']), ('\u{46}', ['\u{66}', '\0', '\0']), ('\u{47}', ['\u{67}', '\0', '\0']), ('\u{48}',
+        ['\u{68}', '\0', '\0']), ('\u{49}', ['\u{69}', '\0', '\0']), ('\u{4a}', ['\u{6a}', '\0',
+        '\0']), ('\u{4b}', ['\u{6b}', '\0', '\0']), ('\u{4c}', ['\u{6c}', '\0', '\0']), ('\u{4d}',
+        ['\u{6d}', '\0', '\0']), ('\u{4e}', ['\u{6e}', '\0', '\0']), ('\u{4f}', ['\u{6f}', '\0',
+        '\0']), ('\u{50}', ['\u{70}', '\0', '\0']), ('\u{51}', ['\u{71}', '\0', '\0']), ('\u{52}',
+        ['\u{72}', '\0', '\0']), ('\u{53}', ['\u{73}', '\0', '\0']), ('\u{54}', ['\u{74}', '\0',
+        '\0']), ('\u{55}', ['\u{75}', '\0', '\0']), ('\u{56}', ['\u{76}', '\0', '\0']), ('\u{57}',
+        ['\u{77}', '\0', '\0']), ('\u{58}', ['\u{78}', '\0', '\0']), ('\u{59}', ['\u{79}', '\0',
+        '\0']), ('\u{5a}', ['\u{7a}', '\0', '\0']), ('\u{c0}', ['\u{e0}', '\0', '\0']), ('\u{c1}',
+        ['\u{e1}', '\0', '\0']), ('\u{c2}', ['\u{e2}', '\0', '\0']), ('\u{c3}', ['\u{e3}', '\0',
+        '\0']), ('\u{c4}', ['\u{e4}', '\0', '\0']), ('\u{c5}', ['\u{e5}', '\0', '\0']), ('\u{c6}',
+        ['\u{e6}', '\0', '\0']), ('\u{c7}', ['\u{e7}', '\0', '\0']), ('\u{c8}', ['\u{e8}', '\0',
+        '\0']), ('\u{c9}', ['\u{e9}', '\0', '\0']), ('\u{ca}', ['\u{ea}', '\0', '\0']), ('\u{cb}',
+        ['\u{eb}', '\0', '\0']), ('\u{cc}', ['\u{ec}', '\0', '\0']), ('\u{cd}', ['\u{ed}', '\0',
+        '\0']), ('\u{ce}', ['\u{ee}', '\0', '\0']), ('\u{cf}', ['\u{ef}', '\0', '\0']), ('\u{d0}',
+        ['\u{f0}', '\0', '\0']), ('\u{d1}', ['\u{f1}', '\0', '\0']), ('\u{d2}', ['\u{f2}', '\0',
+        '\0']), ('\u{d3}', ['\u{f3}', '\0', '\0']), ('\u{d4}', ['\u{f4}', '\0', '\0']), ('\u{d5}',
+        ['\u{f5}', '\0', '\0']), ('\u{d6}', ['\u{f6}', '\0', '\0']), ('\u{d8}', ['\u{f8}', '\0',
+        '\0']), ('\u{d9}', ['\u{f9}', '\0', '\0']), ('\u{da}', ['\u{fa}', '\0', '\0']), ('\u{db}',
+        ['\u{fb}', '\0', '\0']), ('\u{dc}', ['\u{fc}', '\0', '\0']), ('\u{dd}', ['\u{fd}', '\0',
+        '\0']), ('\u{de}', ['\u{fe}', '\0', '\0']), ('\u{100}', ['\u{101}', '\0', '\0']),
+        ('\u{102}', ['\u{103}', '\0', '\0']), ('\u{104}', ['\u{105}', '\0', '\0']), ('\u{106}',
+        ['\u{107}', '\0', '\0']), ('\u{108}', ['\u{109}', '\0', '\0']), ('\u{10a}', ['\u{10b}',
+        '\0', '\0']), ('\u{10c}', ['\u{10d}', '\0', '\0']), ('\u{10e}', ['\u{10f}', '\0', '\0']),
+        ('\u{110}', ['\u{111}', '\0', '\0']), ('\u{112}', ['\u{113}', '\0', '\0']), ('\u{114}',
+        ['\u{115}', '\0', '\0']), ('\u{116}', ['\u{117}', '\0', '\0']), ('\u{118}', ['\u{119}',
+        '\0', '\0']), ('\u{11a}', ['\u{11b}', '\0', '\0']), ('\u{11c}', ['\u{11d}', '\0', '\0']),
+        ('\u{11e}', ['\u{11f}', '\0', '\0']), ('\u{120}', ['\u{121}', '\0', '\0']), ('\u{122}',
+        ['\u{123}', '\0', '\0']), ('\u{124}', ['\u{125}', '\0', '\0']), ('\u{126}', ['\u{127}',
+        '\0', '\0']), ('\u{128}', ['\u{129}', '\0', '\0']), ('\u{12a}', ['\u{12b}', '\0', '\0']),
+        ('\u{12c}', ['\u{12d}', '\0', '\0']), ('\u{12e}', ['\u{12f}', '\0', '\0']), ('\u{130}',
+        ['\u{69}', '\u{307}', '\0']), ('\u{132}', ['\u{133}', '\0', '\0']), ('\u{134}', ['\u{135}',
+        '\0', '\0']), ('\u{136}', ['\u{137}', '\0', '\0']), ('\u{139}', ['\u{13a}', '\0', '\0']),
+        ('\u{13b}', ['\u{13c}', '\0', '\0']), ('\u{13d}', ['\u{13e}', '\0', '\0']), ('\u{13f}',
+        ['\u{140}', '\0', '\0']), ('\u{141}', ['\u{142}', '\0', '\0']), ('\u{143}', ['\u{144}',
+        '\0', '\0']), ('\u{145}', ['\u{146}', '\0', '\0']), ('\u{147}', ['\u{148}', '\0', '\0']),
+        ('\u{14a}', ['\u{14b}', '\0', '\0']), ('\u{14c}', ['\u{14d}', '\0', '\0']), ('\u{14e}',
+        ['\u{14f}', '\0', '\0']), ('\u{150}', ['\u{151}', '\0', '\0']), ('\u{152}', ['\u{153}',
+        '\0', '\0']), ('\u{154}', ['\u{155}', '\0', '\0']), ('\u{156}', ['\u{157}', '\0', '\0']),
+        ('\u{158}', ['\u{159}', '\0', '\0']), ('\u{15a}', ['\u{15b}', '\0', '\0']), ('\u{15c}',
+        ['\u{15d}', '\0', '\0']), ('\u{15e}', ['\u{15f}', '\0', '\0']), ('\u{160}', ['\u{161}',
+        '\0', '\0']), ('\u{162}', ['\u{163}', '\0', '\0']), ('\u{164}', ['\u{165}', '\0', '\0']),
+        ('\u{166}', ['\u{167}', '\0', '\0']), ('\u{168}', ['\u{169}', '\0', '\0']), ('\u{16a}',
+        ['\u{16b}', '\0', '\0']), ('\u{16c}', ['\u{16d}', '\0', '\0']), ('\u{16e}', ['\u{16f}',
+        '\0', '\0']), ('\u{170}', ['\u{171}', '\0', '\0']), ('\u{172}', ['\u{173}', '\0', '\0']),
+        ('\u{174}', ['\u{175}', '\0', '\0']), ('\u{176}', ['\u{177}', '\0', '\0']), ('\u{178}',
+        ['\u{ff}', '\0', '\0']), ('\u{179}', ['\u{17a}', '\0', '\0']), ('\u{17b}', ['\u{17c}', '\0',
+        '\0']), ('\u{17d}', ['\u{17e}', '\0', '\0']), ('\u{181}', ['\u{253}', '\0', '\0']),
+        ('\u{182}', ['\u{183}', '\0', '\0']), ('\u{184}', ['\u{185}', '\0', '\0']), ('\u{186}',
+        ['\u{254}', '\0', '\0']), ('\u{187}', ['\u{188}', '\0', '\0']), ('\u{189}', ['\u{256}',
+        '\0', '\0']), ('\u{18a}', ['\u{257}', '\0', '\0']), ('\u{18b}', ['\u{18c}', '\0', '\0']),
+        ('\u{18e}', ['\u{1dd}', '\0', '\0']), ('\u{18f}', ['\u{259}', '\0', '\0']), ('\u{190}',
+        ['\u{25b}', '\0', '\0']), ('\u{191}', ['\u{192}', '\0', '\0']), ('\u{193}', ['\u{260}',
+        '\0', '\0']), ('\u{194}', ['\u{263}', '\0', '\0']), ('\u{196}', ['\u{269}', '\0', '\0']),
+        ('\u{197}', ['\u{268}', '\0', '\0']), ('\u{198}', ['\u{199}', '\0', '\0']), ('\u{19c}',
+        ['\u{26f}', '\0', '\0']), ('\u{19d}', ['\u{272}', '\0', '\0']), ('\u{19f}', ['\u{275}',
+        '\0', '\0']), ('\u{1a0}', ['\u{1a1}', '\0', '\0']), ('\u{1a2}', ['\u{1a3}', '\0', '\0']),
+        ('\u{1a4}', ['\u{1a5}', '\0', '\0']), ('\u{1a6}', ['\u{280}', '\0', '\0']), ('\u{1a7}',
+        ['\u{1a8}', '\0', '\0']), ('\u{1a9}', ['\u{283}', '\0', '\0']), ('\u{1ac}', ['\u{1ad}',
+        '\0', '\0']), ('\u{1ae}', ['\u{288}', '\0', '\0']), ('\u{1af}', ['\u{1b0}', '\0', '\0']),
+        ('\u{1b1}', ['\u{28a}', '\0', '\0']), ('\u{1b2}', ['\u{28b}', '\0', '\0']), ('\u{1b3}',
+        ['\u{1b4}', '\0', '\0']), ('\u{1b5}', ['\u{1b6}', '\0', '\0']), ('\u{1b7}', ['\u{292}',
+        '\0', '\0']), ('\u{1b8}', ['\u{1b9}', '\0', '\0']), ('\u{1bc}', ['\u{1bd}', '\0', '\0']),
+        ('\u{1c4}', ['\u{1c6}', '\0', '\0']), ('\u{1c5}', ['\u{1c6}', '\0', '\0']), ('\u{1c7}',
+        ['\u{1c9}', '\0', '\0']), ('\u{1c8}', ['\u{1c9}', '\0', '\0']), ('\u{1ca}', ['\u{1cc}',
+        '\0', '\0']), ('\u{1cb}', ['\u{1cc}', '\0', '\0']), ('\u{1cd}', ['\u{1ce}', '\0', '\0']),
+        ('\u{1cf}', ['\u{1d0}', '\0', '\0']), ('\u{1d1}', ['\u{1d2}', '\0', '\0']), ('\u{1d3}',
+        ['\u{1d4}', '\0', '\0']), ('\u{1d5}', ['\u{1d6}', '\0', '\0']), ('\u{1d7}', ['\u{1d8}',
+        '\0', '\0']), ('\u{1d9}', ['\u{1da}', '\0', '\0']), ('\u{1db}', ['\u{1dc}', '\0', '\0']),
+        ('\u{1de}', ['\u{1df}', '\0', '\0']), ('\u{1e0}', ['\u{1e1}', '\0', '\0']), ('\u{1e2}',
+        ['\u{1e3}', '\0', '\0']), ('\u{1e4}', ['\u{1e5}', '\0', '\0']), ('\u{1e6}', ['\u{1e7}',
+        '\0', '\0']), ('\u{1e8}', ['\u{1e9}', '\0', '\0']), ('\u{1ea}', ['\u{1eb}', '\0', '\0']),
+        ('\u{1ec}', ['\u{1ed}', '\0', '\0']), ('\u{1ee}', ['\u{1ef}', '\0', '\0']), ('\u{1f1}',
+        ['\u{1f3}', '\0', '\0']), ('\u{1f2}', ['\u{1f3}', '\0', '\0']), ('\u{1f4}', ['\u{1f5}',
+        '\0', '\0']), ('\u{1f6}', ['\u{195}', '\0', '\0']), ('\u{1f7}', ['\u{1bf}', '\0', '\0']),
+        ('\u{1f8}', ['\u{1f9}', '\0', '\0']), ('\u{1fa}', ['\u{1fb}', '\0', '\0']), ('\u{1fc}',
+        ['\u{1fd}', '\0', '\0']), ('\u{1fe}', ['\u{1ff}', '\0', '\0']), ('\u{200}', ['\u{201}',
+        '\0', '\0']), ('\u{202}', ['\u{203}', '\0', '\0']), ('\u{204}', ['\u{205}', '\0', '\0']),
+        ('\u{206}', ['\u{207}', '\0', '\0']), ('\u{208}', ['\u{209}', '\0', '\0']), ('\u{20a}',
+        ['\u{20b}', '\0', '\0']), ('\u{20c}', ['\u{20d}', '\0', '\0']), ('\u{20e}', ['\u{20f}',
+        '\0', '\0']), ('\u{210}', ['\u{211}', '\0', '\0']), ('\u{212}', ['\u{213}', '\0', '\0']),
+        ('\u{214}', ['\u{215}', '\0', '\0']), ('\u{216}', ['\u{217}', '\0', '\0']), ('\u{218}',
+        ['\u{219}', '\0', '\0']), ('\u{21a}', ['\u{21b}', '\0', '\0']), ('\u{21c}', ['\u{21d}',
+        '\0', '\0']), ('\u{21e}', ['\u{21f}', '\0', '\0']), ('\u{220}', ['\u{19e}', '\0', '\0']),
+        ('\u{222}', ['\u{223}', '\0', '\0']), ('\u{224}', ['\u{225}', '\0', '\0']), ('\u{226}',
+        ['\u{227}', '\0', '\0']), ('\u{228}', ['\u{229}', '\0', '\0']), ('\u{22a}', ['\u{22b}',
+        '\0', '\0']), ('\u{22c}', ['\u{22d}', '\0', '\0']), ('\u{22e}', ['\u{22f}', '\0', '\0']),
+        ('\u{230}', ['\u{231}', '\0', '\0']), ('\u{232}', ['\u{233}', '\0', '\0']), ('\u{23a}',
+        ['\u{2c65}', '\0', '\0']), ('\u{23b}', ['\u{23c}', '\0', '\0']), ('\u{23d}', ['\u{19a}',
+        '\0', '\0']), ('\u{23e}', ['\u{2c66}', '\0', '\0']), ('\u{241}', ['\u{242}', '\0', '\0']),
+        ('\u{243}', ['\u{180}', '\0', '\0']), ('\u{244}', ['\u{289}', '\0', '\0']), ('\u{245}',
+        ['\u{28c}', '\0', '\0']), ('\u{246}', ['\u{247}', '\0', '\0']), ('\u{248}', ['\u{249}',
+        '\0', '\0']), ('\u{24a}', ['\u{24b}', '\0', '\0']), ('\u{24c}', ['\u{24d}', '\0', '\0']),
+        ('\u{24e}', ['\u{24f}', '\0', '\0']), ('\u{370}', ['\u{371}', '\0', '\0']), ('\u{372}',
+        ['\u{373}', '\0', '\0']), ('\u{376}', ['\u{377}', '\0', '\0']), ('\u{37f}', ['\u{3f3}',
+        '\0', '\0']), ('\u{386}', ['\u{3ac}', '\0', '\0']), ('\u{388}', ['\u{3ad}', '\0', '\0']),
+        ('\u{389}', ['\u{3ae}', '\0', '\0']), ('\u{38a}', ['\u{3af}', '\0', '\0']), ('\u{38c}',
+        ['\u{3cc}', '\0', '\0']), ('\u{38e}', ['\u{3cd}', '\0', '\0']), ('\u{38f}', ['\u{3ce}',
+        '\0', '\0']), ('\u{391}', ['\u{3b1}', '\0', '\0']), ('\u{392}', ['\u{3b2}', '\0', '\0']),
+        ('\u{393}', ['\u{3b3}', '\0', '\0']), ('\u{394}', ['\u{3b4}', '\0', '\0']), ('\u{395}',
+        ['\u{3b5}', '\0', '\0']), ('\u{396}', ['\u{3b6}', '\0', '\0']), ('\u{397}', ['\u{3b7}',
+        '\0', '\0']), ('\u{398}', ['\u{3b8}', '\0', '\0']), ('\u{399}', ['\u{3b9}', '\0', '\0']),
+        ('\u{39a}', ['\u{3ba}', '\0', '\0']), ('\u{39b}', ['\u{3bb}', '\0', '\0']), ('\u{39c}',
+        ['\u{3bc}', '\0', '\0']), ('\u{39d}', ['\u{3bd}', '\0', '\0']), ('\u{39e}', ['\u{3be}',
+        '\0', '\0']), ('\u{39f}', ['\u{3bf}', '\0', '\0']), ('\u{3a0}', ['\u{3c0}', '\0', '\0']),
+        ('\u{3a1}', ['\u{3c1}', '\0', '\0']), ('\u{3a3}', ['\u{3c3}', '\0', '\0']), ('\u{3a4}',
+        ['\u{3c4}', '\0', '\0']), ('\u{3a5}', ['\u{3c5}', '\0', '\0']), ('\u{3a6}', ['\u{3c6}',
+        '\0', '\0']), ('\u{3a7}', ['\u{3c7}', '\0', '\0']), ('\u{3a8}', ['\u{3c8}', '\0', '\0']),
+        ('\u{3a9}', ['\u{3c9}', '\0', '\0']), ('\u{3aa}', ['\u{3ca}', '\0', '\0']), ('\u{3ab}',
+        ['\u{3cb}', '\0', '\0']), ('\u{3cf}', ['\u{3d7}', '\0', '\0']), ('\u{3d8}', ['\u{3d9}',
+        '\0', '\0']), ('\u{3da}', ['\u{3db}', '\0', '\0']), ('\u{3dc}', ['\u{3dd}', '\0', '\0']),
+        ('\u{3de}', ['\u{3df}', '\0', '\0']), ('\u{3e0}', ['\u{3e1}', '\0', '\0']), ('\u{3e2}',
+        ['\u{3e3}', '\0', '\0']), ('\u{3e4}', ['\u{3e5}', '\0', '\0']), ('\u{3e6}', ['\u{3e7}',
+        '\0', '\0']), ('\u{3e8}', ['\u{3e9}', '\0', '\0']), ('\u{3ea}', ['\u{3eb}', '\0', '\0']),
+        ('\u{3ec}', ['\u{3ed}', '\0', '\0']), ('\u{3ee}', ['\u{3ef}', '\0', '\0']), ('\u{3f4}',
+        ['\u{3b8}', '\0', '\0']), ('\u{3f7}', ['\u{3f8}', '\0', '\0']), ('\u{3f9}', ['\u{3f2}',
+        '\0', '\0']), ('\u{3fa}', ['\u{3fb}', '\0', '\0']), ('\u{3fd}', ['\u{37b}', '\0', '\0']),
+        ('\u{3fe}', ['\u{37c}', '\0', '\0']), ('\u{3ff}', ['\u{37d}', '\0', '\0']), ('\u{400}',
+        ['\u{450}', '\0', '\0']), ('\u{401}', ['\u{451}', '\0', '\0']), ('\u{402}', ['\u{452}',
+        '\0', '\0']), ('\u{403}', ['\u{453}', '\0', '\0']), ('\u{404}', ['\u{454}', '\0', '\0']),
+        ('\u{405}', ['\u{455}', '\0', '\0']), ('\u{406}', ['\u{456}', '\0', '\0']), ('\u{407}',
+        ['\u{457}', '\0', '\0']), ('\u{408}', ['\u{458}', '\0', '\0']), ('\u{409}', ['\u{459}',
+        '\0', '\0']), ('\u{40a}', ['\u{45a}', '\0', '\0']), ('\u{40b}', ['\u{45b}', '\0', '\0']),
+        ('\u{40c}', ['\u{45c}', '\0', '\0']), ('\u{40d}', ['\u{45d}', '\0', '\0']), ('\u{40e}',
+        ['\u{45e}', '\0', '\0']), ('\u{40f}', ['\u{45f}', '\0', '\0']), ('\u{410}', ['\u{430}',
+        '\0', '\0']), ('\u{411}', ['\u{431}', '\0', '\0']), ('\u{412}', ['\u{432}', '\0', '\0']),
+        ('\u{413}', ['\u{433}', '\0', '\0']), ('\u{414}', ['\u{434}', '\0', '\0']), ('\u{415}',
+        ['\u{435}', '\0', '\0']), ('\u{416}', ['\u{436}', '\0', '\0']), ('\u{417}', ['\u{437}',
+        '\0', '\0']), ('\u{418}', ['\u{438}', '\0', '\0']), ('\u{419}', ['\u{439}', '\0', '\0']),
+        ('\u{41a}', ['\u{43a}', '\0', '\0']), ('\u{41b}', ['\u{43b}', '\0', '\0']), ('\u{41c}',
+        ['\u{43c}', '\0', '\0']), ('\u{41d}', ['\u{43d}', '\0', '\0']), ('\u{41e}', ['\u{43e}',
+        '\0', '\0']), ('\u{41f}', ['\u{43f}', '\0', '\0']), ('\u{420}', ['\u{440}', '\0', '\0']),
+        ('\u{421}', ['\u{441}', '\0', '\0']), ('\u{422}', ['\u{442}', '\0', '\0']), ('\u{423}',
+        ['\u{443}', '\0', '\0']), ('\u{424}', ['\u{444}', '\0', '\0']), ('\u{425}', ['\u{445}',
+        '\0', '\0']), ('\u{426}', ['\u{446}', '\0', '\0']), ('\u{427}', ['\u{447}', '\0', '\0']),
+        ('\u{428}', ['\u{448}', '\0', '\0']), ('\u{429}', ['\u{449}', '\0', '\0']), ('\u{42a}',
+        ['\u{44a}', '\0', '\0']), ('\u{42b}', ['\u{44b}', '\0', '\0']), ('\u{42c}', ['\u{44c}',
+        '\0', '\0']), ('\u{42d}', ['\u{44d}', '\0', '\0']), ('\u{42e}', ['\u{44e}', '\0', '\0']),
+        ('\u{42f}', ['\u{44f}', '\0', '\0']), ('\u{460}', ['\u{461}', '\0', '\0']), ('\u{462}',
+        ['\u{463}', '\0', '\0']), ('\u{464}', ['\u{465}', '\0', '\0']), ('\u{466}', ['\u{467}',
+        '\0', '\0']), ('\u{468}', ['\u{469}', '\0', '\0']), ('\u{46a}', ['\u{46b}', '\0', '\0']),
+        ('\u{46c}', ['\u{46d}', '\0', '\0']), ('\u{46e}', ['\u{46f}', '\0', '\0']), ('\u{470}',
+        ['\u{471}', '\0', '\0']), ('\u{472}', ['\u{473}', '\0', '\0']), ('\u{474}', ['\u{475}',
+        '\0', '\0']), ('\u{476}', ['\u{477}', '\0', '\0']), ('\u{478}', ['\u{479}', '\0', '\0']),
+        ('\u{47a}', ['\u{47b}', '\0', '\0']), ('\u{47c}', ['\u{47d}', '\0', '\0']), ('\u{47e}',
+        ['\u{47f}', '\0', '\0']), ('\u{480}', ['\u{481}', '\0', '\0']), ('\u{48a}', ['\u{48b}',
+        '\0', '\0']), ('\u{48c}', ['\u{48d}', '\0', '\0']), ('\u{48e}', ['\u{48f}', '\0', '\0']),
+        ('\u{490}', ['\u{491}', '\0', '\0']), ('\u{492}', ['\u{493}', '\0', '\0']), ('\u{494}',
+        ['\u{495}', '\0', '\0']), ('\u{496}', ['\u{497}', '\0', '\0']), ('\u{498}', ['\u{499}',
+        '\0', '\0']), ('\u{49a}', ['\u{49b}', '\0', '\0']), ('\u{49c}', ['\u{49d}', '\0', '\0']),
+        ('\u{49e}', ['\u{49f}', '\0', '\0']), ('\u{4a0}', ['\u{4a1}', '\0', '\0']), ('\u{4a2}',
+        ['\u{4a3}', '\0', '\0']), ('\u{4a4}', ['\u{4a5}', '\0', '\0']), ('\u{4a6}', ['\u{4a7}',
+        '\0', '\0']), ('\u{4a8}', ['\u{4a9}', '\0', '\0']), ('\u{4aa}', ['\u{4ab}', '\0', '\0']),
+        ('\u{4ac}', ['\u{4ad}', '\0', '\0']), ('\u{4ae}', ['\u{4af}', '\0', '\0']), ('\u{4b0}',
+        ['\u{4b1}', '\0', '\0']), ('\u{4b2}', ['\u{4b3}', '\0', '\0']), ('\u{4b4}', ['\u{4b5}',
+        '\0', '\0']), ('\u{4b6}', ['\u{4b7}', '\0', '\0']), ('\u{4b8}', ['\u{4b9}', '\0', '\0']),
+        ('\u{4ba}', ['\u{4bb}', '\0', '\0']), ('\u{4bc}', ['\u{4bd}', '\0', '\0']), ('\u{4be}',
+        ['\u{4bf}', '\0', '\0']), ('\u{4c0}', ['\u{4cf}', '\0', '\0']), ('\u{4c1}', ['\u{4c2}',
+        '\0', '\0']), ('\u{4c3}', ['\u{4c4}', '\0', '\0']), ('\u{4c5}', ['\u{4c6}', '\0', '\0']),
+        ('\u{4c7}', ['\u{4c8}', '\0', '\0']), ('\u{4c9}', ['\u{4ca}', '\0', '\0']), ('\u{4cb}',
+        ['\u{4cc}', '\0', '\0']), ('\u{4cd}', ['\u{4ce}', '\0', '\0']), ('\u{4d0}', ['\u{4d1}',
+        '\0', '\0']), ('\u{4d2}', ['\u{4d3}', '\0', '\0']), ('\u{4d4}', ['\u{4d5}', '\0', '\0']),
+        ('\u{4d6}', ['\u{4d7}', '\0', '\0']), ('\u{4d8}', ['\u{4d9}', '\0', '\0']), ('\u{4da}',
+        ['\u{4db}', '\0', '\0']), ('\u{4dc}', ['\u{4dd}', '\0', '\0']), ('\u{4de}', ['\u{4df}',
+        '\0', '\0']), ('\u{4e0}', ['\u{4e1}', '\0', '\0']), ('\u{4e2}', ['\u{4e3}', '\0', '\0']),
+        ('\u{4e4}', ['\u{4e5}', '\0', '\0']), ('\u{4e6}', ['\u{4e7}', '\0', '\0']), ('\u{4e8}',
+        ['\u{4e9}', '\0', '\0']), ('\u{4ea}', ['\u{4eb}', '\0', '\0']), ('\u{4ec}', ['\u{4ed}',
+        '\0', '\0']), ('\u{4ee}', ['\u{4ef}', '\0', '\0']), ('\u{4f0}', ['\u{4f1}', '\0', '\0']),
+        ('\u{4f2}', ['\u{4f3}', '\0', '\0']), ('\u{4f4}', ['\u{4f5}', '\0', '\0']), ('\u{4f6}',
+        ['\u{4f7}', '\0', '\0']), ('\u{4f8}', ['\u{4f9}', '\0', '\0']), ('\u{4fa}', ['\u{4fb}',
+        '\0', '\0']), ('\u{4fc}', ['\u{4fd}', '\0', '\0']), ('\u{4fe}', ['\u{4ff}', '\0', '\0']),
+        ('\u{500}', ['\u{501}', '\0', '\0']), ('\u{502}', ['\u{503}', '\0', '\0']), ('\u{504}',
+        ['\u{505}', '\0', '\0']), ('\u{506}', ['\u{507}', '\0', '\0']), ('\u{508}', ['\u{509}',
+        '\0', '\0']), ('\u{50a}', ['\u{50b}', '\0', '\0']), ('\u{50c}', ['\u{50d}', '\0', '\0']),
+        ('\u{50e}', ['\u{50f}', '\0', '\0']), ('\u{510}', ['\u{511}', '\0', '\0']), ('\u{512}',
+        ['\u{513}', '\0', '\0']), ('\u{514}', ['\u{515}', '\0', '\0']), ('\u{516}', ['\u{517}',
+        '\0', '\0']), ('\u{518}', ['\u{519}', '\0', '\0']), ('\u{51a}', ['\u{51b}', '\0', '\0']),
+        ('\u{51c}', ['\u{51d}', '\0', '\0']), ('\u{51e}', ['\u{51f}', '\0', '\0']), ('\u{520}',
+        ['\u{521}', '\0', '\0']), ('\u{522}', ['\u{523}', '\0', '\0']), ('\u{524}', ['\u{525}',
+        '\0', '\0']), ('\u{526}', ['\u{527}', '\0', '\0']), ('\u{528}', ['\u{529}', '\0', '\0']),
+        ('\u{52a}', ['\u{52b}', '\0', '\0']), ('\u{52c}', ['\u{52d}', '\0', '\0']), ('\u{52e}',
+        ['\u{52f}', '\0', '\0']), ('\u{531}', ['\u{561}', '\0', '\0']), ('\u{532}', ['\u{562}',
+        '\0', '\0']), ('\u{533}', ['\u{563}', '\0', '\0']), ('\u{534}', ['\u{564}', '\0', '\0']),
+        ('\u{535}', ['\u{565}', '\0', '\0']), ('\u{536}', ['\u{566}', '\0', '\0']), ('\u{537}',
+        ['\u{567}', '\0', '\0']), ('\u{538}', ['\u{568}', '\0', '\0']), ('\u{539}', ['\u{569}',
+        '\0', '\0']), ('\u{53a}', ['\u{56a}', '\0', '\0']), ('\u{53b}', ['\u{56b}', '\0', '\0']),
+        ('\u{53c}', ['\u{56c}', '\0', '\0']), ('\u{53d}', ['\u{56d}', '\0', '\0']), ('\u{53e}',
+        ['\u{56e}', '\0', '\0']), ('\u{53f}', ['\u{56f}', '\0', '\0']), ('\u{540}', ['\u{570}',
+        '\0', '\0']), ('\u{541}', ['\u{571}', '\0', '\0']), ('\u{542}', ['\u{572}', '\0', '\0']),
+        ('\u{543}', ['\u{573}', '\0', '\0']), ('\u{544}', ['\u{574}', '\0', '\0']), ('\u{545}',
+        ['\u{575}', '\0', '\0']), ('\u{546}', ['\u{576}', '\0', '\0']), ('\u{547}', ['\u{577}',
+        '\0', '\0']), ('\u{548}', ['\u{578}', '\0', '\0']), ('\u{549}', ['\u{579}', '\0', '\0']),
+        ('\u{54a}', ['\u{57a}', '\0', '\0']), ('\u{54b}', ['\u{57b}', '\0', '\0']), ('\u{54c}',
+        ['\u{57c}', '\0', '\0']), ('\u{54d}', ['\u{57d}', '\0', '\0']), ('\u{54e}', ['\u{57e}',
+        '\0', '\0']), ('\u{54f}', ['\u{57f}', '\0', '\0']), ('\u{550}', ['\u{580}', '\0', '\0']),
+        ('\u{551}', ['\u{581}', '\0', '\0']), ('\u{552}', ['\u{582}', '\0', '\0']), ('\u{553}',
+        ['\u{583}', '\0', '\0']), ('\u{554}', ['\u{584}', '\0', '\0']), ('\u{555}', ['\u{585}',
+        '\0', '\0']), ('\u{556}', ['\u{586}', '\0', '\0']), ('\u{10a0}', ['\u{2d00}', '\0', '\0']),
+        ('\u{10a1}', ['\u{2d01}', '\0', '\0']), ('\u{10a2}', ['\u{2d02}', '\0', '\0']), ('\u{10a3}',
+        ['\u{2d03}', '\0', '\0']), ('\u{10a4}', ['\u{2d04}', '\0', '\0']), ('\u{10a5}', ['\u{2d05}',
+        '\0', '\0']), ('\u{10a6}', ['\u{2d06}', '\0', '\0']), ('\u{10a7}', ['\u{2d07}', '\0',
+        '\0']), ('\u{10a8}', ['\u{2d08}', '\0', '\0']), ('\u{10a9}', ['\u{2d09}', '\0', '\0']),
+        ('\u{10aa}', ['\u{2d0a}', '\0', '\0']), ('\u{10ab}', ['\u{2d0b}', '\0', '\0']), ('\u{10ac}',
+        ['\u{2d0c}', '\0', '\0']), ('\u{10ad}', ['\u{2d0d}', '\0', '\0']), ('\u{10ae}', ['\u{2d0e}',
+        '\0', '\0']), ('\u{10af}', ['\u{2d0f}', '\0', '\0']), ('\u{10b0}', ['\u{2d10}', '\0',
+        '\0']), ('\u{10b1}', ['\u{2d11}', '\0', '\0']), ('\u{10b2}', ['\u{2d12}', '\0', '\0']),
+        ('\u{10b3}', ['\u{2d13}', '\0', '\0']), ('\u{10b4}', ['\u{2d14}', '\0', '\0']), ('\u{10b5}',
+        ['\u{2d15}', '\0', '\0']), ('\u{10b6}', ['\u{2d16}', '\0', '\0']), ('\u{10b7}', ['\u{2d17}',
+        '\0', '\0']), ('\u{10b8}', ['\u{2d18}', '\0', '\0']), ('\u{10b9}', ['\u{2d19}', '\0',
+        '\0']), ('\u{10ba}', ['\u{2d1a}', '\0', '\0']), ('\u{10bb}', ['\u{2d1b}', '\0', '\0']),
+        ('\u{10bc}', ['\u{2d1c}', '\0', '\0']), ('\u{10bd}', ['\u{2d1d}', '\0', '\0']), ('\u{10be}',
+        ['\u{2d1e}', '\0', '\0']), ('\u{10bf}', ['\u{2d1f}', '\0', '\0']), ('\u{10c0}', ['\u{2d20}',
+        '\0', '\0']), ('\u{10c1}', ['\u{2d21}', '\0', '\0']), ('\u{10c2}', ['\u{2d22}', '\0',
+        '\0']), ('\u{10c3}', ['\u{2d23}', '\0', '\0']), ('\u{10c4}', ['\u{2d24}', '\0', '\0']),
+        ('\u{10c5}', ['\u{2d25}', '\0', '\0']), ('\u{10c7}', ['\u{2d27}', '\0', '\0']), ('\u{10cd}',
+        ['\u{2d2d}', '\0', '\0']), ('\u{1e00}', ['\u{1e01}', '\0', '\0']), ('\u{1e02}', ['\u{1e03}',
+        '\0', '\0']), ('\u{1e04}', ['\u{1e05}', '\0', '\0']), ('\u{1e06}', ['\u{1e07}', '\0',
+        '\0']), ('\u{1e08}', ['\u{1e09}', '\0', '\0']), ('\u{1e0a}', ['\u{1e0b}', '\0', '\0']),
+        ('\u{1e0c}', ['\u{1e0d}', '\0', '\0']), ('\u{1e0e}', ['\u{1e0f}', '\0', '\0']), ('\u{1e10}',
+        ['\u{1e11}', '\0', '\0']), ('\u{1e12}', ['\u{1e13}', '\0', '\0']), ('\u{1e14}', ['\u{1e15}',
+        '\0', '\0']), ('\u{1e16}', ['\u{1e17}', '\0', '\0']), ('\u{1e18}', ['\u{1e19}', '\0',
+        '\0']), ('\u{1e1a}', ['\u{1e1b}', '\0', '\0']), ('\u{1e1c}', ['\u{1e1d}', '\0', '\0']),
+        ('\u{1e1e}', ['\u{1e1f}', '\0', '\0']), ('\u{1e20}', ['\u{1e21}', '\0', '\0']), ('\u{1e22}',
+        ['\u{1e23}', '\0', '\0']), ('\u{1e24}', ['\u{1e25}', '\0', '\0']), ('\u{1e26}', ['\u{1e27}',
+        '\0', '\0']), ('\u{1e28}', ['\u{1e29}', '\0', '\0']), ('\u{1e2a}', ['\u{1e2b}', '\0',
+        '\0']), ('\u{1e2c}', ['\u{1e2d}', '\0', '\0']), ('\u{1e2e}', ['\u{1e2f}', '\0', '\0']),
+        ('\u{1e30}', ['\u{1e31}', '\0', '\0']), ('\u{1e32}', ['\u{1e33}', '\0', '\0']), ('\u{1e34}',
+        ['\u{1e35}', '\0', '\0']), ('\u{1e36}', ['\u{1e37}', '\0', '\0']), ('\u{1e38}', ['\u{1e39}',
+        '\0', '\0']), ('\u{1e3a}', ['\u{1e3b}', '\0', '\0']), ('\u{1e3c}', ['\u{1e3d}', '\0',
+        '\0']), ('\u{1e3e}', ['\u{1e3f}', '\0', '\0']), ('\u{1e40}', ['\u{1e41}', '\0', '\0']),
+        ('\u{1e42}', ['\u{1e43}', '\0', '\0']), ('\u{1e44}', ['\u{1e45}', '\0', '\0']), ('\u{1e46}',
+        ['\u{1e47}', '\0', '\0']), ('\u{1e48}', ['\u{1e49}', '\0', '\0']), ('\u{1e4a}', ['\u{1e4b}',
+        '\0', '\0']), ('\u{1e4c}', ['\u{1e4d}', '\0', '\0']), ('\u{1e4e}', ['\u{1e4f}', '\0',
+        '\0']), ('\u{1e50}', ['\u{1e51}', '\0', '\0']), ('\u{1e52}', ['\u{1e53}', '\0', '\0']),
+        ('\u{1e54}', ['\u{1e55}', '\0', '\0']), ('\u{1e56}', ['\u{1e57}', '\0', '\0']), ('\u{1e58}',
+        ['\u{1e59}', '\0', '\0']), ('\u{1e5a}', ['\u{1e5b}', '\0', '\0']), ('\u{1e5c}', ['\u{1e5d}',
+        '\0', '\0']), ('\u{1e5e}', ['\u{1e5f}', '\0', '\0']), ('\u{1e60}', ['\u{1e61}', '\0',
+        '\0']), ('\u{1e62}', ['\u{1e63}', '\0', '\0']), ('\u{1e64}', ['\u{1e65}', '\0', '\0']),
+        ('\u{1e66}', ['\u{1e67}', '\0', '\0']), ('\u{1e68}', ['\u{1e69}', '\0', '\0']), ('\u{1e6a}',
+        ['\u{1e6b}', '\0', '\0']), ('\u{1e6c}', ['\u{1e6d}', '\0', '\0']), ('\u{1e6e}', ['\u{1e6f}',
+        '\0', '\0']), ('\u{1e70}', ['\u{1e71}', '\0', '\0']), ('\u{1e72}', ['\u{1e73}', '\0',
+        '\0']), ('\u{1e74}', ['\u{1e75}', '\0', '\0']), ('\u{1e76}', ['\u{1e77}', '\0', '\0']),
+        ('\u{1e78}', ['\u{1e79}', '\0', '\0']), ('\u{1e7a}', ['\u{1e7b}', '\0', '\0']), ('\u{1e7c}',
+        ['\u{1e7d}', '\0', '\0']), ('\u{1e7e}', ['\u{1e7f}', '\0', '\0']), ('\u{1e80}', ['\u{1e81}',
+        '\0', '\0']), ('\u{1e82}', ['\u{1e83}', '\0', '\0']), ('\u{1e84}', ['\u{1e85}', '\0',
+        '\0']), ('\u{1e86}', ['\u{1e87}', '\0', '\0']), ('\u{1e88}', ['\u{1e89}', '\0', '\0']),
+        ('\u{1e8a}', ['\u{1e8b}', '\0', '\0']), ('\u{1e8c}', ['\u{1e8d}', '\0', '\0']), ('\u{1e8e}',
+        ['\u{1e8f}', '\0', '\0']), ('\u{1e90}', ['\u{1e91}', '\0', '\0']), ('\u{1e92}', ['\u{1e93}',
+        '\0', '\0']), ('\u{1e94}', ['\u{1e95}', '\0', '\0']), ('\u{1e9e}', ['\u{df}', '\0', '\0']),
+        ('\u{1ea0}', ['\u{1ea1}', '\0', '\0']), ('\u{1ea2}', ['\u{1ea3}', '\0', '\0']), ('\u{1ea4}',
+        ['\u{1ea5}', '\0', '\0']), ('\u{1ea6}', ['\u{1ea7}', '\0', '\0']), ('\u{1ea8}', ['\u{1ea9}',
+        '\0', '\0']), ('\u{1eaa}', ['\u{1eab}', '\0', '\0']), ('\u{1eac}', ['\u{1ead}', '\0',
+        '\0']), ('\u{1eae}', ['\u{1eaf}', '\0', '\0']), ('\u{1eb0}', ['\u{1eb1}', '\0', '\0']),
+        ('\u{1eb2}', ['\u{1eb3}', '\0', '\0']), ('\u{1eb4}', ['\u{1eb5}', '\0', '\0']), ('\u{1eb6}',
+        ['\u{1eb7}', '\0', '\0']), ('\u{1eb8}', ['\u{1eb9}', '\0', '\0']), ('\u{1eba}', ['\u{1ebb}',
+        '\0', '\0']), ('\u{1ebc}', ['\u{1ebd}', '\0', '\0']), ('\u{1ebe}', ['\u{1ebf}', '\0',
+        '\0']), ('\u{1ec0}', ['\u{1ec1}', '\0', '\0']), ('\u{1ec2}', ['\u{1ec3}', '\0', '\0']),
+        ('\u{1ec4}', ['\u{1ec5}', '\0', '\0']), ('\u{1ec6}', ['\u{1ec7}', '\0', '\0']), ('\u{1ec8}',
+        ['\u{1ec9}', '\0', '\0']), ('\u{1eca}', ['\u{1ecb}', '\0', '\0']), ('\u{1ecc}', ['\u{1ecd}',
+        '\0', '\0']), ('\u{1ece}', ['\u{1ecf}', '\0', '\0']), ('\u{1ed0}', ['\u{1ed1}', '\0',
+        '\0']), ('\u{1ed2}', ['\u{1ed3}', '\0', '\0']), ('\u{1ed4}', ['\u{1ed5}', '\0', '\0']),
+        ('\u{1ed6}', ['\u{1ed7}', '\0', '\0']), ('\u{1ed8}', ['\u{1ed9}', '\0', '\0']), ('\u{1eda}',
+        ['\u{1edb}', '\0', '\0']), ('\u{1edc}', ['\u{1edd}', '\0', '\0']), ('\u{1ede}', ['\u{1edf}',
+        '\0', '\0']), ('\u{1ee0}', ['\u{1ee1}', '\0', '\0']), ('\u{1ee2}', ['\u{1ee3}', '\0',
+        '\0']), ('\u{1ee4}', ['\u{1ee5}', '\0', '\0']), ('\u{1ee6}', ['\u{1ee7}', '\0', '\0']),
+        ('\u{1ee8}', ['\u{1ee9}', '\0', '\0']), ('\u{1eea}', ['\u{1eeb}', '\0', '\0']), ('\u{1eec}',
+        ['\u{1eed}', '\0', '\0']), ('\u{1eee}', ['\u{1eef}', '\0', '\0']), ('\u{1ef0}', ['\u{1ef1}',
+        '\0', '\0']), ('\u{1ef2}', ['\u{1ef3}', '\0', '\0']), ('\u{1ef4}', ['\u{1ef5}', '\0',
+        '\0']), ('\u{1ef6}', ['\u{1ef7}', '\0', '\0']), ('\u{1ef8}', ['\u{1ef9}', '\0', '\0']),
+        ('\u{1efa}', ['\u{1efb}', '\0', '\0']), ('\u{1efc}', ['\u{1efd}', '\0', '\0']), ('\u{1efe}',
+        ['\u{1eff}', '\0', '\0']), ('\u{1f08}', ['\u{1f00}', '\0', '\0']), ('\u{1f09}', ['\u{1f01}',
+        '\0', '\0']), ('\u{1f0a}', ['\u{1f02}', '\0', '\0']), ('\u{1f0b}', ['\u{1f03}', '\0',
+        '\0']), ('\u{1f0c}', ['\u{1f04}', '\0', '\0']), ('\u{1f0d}', ['\u{1f05}', '\0', '\0']),
+        ('\u{1f0e}', ['\u{1f06}', '\0', '\0']), ('\u{1f0f}', ['\u{1f07}', '\0', '\0']), ('\u{1f18}',
+        ['\u{1f10}', '\0', '\0']), ('\u{1f19}', ['\u{1f11}', '\0', '\0']), ('\u{1f1a}', ['\u{1f12}',
+        '\0', '\0']), ('\u{1f1b}', ['\u{1f13}', '\0', '\0']), ('\u{1f1c}', ['\u{1f14}', '\0',
+        '\0']), ('\u{1f1d}', ['\u{1f15}', '\0', '\0']), ('\u{1f28}', ['\u{1f20}', '\0', '\0']),
+        ('\u{1f29}', ['\u{1f21}', '\0', '\0']), ('\u{1f2a}', ['\u{1f22}', '\0', '\0']), ('\u{1f2b}',
+        ['\u{1f23}', '\0', '\0']), ('\u{1f2c}', ['\u{1f24}', '\0', '\0']), ('\u{1f2d}', ['\u{1f25}',
+        '\0', '\0']), ('\u{1f2e}', ['\u{1f26}', '\0', '\0']), ('\u{1f2f}', ['\u{1f27}', '\0',
+        '\0']), ('\u{1f38}', ['\u{1f30}', '\0', '\0']), ('\u{1f39}', ['\u{1f31}', '\0', '\0']),
+        ('\u{1f3a}', ['\u{1f32}', '\0', '\0']), ('\u{1f3b}', ['\u{1f33}', '\0', '\0']), ('\u{1f3c}',
+        ['\u{1f34}', '\0', '\0']), ('\u{1f3d}', ['\u{1f35}', '\0', '\0']), ('\u{1f3e}', ['\u{1f36}',
+        '\0', '\0']), ('\u{1f3f}', ['\u{1f37}', '\0', '\0']), ('\u{1f48}', ['\u{1f40}', '\0',
+        '\0']), ('\u{1f49}', ['\u{1f41}', '\0', '\0']), ('\u{1f4a}', ['\u{1f42}', '\0', '\0']),
+        ('\u{1f4b}', ['\u{1f43}', '\0', '\0']), ('\u{1f4c}', ['\u{1f44}', '\0', '\0']), ('\u{1f4d}',
+        ['\u{1f45}', '\0', '\0']), ('\u{1f59}', ['\u{1f51}', '\0', '\0']), ('\u{1f5b}', ['\u{1f53}',
+        '\0', '\0']), ('\u{1f5d}', ['\u{1f55}', '\0', '\0']), ('\u{1f5f}', ['\u{1f57}', '\0',
+        '\0']), ('\u{1f68}', ['\u{1f60}', '\0', '\0']), ('\u{1f69}', ['\u{1f61}', '\0', '\0']),
+        ('\u{1f6a}', ['\u{1f62}', '\0', '\0']), ('\u{1f6b}', ['\u{1f63}', '\0', '\0']), ('\u{1f6c}',
+        ['\u{1f64}', '\0', '\0']), ('\u{1f6d}', ['\u{1f65}', '\0', '\0']), ('\u{1f6e}', ['\u{1f66}',
+        '\0', '\0']), ('\u{1f6f}', ['\u{1f67}', '\0', '\0']), ('\u{1f88}', ['\u{1f80}', '\0',
+        '\0']), ('\u{1f89}', ['\u{1f81}', '\0', '\0']), ('\u{1f8a}', ['\u{1f82}', '\0', '\0']),
+        ('\u{1f8b}', ['\u{1f83}', '\0', '\0']), ('\u{1f8c}', ['\u{1f84}', '\0', '\0']), ('\u{1f8d}',
+        ['\u{1f85}', '\0', '\0']), ('\u{1f8e}', ['\u{1f86}', '\0', '\0']), ('\u{1f8f}', ['\u{1f87}',
+        '\0', '\0']), ('\u{1f98}', ['\u{1f90}', '\0', '\0']), ('\u{1f99}', ['\u{1f91}', '\0',
+        '\0']), ('\u{1f9a}', ['\u{1f92}', '\0', '\0']), ('\u{1f9b}', ['\u{1f93}', '\0', '\0']),
+        ('\u{1f9c}', ['\u{1f94}', '\0', '\0']), ('\u{1f9d}', ['\u{1f95}', '\0', '\0']), ('\u{1f9e}',
+        ['\u{1f96}', '\0', '\0']), ('\u{1f9f}', ['\u{1f97}', '\0', '\0']), ('\u{1fa8}', ['\u{1fa0}',
+        '\0', '\0']), ('\u{1fa9}', ['\u{1fa1}', '\0', '\0']), ('\u{1faa}', ['\u{1fa2}', '\0',
+        '\0']), ('\u{1fab}', ['\u{1fa3}', '\0', '\0']), ('\u{1fac}', ['\u{1fa4}', '\0', '\0']),
+        ('\u{1fad}', ['\u{1fa5}', '\0', '\0']), ('\u{1fae}', ['\u{1fa6}', '\0', '\0']), ('\u{1faf}',
+        ['\u{1fa7}', '\0', '\0']), ('\u{1fb8}', ['\u{1fb0}', '\0', '\0']), ('\u{1fb9}', ['\u{1fb1}',
+        '\0', '\0']), ('\u{1fba}', ['\u{1f70}', '\0', '\0']), ('\u{1fbb}', ['\u{1f71}', '\0',
+        '\0']), ('\u{1fbc}', ['\u{1fb3}', '\0', '\0']), ('\u{1fc8}', ['\u{1f72}', '\0', '\0']),
+        ('\u{1fc9}', ['\u{1f73}', '\0', '\0']), ('\u{1fca}', ['\u{1f74}', '\0', '\0']), ('\u{1fcb}',
+        ['\u{1f75}', '\0', '\0']), ('\u{1fcc}', ['\u{1fc3}', '\0', '\0']), ('\u{1fd8}', ['\u{1fd0}',
+        '\0', '\0']), ('\u{1fd9}', ['\u{1fd1}', '\0', '\0']), ('\u{1fda}', ['\u{1f76}', '\0',
+        '\0']), ('\u{1fdb}', ['\u{1f77}', '\0', '\0']), ('\u{1fe8}', ['\u{1fe0}', '\0', '\0']),
+        ('\u{1fe9}', ['\u{1fe1}', '\0', '\0']), ('\u{1fea}', ['\u{1f7a}', '\0', '\0']), ('\u{1feb}',
+        ['\u{1f7b}', '\0', '\0']), ('\u{1fec}', ['\u{1fe5}', '\0', '\0']), ('\u{1ff8}', ['\u{1f78}',
+        '\0', '\0']), ('\u{1ff9}', ['\u{1f79}', '\0', '\0']), ('\u{1ffa}', ['\u{1f7c}', '\0',
+        '\0']), ('\u{1ffb}', ['\u{1f7d}', '\0', '\0']), ('\u{1ffc}', ['\u{1ff3}', '\0', '\0']),
+        ('\u{2126}', ['\u{3c9}', '\0', '\0']), ('\u{212a}', ['\u{6b}', '\0', '\0']), ('\u{212b}',
+        ['\u{e5}', '\0', '\0']), ('\u{2132}', ['\u{214e}', '\0', '\0']), ('\u{2160}', ['\u{2170}',
+        '\0', '\0']), ('\u{2161}', ['\u{2171}', '\0', '\0']), ('\u{2162}', ['\u{2172}', '\0',
+        '\0']), ('\u{2163}', ['\u{2173}', '\0', '\0']), ('\u{2164}', ['\u{2174}', '\0', '\0']),
+        ('\u{2165}', ['\u{2175}', '\0', '\0']), ('\u{2166}', ['\u{2176}', '\0', '\0']), ('\u{2167}',
+        ['\u{2177}', '\0', '\0']), ('\u{2168}', ['\u{2178}', '\0', '\0']), ('\u{2169}', ['\u{2179}',
+        '\0', '\0']), ('\u{216a}', ['\u{217a}', '\0', '\0']), ('\u{216b}', ['\u{217b}', '\0',
+        '\0']), ('\u{216c}', ['\u{217c}', '\0', '\0']), ('\u{216d}', ['\u{217d}', '\0', '\0']),
+        ('\u{216e}', ['\u{217e}', '\0', '\0']), ('\u{216f}', ['\u{217f}', '\0', '\0']), ('\u{2183}',
+        ['\u{2184}', '\0', '\0']), ('\u{24b6}', ['\u{24d0}', '\0', '\0']), ('\u{24b7}', ['\u{24d1}',
+        '\0', '\0']), ('\u{24b8}', ['\u{24d2}', '\0', '\0']), ('\u{24b9}', ['\u{24d3}', '\0',
+        '\0']), ('\u{24ba}', ['\u{24d4}', '\0', '\0']), ('\u{24bb}', ['\u{24d5}', '\0', '\0']),
+        ('\u{24bc}', ['\u{24d6}', '\0', '\0']), ('\u{24bd}', ['\u{24d7}', '\0', '\0']), ('\u{24be}',
+        ['\u{24d8}', '\0', '\0']), ('\u{24bf}', ['\u{24d9}', '\0', '\0']), ('\u{24c0}', ['\u{24da}',
+        '\0', '\0']), ('\u{24c1}', ['\u{24db}', '\0', '\0']), ('\u{24c2}', ['\u{24dc}', '\0',
+        '\0']), ('\u{24c3}', ['\u{24dd}', '\0', '\0']), ('\u{24c4}', ['\u{24de}', '\0', '\0']),
+        ('\u{24c5}', ['\u{24df}', '\0', '\0']), ('\u{24c6}', ['\u{24e0}', '\0', '\0']), ('\u{24c7}',
+        ['\u{24e1}', '\0', '\0']), ('\u{24c8}', ['\u{24e2}', '\0', '\0']), ('\u{24c9}', ['\u{24e3}',
+        '\0', '\0']), ('\u{24ca}', ['\u{24e4}', '\0', '\0']), ('\u{24cb}', ['\u{24e5}', '\0',
+        '\0']), ('\u{24cc}', ['\u{24e6}', '\0', '\0']), ('\u{24cd}', ['\u{24e7}', '\0', '\0']),
+        ('\u{24ce}', ['\u{24e8}', '\0', '\0']), ('\u{24cf}', ['\u{24e9}', '\0', '\0']), ('\u{2c00}',
+        ['\u{2c30}', '\0', '\0']), ('\u{2c01}', ['\u{2c31}', '\0', '\0']), ('\u{2c02}', ['\u{2c32}',
+        '\0', '\0']), ('\u{2c03}', ['\u{2c33}', '\0', '\0']), ('\u{2c04}', ['\u{2c34}', '\0',
+        '\0']), ('\u{2c05}', ['\u{2c35}', '\0', '\0']), ('\u{2c06}', ['\u{2c36}', '\0', '\0']),
+        ('\u{2c07}', ['\u{2c37}', '\0', '\0']), ('\u{2c08}', ['\u{2c38}', '\0', '\0']), ('\u{2c09}',
+        ['\u{2c39}', '\0', '\0']), ('\u{2c0a}', ['\u{2c3a}', '\0', '\0']), ('\u{2c0b}', ['\u{2c3b}',
+        '\0', '\0']), ('\u{2c0c}', ['\u{2c3c}', '\0', '\0']), ('\u{2c0d}', ['\u{2c3d}', '\0',
+        '\0']), ('\u{2c0e}', ['\u{2c3e}', '\0', '\0']), ('\u{2c0f}', ['\u{2c3f}', '\0', '\0']),
+        ('\u{2c10}', ['\u{2c40}', '\0', '\0']), ('\u{2c11}', ['\u{2c41}', '\0', '\0']), ('\u{2c12}',
+        ['\u{2c42}', '\0', '\0']), ('\u{2c13}', ['\u{2c43}', '\0', '\0']), ('\u{2c14}', ['\u{2c44}',
+        '\0', '\0']), ('\u{2c15}', ['\u{2c45}', '\0', '\0']), ('\u{2c16}', ['\u{2c46}', '\0',
+        '\0']), ('\u{2c17}', ['\u{2c47}', '\0', '\0']), ('\u{2c18}', ['\u{2c48}', '\0', '\0']),
+        ('\u{2c19}', ['\u{2c49}', '\0', '\0']), ('\u{2c1a}', ['\u{2c4a}', '\0', '\0']), ('\u{2c1b}',
+        ['\u{2c4b}', '\0', '\0']), ('\u{2c1c}', ['\u{2c4c}', '\0', '\0']), ('\u{2c1d}', ['\u{2c4d}',
+        '\0', '\0']), ('\u{2c1e}', ['\u{2c4e}', '\0', '\0']), ('\u{2c1f}', ['\u{2c4f}', '\0',
+        '\0']), ('\u{2c20}', ['\u{2c50}', '\0', '\0']), ('\u{2c21}', ['\u{2c51}', '\0', '\0']),
+        ('\u{2c22}', ['\u{2c52}', '\0', '\0']), ('\u{2c23}', ['\u{2c53}', '\0', '\0']), ('\u{2c24}',
+        ['\u{2c54}', '\0', '\0']), ('\u{2c25}', ['\u{2c55}', '\0', '\0']), ('\u{2c26}', ['\u{2c56}',
+        '\0', '\0']), ('\u{2c27}', ['\u{2c57}', '\0', '\0']), ('\u{2c28}', ['\u{2c58}', '\0',
+        '\0']), ('\u{2c29}', ['\u{2c59}', '\0', '\0']), ('\u{2c2a}', ['\u{2c5a}', '\0', '\0']),
+        ('\u{2c2b}', ['\u{2c5b}', '\0', '\0']), ('\u{2c2c}', ['\u{2c5c}', '\0', '\0']), ('\u{2c2d}',
+        ['\u{2c5d}', '\0', '\0']), ('\u{2c2e}', ['\u{2c5e}', '\0', '\0']), ('\u{2c60}', ['\u{2c61}',
+        '\0', '\0']), ('\u{2c62}', ['\u{26b}', '\0', '\0']), ('\u{2c63}', ['\u{1d7d}', '\0', '\0']),
+        ('\u{2c64}', ['\u{27d}', '\0', '\0']), ('\u{2c67}', ['\u{2c68}', '\0', '\0']), ('\u{2c69}',
+        ['\u{2c6a}', '\0', '\0']), ('\u{2c6b}', ['\u{2c6c}', '\0', '\0']), ('\u{2c6d}', ['\u{251}',
+        '\0', '\0']), ('\u{2c6e}', ['\u{271}', '\0', '\0']), ('\u{2c6f}', ['\u{250}', '\0', '\0']),
+        ('\u{2c70}', ['\u{252}', '\0', '\0']), ('\u{2c72}', ['\u{2c73}', '\0', '\0']), ('\u{2c75}',
+        ['\u{2c76}', '\0', '\0']), ('\u{2c7e}', ['\u{23f}', '\0', '\0']), ('\u{2c7f}', ['\u{240}',
+        '\0', '\0']), ('\u{2c80}', ['\u{2c81}', '\0', '\0']), ('\u{2c82}', ['\u{2c83}', '\0',
+        '\0']), ('\u{2c84}', ['\u{2c85}', '\0', '\0']), ('\u{2c86}', ['\u{2c87}', '\0', '\0']),
+        ('\u{2c88}', ['\u{2c89}', '\0', '\0']), ('\u{2c8a}', ['\u{2c8b}', '\0', '\0']), ('\u{2c8c}',
+        ['\u{2c8d}', '\0', '\0']), ('\u{2c8e}', ['\u{2c8f}', '\0', '\0']), ('\u{2c90}', ['\u{2c91}',
+        '\0', '\0']), ('\u{2c92}', ['\u{2c93}', '\0', '\0']), ('\u{2c94}', ['\u{2c95}', '\0',
+        '\0']), ('\u{2c96}', ['\u{2c97}', '\0', '\0']), ('\u{2c98}', ['\u{2c99}', '\0', '\0']),
+        ('\u{2c9a}', ['\u{2c9b}', '\0', '\0']), ('\u{2c9c}', ['\u{2c9d}', '\0', '\0']), ('\u{2c9e}',
+        ['\u{2c9f}', '\0', '\0']), ('\u{2ca0}', ['\u{2ca1}', '\0', '\0']), ('\u{2ca2}', ['\u{2ca3}',
+        '\0', '\0']), ('\u{2ca4}', ['\u{2ca5}', '\0', '\0']), ('\u{2ca6}', ['\u{2ca7}', '\0',
+        '\0']), ('\u{2ca8}', ['\u{2ca9}', '\0', '\0']), ('\u{2caa}', ['\u{2cab}', '\0', '\0']),
+        ('\u{2cac}', ['\u{2cad}', '\0', '\0']), ('\u{2cae}', ['\u{2caf}', '\0', '\0']), ('\u{2cb0}',
+        ['\u{2cb1}', '\0', '\0']), ('\u{2cb2}', ['\u{2cb3}', '\0', '\0']), ('\u{2cb4}', ['\u{2cb5}',
+        '\0', '\0']), ('\u{2cb6}', ['\u{2cb7}', '\0', '\0']), ('\u{2cb8}', ['\u{2cb9}', '\0',
+        '\0']), ('\u{2cba}', ['\u{2cbb}', '\0', '\0']), ('\u{2cbc}', ['\u{2cbd}', '\0', '\0']),
+        ('\u{2cbe}', ['\u{2cbf}', '\0', '\0']), ('\u{2cc0}', ['\u{2cc1}', '\0', '\0']), ('\u{2cc2}',
+        ['\u{2cc3}', '\0', '\0']), ('\u{2cc4}', ['\u{2cc5}', '\0', '\0']), ('\u{2cc6}', ['\u{2cc7}',
+        '\0', '\0']), ('\u{2cc8}', ['\u{2cc9}', '\0', '\0']), ('\u{2cca}', ['\u{2ccb}', '\0',
+        '\0']), ('\u{2ccc}', ['\u{2ccd}', '\0', '\0']), ('\u{2cce}', ['\u{2ccf}', '\0', '\0']),
+        ('\u{2cd0}', ['\u{2cd1}', '\0', '\0']), ('\u{2cd2}', ['\u{2cd3}', '\0', '\0']), ('\u{2cd4}',
+        ['\u{2cd5}', '\0', '\0']), ('\u{2cd6}', ['\u{2cd7}', '\0', '\0']), ('\u{2cd8}', ['\u{2cd9}',
+        '\0', '\0']), ('\u{2cda}', ['\u{2cdb}', '\0', '\0']), ('\u{2cdc}', ['\u{2cdd}', '\0',
+        '\0']), ('\u{2cde}', ['\u{2cdf}', '\0', '\0']), ('\u{2ce0}', ['\u{2ce1}', '\0', '\0']),
+        ('\u{2ce2}', ['\u{2ce3}', '\0', '\0']), ('\u{2ceb}', ['\u{2cec}', '\0', '\0']), ('\u{2ced}',
+        ['\u{2cee}', '\0', '\0']), ('\u{2cf2}', ['\u{2cf3}', '\0', '\0']), ('\u{a640}', ['\u{a641}',
+        '\0', '\0']), ('\u{a642}', ['\u{a643}', '\0', '\0']), ('\u{a644}', ['\u{a645}', '\0',
+        '\0']), ('\u{a646}', ['\u{a647}', '\0', '\0']), ('\u{a648}', ['\u{a649}', '\0', '\0']),
+        ('\u{a64a}', ['\u{a64b}', '\0', '\0']), ('\u{a64c}', ['\u{a64d}', '\0', '\0']), ('\u{a64e}',
+        ['\u{a64f}', '\0', '\0']), ('\u{a650}', ['\u{a651}', '\0', '\0']), ('\u{a652}', ['\u{a653}',
+        '\0', '\0']), ('\u{a654}', ['\u{a655}', '\0', '\0']), ('\u{a656}', ['\u{a657}', '\0',
+        '\0']), ('\u{a658}', ['\u{a659}', '\0', '\0']), ('\u{a65a}', ['\u{a65b}', '\0', '\0']),
+        ('\u{a65c}', ['\u{a65d}', '\0', '\0']), ('\u{a65e}', ['\u{a65f}', '\0', '\0']), ('\u{a660}',
+        ['\u{a661}', '\0', '\0']), ('\u{a662}', ['\u{a663}', '\0', '\0']), ('\u{a664}', ['\u{a665}',
+        '\0', '\0']), ('\u{a666}', ['\u{a667}', '\0', '\0']), ('\u{a668}', ['\u{a669}', '\0',
+        '\0']), ('\u{a66a}', ['\u{a66b}', '\0', '\0']), ('\u{a66c}', ['\u{a66d}', '\0', '\0']),
+        ('\u{a680}', ['\u{a681}', '\0', '\0']), ('\u{a682}', ['\u{a683}', '\0', '\0']), ('\u{a684}',
+        ['\u{a685}', '\0', '\0']), ('\u{a686}', ['\u{a687}', '\0', '\0']), ('\u{a688}', ['\u{a689}',
+        '\0', '\0']), ('\u{a68a}', ['\u{a68b}', '\0', '\0']), ('\u{a68c}', ['\u{a68d}', '\0',
+        '\0']), ('\u{a68e}', ['\u{a68f}', '\0', '\0']), ('\u{a690}', ['\u{a691}', '\0', '\0']),
+        ('\u{a692}', ['\u{a693}', '\0', '\0']), ('\u{a694}', ['\u{a695}', '\0', '\0']), ('\u{a696}',
+        ['\u{a697}', '\0', '\0']), ('\u{a698}', ['\u{a699}', '\0', '\0']), ('\u{a69a}', ['\u{a69b}',
+        '\0', '\0']), ('\u{a722}', ['\u{a723}', '\0', '\0']), ('\u{a724}', ['\u{a725}', '\0',
+        '\0']), ('\u{a726}', ['\u{a727}', '\0', '\0']), ('\u{a728}', ['\u{a729}', '\0', '\0']),
+        ('\u{a72a}', ['\u{a72b}', '\0', '\0']), ('\u{a72c}', ['\u{a72d}', '\0', '\0']), ('\u{a72e}',
+        ['\u{a72f}', '\0', '\0']), ('\u{a732}', ['\u{a733}', '\0', '\0']), ('\u{a734}', ['\u{a735}',
+        '\0', '\0']), ('\u{a736}', ['\u{a737}', '\0', '\0']), ('\u{a738}', ['\u{a739}', '\0',
+        '\0']), ('\u{a73a}', ['\u{a73b}', '\0', '\0']), ('\u{a73c}', ['\u{a73d}', '\0', '\0']),
+        ('\u{a73e}', ['\u{a73f}', '\0', '\0']), ('\u{a740}', ['\u{a741}', '\0', '\0']), ('\u{a742}',
+        ['\u{a743}', '\0', '\0']), ('\u{a744}', ['\u{a745}', '\0', '\0']), ('\u{a746}', ['\u{a747}',
+        '\0', '\0']), ('\u{a748}', ['\u{a749}', '\0', '\0']), ('\u{a74a}', ['\u{a74b}', '\0',
+        '\0']), ('\u{a74c}', ['\u{a74d}', '\0', '\0']), ('\u{a74e}', ['\u{a74f}', '\0', '\0']),
+        ('\u{a750}', ['\u{a751}', '\0', '\0']), ('\u{a752}', ['\u{a753}', '\0', '\0']), ('\u{a754}',
+        ['\u{a755}', '\0', '\0']), ('\u{a756}', ['\u{a757}', '\0', '\0']), ('\u{a758}', ['\u{a759}',
+        '\0', '\0']), ('\u{a75a}', ['\u{a75b}', '\0', '\0']), ('\u{a75c}', ['\u{a75d}', '\0',
+        '\0']), ('\u{a75e}', ['\u{a75f}', '\0', '\0']), ('\u{a760}', ['\u{a761}', '\0', '\0']),
+        ('\u{a762}', ['\u{a763}', '\0', '\0']), ('\u{a764}', ['\u{a765}', '\0', '\0']), ('\u{a766}',
+        ['\u{a767}', '\0', '\0']), ('\u{a768}', ['\u{a769}', '\0', '\0']), ('\u{a76a}', ['\u{a76b}',
+        '\0', '\0']), ('\u{a76c}', ['\u{a76d}', '\0', '\0']), ('\u{a76e}', ['\u{a76f}', '\0',
+        '\0']), ('\u{a779}', ['\u{a77a}', '\0', '\0']), ('\u{a77b}', ['\u{a77c}', '\0', '\0']),
+        ('\u{a77d}', ['\u{1d79}', '\0', '\0']), ('\u{a77e}', ['\u{a77f}', '\0', '\0']), ('\u{a780}',
+        ['\u{a781}', '\0', '\0']), ('\u{a782}', ['\u{a783}', '\0', '\0']), ('\u{a784}', ['\u{a785}',
+        '\0', '\0']), ('\u{a786}', ['\u{a787}', '\0', '\0']), ('\u{a78b}', ['\u{a78c}', '\0',
+        '\0']), ('\u{a78d}', ['\u{265}', '\0', '\0']), ('\u{a790}', ['\u{a791}', '\0', '\0']),
+        ('\u{a792}', ['\u{a793}', '\0', '\0']), ('\u{a796}', ['\u{a797}', '\0', '\0']), ('\u{a798}',
+        ['\u{a799}', '\0', '\0']), ('\u{a79a}', ['\u{a79b}', '\0', '\0']), ('\u{a79c}', ['\u{a79d}',
+        '\0', '\0']), ('\u{a79e}', ['\u{a79f}', '\0', '\0']), ('\u{a7a0}', ['\u{a7a1}', '\0',
+        '\0']), ('\u{a7a2}', ['\u{a7a3}', '\0', '\0']), ('\u{a7a4}', ['\u{a7a5}', '\0', '\0']),
+        ('\u{a7a6}', ['\u{a7a7}', '\0', '\0']), ('\u{a7a8}', ['\u{a7a9}', '\0', '\0']), ('\u{a7aa}',
+        ['\u{266}', '\0', '\0']), ('\u{a7ab}', ['\u{25c}', '\0', '\0']), ('\u{a7ac}', ['\u{261}',
+        '\0', '\0']), ('\u{a7ad}', ['\u{26c}', '\0', '\0']), ('\u{a7b0}', ['\u{29e}', '\0', '\0']),
+        ('\u{a7b1}', ['\u{287}', '\0', '\0']), ('\u{ff21}', ['\u{ff41}', '\0', '\0']), ('\u{ff22}',
+        ['\u{ff42}', '\0', '\0']), ('\u{ff23}', ['\u{ff43}', '\0', '\0']), ('\u{ff24}', ['\u{ff44}',
+        '\0', '\0']), ('\u{ff25}', ['\u{ff45}', '\0', '\0']), ('\u{ff26}', ['\u{ff46}', '\0',
+        '\0']), ('\u{ff27}', ['\u{ff47}', '\0', '\0']), ('\u{ff28}', ['\u{ff48}', '\0', '\0']),
+        ('\u{ff29}', ['\u{ff49}', '\0', '\0']), ('\u{ff2a}', ['\u{ff4a}', '\0', '\0']), ('\u{ff2b}',
+        ['\u{ff4b}', '\0', '\0']), ('\u{ff2c}', ['\u{ff4c}', '\0', '\0']), ('\u{ff2d}', ['\u{ff4d}',
+        '\0', '\0']), ('\u{ff2e}', ['\u{ff4e}', '\0', '\0']), ('\u{ff2f}', ['\u{ff4f}', '\0',
+        '\0']), ('\u{ff30}', ['\u{ff50}', '\0', '\0']), ('\u{ff31}', ['\u{ff51}', '\0', '\0']),
+        ('\u{ff32}', ['\u{ff52}', '\0', '\0']), ('\u{ff33}', ['\u{ff53}', '\0', '\0']), ('\u{ff34}',
+        ['\u{ff54}', '\0', '\0']), ('\u{ff35}', ['\u{ff55}', '\0', '\0']), ('\u{ff36}', ['\u{ff56}',
+        '\0', '\0']), ('\u{ff37}', ['\u{ff57}', '\0', '\0']), ('\u{ff38}', ['\u{ff58}', '\0',
+        '\0']), ('\u{ff39}', ['\u{ff59}', '\0', '\0']), ('\u{ff3a}', ['\u{ff5a}', '\0', '\0']),
+        ('\u{10400}', ['\u{10428}', '\0', '\0']), ('\u{10401}', ['\u{10429}', '\0', '\0']),
+        ('\u{10402}', ['\u{1042a}', '\0', '\0']), ('\u{10403}', ['\u{1042b}', '\0', '\0']),
+        ('\u{10404}', ['\u{1042c}', '\0', '\0']), ('\u{10405}', ['\u{1042d}', '\0', '\0']),
+        ('\u{10406}', ['\u{1042e}', '\0', '\0']), ('\u{10407}', ['\u{1042f}', '\0', '\0']),
+        ('\u{10408}', ['\u{10430}', '\0', '\0']), ('\u{10409}', ['\u{10431}', '\0', '\0']),
+        ('\u{1040a}', ['\u{10432}', '\0', '\0']), ('\u{1040b}', ['\u{10433}', '\0', '\0']),
+        ('\u{1040c}', ['\u{10434}', '\0', '\0']), ('\u{1040d}', ['\u{10435}', '\0', '\0']),
+        ('\u{1040e}', ['\u{10436}', '\0', '\0']), ('\u{1040f}', ['\u{10437}', '\0', '\0']),
+        ('\u{10410}', ['\u{10438}', '\0', '\0']), ('\u{10411}', ['\u{10439}', '\0', '\0']),
+        ('\u{10412}', ['\u{1043a}', '\0', '\0']), ('\u{10413}', ['\u{1043b}', '\0', '\0']),
+        ('\u{10414}', ['\u{1043c}', '\0', '\0']), ('\u{10415}', ['\u{1043d}', '\0', '\0']),
+        ('\u{10416}', ['\u{1043e}', '\0', '\0']), ('\u{10417}', ['\u{1043f}', '\0', '\0']),
+        ('\u{10418}', ['\u{10440}', '\0', '\0']), ('\u{10419}', ['\u{10441}', '\0', '\0']),
+        ('\u{1041a}', ['\u{10442}', '\0', '\0']), ('\u{1041b}', ['\u{10443}', '\0', '\0']),
+        ('\u{1041c}', ['\u{10444}', '\0', '\0']), ('\u{1041d}', ['\u{10445}', '\0', '\0']),
+        ('\u{1041e}', ['\u{10446}', '\0', '\0']), ('\u{1041f}', ['\u{10447}', '\0', '\0']),
+        ('\u{10420}', ['\u{10448}', '\0', '\0']), ('\u{10421}', ['\u{10449}', '\0', '\0']),
+        ('\u{10422}', ['\u{1044a}', '\0', '\0']), ('\u{10423}', ['\u{1044b}', '\0', '\0']),
+        ('\u{10424}', ['\u{1044c}', '\0', '\0']), ('\u{10425}', ['\u{1044d}', '\0', '\0']),
+        ('\u{10426}', ['\u{1044e}', '\0', '\0']), ('\u{10427}', ['\u{1044f}', '\0', '\0']),
+        ('\u{118a0}', ['\u{118c0}', '\0', '\0']), ('\u{118a1}', ['\u{118c1}', '\0', '\0']),
+        ('\u{118a2}', ['\u{118c2}', '\0', '\0']), ('\u{118a3}', ['\u{118c3}', '\0', '\0']),
+        ('\u{118a4}', ['\u{118c4}', '\0', '\0']), ('\u{118a5}', ['\u{118c5}', '\0', '\0']),
+        ('\u{118a6}', ['\u{118c6}', '\0', '\0']), ('\u{118a7}', ['\u{118c7}', '\0', '\0']),
+        ('\u{118a8}', ['\u{118c8}', '\0', '\0']), ('\u{118a9}', ['\u{118c9}', '\0', '\0']),
+        ('\u{118aa}', ['\u{118ca}', '\0', '\0']), ('\u{118ab}', ['\u{118cb}', '\0', '\0']),
+        ('\u{118ac}', ['\u{118cc}', '\0', '\0']), ('\u{118ad}', ['\u{118cd}', '\0', '\0']),
+        ('\u{118ae}', ['\u{118ce}', '\0', '\0']), ('\u{118af}', ['\u{118cf}', '\0', '\0']),
+        ('\u{118b0}', ['\u{118d0}', '\0', '\0']), ('\u{118b1}', ['\u{118d1}', '\0', '\0']),
+        ('\u{118b2}', ['\u{118d2}', '\0', '\0']), ('\u{118b3}', ['\u{118d3}', '\0', '\0']),
+        ('\u{118b4}', ['\u{118d4}', '\0', '\0']), ('\u{118b5}', ['\u{118d5}', '\0', '\0']),
+        ('\u{118b6}', ['\u{118d6}', '\0', '\0']), ('\u{118b7}', ['\u{118d7}', '\0', '\0']),
+        ('\u{118b8}', ['\u{118d8}', '\0', '\0']), ('\u{118b9}', ['\u{118d9}', '\0', '\0']),
+        ('\u{118ba}', ['\u{118da}', '\0', '\0']), ('\u{118bb}', ['\u{118db}', '\0', '\0']),
+        ('\u{118bc}', ['\u{118dc}', '\0', '\0']), ('\u{118bd}', ['\u{118dd}', '\0', '\0']),
+        ('\u{118be}', ['\u{118de}', '\0', '\0']), ('\u{118bf}', ['\u{118df}', '\0', '\0'])
+    ];
+
+    const to_uppercase_table: &'static [(char, [char; 3])] = &[
+        ('\u{61}', ['\u{41}', '\0', '\0']), ('\u{62}', ['\u{42}', '\0', '\0']), ('\u{63}',
+        ['\u{43}', '\0', '\0']), ('\u{64}', ['\u{44}', '\0', '\0']), ('\u{65}', ['\u{45}', '\0',
+        '\0']), ('\u{66}', ['\u{46}', '\0', '\0']), ('\u{67}', ['\u{47}', '\0', '\0']), ('\u{68}',
+        ['\u{48}', '\0', '\0']), ('\u{69}', ['\u{49}', '\0', '\0']), ('\u{6a}', ['\u{4a}', '\0',
+        '\0']), ('\u{6b}', ['\u{4b}', '\0', '\0']), ('\u{6c}', ['\u{4c}', '\0', '\0']), ('\u{6d}',
+        ['\u{4d}', '\0', '\0']), ('\u{6e}', ['\u{4e}', '\0', '\0']), ('\u{6f}', ['\u{4f}', '\0',
+        '\0']), ('\u{70}', ['\u{50}', '\0', '\0']), ('\u{71}', ['\u{51}', '\0', '\0']), ('\u{72}',
+        ['\u{52}', '\0', '\0']), ('\u{73}', ['\u{53}', '\0', '\0']), ('\u{74}', ['\u{54}', '\0',
+        '\0']), ('\u{75}', ['\u{55}', '\0', '\0']), ('\u{76}', ['\u{56}', '\0', '\0']), ('\u{77}',
+        ['\u{57}', '\0', '\0']), ('\u{78}', ['\u{58}', '\0', '\0']), ('\u{79}', ['\u{59}', '\0',
+        '\0']), ('\u{7a}', ['\u{5a}', '\0', '\0']), ('\u{b5}', ['\u{39c}', '\0', '\0']), ('\u{df}',
+        ['\u{53}', '\u{53}', '\0']), ('\u{e0}', ['\u{c0}', '\0', '\0']), ('\u{e1}', ['\u{c1}', '\0',
+        '\0']), ('\u{e2}', ['\u{c2}', '\0', '\0']), ('\u{e3}', ['\u{c3}', '\0', '\0']), ('\u{e4}',
+        ['\u{c4}', '\0', '\0']), ('\u{e5}', ['\u{c5}', '\0', '\0']), ('\u{e6}', ['\u{c6}', '\0',
+        '\0']), ('\u{e7}', ['\u{c7}', '\0', '\0']), ('\u{e8}', ['\u{c8}', '\0', '\0']), ('\u{e9}',
+        ['\u{c9}', '\0', '\0']), ('\u{ea}', ['\u{ca}', '\0', '\0']), ('\u{eb}', ['\u{cb}', '\0',
+        '\0']), ('\u{ec}', ['\u{cc}', '\0', '\0']), ('\u{ed}', ['\u{cd}', '\0', '\0']), ('\u{ee}',
+        ['\u{ce}', '\0', '\0']), ('\u{ef}', ['\u{cf}', '\0', '\0']), ('\u{f0}', ['\u{d0}', '\0',
+        '\0']), ('\u{f1}', ['\u{d1}', '\0', '\0']), ('\u{f2}', ['\u{d2}', '\0', '\0']), ('\u{f3}',
+        ['\u{d3}', '\0', '\0']), ('\u{f4}', ['\u{d4}', '\0', '\0']), ('\u{f5}', ['\u{d5}', '\0',
+        '\0']), ('\u{f6}', ['\u{d6}', '\0', '\0']), ('\u{f8}', ['\u{d8}', '\0', '\0']), ('\u{f9}',
+        ['\u{d9}', '\0', '\0']), ('\u{fa}', ['\u{da}', '\0', '\0']), ('\u{fb}', ['\u{db}', '\0',
+        '\0']), ('\u{fc}', ['\u{dc}', '\0', '\0']), ('\u{fd}', ['\u{dd}', '\0', '\0']), ('\u{fe}',
+        ['\u{de}', '\0', '\0']), ('\u{ff}', ['\u{178}', '\0', '\0']), ('\u{101}', ['\u{100}', '\0',
+        '\0']), ('\u{103}', ['\u{102}', '\0', '\0']), ('\u{105}', ['\u{104}', '\0', '\0']),
+        ('\u{107}', ['\u{106}', '\0', '\0']), ('\u{109}', ['\u{108}', '\0', '\0']), ('\u{10b}',
+        ['\u{10a}', '\0', '\0']), ('\u{10d}', ['\u{10c}', '\0', '\0']), ('\u{10f}', ['\u{10e}',
+        '\0', '\0']), ('\u{111}', ['\u{110}', '\0', '\0']), ('\u{113}', ['\u{112}', '\0', '\0']),
+        ('\u{115}', ['\u{114}', '\0', '\0']), ('\u{117}', ['\u{116}', '\0', '\0']), ('\u{119}',
+        ['\u{118}', '\0', '\0']), ('\u{11b}', ['\u{11a}', '\0', '\0']), ('\u{11d}', ['\u{11c}',
+        '\0', '\0']), ('\u{11f}', ['\u{11e}', '\0', '\0']), ('\u{121}', ['\u{120}', '\0', '\0']),
+        ('\u{123}', ['\u{122}', '\0', '\0']), ('\u{125}', ['\u{124}', '\0', '\0']), ('\u{127}',
+        ['\u{126}', '\0', '\0']), ('\u{129}', ['\u{128}', '\0', '\0']), ('\u{12b}', ['\u{12a}',
+        '\0', '\0']), ('\u{12d}', ['\u{12c}', '\0', '\0']), ('\u{12f}', ['\u{12e}', '\0', '\0']),
+        ('\u{131}', ['\u{49}', '\0', '\0']), ('\u{133}', ['\u{132}', '\0', '\0']), ('\u{135}',
+        ['\u{134}', '\0', '\0']), ('\u{137}', ['\u{136}', '\0', '\0']), ('\u{13a}', ['\u{139}',
+        '\0', '\0']), ('\u{13c}', ['\u{13b}', '\0', '\0']), ('\u{13e}', ['\u{13d}', '\0', '\0']),
+        ('\u{140}', ['\u{13f}', '\0', '\0']), ('\u{142}', ['\u{141}', '\0', '\0']), ('\u{144}',
+        ['\u{143}', '\0', '\0']), ('\u{146}', ['\u{145}', '\0', '\0']), ('\u{148}', ['\u{147}',
+        '\0', '\0']), ('\u{149}', ['\u{2bc}', '\u{4e}', '\0']), ('\u{14b}', ['\u{14a}', '\0',
+        '\0']), ('\u{14d}', ['\u{14c}', '\0', '\0']), ('\u{14f}', ['\u{14e}', '\0', '\0']),
+        ('\u{151}', ['\u{150}', '\0', '\0']), ('\u{153}', ['\u{152}', '\0', '\0']), ('\u{155}',
+        ['\u{154}', '\0', '\0']), ('\u{157}', ['\u{156}', '\0', '\0']), ('\u{159}', ['\u{158}',
+        '\0', '\0']), ('\u{15b}', ['\u{15a}', '\0', '\0']), ('\u{15d}', ['\u{15c}', '\0', '\0']),
+        ('\u{15f}', ['\u{15e}', '\0', '\0']), ('\u{161}', ['\u{160}', '\0', '\0']), ('\u{163}',
+        ['\u{162}', '\0', '\0']), ('\u{165}', ['\u{164}', '\0', '\0']), ('\u{167}', ['\u{166}',
+        '\0', '\0']), ('\u{169}', ['\u{168}', '\0', '\0']), ('\u{16b}', ['\u{16a}', '\0', '\0']),
+        ('\u{16d}', ['\u{16c}', '\0', '\0']), ('\u{16f}', ['\u{16e}', '\0', '\0']), ('\u{171}',
+        ['\u{170}', '\0', '\0']), ('\u{173}', ['\u{172}', '\0', '\0']), ('\u{175}', ['\u{174}',
+        '\0', '\0']), ('\u{177}', ['\u{176}', '\0', '\0']), ('\u{17a}', ['\u{179}', '\0', '\0']),
+        ('\u{17c}', ['\u{17b}', '\0', '\0']), ('\u{17e}', ['\u{17d}', '\0', '\0']), ('\u{17f}',
+        ['\u{53}', '\0', '\0']), ('\u{180}', ['\u{243}', '\0', '\0']), ('\u{183}', ['\u{182}', '\0',
+        '\0']), ('\u{185}', ['\u{184}', '\0', '\0']), ('\u{188}', ['\u{187}', '\0', '\0']),
+        ('\u{18c}', ['\u{18b}', '\0', '\0']), ('\u{192}', ['\u{191}', '\0', '\0']), ('\u{195}',
+        ['\u{1f6}', '\0', '\0']), ('\u{199}', ['\u{198}', '\0', '\0']), ('\u{19a}', ['\u{23d}',
+        '\0', '\0']), ('\u{19e}', ['\u{220}', '\0', '\0']), ('\u{1a1}', ['\u{1a0}', '\0', '\0']),
+        ('\u{1a3}', ['\u{1a2}', '\0', '\0']), ('\u{1a5}', ['\u{1a4}', '\0', '\0']), ('\u{1a8}',
+        ['\u{1a7}', '\0', '\0']), ('\u{1ad}', ['\u{1ac}', '\0', '\0']), ('\u{1b0}', ['\u{1af}',
+        '\0', '\0']), ('\u{1b4}', ['\u{1b3}', '\0', '\0']), ('\u{1b6}', ['\u{1b5}', '\0', '\0']),
+        ('\u{1b9}', ['\u{1b8}', '\0', '\0']), ('\u{1bd}', ['\u{1bc}', '\0', '\0']), ('\u{1bf}',
+        ['\u{1f7}', '\0', '\0']), ('\u{1c5}', ['\u{1c4}', '\0', '\0']), ('\u{1c6}', ['\u{1c4}',
+        '\0', '\0']), ('\u{1c8}', ['\u{1c7}', '\0', '\0']), ('\u{1c9}', ['\u{1c7}', '\0', '\0']),
+        ('\u{1cb}', ['\u{1ca}', '\0', '\0']), ('\u{1cc}', ['\u{1ca}', '\0', '\0']), ('\u{1ce}',
+        ['\u{1cd}', '\0', '\0']), ('\u{1d0}', ['\u{1cf}', '\0', '\0']), ('\u{1d2}', ['\u{1d1}',
+        '\0', '\0']), ('\u{1d4}', ['\u{1d3}', '\0', '\0']), ('\u{1d6}', ['\u{1d5}', '\0', '\0']),
+        ('\u{1d8}', ['\u{1d7}', '\0', '\0']), ('\u{1da}', ['\u{1d9}', '\0', '\0']), ('\u{1dc}',
+        ['\u{1db}', '\0', '\0']), ('\u{1dd}', ['\u{18e}', '\0', '\0']), ('\u{1df}', ['\u{1de}',
+        '\0', '\0']), ('\u{1e1}', ['\u{1e0}', '\0', '\0']), ('\u{1e3}', ['\u{1e2}', '\0', '\0']),
+        ('\u{1e5}', ['\u{1e4}', '\0', '\0']), ('\u{1e7}', ['\u{1e6}', '\0', '\0']), ('\u{1e9}',
+        ['\u{1e8}', '\0', '\0']), ('\u{1eb}', ['\u{1ea}', '\0', '\0']), ('\u{1ed}', ['\u{1ec}',
+        '\0', '\0']), ('\u{1ef}', ['\u{1ee}', '\0', '\0']), ('\u{1f0}', ['\u{4a}', '\u{30c}',
+        '\0']), ('\u{1f2}', ['\u{1f1}', '\0', '\0']), ('\u{1f3}', ['\u{1f1}', '\0', '\0']),
+        ('\u{1f5}', ['\u{1f4}', '\0', '\0']), ('\u{1f9}', ['\u{1f8}', '\0', '\0']), ('\u{1fb}',
+        ['\u{1fa}', '\0', '\0']), ('\u{1fd}', ['\u{1fc}', '\0', '\0']), ('\u{1ff}', ['\u{1fe}',
+        '\0', '\0']), ('\u{201}', ['\u{200}', '\0', '\0']), ('\u{203}', ['\u{202}', '\0', '\0']),
+        ('\u{205}', ['\u{204}', '\0', '\0']), ('\u{207}', ['\u{206}', '\0', '\0']), ('\u{209}',
+        ['\u{208}', '\0', '\0']), ('\u{20b}', ['\u{20a}', '\0', '\0']), ('\u{20d}', ['\u{20c}',
+        '\0', '\0']), ('\u{20f}', ['\u{20e}', '\0', '\0']), ('\u{211}', ['\u{210}', '\0', '\0']),
+        ('\u{213}', ['\u{212}', '\0', '\0']), ('\u{215}', ['\u{214}', '\0', '\0']), ('\u{217}',
+        ['\u{216}', '\0', '\0']), ('\u{219}', ['\u{218}', '\0', '\0']), ('\u{21b}', ['\u{21a}',
+        '\0', '\0']), ('\u{21d}', ['\u{21c}', '\0', '\0']), ('\u{21f}', ['\u{21e}', '\0', '\0']),
+        ('\u{223}', ['\u{222}', '\0', '\0']), ('\u{225}', ['\u{224}', '\0', '\0']), ('\u{227}',
+        ['\u{226}', '\0', '\0']), ('\u{229}', ['\u{228}', '\0', '\0']), ('\u{22b}', ['\u{22a}',
+        '\0', '\0']), ('\u{22d}', ['\u{22c}', '\0', '\0']), ('\u{22f}', ['\u{22e}', '\0', '\0']),
+        ('\u{231}', ['\u{230}', '\0', '\0']), ('\u{233}', ['\u{232}', '\0', '\0']), ('\u{23c}',
+        ['\u{23b}', '\0', '\0']), ('\u{23f}', ['\u{2c7e}', '\0', '\0']), ('\u{240}', ['\u{2c7f}',
+        '\0', '\0']), ('\u{242}', ['\u{241}', '\0', '\0']), ('\u{247}', ['\u{246}', '\0', '\0']),
+        ('\u{249}', ['\u{248}', '\0', '\0']), ('\u{24b}', ['\u{24a}', '\0', '\0']), ('\u{24d}',
+        ['\u{24c}', '\0', '\0']), ('\u{24f}', ['\u{24e}', '\0', '\0']), ('\u{250}', ['\u{2c6f}',
+        '\0', '\0']), ('\u{251}', ['\u{2c6d}', '\0', '\0']), ('\u{252}', ['\u{2c70}', '\0', '\0']),
+        ('\u{253}', ['\u{181}', '\0', '\0']), ('\u{254}', ['\u{186}', '\0', '\0']), ('\u{256}',
+        ['\u{189}', '\0', '\0']), ('\u{257}', ['\u{18a}', '\0', '\0']), ('\u{259}', ['\u{18f}',
+        '\0', '\0']), ('\u{25b}', ['\u{190}', '\0', '\0']), ('\u{25c}', ['\u{a7ab}', '\0', '\0']),
+        ('\u{260}', ['\u{193}', '\0', '\0']), ('\u{261}', ['\u{a7ac}', '\0', '\0']), ('\u{263}',
+        ['\u{194}', '\0', '\0']), ('\u{265}', ['\u{a78d}', '\0', '\0']), ('\u{266}', ['\u{a7aa}',
+        '\0', '\0']), ('\u{268}', ['\u{197}', '\0', '\0']), ('\u{269}', ['\u{196}', '\0', '\0']),
+        ('\u{26b}', ['\u{2c62}', '\0', '\0']), ('\u{26c}', ['\u{a7ad}', '\0', '\0']), ('\u{26f}',
+        ['\u{19c}', '\0', '\0']), ('\u{271}', ['\u{2c6e}', '\0', '\0']), ('\u{272}', ['\u{19d}',
+        '\0', '\0']), ('\u{275}', ['\u{19f}', '\0', '\0']), ('\u{27d}', ['\u{2c64}', '\0', '\0']),
+        ('\u{280}', ['\u{1a6}', '\0', '\0']), ('\u{283}', ['\u{1a9}', '\0', '\0']), ('\u{287}',
+        ['\u{a7b1}', '\0', '\0']), ('\u{288}', ['\u{1ae}', '\0', '\0']), ('\u{289}', ['\u{244}',
+        '\0', '\0']), ('\u{28a}', ['\u{1b1}', '\0', '\0']), ('\u{28b}', ['\u{1b2}', '\0', '\0']),
+        ('\u{28c}', ['\u{245}', '\0', '\0']), ('\u{292}', ['\u{1b7}', '\0', '\0']), ('\u{29e}',
+        ['\u{a7b0}', '\0', '\0']), ('\u{345}', ['\u{399}', '\0', '\0']), ('\u{371}', ['\u{370}',
+        '\0', '\0']), ('\u{373}', ['\u{372}', '\0', '\0']), ('\u{377}', ['\u{376}', '\0', '\0']),
+        ('\u{37b}', ['\u{3fd}', '\0', '\0']), ('\u{37c}', ['\u{3fe}', '\0', '\0']), ('\u{37d}',
+        ['\u{3ff}', '\0', '\0']), ('\u{390}', ['\u{399}', '\u{308}', '\u{301}']), ('\u{3ac}',
+        ['\u{386}', '\0', '\0']), ('\u{3ad}', ['\u{388}', '\0', '\0']), ('\u{3ae}', ['\u{389}',
+        '\0', '\0']), ('\u{3af}', ['\u{38a}', '\0', '\0']), ('\u{3b0}', ['\u{3a5}', '\u{308}',
+        '\u{301}']), ('\u{3b1}', ['\u{391}', '\0', '\0']), ('\u{3b2}', ['\u{392}', '\0', '\0']),
+        ('\u{3b3}', ['\u{393}', '\0', '\0']), ('\u{3b4}', ['\u{394}', '\0', '\0']), ('\u{3b5}',
+        ['\u{395}', '\0', '\0']), ('\u{3b6}', ['\u{396}', '\0', '\0']), ('\u{3b7}', ['\u{397}',
+        '\0', '\0']), ('\u{3b8}', ['\u{398}', '\0', '\0']), ('\u{3b9}', ['\u{399}', '\0', '\0']),
+        ('\u{3ba}', ['\u{39a}', '\0', '\0']), ('\u{3bb}', ['\u{39b}', '\0', '\0']), ('\u{3bc}',
+        ['\u{39c}', '\0', '\0']), ('\u{3bd}', ['\u{39d}', '\0', '\0']), ('\u{3be}', ['\u{39e}',
+        '\0', '\0']), ('\u{3bf}', ['\u{39f}', '\0', '\0']), ('\u{3c0}', ['\u{3a0}', '\0', '\0']),
+        ('\u{3c1}', ['\u{3a1}', '\0', '\0']), ('\u{3c2}', ['\u{3a3}', '\0', '\0']), ('\u{3c3}',
+        ['\u{3a3}', '\0', '\0']), ('\u{3c4}', ['\u{3a4}', '\0', '\0']), ('\u{3c5}', ['\u{3a5}',
+        '\0', '\0']), ('\u{3c6}', ['\u{3a6}', '\0', '\0']), ('\u{3c7}', ['\u{3a7}', '\0', '\0']),
+        ('\u{3c8}', ['\u{3a8}', '\0', '\0']), ('\u{3c9}', ['\u{3a9}', '\0', '\0']), ('\u{3ca}',
+        ['\u{3aa}', '\0', '\0']), ('\u{3cb}', ['\u{3ab}', '\0', '\0']), ('\u{3cc}', ['\u{38c}',
+        '\0', '\0']), ('\u{3cd}', ['\u{38e}', '\0', '\0']), ('\u{3ce}', ['\u{38f}', '\0', '\0']),
+        ('\u{3d0}', ['\u{392}', '\0', '\0']), ('\u{3d1}', ['\u{398}', '\0', '\0']), ('\u{3d5}',
+        ['\u{3a6}', '\0', '\0']), ('\u{3d6}', ['\u{3a0}', '\0', '\0']), ('\u{3d7}', ['\u{3cf}',
+        '\0', '\0']), ('\u{3d9}', ['\u{3d8}', '\0', '\0']), ('\u{3db}', ['\u{3da}', '\0', '\0']),
+        ('\u{3dd}', ['\u{3dc}', '\0', '\0']), ('\u{3df}', ['\u{3de}', '\0', '\0']), ('\u{3e1}',
+        ['\u{3e0}', '\0', '\0']), ('\u{3e3}', ['\u{3e2}', '\0', '\0']), ('\u{3e5}', ['\u{3e4}',
+        '\0', '\0']), ('\u{3e7}', ['\u{3e6}', '\0', '\0']), ('\u{3e9}', ['\u{3e8}', '\0', '\0']),
+        ('\u{3eb}', ['\u{3ea}', '\0', '\0']), ('\u{3ed}', ['\u{3ec}', '\0', '\0']), ('\u{3ef}',
+        ['\u{3ee}', '\0', '\0']), ('\u{3f0}', ['\u{39a}', '\0', '\0']), ('\u{3f1}', ['\u{3a1}',
+        '\0', '\0']), ('\u{3f2}', ['\u{3f9}', '\0', '\0']), ('\u{3f3}', ['\u{37f}', '\0', '\0']),
+        ('\u{3f5}', ['\u{395}', '\0', '\0']), ('\u{3f8}', ['\u{3f7}', '\0', '\0']), ('\u{3fb}',
+        ['\u{3fa}', '\0', '\0']), ('\u{430}', ['\u{410}', '\0', '\0']), ('\u{431}', ['\u{411}',
+        '\0', '\0']), ('\u{432}', ['\u{412}', '\0', '\0']), ('\u{433}', ['\u{413}', '\0', '\0']),
+        ('\u{434}', ['\u{414}', '\0', '\0']), ('\u{435}', ['\u{415}', '\0', '\0']), ('\u{436}',
+        ['\u{416}', '\0', '\0']), ('\u{437}', ['\u{417}', '\0', '\0']), ('\u{438}', ['\u{418}',
+        '\0', '\0']), ('\u{439}', ['\u{419}', '\0', '\0']), ('\u{43a}', ['\u{41a}', '\0', '\0']),
+        ('\u{43b}', ['\u{41b}', '\0', '\0']), ('\u{43c}', ['\u{41c}', '\0', '\0']), ('\u{43d}',
+        ['\u{41d}', '\0', '\0']), ('\u{43e}', ['\u{41e}', '\0', '\0']), ('\u{43f}', ['\u{41f}',
+        '\0', '\0']), ('\u{440}', ['\u{420}', '\0', '\0']), ('\u{441}', ['\u{421}', '\0', '\0']),
+        ('\u{442}', ['\u{422}', '\0', '\0']), ('\u{443}', ['\u{423}', '\0', '\0']), ('\u{444}',
+        ['\u{424}', '\0', '\0']), ('\u{445}', ['\u{425}', '\0', '\0']), ('\u{446}', ['\u{426}',
+        '\0', '\0']), ('\u{447}', ['\u{427}', '\0', '\0']), ('\u{448}', ['\u{428}', '\0', '\0']),
+        ('\u{449}', ['\u{429}', '\0', '\0']), ('\u{44a}', ['\u{42a}', '\0', '\0']), ('\u{44b}',
+        ['\u{42b}', '\0', '\0']), ('\u{44c}', ['\u{42c}', '\0', '\0']), ('\u{44d}', ['\u{42d}',
+        '\0', '\0']), ('\u{44e}', ['\u{42e}', '\0', '\0']), ('\u{44f}', ['\u{42f}', '\0', '\0']),
+        ('\u{450}', ['\u{400}', '\0', '\0']), ('\u{451}', ['\u{401}', '\0', '\0']), ('\u{452}',
+        ['\u{402}', '\0', '\0']), ('\u{453}', ['\u{403}', '\0', '\0']), ('\u{454}', ['\u{404}',
+        '\0', '\0']), ('\u{455}', ['\u{405}', '\0', '\0']), ('\u{456}', ['\u{406}', '\0', '\0']),
+        ('\u{457}', ['\u{407}', '\0', '\0']), ('\u{458}', ['\u{408}', '\0', '\0']), ('\u{459}',
+        ['\u{409}', '\0', '\0']), ('\u{45a}', ['\u{40a}', '\0', '\0']), ('\u{45b}', ['\u{40b}',
+        '\0', '\0']), ('\u{45c}', ['\u{40c}', '\0', '\0']), ('\u{45d}', ['\u{40d}', '\0', '\0']),
+        ('\u{45e}', ['\u{40e}', '\0', '\0']), ('\u{45f}', ['\u{40f}', '\0', '\0']), ('\u{461}',
+        ['\u{460}', '\0', '\0']), ('\u{463}', ['\u{462}', '\0', '\0']), ('\u{465}', ['\u{464}',
+        '\0', '\0']), ('\u{467}', ['\u{466}', '\0', '\0']), ('\u{469}', ['\u{468}', '\0', '\0']),
+        ('\u{46b}', ['\u{46a}', '\0', '\0']), ('\u{46d}', ['\u{46c}', '\0', '\0']), ('\u{46f}',
+        ['\u{46e}', '\0', '\0']), ('\u{471}', ['\u{470}', '\0', '\0']), ('\u{473}', ['\u{472}',
+        '\0', '\0']), ('\u{475}', ['\u{474}', '\0', '\0']), ('\u{477}', ['\u{476}', '\0', '\0']),
+        ('\u{479}', ['\u{478}', '\0', '\0']), ('\u{47b}', ['\u{47a}', '\0', '\0']), ('\u{47d}',
+        ['\u{47c}', '\0', '\0']), ('\u{47f}', ['\u{47e}', '\0', '\0']), ('\u{481}', ['\u{480}',
+        '\0', '\0']), ('\u{48b}', ['\u{48a}', '\0', '\0']), ('\u{48d}', ['\u{48c}', '\0', '\0']),
+        ('\u{48f}', ['\u{48e}', '\0', '\0']), ('\u{491}', ['\u{490}', '\0', '\0']), ('\u{493}',
+        ['\u{492}', '\0', '\0']), ('\u{495}', ['\u{494}', '\0', '\0']), ('\u{497}', ['\u{496}',
+        '\0', '\0']), ('\u{499}', ['\u{498}', '\0', '\0']), ('\u{49b}', ['\u{49a}', '\0', '\0']),
+        ('\u{49d}', ['\u{49c}', '\0', '\0']), ('\u{49f}', ['\u{49e}', '\0', '\0']), ('\u{4a1}',
+        ['\u{4a0}', '\0', '\0']), ('\u{4a3}', ['\u{4a2}', '\0', '\0']), ('\u{4a5}', ['\u{4a4}',
+        '\0', '\0']), ('\u{4a7}', ['\u{4a6}', '\0', '\0']), ('\u{4a9}', ['\u{4a8}', '\0', '\0']),
+        ('\u{4ab}', ['\u{4aa}', '\0', '\0']), ('\u{4ad}', ['\u{4ac}', '\0', '\0']), ('\u{4af}',
+        ['\u{4ae}', '\0', '\0']), ('\u{4b1}', ['\u{4b0}', '\0', '\0']), ('\u{4b3}', ['\u{4b2}',
+        '\0', '\0']), ('\u{4b5}', ['\u{4b4}', '\0', '\0']), ('\u{4b7}', ['\u{4b6}', '\0', '\0']),
+        ('\u{4b9}', ['\u{4b8}', '\0', '\0']), ('\u{4bb}', ['\u{4ba}', '\0', '\0']), ('\u{4bd}',
+        ['\u{4bc}', '\0', '\0']), ('\u{4bf}', ['\u{4be}', '\0', '\0']), ('\u{4c2}', ['\u{4c1}',
+        '\0', '\0']), ('\u{4c4}', ['\u{4c3}', '\0', '\0']), ('\u{4c6}', ['\u{4c5}', '\0', '\0']),
+        ('\u{4c8}', ['\u{4c7}', '\0', '\0']), ('\u{4ca}', ['\u{4c9}', '\0', '\0']), ('\u{4cc}',
+        ['\u{4cb}', '\0', '\0']), ('\u{4ce}', ['\u{4cd}', '\0', '\0']), ('\u{4cf}', ['\u{4c0}',
+        '\0', '\0']), ('\u{4d1}', ['\u{4d0}', '\0', '\0']), ('\u{4d3}', ['\u{4d2}', '\0', '\0']),
+        ('\u{4d5}', ['\u{4d4}', '\0', '\0']), ('\u{4d7}', ['\u{4d6}', '\0', '\0']), ('\u{4d9}',
+        ['\u{4d8}', '\0', '\0']), ('\u{4db}', ['\u{4da}', '\0', '\0']), ('\u{4dd}', ['\u{4dc}',
+        '\0', '\0']), ('\u{4df}', ['\u{4de}', '\0', '\0']), ('\u{4e1}', ['\u{4e0}', '\0', '\0']),
+        ('\u{4e3}', ['\u{4e2}', '\0', '\0']), ('\u{4e5}', ['\u{4e4}', '\0', '\0']), ('\u{4e7}',
+        ['\u{4e6}', '\0', '\0']), ('\u{4e9}', ['\u{4e8}', '\0', '\0']), ('\u{4eb}', ['\u{4ea}',
+        '\0', '\0']), ('\u{4ed}', ['\u{4ec}', '\0', '\0']), ('\u{4ef}', ['\u{4ee}', '\0', '\0']),
+        ('\u{4f1}', ['\u{4f0}', '\0', '\0']), ('\u{4f3}', ['\u{4f2}', '\0', '\0']), ('\u{4f5}',
+        ['\u{4f4}', '\0', '\0']), ('\u{4f7}', ['\u{4f6}', '\0', '\0']), ('\u{4f9}', ['\u{4f8}',
+        '\0', '\0']), ('\u{4fb}', ['\u{4fa}', '\0', '\0']), ('\u{4fd}', ['\u{4fc}', '\0', '\0']),
+        ('\u{4ff}', ['\u{4fe}', '\0', '\0']), ('\u{501}', ['\u{500}', '\0', '\0']), ('\u{503}',
+        ['\u{502}', '\0', '\0']), ('\u{505}', ['\u{504}', '\0', '\0']), ('\u{507}', ['\u{506}',
+        '\0', '\0']), ('\u{509}', ['\u{508}', '\0', '\0']), ('\u{50b}', ['\u{50a}', '\0', '\0']),
+        ('\u{50d}', ['\u{50c}', '\0', '\0']), ('\u{50f}', ['\u{50e}', '\0', '\0']), ('\u{511}',
+        ['\u{510}', '\0', '\0']), ('\u{513}', ['\u{512}', '\0', '\0']), ('\u{515}', ['\u{514}',
+        '\0', '\0']), ('\u{517}', ['\u{516}', '\0', '\0']), ('\u{519}', ['\u{518}', '\0', '\0']),
+        ('\u{51b}', ['\u{51a}', '\0', '\0']), ('\u{51d}', ['\u{51c}', '\0', '\0']), ('\u{51f}',
+        ['\u{51e}', '\0', '\0']), ('\u{521}', ['\u{520}', '\0', '\0']), ('\u{523}', ['\u{522}',
+        '\0', '\0']), ('\u{525}', ['\u{524}', '\0', '\0']), ('\u{527}', ['\u{526}', '\0', '\0']),
+        ('\u{529}', ['\u{528}', '\0', '\0']), ('\u{52b}', ['\u{52a}', '\0', '\0']), ('\u{52d}',
+        ['\u{52c}', '\0', '\0']), ('\u{52f}', ['\u{52e}', '\0', '\0']), ('\u{561}', ['\u{531}',
+        '\0', '\0']), ('\u{562}', ['\u{532}', '\0', '\0']), ('\u{563}', ['\u{533}', '\0', '\0']),
+        ('\u{564}', ['\u{534}', '\0', '\0']), ('\u{565}', ['\u{535}', '\0', '\0']), ('\u{566}',
+        ['\u{536}', '\0', '\0']), ('\u{567}', ['\u{537}', '\0', '\0']), ('\u{568}', ['\u{538}',
+        '\0', '\0']), ('\u{569}', ['\u{539}', '\0', '\0']), ('\u{56a}', ['\u{53a}', '\0', '\0']),
+        ('\u{56b}', ['\u{53b}', '\0', '\0']), ('\u{56c}', ['\u{53c}', '\0', '\0']), ('\u{56d}',
+        ['\u{53d}', '\0', '\0']), ('\u{56e}', ['\u{53e}', '\0', '\0']), ('\u{56f}', ['\u{53f}',
+        '\0', '\0']), ('\u{570}', ['\u{540}', '\0', '\0']), ('\u{571}', ['\u{541}', '\0', '\0']),
+        ('\u{572}', ['\u{542}', '\0', '\0']), ('\u{573}', ['\u{543}', '\0', '\0']), ('\u{574}',
+        ['\u{544}', '\0', '\0']), ('\u{575}', ['\u{545}', '\0', '\0']), ('\u{576}', ['\u{546}',
+        '\0', '\0']), ('\u{577}', ['\u{547}', '\0', '\0']), ('\u{578}', ['\u{548}', '\0', '\0']),
+        ('\u{579}', ['\u{549}', '\0', '\0']), ('\u{57a}', ['\u{54a}', '\0', '\0']), ('\u{57b}',
+        ['\u{54b}', '\0', '\0']), ('\u{57c}', ['\u{54c}', '\0', '\0']), ('\u{57d}', ['\u{54d}',
+        '\0', '\0']), ('\u{57e}', ['\u{54e}', '\0', '\0']), ('\u{57f}', ['\u{54f}', '\0', '\0']),
+        ('\u{580}', ['\u{550}', '\0', '\0']), ('\u{581}', ['\u{551}', '\0', '\0']), ('\u{582}',
+        ['\u{552}', '\0', '\0']), ('\u{583}', ['\u{553}', '\0', '\0']), ('\u{584}', ['\u{554}',
+        '\0', '\0']), ('\u{585}', ['\u{555}', '\0', '\0']), ('\u{586}', ['\u{556}', '\0', '\0']),
+        ('\u{587}', ['\u{535}', '\u{552}', '\0']), ('\u{1d79}', ['\u{a77d}', '\0', '\0']),
+        ('\u{1d7d}', ['\u{2c63}', '\0', '\0']), ('\u{1e01}', ['\u{1e00}', '\0', '\0']), ('\u{1e03}',
+        ['\u{1e02}', '\0', '\0']), ('\u{1e05}', ['\u{1e04}', '\0', '\0']), ('\u{1e07}', ['\u{1e06}',
+        '\0', '\0']), ('\u{1e09}', ['\u{1e08}', '\0', '\0']), ('\u{1e0b}', ['\u{1e0a}', '\0',
+        '\0']), ('\u{1e0d}', ['\u{1e0c}', '\0', '\0']), ('\u{1e0f}', ['\u{1e0e}', '\0', '\0']),
+        ('\u{1e11}', ['\u{1e10}', '\0', '\0']), ('\u{1e13}', ['\u{1e12}', '\0', '\0']), ('\u{1e15}',
+        ['\u{1e14}', '\0', '\0']), ('\u{1e17}', ['\u{1e16}', '\0', '\0']), ('\u{1e19}', ['\u{1e18}',
+        '\0', '\0']), ('\u{1e1b}', ['\u{1e1a}', '\0', '\0']), ('\u{1e1d}', ['\u{1e1c}', '\0',
+        '\0']), ('\u{1e1f}', ['\u{1e1e}', '\0', '\0']), ('\u{1e21}', ['\u{1e20}', '\0', '\0']),
+        ('\u{1e23}', ['\u{1e22}', '\0', '\0']), ('\u{1e25}', ['\u{1e24}', '\0', '\0']), ('\u{1e27}',
+        ['\u{1e26}', '\0', '\0']), ('\u{1e29}', ['\u{1e28}', '\0', '\0']), ('\u{1e2b}', ['\u{1e2a}',
+        '\0', '\0']), ('\u{1e2d}', ['\u{1e2c}', '\0', '\0']), ('\u{1e2f}', ['\u{1e2e}', '\0',
+        '\0']), ('\u{1e31}', ['\u{1e30}', '\0', '\0']), ('\u{1e33}', ['\u{1e32}', '\0', '\0']),
+        ('\u{1e35}', ['\u{1e34}', '\0', '\0']), ('\u{1e37}', ['\u{1e36}', '\0', '\0']), ('\u{1e39}',
+        ['\u{1e38}', '\0', '\0']), ('\u{1e3b}', ['\u{1e3a}', '\0', '\0']), ('\u{1e3d}', ['\u{1e3c}',
+        '\0', '\0']), ('\u{1e3f}', ['\u{1e3e}', '\0', '\0']), ('\u{1e41}', ['\u{1e40}', '\0',
+        '\0']), ('\u{1e43}', ['\u{1e42}', '\0', '\0']), ('\u{1e45}', ['\u{1e44}', '\0', '\0']),
+        ('\u{1e47}', ['\u{1e46}', '\0', '\0']), ('\u{1e49}', ['\u{1e48}', '\0', '\0']), ('\u{1e4b}',
+        ['\u{1e4a}', '\0', '\0']), ('\u{1e4d}', ['\u{1e4c}', '\0', '\0']), ('\u{1e4f}', ['\u{1e4e}',
+        '\0', '\0']), ('\u{1e51}', ['\u{1e50}', '\0', '\0']), ('\u{1e53}', ['\u{1e52}', '\0',
+        '\0']), ('\u{1e55}', ['\u{1e54}', '\0', '\0']), ('\u{1e57}', ['\u{1e56}', '\0', '\0']),
+        ('\u{1e59}', ['\u{1e58}', '\0', '\0']), ('\u{1e5b}', ['\u{1e5a}', '\0', '\0']), ('\u{1e5d}',
+        ['\u{1e5c}', '\0', '\0']), ('\u{1e5f}', ['\u{1e5e}', '\0', '\0']), ('\u{1e61}', ['\u{1e60}',
+        '\0', '\0']), ('\u{1e63}', ['\u{1e62}', '\0', '\0']), ('\u{1e65}', ['\u{1e64}', '\0',
+        '\0']), ('\u{1e67}', ['\u{1e66}', '\0', '\0']), ('\u{1e69}', ['\u{1e68}', '\0', '\0']),
+        ('\u{1e6b}', ['\u{1e6a}', '\0', '\0']), ('\u{1e6d}', ['\u{1e6c}', '\0', '\0']), ('\u{1e6f}',
+        ['\u{1e6e}', '\0', '\0']), ('\u{1e71}', ['\u{1e70}', '\0', '\0']), ('\u{1e73}', ['\u{1e72}',
+        '\0', '\0']), ('\u{1e75}', ['\u{1e74}', '\0', '\0']), ('\u{1e77}', ['\u{1e76}', '\0',
+        '\0']), ('\u{1e79}', ['\u{1e78}', '\0', '\0']), ('\u{1e7b}', ['\u{1e7a}', '\0', '\0']),
+        ('\u{1e7d}', ['\u{1e7c}', '\0', '\0']), ('\u{1e7f}', ['\u{1e7e}', '\0', '\0']), ('\u{1e81}',
+        ['\u{1e80}', '\0', '\0']), ('\u{1e83}', ['\u{1e82}', '\0', '\0']), ('\u{1e85}', ['\u{1e84}',
+        '\0', '\0']), ('\u{1e87}', ['\u{1e86}', '\0', '\0']), ('\u{1e89}', ['\u{1e88}', '\0',
+        '\0']), ('\u{1e8b}', ['\u{1e8a}', '\0', '\0']), ('\u{1e8d}', ['\u{1e8c}', '\0', '\0']),
+        ('\u{1e8f}', ['\u{1e8e}', '\0', '\0']), ('\u{1e91}', ['\u{1e90}', '\0', '\0']), ('\u{1e93}',
+        ['\u{1e92}', '\0', '\0']), ('\u{1e95}', ['\u{1e94}', '\0', '\0']), ('\u{1e96}', ['\u{48}',
+        '\u{331}', '\0']), ('\u{1e97}', ['\u{54}', '\u{308}', '\0']), ('\u{1e98}', ['\u{57}',
+        '\u{30a}', '\0']), ('\u{1e99}', ['\u{59}', '\u{30a}', '\0']), ('\u{1e9a}', ['\u{41}',
+        '\u{2be}', '\0']), ('\u{1e9b}', ['\u{1e60}', '\0', '\0']), ('\u{1ea1}', ['\u{1ea0}', '\0',
+        '\0']), ('\u{1ea3}', ['\u{1ea2}', '\0', '\0']), ('\u{1ea5}', ['\u{1ea4}', '\0', '\0']),
+        ('\u{1ea7}', ['\u{1ea6}', '\0', '\0']), ('\u{1ea9}', ['\u{1ea8}', '\0', '\0']), ('\u{1eab}',
+        ['\u{1eaa}', '\0', '\0']), ('\u{1ead}', ['\u{1eac}', '\0', '\0']), ('\u{1eaf}', ['\u{1eae}',
+        '\0', '\0']), ('\u{1eb1}', ['\u{1eb0}', '\0', '\0']), ('\u{1eb3}', ['\u{1eb2}', '\0',
+        '\0']), ('\u{1eb5}', ['\u{1eb4}', '\0', '\0']), ('\u{1eb7}', ['\u{1eb6}', '\0', '\0']),
+        ('\u{1eb9}', ['\u{1eb8}', '\0', '\0']), ('\u{1ebb}', ['\u{1eba}', '\0', '\0']), ('\u{1ebd}',
+        ['\u{1ebc}', '\0', '\0']), ('\u{1ebf}', ['\u{1ebe}', '\0', '\0']), ('\u{1ec1}', ['\u{1ec0}',
+        '\0', '\0']), ('\u{1ec3}', ['\u{1ec2}', '\0', '\0']), ('\u{1ec5}', ['\u{1ec4}', '\0',
+        '\0']), ('\u{1ec7}', ['\u{1ec6}', '\0', '\0']), ('\u{1ec9}', ['\u{1ec8}', '\0', '\0']),
+        ('\u{1ecb}', ['\u{1eca}', '\0', '\0']), ('\u{1ecd}', ['\u{1ecc}', '\0', '\0']), ('\u{1ecf}',
+        ['\u{1ece}', '\0', '\0']), ('\u{1ed1}', ['\u{1ed0}', '\0', '\0']), ('\u{1ed3}', ['\u{1ed2}',
+        '\0', '\0']), ('\u{1ed5}', ['\u{1ed4}', '\0', '\0']), ('\u{1ed7}', ['\u{1ed6}', '\0',
+        '\0']), ('\u{1ed9}', ['\u{1ed8}', '\0', '\0']), ('\u{1edb}', ['\u{1eda}', '\0', '\0']),
+        ('\u{1edd}', ['\u{1edc}', '\0', '\0']), ('\u{1edf}', ['\u{1ede}', '\0', '\0']), ('\u{1ee1}',
+        ['\u{1ee0}', '\0', '\0']), ('\u{1ee3}', ['\u{1ee2}', '\0', '\0']), ('\u{1ee5}', ['\u{1ee4}',
+        '\0', '\0']), ('\u{1ee7}', ['\u{1ee6}', '\0', '\0']), ('\u{1ee9}', ['\u{1ee8}', '\0',
+        '\0']), ('\u{1eeb}', ['\u{1eea}', '\0', '\0']), ('\u{1eed}', ['\u{1eec}', '\0', '\0']),
+        ('\u{1eef}', ['\u{1eee}', '\0', '\0']), ('\u{1ef1}', ['\u{1ef0}', '\0', '\0']), ('\u{1ef3}',
+        ['\u{1ef2}', '\0', '\0']), ('\u{1ef5}', ['\u{1ef4}', '\0', '\0']), ('\u{1ef7}', ['\u{1ef6}',
+        '\0', '\0']), ('\u{1ef9}', ['\u{1ef8}', '\0', '\0']), ('\u{1efb}', ['\u{1efa}', '\0',
+        '\0']), ('\u{1efd}', ['\u{1efc}', '\0', '\0']), ('\u{1eff}', ['\u{1efe}', '\0', '\0']),
+        ('\u{1f00}', ['\u{1f08}', '\0', '\0']), ('\u{1f01}', ['\u{1f09}', '\0', '\0']), ('\u{1f02}',
+        ['\u{1f0a}', '\0', '\0']), ('\u{1f03}', ['\u{1f0b}', '\0', '\0']), ('\u{1f04}', ['\u{1f0c}',
+        '\0', '\0']), ('\u{1f05}', ['\u{1f0d}', '\0', '\0']), ('\u{1f06}', ['\u{1f0e}', '\0',
+        '\0']), ('\u{1f07}', ['\u{1f0f}', '\0', '\0']), ('\u{1f10}', ['\u{1f18}', '\0', '\0']),
+        ('\u{1f11}', ['\u{1f19}', '\0', '\0']), ('\u{1f12}', ['\u{1f1a}', '\0', '\0']), ('\u{1f13}',
+        ['\u{1f1b}', '\0', '\0']), ('\u{1f14}', ['\u{1f1c}', '\0', '\0']), ('\u{1f15}', ['\u{1f1d}',
+        '\0', '\0']), ('\u{1f20}', ['\u{1f28}', '\0', '\0']), ('\u{1f21}', ['\u{1f29}', '\0',
+        '\0']), ('\u{1f22}', ['\u{1f2a}', '\0', '\0']), ('\u{1f23}', ['\u{1f2b}', '\0', '\0']),
+        ('\u{1f24}', ['\u{1f2c}', '\0', '\0']), ('\u{1f25}', ['\u{1f2d}', '\0', '\0']), ('\u{1f26}',
+        ['\u{1f2e}', '\0', '\0']), ('\u{1f27}', ['\u{1f2f}', '\0', '\0']), ('\u{1f30}', ['\u{1f38}',
+        '\0', '\0']), ('\u{1f31}', ['\u{1f39}', '\0', '\0']), ('\u{1f32}', ['\u{1f3a}', '\0',
+        '\0']), ('\u{1f33}', ['\u{1f3b}', '\0', '\0']), ('\u{1f34}', ['\u{1f3c}', '\0', '\0']),
+        ('\u{1f35}', ['\u{1f3d}', '\0', '\0']), ('\u{1f36}', ['\u{1f3e}', '\0', '\0']), ('\u{1f37}',
+        ['\u{1f3f}', '\0', '\0']), ('\u{1f40}', ['\u{1f48}', '\0', '\0']), ('\u{1f41}', ['\u{1f49}',
+        '\0', '\0']), ('\u{1f42}', ['\u{1f4a}', '\0', '\0']), ('\u{1f43}', ['\u{1f4b}', '\0',
+        '\0']), ('\u{1f44}', ['\u{1f4c}', '\0', '\0']), ('\u{1f45}', ['\u{1f4d}', '\0', '\0']),
+        ('\u{1f50}', ['\u{3a5}', '\u{313}', '\0']), ('\u{1f51}', ['\u{1f59}', '\0', '\0']),
+        ('\u{1f52}', ['\u{3a5}', '\u{313}', '\u{300}']), ('\u{1f53}', ['\u{1f5b}', '\0', '\0']),
+        ('\u{1f54}', ['\u{3a5}', '\u{313}', '\u{301}']), ('\u{1f55}', ['\u{1f5d}', '\0', '\0']),
+        ('\u{1f56}', ['\u{3a5}', '\u{313}', '\u{342}']), ('\u{1f57}', ['\u{1f5f}', '\0', '\0']),
+        ('\u{1f60}', ['\u{1f68}', '\0', '\0']), ('\u{1f61}', ['\u{1f69}', '\0', '\0']), ('\u{1f62}',
+        ['\u{1f6a}', '\0', '\0']), ('\u{1f63}', ['\u{1f6b}', '\0', '\0']), ('\u{1f64}', ['\u{1f6c}',
+        '\0', '\0']), ('\u{1f65}', ['\u{1f6d}', '\0', '\0']), ('\u{1f66}', ['\u{1f6e}', '\0',
+        '\0']), ('\u{1f67}', ['\u{1f6f}', '\0', '\0']), ('\u{1f70}', ['\u{1fba}', '\0', '\0']),
+        ('\u{1f71}', ['\u{1fbb}', '\0', '\0']), ('\u{1f72}', ['\u{1fc8}', '\0', '\0']), ('\u{1f73}',
+        ['\u{1fc9}', '\0', '\0']), ('\u{1f74}', ['\u{1fca}', '\0', '\0']), ('\u{1f75}', ['\u{1fcb}',
+        '\0', '\0']), ('\u{1f76}', ['\u{1fda}', '\0', '\0']), ('\u{1f77}', ['\u{1fdb}', '\0',
+        '\0']), ('\u{1f78}', ['\u{1ff8}', '\0', '\0']), ('\u{1f79}', ['\u{1ff9}', '\0', '\0']),
+        ('\u{1f7a}', ['\u{1fea}', '\0', '\0']), ('\u{1f7b}', ['\u{1feb}', '\0', '\0']), ('\u{1f7c}',
+        ['\u{1ffa}', '\0', '\0']), ('\u{1f7d}', ['\u{1ffb}', '\0', '\0']), ('\u{1f80}', ['\u{1f08}',
+        '\u{399}', '\0']), ('\u{1f81}', ['\u{1f09}', '\u{399}', '\0']), ('\u{1f82}', ['\u{1f0a}',
+        '\u{399}', '\0']), ('\u{1f83}', ['\u{1f0b}', '\u{399}', '\0']), ('\u{1f84}', ['\u{1f0c}',
+        '\u{399}', '\0']), ('\u{1f85}', ['\u{1f0d}', '\u{399}', '\0']), ('\u{1f86}', ['\u{1f0e}',
+        '\u{399}', '\0']), ('\u{1f87}', ['\u{1f0f}', '\u{399}', '\0']), ('\u{1f88}', ['\u{1f08}',
+        '\u{399}', '\0']), ('\u{1f89}', ['\u{1f09}', '\u{399}', '\0']), ('\u{1f8a}', ['\u{1f0a}',
+        '\u{399}', '\0']), ('\u{1f8b}', ['\u{1f0b}', '\u{399}', '\0']), ('\u{1f8c}', ['\u{1f0c}',
+        '\u{399}', '\0']), ('\u{1f8d}', ['\u{1f0d}', '\u{399}', '\0']), ('\u{1f8e}', ['\u{1f0e}',
+        '\u{399}', '\0']), ('\u{1f8f}', ['\u{1f0f}', '\u{399}', '\0']), ('\u{1f90}', ['\u{1f28}',
+        '\u{399}', '\0']), ('\u{1f91}', ['\u{1f29}', '\u{399}', '\0']), ('\u{1f92}', ['\u{1f2a}',
+        '\u{399}', '\0']), ('\u{1f93}', ['\u{1f2b}', '\u{399}', '\0']), ('\u{1f94}', ['\u{1f2c}',
+        '\u{399}', '\0']), ('\u{1f95}', ['\u{1f2d}', '\u{399}', '\0']), ('\u{1f96}', ['\u{1f2e}',
+        '\u{399}', '\0']), ('\u{1f97}', ['\u{1f2f}', '\u{399}', '\0']), ('\u{1f98}', ['\u{1f28}',
+        '\u{399}', '\0']), ('\u{1f99}', ['\u{1f29}', '\u{399}', '\0']), ('\u{1f9a}', ['\u{1f2a}',
+        '\u{399}', '\0']), ('\u{1f9b}', ['\u{1f2b}', '\u{399}', '\0']), ('\u{1f9c}', ['\u{1f2c}',
+        '\u{399}', '\0']), ('\u{1f9d}', ['\u{1f2d}', '\u{399}', '\0']), ('\u{1f9e}', ['\u{1f2e}',
+        '\u{399}', '\0']), ('\u{1f9f}', ['\u{1f2f}', '\u{399}', '\0']), ('\u{1fa0}', ['\u{1f68}',
+        '\u{399}', '\0']), ('\u{1fa1}', ['\u{1f69}', '\u{399}', '\0']), ('\u{1fa2}', ['\u{1f6a}',
+        '\u{399}', '\0']), ('\u{1fa3}', ['\u{1f6b}', '\u{399}', '\0']), ('\u{1fa4}', ['\u{1f6c}',
+        '\u{399}', '\0']), ('\u{1fa5}', ['\u{1f6d}', '\u{399}', '\0']), ('\u{1fa6}', ['\u{1f6e}',
+        '\u{399}', '\0']), ('\u{1fa7}', ['\u{1f6f}', '\u{399}', '\0']), ('\u{1fa8}', ['\u{1f68}',
+        '\u{399}', '\0']), ('\u{1fa9}', ['\u{1f69}', '\u{399}', '\0']), ('\u{1faa}', ['\u{1f6a}',
+        '\u{399}', '\0']), ('\u{1fab}', ['\u{1f6b}', '\u{399}', '\0']), ('\u{1fac}', ['\u{1f6c}',
+        '\u{399}', '\0']), ('\u{1fad}', ['\u{1f6d}', '\u{399}', '\0']), ('\u{1fae}', ['\u{1f6e}',
+        '\u{399}', '\0']), ('\u{1faf}', ['\u{1f6f}', '\u{399}', '\0']), ('\u{1fb0}', ['\u{1fb8}',
+        '\0', '\0']), ('\u{1fb1}', ['\u{1fb9}', '\0', '\0']), ('\u{1fb2}', ['\u{1fba}', '\u{399}',
+        '\0']), ('\u{1fb3}', ['\u{391}', '\u{399}', '\0']), ('\u{1fb4}', ['\u{386}', '\u{399}',
+        '\0']), ('\u{1fb6}', ['\u{391}', '\u{342}', '\0']), ('\u{1fb7}', ['\u{391}', '\u{342}',
+        '\u{399}']), ('\u{1fbc}', ['\u{391}', '\u{399}', '\0']), ('\u{1fbe}', ['\u{399}', '\0',
+        '\0']), ('\u{1fc2}', ['\u{1fca}', '\u{399}', '\0']), ('\u{1fc3}', ['\u{397}', '\u{399}',
+        '\0']), ('\u{1fc4}', ['\u{389}', '\u{399}', '\0']), ('\u{1fc6}', ['\u{397}', '\u{342}',
+        '\0']), ('\u{1fc7}', ['\u{397}', '\u{342}', '\u{399}']), ('\u{1fcc}', ['\u{397}', '\u{399}',
+        '\0']), ('\u{1fd0}', ['\u{1fd8}', '\0', '\0']), ('\u{1fd1}', ['\u{1fd9}', '\0', '\0']),
+        ('\u{1fd2}', ['\u{399}', '\u{308}', '\u{300}']), ('\u{1fd3}', ['\u{399}', '\u{308}',
+        '\u{301}']), ('\u{1fd6}', ['\u{399}', '\u{342}', '\0']), ('\u{1fd7}', ['\u{399}', '\u{308}',
+        '\u{342}']), ('\u{1fe0}', ['\u{1fe8}', '\0', '\0']), ('\u{1fe1}', ['\u{1fe9}', '\0', '\0']),
+        ('\u{1fe2}', ['\u{3a5}', '\u{308}', '\u{300}']), ('\u{1fe3}', ['\u{3a5}', '\u{308}',
+        '\u{301}']), ('\u{1fe4}', ['\u{3a1}', '\u{313}', '\0']), ('\u{1fe5}', ['\u{1fec}', '\0',
+        '\0']), ('\u{1fe6}', ['\u{3a5}', '\u{342}', '\0']), ('\u{1fe7}', ['\u{3a5}', '\u{308}',
+        '\u{342}']), ('\u{1ff2}', ['\u{1ffa}', '\u{399}', '\0']), ('\u{1ff3}', ['\u{3a9}',
+        '\u{399}', '\0']), ('\u{1ff4}', ['\u{38f}', '\u{399}', '\0']), ('\u{1ff6}', ['\u{3a9}',
+        '\u{342}', '\0']), ('\u{1ff7}', ['\u{3a9}', '\u{342}', '\u{399}']), ('\u{1ffc}', ['\u{3a9}',
+        '\u{399}', '\0']), ('\u{214e}', ['\u{2132}', '\0', '\0']), ('\u{2170}', ['\u{2160}', '\0',
+        '\0']), ('\u{2171}', ['\u{2161}', '\0', '\0']), ('\u{2172}', ['\u{2162}', '\0', '\0']),
+        ('\u{2173}', ['\u{2163}', '\0', '\0']), ('\u{2174}', ['\u{2164}', '\0', '\0']), ('\u{2175}',
+        ['\u{2165}', '\0', '\0']), ('\u{2176}', ['\u{2166}', '\0', '\0']), ('\u{2177}', ['\u{2167}',
+        '\0', '\0']), ('\u{2178}', ['\u{2168}', '\0', '\0']), ('\u{2179}', ['\u{2169}', '\0',
+        '\0']), ('\u{217a}', ['\u{216a}', '\0', '\0']), ('\u{217b}', ['\u{216b}', '\0', '\0']),
+        ('\u{217c}', ['\u{216c}', '\0', '\0']), ('\u{217d}', ['\u{216d}', '\0', '\0']), ('\u{217e}',
+        ['\u{216e}', '\0', '\0']), ('\u{217f}', ['\u{216f}', '\0', '\0']), ('\u{2184}', ['\u{2183}',
+        '\0', '\0']), ('\u{24d0}', ['\u{24b6}', '\0', '\0']), ('\u{24d1}', ['\u{24b7}', '\0',
+        '\0']), ('\u{24d2}', ['\u{24b8}', '\0', '\0']), ('\u{24d3}', ['\u{24b9}', '\0', '\0']),
+        ('\u{24d4}', ['\u{24ba}', '\0', '\0']), ('\u{24d5}', ['\u{24bb}', '\0', '\0']), ('\u{24d6}',
+        ['\u{24bc}', '\0', '\0']), ('\u{24d7}', ['\u{24bd}', '\0', '\0']), ('\u{24d8}', ['\u{24be}',
+        '\0', '\0']), ('\u{24d9}', ['\u{24bf}', '\0', '\0']), ('\u{24da}', ['\u{24c0}', '\0',
+        '\0']), ('\u{24db}', ['\u{24c1}', '\0', '\0']), ('\u{24dc}', ['\u{24c2}', '\0', '\0']),
+        ('\u{24dd}', ['\u{24c3}', '\0', '\0']), ('\u{24de}', ['\u{24c4}', '\0', '\0']), ('\u{24df}',
+        ['\u{24c5}', '\0', '\0']), ('\u{24e0}', ['\u{24c6}', '\0', '\0']), ('\u{24e1}', ['\u{24c7}',
+        '\0', '\0']), ('\u{24e2}', ['\u{24c8}', '\0', '\0']), ('\u{24e3}', ['\u{24c9}', '\0',
+        '\0']), ('\u{24e4}', ['\u{24ca}', '\0', '\0']), ('\u{24e5}', ['\u{24cb}', '\0', '\0']),
+        ('\u{24e6}', ['\u{24cc}', '\0', '\0']), ('\u{24e7}', ['\u{24cd}', '\0', '\0']), ('\u{24e8}',
+        ['\u{24ce}', '\0', '\0']), ('\u{24e9}', ['\u{24cf}', '\0', '\0']), ('\u{2c30}', ['\u{2c00}',
+        '\0', '\0']), ('\u{2c31}', ['\u{2c01}', '\0', '\0']), ('\u{2c32}', ['\u{2c02}', '\0',
+        '\0']), ('\u{2c33}', ['\u{2c03}', '\0', '\0']), ('\u{2c34}', ['\u{2c04}', '\0', '\0']),
+        ('\u{2c35}', ['\u{2c05}', '\0', '\0']), ('\u{2c36}', ['\u{2c06}', '\0', '\0']), ('\u{2c37}',
+        ['\u{2c07}', '\0', '\0']), ('\u{2c38}', ['\u{2c08}', '\0', '\0']), ('\u{2c39}', ['\u{2c09}',
+        '\0', '\0']), ('\u{2c3a}', ['\u{2c0a}', '\0', '\0']), ('\u{2c3b}', ['\u{2c0b}', '\0',
+        '\0']), ('\u{2c3c}', ['\u{2c0c}', '\0', '\0']), ('\u{2c3d}', ['\u{2c0d}', '\0', '\0']),
+        ('\u{2c3e}', ['\u{2c0e}', '\0', '\0']), ('\u{2c3f}', ['\u{2c0f}', '\0', '\0']), ('\u{2c40}',
+        ['\u{2c10}', '\0', '\0']), ('\u{2c41}', ['\u{2c11}', '\0', '\0']), ('\u{2c42}', ['\u{2c12}',
+        '\0', '\0']), ('\u{2c43}', ['\u{2c13}', '\0', '\0']), ('\u{2c44}', ['\u{2c14}', '\0',
+        '\0']), ('\u{2c45}', ['\u{2c15}', '\0', '\0']), ('\u{2c46}', ['\u{2c16}', '\0', '\0']),
+        ('\u{2c47}', ['\u{2c17}', '\0', '\0']), ('\u{2c48}', ['\u{2c18}', '\0', '\0']), ('\u{2c49}',
+        ['\u{2c19}', '\0', '\0']), ('\u{2c4a}', ['\u{2c1a}', '\0', '\0']), ('\u{2c4b}', ['\u{2c1b}',
+        '\0', '\0']), ('\u{2c4c}', ['\u{2c1c}', '\0', '\0']), ('\u{2c4d}', ['\u{2c1d}', '\0',
+        '\0']), ('\u{2c4e}', ['\u{2c1e}', '\0', '\0']), ('\u{2c4f}', ['\u{2c1f}', '\0', '\0']),
+        ('\u{2c50}', ['\u{2c20}', '\0', '\0']), ('\u{2c51}', ['\u{2c21}', '\0', '\0']), ('\u{2c52}',
+        ['\u{2c22}', '\0', '\0']), ('\u{2c53}', ['\u{2c23}', '\0', '\0']), ('\u{2c54}', ['\u{2c24}',
+        '\0', '\0']), ('\u{2c55}', ['\u{2c25}', '\0', '\0']), ('\u{2c56}', ['\u{2c26}', '\0',
+        '\0']), ('\u{2c57}', ['\u{2c27}', '\0', '\0']), ('\u{2c58}', ['\u{2c28}', '\0', '\0']),
+        ('\u{2c59}', ['\u{2c29}', '\0', '\0']), ('\u{2c5a}', ['\u{2c2a}', '\0', '\0']), ('\u{2c5b}',
+        ['\u{2c2b}', '\0', '\0']), ('\u{2c5c}', ['\u{2c2c}', '\0', '\0']), ('\u{2c5d}', ['\u{2c2d}',
+        '\0', '\0']), ('\u{2c5e}', ['\u{2c2e}', '\0', '\0']), ('\u{2c61}', ['\u{2c60}', '\0',
+        '\0']), ('\u{2c65}', ['\u{23a}', '\0', '\0']), ('\u{2c66}', ['\u{23e}', '\0', '\0']),
+        ('\u{2c68}', ['\u{2c67}', '\0', '\0']), ('\u{2c6a}', ['\u{2c69}', '\0', '\0']), ('\u{2c6c}',
+        ['\u{2c6b}', '\0', '\0']), ('\u{2c73}', ['\u{2c72}', '\0', '\0']), ('\u{2c76}', ['\u{2c75}',
+        '\0', '\0']), ('\u{2c81}', ['\u{2c80}', '\0', '\0']), ('\u{2c83}', ['\u{2c82}', '\0',
+        '\0']), ('\u{2c85}', ['\u{2c84}', '\0', '\0']), ('\u{2c87}', ['\u{2c86}', '\0', '\0']),
+        ('\u{2c89}', ['\u{2c88}', '\0', '\0']), ('\u{2c8b}', ['\u{2c8a}', '\0', '\0']), ('\u{2c8d}',
+        ['\u{2c8c}', '\0', '\0']), ('\u{2c8f}', ['\u{2c8e}', '\0', '\0']), ('\u{2c91}', ['\u{2c90}',
+        '\0', '\0']), ('\u{2c93}', ['\u{2c92}', '\0', '\0']), ('\u{2c95}', ['\u{2c94}', '\0',
+        '\0']), ('\u{2c97}', ['\u{2c96}', '\0', '\0']), ('\u{2c99}', ['\u{2c98}', '\0', '\0']),
+        ('\u{2c9b}', ['\u{2c9a}', '\0', '\0']), ('\u{2c9d}', ['\u{2c9c}', '\0', '\0']), ('\u{2c9f}',
+        ['\u{2c9e}', '\0', '\0']), ('\u{2ca1}', ['\u{2ca0}', '\0', '\0']), ('\u{2ca3}', ['\u{2ca2}',
+        '\0', '\0']), ('\u{2ca5}', ['\u{2ca4}', '\0', '\0']), ('\u{2ca7}', ['\u{2ca6}', '\0',
+        '\0']), ('\u{2ca9}', ['\u{2ca8}', '\0', '\0']), ('\u{2cab}', ['\u{2caa}', '\0', '\0']),
+        ('\u{2cad}', ['\u{2cac}', '\0', '\0']), ('\u{2caf}', ['\u{2cae}', '\0', '\0']), ('\u{2cb1}',
+        ['\u{2cb0}', '\0', '\0']), ('\u{2cb3}', ['\u{2cb2}', '\0', '\0']), ('\u{2cb5}', ['\u{2cb4}',
+        '\0', '\0']), ('\u{2cb7}', ['\u{2cb6}', '\0', '\0']), ('\u{2cb9}', ['\u{2cb8}', '\0',
+        '\0']), ('\u{2cbb}', ['\u{2cba}', '\0', '\0']), ('\u{2cbd}', ['\u{2cbc}', '\0', '\0']),
+        ('\u{2cbf}', ['\u{2cbe}', '\0', '\0']), ('\u{2cc1}', ['\u{2cc0}', '\0', '\0']), ('\u{2cc3}',
+        ['\u{2cc2}', '\0', '\0']), ('\u{2cc5}', ['\u{2cc4}', '\0', '\0']), ('\u{2cc7}', ['\u{2cc6}',
+        '\0', '\0']), ('\u{2cc9}', ['\u{2cc8}', '\0', '\0']), ('\u{2ccb}', ['\u{2cca}', '\0',
+        '\0']), ('\u{2ccd}', ['\u{2ccc}', '\0', '\0']), ('\u{2ccf}', ['\u{2cce}', '\0', '\0']),
+        ('\u{2cd1}', ['\u{2cd0}', '\0', '\0']), ('\u{2cd3}', ['\u{2cd2}', '\0', '\0']), ('\u{2cd5}',
+        ['\u{2cd4}', '\0', '\0']), ('\u{2cd7}', ['\u{2cd6}', '\0', '\0']), ('\u{2cd9}', ['\u{2cd8}',
+        '\0', '\0']), ('\u{2cdb}', ['\u{2cda}', '\0', '\0']), ('\u{2cdd}', ['\u{2cdc}', '\0',
+        '\0']), ('\u{2cdf}', ['\u{2cde}', '\0', '\0']), ('\u{2ce1}', ['\u{2ce0}', '\0', '\0']),
+        ('\u{2ce3}', ['\u{2ce2}', '\0', '\0']), ('\u{2cec}', ['\u{2ceb}', '\0', '\0']), ('\u{2cee}',
+        ['\u{2ced}', '\0', '\0']), ('\u{2cf3}', ['\u{2cf2}', '\0', '\0']), ('\u{2d00}', ['\u{10a0}',
+        '\0', '\0']), ('\u{2d01}', ['\u{10a1}', '\0', '\0']), ('\u{2d02}', ['\u{10a2}', '\0',
+        '\0']), ('\u{2d03}', ['\u{10a3}', '\0', '\0']), ('\u{2d04}', ['\u{10a4}', '\0', '\0']),
+        ('\u{2d05}', ['\u{10a5}', '\0', '\0']), ('\u{2d06}', ['\u{10a6}', '\0', '\0']), ('\u{2d07}',
+        ['\u{10a7}', '\0', '\0']), ('\u{2d08}', ['\u{10a8}', '\0', '\0']), ('\u{2d09}', ['\u{10a9}',
+        '\0', '\0']), ('\u{2d0a}', ['\u{10aa}', '\0', '\0']), ('\u{2d0b}', ['\u{10ab}', '\0',
+        '\0']), ('\u{2d0c}', ['\u{10ac}', '\0', '\0']), ('\u{2d0d}', ['\u{10ad}', '\0', '\0']),
+        ('\u{2d0e}', ['\u{10ae}', '\0', '\0']), ('\u{2d0f}', ['\u{10af}', '\0', '\0']), ('\u{2d10}',
+        ['\u{10b0}', '\0', '\0']), ('\u{2d11}', ['\u{10b1}', '\0', '\0']), ('\u{2d12}', ['\u{10b2}',
+        '\0', '\0']), ('\u{2d13}', ['\u{10b3}', '\0', '\0']), ('\u{2d14}', ['\u{10b4}', '\0',
+        '\0']), ('\u{2d15}', ['\u{10b5}', '\0', '\0']), ('\u{2d16}', ['\u{10b6}', '\0', '\0']),
+        ('\u{2d17}', ['\u{10b7}', '\0', '\0']), ('\u{2d18}', ['\u{10b8}', '\0', '\0']), ('\u{2d19}',
+        ['\u{10b9}', '\0', '\0']), ('\u{2d1a}', ['\u{10ba}', '\0', '\0']), ('\u{2d1b}', ['\u{10bb}',
+        '\0', '\0']), ('\u{2d1c}', ['\u{10bc}', '\0', '\0']), ('\u{2d1d}', ['\u{10bd}', '\0',
+        '\0']), ('\u{2d1e}', ['\u{10be}', '\0', '\0']), ('\u{2d1f}', ['\u{10bf}', '\0', '\0']),
+        ('\u{2d20}', ['\u{10c0}', '\0', '\0']), ('\u{2d21}', ['\u{10c1}', '\0', '\0']), ('\u{2d22}',
+        ['\u{10c2}', '\0', '\0']), ('\u{2d23}', ['\u{10c3}', '\0', '\0']), ('\u{2d24}', ['\u{10c4}',
+        '\0', '\0']), ('\u{2d25}', ['\u{10c5}', '\0', '\0']), ('\u{2d27}', ['\u{10c7}', '\0',
+        '\0']), ('\u{2d2d}', ['\u{10cd}', '\0', '\0']), ('\u{a641}', ['\u{a640}', '\0', '\0']),
+        ('\u{a643}', ['\u{a642}', '\0', '\0']), ('\u{a645}', ['\u{a644}', '\0', '\0']), ('\u{a647}',
+        ['\u{a646}', '\0', '\0']), ('\u{a649}', ['\u{a648}', '\0', '\0']), ('\u{a64b}', ['\u{a64a}',
+        '\0', '\0']), ('\u{a64d}', ['\u{a64c}', '\0', '\0']), ('\u{a64f}', ['\u{a64e}', '\0',
+        '\0']), ('\u{a651}', ['\u{a650}', '\0', '\0']), ('\u{a653}', ['\u{a652}', '\0', '\0']),
+        ('\u{a655}', ['\u{a654}', '\0', '\0']), ('\u{a657}', ['\u{a656}', '\0', '\0']), ('\u{a659}',
+        ['\u{a658}', '\0', '\0']), ('\u{a65b}', ['\u{a65a}', '\0', '\0']), ('\u{a65d}', ['\u{a65c}',
+        '\0', '\0']), ('\u{a65f}', ['\u{a65e}', '\0', '\0']), ('\u{a661}', ['\u{a660}', '\0',
+        '\0']), ('\u{a663}', ['\u{a662}', '\0', '\0']), ('\u{a665}', ['\u{a664}', '\0', '\0']),
+        ('\u{a667}', ['\u{a666}', '\0', '\0']), ('\u{a669}', ['\u{a668}', '\0', '\0']), ('\u{a66b}',
+        ['\u{a66a}', '\0', '\0']), ('\u{a66d}', ['\u{a66c}', '\0', '\0']), ('\u{a681}', ['\u{a680}',
+        '\0', '\0']), ('\u{a683}', ['\u{a682}', '\0', '\0']), ('\u{a685}', ['\u{a684}', '\0',
+        '\0']), ('\u{a687}', ['\u{a686}', '\0', '\0']), ('\u{a689}', ['\u{a688}', '\0', '\0']),
+        ('\u{a68b}', ['\u{a68a}', '\0', '\0']), ('\u{a68d}', ['\u{a68c}', '\0', '\0']), ('\u{a68f}',
+        ['\u{a68e}', '\0', '\0']), ('\u{a691}', ['\u{a690}', '\0', '\0']), ('\u{a693}', ['\u{a692}',
+        '\0', '\0']), ('\u{a695}', ['\u{a694}', '\0', '\0']), ('\u{a697}', ['\u{a696}', '\0',
+        '\0']), ('\u{a699}', ['\u{a698}', '\0', '\0']), ('\u{a69b}', ['\u{a69a}', '\0', '\0']),
+        ('\u{a723}', ['\u{a722}', '\0', '\0']), ('\u{a725}', ['\u{a724}', '\0', '\0']), ('\u{a727}',
+        ['\u{a726}', '\0', '\0']), ('\u{a729}', ['\u{a728}', '\0', '\0']), ('\u{a72b}', ['\u{a72a}',
+        '\0', '\0']), ('\u{a72d}', ['\u{a72c}', '\0', '\0']), ('\u{a72f}', ['\u{a72e}', '\0',
+        '\0']), ('\u{a733}', ['\u{a732}', '\0', '\0']), ('\u{a735}', ['\u{a734}', '\0', '\0']),
+        ('\u{a737}', ['\u{a736}', '\0', '\0']), ('\u{a739}', ['\u{a738}', '\0', '\0']), ('\u{a73b}',
+        ['\u{a73a}', '\0', '\0']), ('\u{a73d}', ['\u{a73c}', '\0', '\0']), ('\u{a73f}', ['\u{a73e}',
+        '\0', '\0']), ('\u{a741}', ['\u{a740}', '\0', '\0']), ('\u{a743}', ['\u{a742}', '\0',
+        '\0']), ('\u{a745}', ['\u{a744}', '\0', '\0']), ('\u{a747}', ['\u{a746}', '\0', '\0']),
+        ('\u{a749}', ['\u{a748}', '\0', '\0']), ('\u{a74b}', ['\u{a74a}', '\0', '\0']), ('\u{a74d}',
+        ['\u{a74c}', '\0', '\0']), ('\u{a74f}', ['\u{a74e}', '\0', '\0']), ('\u{a751}', ['\u{a750}',
+        '\0', '\0']), ('\u{a753}', ['\u{a752}', '\0', '\0']), ('\u{a755}', ['\u{a754}', '\0',
+        '\0']), ('\u{a757}', ['\u{a756}', '\0', '\0']), ('\u{a759}', ['\u{a758}', '\0', '\0']),
+        ('\u{a75b}', ['\u{a75a}', '\0', '\0']), ('\u{a75d}', ['\u{a75c}', '\0', '\0']), ('\u{a75f}',
+        ['\u{a75e}', '\0', '\0']), ('\u{a761}', ['\u{a760}', '\0', '\0']), ('\u{a763}', ['\u{a762}',
+        '\0', '\0']), ('\u{a765}', ['\u{a764}', '\0', '\0']), ('\u{a767}', ['\u{a766}', '\0',
+        '\0']), ('\u{a769}', ['\u{a768}', '\0', '\0']), ('\u{a76b}', ['\u{a76a}', '\0', '\0']),
+        ('\u{a76d}', ['\u{a76c}', '\0', '\0']), ('\u{a76f}', ['\u{a76e}', '\0', '\0']), ('\u{a77a}',
+        ['\u{a779}', '\0', '\0']), ('\u{a77c}', ['\u{a77b}', '\0', '\0']), ('\u{a77f}', ['\u{a77e}',
+        '\0', '\0']), ('\u{a781}', ['\u{a780}', '\0', '\0']), ('\u{a783}', ['\u{a782}', '\0',
+        '\0']), ('\u{a785}', ['\u{a784}', '\0', '\0']), ('\u{a787}', ['\u{a786}', '\0', '\0']),
+        ('\u{a78c}', ['\u{a78b}', '\0', '\0']), ('\u{a791}', ['\u{a790}', '\0', '\0']), ('\u{a793}',
+        ['\u{a792}', '\0', '\0']), ('\u{a797}', ['\u{a796}', '\0', '\0']), ('\u{a799}', ['\u{a798}',
+        '\0', '\0']), ('\u{a79b}', ['\u{a79a}', '\0', '\0']), ('\u{a79d}', ['\u{a79c}', '\0',
+        '\0']), ('\u{a79f}', ['\u{a79e}', '\0', '\0']), ('\u{a7a1}', ['\u{a7a0}', '\0', '\0']),
+        ('\u{a7a3}', ['\u{a7a2}', '\0', '\0']), ('\u{a7a5}', ['\u{a7a4}', '\0', '\0']), ('\u{a7a7}',
+        ['\u{a7a6}', '\0', '\0']), ('\u{a7a9}', ['\u{a7a8}', '\0', '\0']), ('\u{fb00}', ['\u{46}',
+        '\u{46}', '\0']), ('\u{fb01}', ['\u{46}', '\u{49}', '\0']), ('\u{fb02}', ['\u{46}',
+        '\u{4c}', '\0']), ('\u{fb03}', ['\u{46}', '\u{46}', '\u{49}']), ('\u{fb04}', ['\u{46}',
+        '\u{46}', '\u{4c}']), ('\u{fb05}', ['\u{53}', '\u{54}', '\0']), ('\u{fb06}', ['\u{53}',
+        '\u{54}', '\0']), ('\u{fb13}', ['\u{544}', '\u{546}', '\0']), ('\u{fb14}', ['\u{544}',
+        '\u{535}', '\0']), ('\u{fb15}', ['\u{544}', '\u{53b}', '\0']), ('\u{fb16}', ['\u{54e}',
+        '\u{546}', '\0']), ('\u{fb17}', ['\u{544}', '\u{53d}', '\0']), ('\u{ff41}', ['\u{ff21}',
+        '\0', '\0']), ('\u{ff42}', ['\u{ff22}', '\0', '\0']), ('\u{ff43}', ['\u{ff23}', '\0',
+        '\0']), ('\u{ff44}', ['\u{ff24}', '\0', '\0']), ('\u{ff45}', ['\u{ff25}', '\0', '\0']),
+        ('\u{ff46}', ['\u{ff26}', '\0', '\0']), ('\u{ff47}', ['\u{ff27}', '\0', '\0']), ('\u{ff48}',
+        ['\u{ff28}', '\0', '\0']), ('\u{ff49}', ['\u{ff29}', '\0', '\0']), ('\u{ff4a}', ['\u{ff2a}',
+        '\0', '\0']), ('\u{ff4b}', ['\u{ff2b}', '\0', '\0']), ('\u{ff4c}', ['\u{ff2c}', '\0',
+        '\0']), ('\u{ff4d}', ['\u{ff2d}', '\0', '\0']), ('\u{ff4e}', ['\u{ff2e}', '\0', '\0']),
+        ('\u{ff4f}', ['\u{ff2f}', '\0', '\0']), ('\u{ff50}', ['\u{ff30}', '\0', '\0']), ('\u{ff51}',
+        ['\u{ff31}', '\0', '\0']), ('\u{ff52}', ['\u{ff32}', '\0', '\0']), ('\u{ff53}', ['\u{ff33}',
+        '\0', '\0']), ('\u{ff54}', ['\u{ff34}', '\0', '\0']), ('\u{ff55}', ['\u{ff35}', '\0',
+        '\0']), ('\u{ff56}', ['\u{ff36}', '\0', '\0']), ('\u{ff57}', ['\u{ff37}', '\0', '\0']),
+        ('\u{ff58}', ['\u{ff38}', '\0', '\0']), ('\u{ff59}', ['\u{ff39}', '\0', '\0']), ('\u{ff5a}',
+        ['\u{ff3a}', '\0', '\0']), ('\u{10428}', ['\u{10400}', '\0', '\0']), ('\u{10429}',
+        ['\u{10401}', '\0', '\0']), ('\u{1042a}', ['\u{10402}', '\0', '\0']), ('\u{1042b}',
+        ['\u{10403}', '\0', '\0']), ('\u{1042c}', ['\u{10404}', '\0', '\0']), ('\u{1042d}',
+        ['\u{10405}', '\0', '\0']), ('\u{1042e}', ['\u{10406}', '\0', '\0']), ('\u{1042f}',
+        ['\u{10407}', '\0', '\0']), ('\u{10430}', ['\u{10408}', '\0', '\0']), ('\u{10431}',
+        ['\u{10409}', '\0', '\0']), ('\u{10432}', ['\u{1040a}', '\0', '\0']), ('\u{10433}',
+        ['\u{1040b}', '\0', '\0']), ('\u{10434}', ['\u{1040c}', '\0', '\0']), ('\u{10435}',
+        ['\u{1040d}', '\0', '\0']), ('\u{10436}', ['\u{1040e}', '\0', '\0']), ('\u{10437}',
+        ['\u{1040f}', '\0', '\0']), ('\u{10438}', ['\u{10410}', '\0', '\0']), ('\u{10439}',
+        ['\u{10411}', '\0', '\0']), ('\u{1043a}', ['\u{10412}', '\0', '\0']), ('\u{1043b}',
+        ['\u{10413}', '\0', '\0']), ('\u{1043c}', ['\u{10414}', '\0', '\0']), ('\u{1043d}',
+        ['\u{10415}', '\0', '\0']), ('\u{1043e}', ['\u{10416}', '\0', '\0']), ('\u{1043f}',
+        ['\u{10417}', '\0', '\0']), ('\u{10440}', ['\u{10418}', '\0', '\0']), ('\u{10441}',
+        ['\u{10419}', '\0', '\0']), ('\u{10442}', ['\u{1041a}', '\0', '\0']), ('\u{10443}',
+        ['\u{1041b}', '\0', '\0']), ('\u{10444}', ['\u{1041c}', '\0', '\0']), ('\u{10445}',
+        ['\u{1041d}', '\0', '\0']), ('\u{10446}', ['\u{1041e}', '\0', '\0']), ('\u{10447}',
+        ['\u{1041f}', '\0', '\0']), ('\u{10448}', ['\u{10420}', '\0', '\0']), ('\u{10449}',
+        ['\u{10421}', '\0', '\0']), ('\u{1044a}', ['\u{10422}', '\0', '\0']), ('\u{1044b}',
+        ['\u{10423}', '\0', '\0']), ('\u{1044c}', ['\u{10424}', '\0', '\0']), ('\u{1044d}',
+        ['\u{10425}', '\0', '\0']), ('\u{1044e}', ['\u{10426}', '\0', '\0']), ('\u{1044f}',
+        ['\u{10427}', '\0', '\0']), ('\u{118c0}', ['\u{118a0}', '\0', '\0']), ('\u{118c1}',
+        ['\u{118a1}', '\0', '\0']), ('\u{118c2}', ['\u{118a2}', '\0', '\0']), ('\u{118c3}',
+        ['\u{118a3}', '\0', '\0']), ('\u{118c4}', ['\u{118a4}', '\0', '\0']), ('\u{118c5}',
+        ['\u{118a5}', '\0', '\0']), ('\u{118c6}', ['\u{118a6}', '\0', '\0']), ('\u{118c7}',
+        ['\u{118a7}', '\0', '\0']), ('\u{118c8}', ['\u{118a8}', '\0', '\0']), ('\u{118c9}',
+        ['\u{118a9}', '\0', '\0']), ('\u{118ca}', ['\u{118aa}', '\0', '\0']), ('\u{118cb}',
+        ['\u{118ab}', '\0', '\0']), ('\u{118cc}', ['\u{118ac}', '\0', '\0']), ('\u{118cd}',
+        ['\u{118ad}', '\0', '\0']), ('\u{118ce}', ['\u{118ae}', '\0', '\0']), ('\u{118cf}',
+        ['\u{118af}', '\0', '\0']), ('\u{118d0}', ['\u{118b0}', '\0', '\0']), ('\u{118d1}',
+        ['\u{118b1}', '\0', '\0']), ('\u{118d2}', ['\u{118b2}', '\0', '\0']), ('\u{118d3}',
+        ['\u{118b3}', '\0', '\0']), ('\u{118d4}', ['\u{118b4}', '\0', '\0']), ('\u{118d5}',
+        ['\u{118b5}', '\0', '\0']), ('\u{118d6}', ['\u{118b6}', '\0', '\0']), ('\u{118d7}',
+        ['\u{118b7}', '\0', '\0']), ('\u{118d8}', ['\u{118b8}', '\0', '\0']), ('\u{118d9}',
+        ['\u{118b9}', '\0', '\0']), ('\u{118da}', ['\u{118ba}', '\0', '\0']), ('\u{118db}',
+        ['\u{118bb}', '\0', '\0']), ('\u{118dc}', ['\u{118bc}', '\0', '\0']), ('\u{118dd}',
+        ['\u{118bd}', '\0', '\0']), ('\u{118de}', ['\u{118be}', '\0', '\0']), ('\u{118df}',
+        ['\u{118bf}', '\0', '\0'])
     ];
 
-    const LlLu_table: &'static [(char, char)] = &[
-        ('\u{61}', '\u{41}'), ('\u{62}', '\u{42}'), ('\u{63}', '\u{43}'), ('\u{64}', '\u{44}'),
-        ('\u{65}', '\u{45}'), ('\u{66}', '\u{46}'), ('\u{67}', '\u{47}'), ('\u{68}', '\u{48}'),
-        ('\u{69}', '\u{49}'), ('\u{6a}', '\u{4a}'), ('\u{6b}', '\u{4b}'), ('\u{6c}', '\u{4c}'),
-        ('\u{6d}', '\u{4d}'), ('\u{6e}', '\u{4e}'), ('\u{6f}', '\u{4f}'), ('\u{70}', '\u{50}'),
-        ('\u{71}', '\u{51}'), ('\u{72}', '\u{52}'), ('\u{73}', '\u{53}'), ('\u{74}', '\u{54}'),
-        ('\u{75}', '\u{55}'), ('\u{76}', '\u{56}'), ('\u{77}', '\u{57}'), ('\u{78}', '\u{58}'),
-        ('\u{79}', '\u{59}'), ('\u{7a}', '\u{5a}'), ('\u{b5}', '\u{39c}'), ('\u{e0}', '\u{c0}'),
-        ('\u{e1}', '\u{c1}'), ('\u{e2}', '\u{c2}'), ('\u{e3}', '\u{c3}'), ('\u{e4}', '\u{c4}'),
-        ('\u{e5}', '\u{c5}'), ('\u{e6}', '\u{c6}'), ('\u{e7}', '\u{c7}'), ('\u{e8}', '\u{c8}'),
-        ('\u{e9}', '\u{c9}'), ('\u{ea}', '\u{ca}'), ('\u{eb}', '\u{cb}'), ('\u{ec}', '\u{cc}'),
-        ('\u{ed}', '\u{cd}'), ('\u{ee}', '\u{ce}'), ('\u{ef}', '\u{cf}'), ('\u{f0}', '\u{d0}'),
-        ('\u{f1}', '\u{d1}'), ('\u{f2}', '\u{d2}'), ('\u{f3}', '\u{d3}'), ('\u{f4}', '\u{d4}'),
-        ('\u{f5}', '\u{d5}'), ('\u{f6}', '\u{d6}'), ('\u{f8}', '\u{d8}'), ('\u{f9}', '\u{d9}'),
-        ('\u{fa}', '\u{da}'), ('\u{fb}', '\u{db}'), ('\u{fc}', '\u{dc}'), ('\u{fd}', '\u{dd}'),
-        ('\u{fe}', '\u{de}'), ('\u{ff}', '\u{178}'), ('\u{101}', '\u{100}'), ('\u{103}', '\u{102}'),
-        ('\u{105}', '\u{104}'), ('\u{107}', '\u{106}'), ('\u{109}', '\u{108}'), ('\u{10b}',
-        '\u{10a}'), ('\u{10d}', '\u{10c}'), ('\u{10f}', '\u{10e}'), ('\u{111}', '\u{110}'),
-        ('\u{113}', '\u{112}'), ('\u{115}', '\u{114}'), ('\u{117}', '\u{116}'), ('\u{119}',
-        '\u{118}'), ('\u{11b}', '\u{11a}'), ('\u{11d}', '\u{11c}'), ('\u{11f}', '\u{11e}'),
-        ('\u{121}', '\u{120}'), ('\u{123}', '\u{122}'), ('\u{125}', '\u{124}'), ('\u{127}',
-        '\u{126}'), ('\u{129}', '\u{128}'), ('\u{12b}', '\u{12a}'), ('\u{12d}', '\u{12c}'),
-        ('\u{12f}', '\u{12e}'), ('\u{131}', '\u{49}'), ('\u{133}', '\u{132}'), ('\u{135}',
-        '\u{134}'), ('\u{137}', '\u{136}'), ('\u{13a}', '\u{139}'), ('\u{13c}', '\u{13b}'),
-        ('\u{13e}', '\u{13d}'), ('\u{140}', '\u{13f}'), ('\u{142}', '\u{141}'), ('\u{144}',
-        '\u{143}'), ('\u{146}', '\u{145}'), ('\u{148}', '\u{147}'), ('\u{14b}', '\u{14a}'),
-        ('\u{14d}', '\u{14c}'), ('\u{14f}', '\u{14e}'), ('\u{151}', '\u{150}'), ('\u{153}',
-        '\u{152}'), ('\u{155}', '\u{154}'), ('\u{157}', '\u{156}'), ('\u{159}', '\u{158}'),
-        ('\u{15b}', '\u{15a}'), ('\u{15d}', '\u{15c}'), ('\u{15f}', '\u{15e}'), ('\u{161}',
-        '\u{160}'), ('\u{163}', '\u{162}'), ('\u{165}', '\u{164}'), ('\u{167}', '\u{166}'),
-        ('\u{169}', '\u{168}'), ('\u{16b}', '\u{16a}'), ('\u{16d}', '\u{16c}'), ('\u{16f}',
-        '\u{16e}'), ('\u{171}', '\u{170}'), ('\u{173}', '\u{172}'), ('\u{175}', '\u{174}'),
-        ('\u{177}', '\u{176}'), ('\u{17a}', '\u{179}'), ('\u{17c}', '\u{17b}'), ('\u{17e}',
-        '\u{17d}'), ('\u{17f}', '\u{53}'), ('\u{180}', '\u{243}'), ('\u{183}', '\u{182}'),
-        ('\u{185}', '\u{184}'), ('\u{188}', '\u{187}'), ('\u{18c}', '\u{18b}'), ('\u{192}',
-        '\u{191}'), ('\u{195}', '\u{1f6}'), ('\u{199}', '\u{198}'), ('\u{19a}', '\u{23d}'),
-        ('\u{19e}', '\u{220}'), ('\u{1a1}', '\u{1a0}'), ('\u{1a3}', '\u{1a2}'), ('\u{1a5}',
-        '\u{1a4}'), ('\u{1a8}', '\u{1a7}'), ('\u{1ad}', '\u{1ac}'), ('\u{1b0}', '\u{1af}'),
-        ('\u{1b4}', '\u{1b3}'), ('\u{1b6}', '\u{1b5}'), ('\u{1b9}', '\u{1b8}'), ('\u{1bd}',
-        '\u{1bc}'), ('\u{1bf}', '\u{1f7}'), ('\u{1c6}', '\u{1c4}'), ('\u{1c9}', '\u{1c7}'),
-        ('\u{1cc}', '\u{1ca}'), ('\u{1ce}', '\u{1cd}'), ('\u{1d0}', '\u{1cf}'), ('\u{1d2}',
-        '\u{1d1}'), ('\u{1d4}', '\u{1d3}'), ('\u{1d6}', '\u{1d5}'), ('\u{1d8}', '\u{1d7}'),
-        ('\u{1da}', '\u{1d9}'), ('\u{1dc}', '\u{1db}'), ('\u{1dd}', '\u{18e}'), ('\u{1df}',
-        '\u{1de}'), ('\u{1e1}', '\u{1e0}'), ('\u{1e3}', '\u{1e2}'), ('\u{1e5}', '\u{1e4}'),
-        ('\u{1e7}', '\u{1e6}'), ('\u{1e9}', '\u{1e8}'), ('\u{1eb}', '\u{1ea}'), ('\u{1ed}',
-        '\u{1ec}'), ('\u{1ef}', '\u{1ee}'), ('\u{1f3}', '\u{1f1}'), ('\u{1f5}', '\u{1f4}'),
-        ('\u{1f9}', '\u{1f8}'), ('\u{1fb}', '\u{1fa}'), ('\u{1fd}', '\u{1fc}'), ('\u{1ff}',
-        '\u{1fe}'), ('\u{201}', '\u{200}'), ('\u{203}', '\u{202}'), ('\u{205}', '\u{204}'),
-        ('\u{207}', '\u{206}'), ('\u{209}', '\u{208}'), ('\u{20b}', '\u{20a}'), ('\u{20d}',
-        '\u{20c}'), ('\u{20f}', '\u{20e}'), ('\u{211}', '\u{210}'), ('\u{213}', '\u{212}'),
-        ('\u{215}', '\u{214}'), ('\u{217}', '\u{216}'), ('\u{219}', '\u{218}'), ('\u{21b}',
-        '\u{21a}'), ('\u{21d}', '\u{21c}'), ('\u{21f}', '\u{21e}'), ('\u{223}', '\u{222}'),
-        ('\u{225}', '\u{224}'), ('\u{227}', '\u{226}'), ('\u{229}', '\u{228}'), ('\u{22b}',
-        '\u{22a}'), ('\u{22d}', '\u{22c}'), ('\u{22f}', '\u{22e}'), ('\u{231}', '\u{230}'),
-        ('\u{233}', '\u{232}'), ('\u{23c}', '\u{23b}'), ('\u{23f}', '\u{2c7e}'), ('\u{240}',
-        '\u{2c7f}'), ('\u{242}', '\u{241}'), ('\u{247}', '\u{246}'), ('\u{249}', '\u{248}'),
-        ('\u{24b}', '\u{24a}'), ('\u{24d}', '\u{24c}'), ('\u{24f}', '\u{24e}'), ('\u{250}',
-        '\u{2c6f}'), ('\u{251}', '\u{2c6d}'), ('\u{252}', '\u{2c70}'), ('\u{253}', '\u{181}'),
-        ('\u{254}', '\u{186}'), ('\u{256}', '\u{189}'), ('\u{257}', '\u{18a}'), ('\u{259}',
-        '\u{18f}'), ('\u{25b}', '\u{190}'), ('\u{25c}', '\u{a7ab}'), ('\u{260}', '\u{193}'),
-        ('\u{261}', '\u{a7ac}'), ('\u{263}', '\u{194}'), ('\u{265}', '\u{a78d}'), ('\u{266}',
-        '\u{a7aa}'), ('\u{268}', '\u{197}'), ('\u{269}', '\u{196}'), ('\u{26b}', '\u{2c62}'),
-        ('\u{26c}', '\u{a7ad}'), ('\u{26f}', '\u{19c}'), ('\u{271}', '\u{2c6e}'), ('\u{272}',
-        '\u{19d}'), ('\u{275}', '\u{19f}'), ('\u{27d}', '\u{2c64}'), ('\u{280}', '\u{1a6}'),
-        ('\u{283}', '\u{1a9}'), ('\u{287}', '\u{a7b1}'), ('\u{288}', '\u{1ae}'), ('\u{289}',
-        '\u{244}'), ('\u{28a}', '\u{1b1}'), ('\u{28b}', '\u{1b2}'), ('\u{28c}', '\u{245}'),
-        ('\u{292}', '\u{1b7}'), ('\u{29e}', '\u{a7b0}'), ('\u{371}', '\u{370}'), ('\u{373}',
-        '\u{372}'), ('\u{377}', '\u{376}'), ('\u{37b}', '\u{3fd}'), ('\u{37c}', '\u{3fe}'),
-        ('\u{37d}', '\u{3ff}'), ('\u{3ac}', '\u{386}'), ('\u{3ad}', '\u{388}'), ('\u{3ae}',
-        '\u{389}'), ('\u{3af}', '\u{38a}'), ('\u{3b1}', '\u{391}'), ('\u{3b2}', '\u{392}'),
-        ('\u{3b3}', '\u{393}'), ('\u{3b4}', '\u{394}'), ('\u{3b5}', '\u{395}'), ('\u{3b6}',
-        '\u{396}'), ('\u{3b7}', '\u{397}'), ('\u{3b8}', '\u{398}'), ('\u{3b9}', '\u{399}'),
-        ('\u{3ba}', '\u{39a}'), ('\u{3bb}', '\u{39b}'), ('\u{3bc}', '\u{39c}'), ('\u{3bd}',
-        '\u{39d}'), ('\u{3be}', '\u{39e}'), ('\u{3bf}', '\u{39f}'), ('\u{3c0}', '\u{3a0}'),
-        ('\u{3c1}', '\u{3a1}'), ('\u{3c2}', '\u{3a3}'), ('\u{3c3}', '\u{3a3}'), ('\u{3c4}',
-        '\u{3a4}'), ('\u{3c5}', '\u{3a5}'), ('\u{3c6}', '\u{3a6}'), ('\u{3c7}', '\u{3a7}'),
-        ('\u{3c8}', '\u{3a8}'), ('\u{3c9}', '\u{3a9}'), ('\u{3ca}', '\u{3aa}'), ('\u{3cb}',
-        '\u{3ab}'), ('\u{3cc}', '\u{38c}'), ('\u{3cd}', '\u{38e}'), ('\u{3ce}', '\u{38f}'),
-        ('\u{3d0}', '\u{392}'), ('\u{3d1}', '\u{398}'), ('\u{3d5}', '\u{3a6}'), ('\u{3d6}',
-        '\u{3a0}'), ('\u{3d7}', '\u{3cf}'), ('\u{3d9}', '\u{3d8}'), ('\u{3db}', '\u{3da}'),
-        ('\u{3dd}', '\u{3dc}'), ('\u{3df}', '\u{3de}'), ('\u{3e1}', '\u{3e0}'), ('\u{3e3}',
-        '\u{3e2}'), ('\u{3e5}', '\u{3e4}'), ('\u{3e7}', '\u{3e6}'), ('\u{3e9}', '\u{3e8}'),
-        ('\u{3eb}', '\u{3ea}'), ('\u{3ed}', '\u{3ec}'), ('\u{3ef}', '\u{3ee}'), ('\u{3f0}',
-        '\u{39a}'), ('\u{3f1}', '\u{3a1}'), ('\u{3f2}', '\u{3f9}'), ('\u{3f3}', '\u{37f}'),
-        ('\u{3f5}', '\u{395}'), ('\u{3f8}', '\u{3f7}'), ('\u{3fb}', '\u{3fa}'), ('\u{430}',
-        '\u{410}'), ('\u{431}', '\u{411}'), ('\u{432}', '\u{412}'), ('\u{433}', '\u{413}'),
-        ('\u{434}', '\u{414}'), ('\u{435}', '\u{415}'), ('\u{436}', '\u{416}'), ('\u{437}',
-        '\u{417}'), ('\u{438}', '\u{418}'), ('\u{439}', '\u{419}'), ('\u{43a}', '\u{41a}'),
-        ('\u{43b}', '\u{41b}'), ('\u{43c}', '\u{41c}'), ('\u{43d}', '\u{41d}'), ('\u{43e}',
-        '\u{41e}'), ('\u{43f}', '\u{41f}'), ('\u{440}', '\u{420}'), ('\u{441}', '\u{421}'),
-        ('\u{442}', '\u{422}'), ('\u{443}', '\u{423}'), ('\u{444}', '\u{424}'), ('\u{445}',
-        '\u{425}'), ('\u{446}', '\u{426}'), ('\u{447}', '\u{427}'), ('\u{448}', '\u{428}'),
-        ('\u{449}', '\u{429}'), ('\u{44a}', '\u{42a}'), ('\u{44b}', '\u{42b}'), ('\u{44c}',
-        '\u{42c}'), ('\u{44d}', '\u{42d}'), ('\u{44e}', '\u{42e}'), ('\u{44f}', '\u{42f}'),
-        ('\u{450}', '\u{400}'), ('\u{451}', '\u{401}'), ('\u{452}', '\u{402}'), ('\u{453}',
-        '\u{403}'), ('\u{454}', '\u{404}'), ('\u{455}', '\u{405}'), ('\u{456}', '\u{406}'),
-        ('\u{457}', '\u{407}'), ('\u{458}', '\u{408}'), ('\u{459}', '\u{409}'), ('\u{45a}',
-        '\u{40a}'), ('\u{45b}', '\u{40b}'), ('\u{45c}', '\u{40c}'), ('\u{45d}', '\u{40d}'),
-        ('\u{45e}', '\u{40e}'), ('\u{45f}', '\u{40f}'), ('\u{461}', '\u{460}'), ('\u{463}',
-        '\u{462}'), ('\u{465}', '\u{464}'), ('\u{467}', '\u{466}'), ('\u{469}', '\u{468}'),
-        ('\u{46b}', '\u{46a}'), ('\u{46d}', '\u{46c}'), ('\u{46f}', '\u{46e}'), ('\u{471}',
-        '\u{470}'), ('\u{473}', '\u{472}'), ('\u{475}', '\u{474}'), ('\u{477}', '\u{476}'),
-        ('\u{479}', '\u{478}'), ('\u{47b}', '\u{47a}'), ('\u{47d}', '\u{47c}'), ('\u{47f}',
-        '\u{47e}'), ('\u{481}', '\u{480}'), ('\u{48b}', '\u{48a}'), ('\u{48d}', '\u{48c}'),
-        ('\u{48f}', '\u{48e}'), ('\u{491}', '\u{490}'), ('\u{493}', '\u{492}'), ('\u{495}',
-        '\u{494}'), ('\u{497}', '\u{496}'), ('\u{499}', '\u{498}'), ('\u{49b}', '\u{49a}'),
-        ('\u{49d}', '\u{49c}'), ('\u{49f}', '\u{49e}'), ('\u{4a1}', '\u{4a0}'), ('\u{4a3}',
-        '\u{4a2}'), ('\u{4a5}', '\u{4a4}'), ('\u{4a7}', '\u{4a6}'), ('\u{4a9}', '\u{4a8}'),
-        ('\u{4ab}', '\u{4aa}'), ('\u{4ad}', '\u{4ac}'), ('\u{4af}', '\u{4ae}'), ('\u{4b1}',
-        '\u{4b0}'), ('\u{4b3}', '\u{4b2}'), ('\u{4b5}', '\u{4b4}'), ('\u{4b7}', '\u{4b6}'),
-        ('\u{4b9}', '\u{4b8}'), ('\u{4bb}', '\u{4ba}'), ('\u{4bd}', '\u{4bc}'), ('\u{4bf}',
-        '\u{4be}'), ('\u{4c2}', '\u{4c1}'), ('\u{4c4}', '\u{4c3}'), ('\u{4c6}', '\u{4c5}'),
-        ('\u{4c8}', '\u{4c7}'), ('\u{4ca}', '\u{4c9}'), ('\u{4cc}', '\u{4cb}'), ('\u{4ce}',
-        '\u{4cd}'), ('\u{4cf}', '\u{4c0}'), ('\u{4d1}', '\u{4d0}'), ('\u{4d3}', '\u{4d2}'),
-        ('\u{4d5}', '\u{4d4}'), ('\u{4d7}', '\u{4d6}'), ('\u{4d9}', '\u{4d8}'), ('\u{4db}',
-        '\u{4da}'), ('\u{4dd}', '\u{4dc}'), ('\u{4df}', '\u{4de}'), ('\u{4e1}', '\u{4e0}'),
-        ('\u{4e3}', '\u{4e2}'), ('\u{4e5}', '\u{4e4}'), ('\u{4e7}', '\u{4e6}'), ('\u{4e9}',
-        '\u{4e8}'), ('\u{4eb}', '\u{4ea}'), ('\u{4ed}', '\u{4ec}'), ('\u{4ef}', '\u{4ee}'),
-        ('\u{4f1}', '\u{4f0}'), ('\u{4f3}', '\u{4f2}'), ('\u{4f5}', '\u{4f4}'), ('\u{4f7}',
-        '\u{4f6}'), ('\u{4f9}', '\u{4f8}'), ('\u{4fb}', '\u{4fa}'), ('\u{4fd}', '\u{4fc}'),
-        ('\u{4ff}', '\u{4fe}'), ('\u{501}', '\u{500}'), ('\u{503}', '\u{502}'), ('\u{505}',
-        '\u{504}'), ('\u{507}', '\u{506}'), ('\u{509}', '\u{508}'), ('\u{50b}', '\u{50a}'),
-        ('\u{50d}', '\u{50c}'), ('\u{50f}', '\u{50e}'), ('\u{511}', '\u{510}'), ('\u{513}',
-        '\u{512}'), ('\u{515}', '\u{514}'), ('\u{517}', '\u{516}'), ('\u{519}', '\u{518}'),
-        ('\u{51b}', '\u{51a}'), ('\u{51d}', '\u{51c}'), ('\u{51f}', '\u{51e}'), ('\u{521}',
-        '\u{520}'), ('\u{523}', '\u{522}'), ('\u{525}', '\u{524}'), ('\u{527}', '\u{526}'),
-        ('\u{529}', '\u{528}'), ('\u{52b}', '\u{52a}'), ('\u{52d}', '\u{52c}'), ('\u{52f}',
-        '\u{52e}'), ('\u{561}', '\u{531}'), ('\u{562}', '\u{532}'), ('\u{563}', '\u{533}'),
-        ('\u{564}', '\u{534}'), ('\u{565}', '\u{535}'), ('\u{566}', '\u{536}'), ('\u{567}',
-        '\u{537}'), ('\u{568}', '\u{538}'), ('\u{569}', '\u{539}'), ('\u{56a}', '\u{53a}'),
-        ('\u{56b}', '\u{53b}'), ('\u{56c}', '\u{53c}'), ('\u{56d}', '\u{53d}'), ('\u{56e}',
-        '\u{53e}'), ('\u{56f}', '\u{53f}'), ('\u{570}', '\u{540}'), ('\u{571}', '\u{541}'),
-        ('\u{572}', '\u{542}'), ('\u{573}', '\u{543}'), ('\u{574}', '\u{544}'), ('\u{575}',
-        '\u{545}'), ('\u{576}', '\u{546}'), ('\u{577}', '\u{547}'), ('\u{578}', '\u{548}'),
-        ('\u{579}', '\u{549}'), ('\u{57a}', '\u{54a}'), ('\u{57b}', '\u{54b}'), ('\u{57c}',
-        '\u{54c}'), ('\u{57d}', '\u{54d}'), ('\u{57e}', '\u{54e}'), ('\u{57f}', '\u{54f}'),
-        ('\u{580}', '\u{550}'), ('\u{581}', '\u{551}'), ('\u{582}', '\u{552}'), ('\u{583}',
-        '\u{553}'), ('\u{584}', '\u{554}'), ('\u{585}', '\u{555}'), ('\u{586}', '\u{556}'),
-        ('\u{1d79}', '\u{a77d}'), ('\u{1d7d}', '\u{2c63}'), ('\u{1e01}', '\u{1e00}'), ('\u{1e03}',
-        '\u{1e02}'), ('\u{1e05}', '\u{1e04}'), ('\u{1e07}', '\u{1e06}'), ('\u{1e09}', '\u{1e08}'),
-        ('\u{1e0b}', '\u{1e0a}'), ('\u{1e0d}', '\u{1e0c}'), ('\u{1e0f}', '\u{1e0e}'), ('\u{1e11}',
-        '\u{1e10}'), ('\u{1e13}', '\u{1e12}'), ('\u{1e15}', '\u{1e14}'), ('\u{1e17}', '\u{1e16}'),
-        ('\u{1e19}', '\u{1e18}'), ('\u{1e1b}', '\u{1e1a}'), ('\u{1e1d}', '\u{1e1c}'), ('\u{1e1f}',
-        '\u{1e1e}'), ('\u{1e21}', '\u{1e20}'), ('\u{1e23}', '\u{1e22}'), ('\u{1e25}', '\u{1e24}'),
-        ('\u{1e27}', '\u{1e26}'), ('\u{1e29}', '\u{1e28}'), ('\u{1e2b}', '\u{1e2a}'), ('\u{1e2d}',
-        '\u{1e2c}'), ('\u{1e2f}', '\u{1e2e}'), ('\u{1e31}', '\u{1e30}'), ('\u{1e33}', '\u{1e32}'),
-        ('\u{1e35}', '\u{1e34}'), ('\u{1e37}', '\u{1e36}'), ('\u{1e39}', '\u{1e38}'), ('\u{1e3b}',
-        '\u{1e3a}'), ('\u{1e3d}', '\u{1e3c}'), ('\u{1e3f}', '\u{1e3e}'), ('\u{1e41}', '\u{1e40}'),
-        ('\u{1e43}', '\u{1e42}'), ('\u{1e45}', '\u{1e44}'), ('\u{1e47}', '\u{1e46}'), ('\u{1e49}',
-        '\u{1e48}'), ('\u{1e4b}', '\u{1e4a}'), ('\u{1e4d}', '\u{1e4c}'), ('\u{1e4f}', '\u{1e4e}'),
-        ('\u{1e51}', '\u{1e50}'), ('\u{1e53}', '\u{1e52}'), ('\u{1e55}', '\u{1e54}'), ('\u{1e57}',
-        '\u{1e56}'), ('\u{1e59}', '\u{1e58}'), ('\u{1e5b}', '\u{1e5a}'), ('\u{1e5d}', '\u{1e5c}'),
-        ('\u{1e5f}', '\u{1e5e}'), ('\u{1e61}', '\u{1e60}'), ('\u{1e63}', '\u{1e62}'), ('\u{1e65}',
-        '\u{1e64}'), ('\u{1e67}', '\u{1e66}'), ('\u{1e69}', '\u{1e68}'), ('\u{1e6b}', '\u{1e6a}'),
-        ('\u{1e6d}', '\u{1e6c}'), ('\u{1e6f}', '\u{1e6e}'), ('\u{1e71}', '\u{1e70}'), ('\u{1e73}',
-        '\u{1e72}'), ('\u{1e75}', '\u{1e74}'), ('\u{1e77}', '\u{1e76}'), ('\u{1e79}', '\u{1e78}'),
-        ('\u{1e7b}', '\u{1e7a}'), ('\u{1e7d}', '\u{1e7c}'), ('\u{1e7f}', '\u{1e7e}'), ('\u{1e81}',
-        '\u{1e80}'), ('\u{1e83}', '\u{1e82}'), ('\u{1e85}', '\u{1e84}'), ('\u{1e87}', '\u{1e86}'),
-        ('\u{1e89}', '\u{1e88}'), ('\u{1e8b}', '\u{1e8a}'), ('\u{1e8d}', '\u{1e8c}'), ('\u{1e8f}',
-        '\u{1e8e}'), ('\u{1e91}', '\u{1e90}'), ('\u{1e93}', '\u{1e92}'), ('\u{1e95}', '\u{1e94}'),
-        ('\u{1e9b}', '\u{1e60}'), ('\u{1ea1}', '\u{1ea0}'), ('\u{1ea3}', '\u{1ea2}'), ('\u{1ea5}',
-        '\u{1ea4}'), ('\u{1ea7}', '\u{1ea6}'), ('\u{1ea9}', '\u{1ea8}'), ('\u{1eab}', '\u{1eaa}'),
-        ('\u{1ead}', '\u{1eac}'), ('\u{1eaf}', '\u{1eae}'), ('\u{1eb1}', '\u{1eb0}'), ('\u{1eb3}',
-        '\u{1eb2}'), ('\u{1eb5}', '\u{1eb4}'), ('\u{1eb7}', '\u{1eb6}'), ('\u{1eb9}', '\u{1eb8}'),
-        ('\u{1ebb}', '\u{1eba}'), ('\u{1ebd}', '\u{1ebc}'), ('\u{1ebf}', '\u{1ebe}'), ('\u{1ec1}',
-        '\u{1ec0}'), ('\u{1ec3}', '\u{1ec2}'), ('\u{1ec5}', '\u{1ec4}'), ('\u{1ec7}', '\u{1ec6}'),
-        ('\u{1ec9}', '\u{1ec8}'), ('\u{1ecb}', '\u{1eca}'), ('\u{1ecd}', '\u{1ecc}'), ('\u{1ecf}',
-        '\u{1ece}'), ('\u{1ed1}', '\u{1ed0}'), ('\u{1ed3}', '\u{1ed2}'), ('\u{1ed5}', '\u{1ed4}'),
-        ('\u{1ed7}', '\u{1ed6}'), ('\u{1ed9}', '\u{1ed8}'), ('\u{1edb}', '\u{1eda}'), ('\u{1edd}',
-        '\u{1edc}'), ('\u{1edf}', '\u{1ede}'), ('\u{1ee1}', '\u{1ee0}'), ('\u{1ee3}', '\u{1ee2}'),
-        ('\u{1ee5}', '\u{1ee4}'), ('\u{1ee7}', '\u{1ee6}'), ('\u{1ee9}', '\u{1ee8}'), ('\u{1eeb}',
-        '\u{1eea}'), ('\u{1eed}', '\u{1eec}'), ('\u{1eef}', '\u{1eee}'), ('\u{1ef1}', '\u{1ef0}'),
-        ('\u{1ef3}', '\u{1ef2}'), ('\u{1ef5}', '\u{1ef4}'), ('\u{1ef7}', '\u{1ef6}'), ('\u{1ef9}',
-        '\u{1ef8}'), ('\u{1efb}', '\u{1efa}'), ('\u{1efd}', '\u{1efc}'), ('\u{1eff}', '\u{1efe}'),
-        ('\u{1f00}', '\u{1f08}'), ('\u{1f01}', '\u{1f09}'), ('\u{1f02}', '\u{1f0a}'), ('\u{1f03}',
-        '\u{1f0b}'), ('\u{1f04}', '\u{1f0c}'), ('\u{1f05}', '\u{1f0d}'), ('\u{1f06}', '\u{1f0e}'),
-        ('\u{1f07}', '\u{1f0f}'), ('\u{1f10}', '\u{1f18}'), ('\u{1f11}', '\u{1f19}'), ('\u{1f12}',
-        '\u{1f1a}'), ('\u{1f13}', '\u{1f1b}'), ('\u{1f14}', '\u{1f1c}'), ('\u{1f15}', '\u{1f1d}'),
-        ('\u{1f20}', '\u{1f28}'), ('\u{1f21}', '\u{1f29}'), ('\u{1f22}', '\u{1f2a}'), ('\u{1f23}',
-        '\u{1f2b}'), ('\u{1f24}', '\u{1f2c}'), ('\u{1f25}', '\u{1f2d}'), ('\u{1f26}', '\u{1f2e}'),
-        ('\u{1f27}', '\u{1f2f}'), ('\u{1f30}', '\u{1f38}'), ('\u{1f31}', '\u{1f39}'), ('\u{1f32}',
-        '\u{1f3a}'), ('\u{1f33}', '\u{1f3b}'), ('\u{1f34}', '\u{1f3c}'), ('\u{1f35}', '\u{1f3d}'),
-        ('\u{1f36}', '\u{1f3e}'), ('\u{1f37}', '\u{1f3f}'), ('\u{1f40}', '\u{1f48}'), ('\u{1f41}',
-        '\u{1f49}'), ('\u{1f42}', '\u{1f4a}'), ('\u{1f43}', '\u{1f4b}'), ('\u{1f44}', '\u{1f4c}'),
-        ('\u{1f45}', '\u{1f4d}'), ('\u{1f51}', '\u{1f59}'), ('\u{1f53}', '\u{1f5b}'), ('\u{1f55}',
-        '\u{1f5d}'), ('\u{1f57}', '\u{1f5f}'), ('\u{1f60}', '\u{1f68}'), ('\u{1f61}', '\u{1f69}'),
-        ('\u{1f62}', '\u{1f6a}'), ('\u{1f63}', '\u{1f6b}'), ('\u{1f64}', '\u{1f6c}'), ('\u{1f65}',
-        '\u{1f6d}'), ('\u{1f66}', '\u{1f6e}'), ('\u{1f67}', '\u{1f6f}'), ('\u{1f70}', '\u{1fba}'),
-        ('\u{1f71}', '\u{1fbb}'), ('\u{1f72}', '\u{1fc8}'), ('\u{1f73}', '\u{1fc9}'), ('\u{1f74}',
-        '\u{1fca}'), ('\u{1f75}', '\u{1fcb}'), ('\u{1f76}', '\u{1fda}'), ('\u{1f77}', '\u{1fdb}'),
-        ('\u{1f78}', '\u{1ff8}'), ('\u{1f79}', '\u{1ff9}'), ('\u{1f7a}', '\u{1fea}'), ('\u{1f7b}',
-        '\u{1feb}'), ('\u{1f7c}', '\u{1ffa}'), ('\u{1f7d}', '\u{1ffb}'), ('\u{1f80}', '\u{1f88}'),
-        ('\u{1f81}', '\u{1f89}'), ('\u{1f82}', '\u{1f8a}'), ('\u{1f83}', '\u{1f8b}'), ('\u{1f84}',
-        '\u{1f8c}'), ('\u{1f85}', '\u{1f8d}'), ('\u{1f86}', '\u{1f8e}'), ('\u{1f87}', '\u{1f8f}'),
-        ('\u{1f90}', '\u{1f98}'), ('\u{1f91}', '\u{1f99}'), ('\u{1f92}', '\u{1f9a}'), ('\u{1f93}',
-        '\u{1f9b}'), ('\u{1f94}', '\u{1f9c}'), ('\u{1f95}', '\u{1f9d}'), ('\u{1f96}', '\u{1f9e}'),
-        ('\u{1f97}', '\u{1f9f}'), ('\u{1fa0}', '\u{1fa8}'), ('\u{1fa1}', '\u{1fa9}'), ('\u{1fa2}',
-        '\u{1faa}'), ('\u{1fa3}', '\u{1fab}'), ('\u{1fa4}', '\u{1fac}'), ('\u{1fa5}', '\u{1fad}'),
-        ('\u{1fa6}', '\u{1fae}'), ('\u{1fa7}', '\u{1faf}'), ('\u{1fb0}', '\u{1fb8}'), ('\u{1fb1}',
-        '\u{1fb9}'), ('\u{1fb3}', '\u{1fbc}'), ('\u{1fbe}', '\u{399}'), ('\u{1fc3}', '\u{1fcc}'),
-        ('\u{1fd0}', '\u{1fd8}'), ('\u{1fd1}', '\u{1fd9}'), ('\u{1fe0}', '\u{1fe8}'), ('\u{1fe1}',
-        '\u{1fe9}'), ('\u{1fe5}', '\u{1fec}'), ('\u{1ff3}', '\u{1ffc}'), ('\u{214e}', '\u{2132}'),
-        ('\u{2184}', '\u{2183}'), ('\u{2c30}', '\u{2c00}'), ('\u{2c31}', '\u{2c01}'), ('\u{2c32}',
-        '\u{2c02}'), ('\u{2c33}', '\u{2c03}'), ('\u{2c34}', '\u{2c04}'), ('\u{2c35}', '\u{2c05}'),
-        ('\u{2c36}', '\u{2c06}'), ('\u{2c37}', '\u{2c07}'), ('\u{2c38}', '\u{2c08}'), ('\u{2c39}',
-        '\u{2c09}'), ('\u{2c3a}', '\u{2c0a}'), ('\u{2c3b}', '\u{2c0b}'), ('\u{2c3c}', '\u{2c0c}'),
-        ('\u{2c3d}', '\u{2c0d}'), ('\u{2c3e}', '\u{2c0e}'), ('\u{2c3f}', '\u{2c0f}'), ('\u{2c40}',
-        '\u{2c10}'), ('\u{2c41}', '\u{2c11}'), ('\u{2c42}', '\u{2c12}'), ('\u{2c43}', '\u{2c13}'),
-        ('\u{2c44}', '\u{2c14}'), ('\u{2c45}', '\u{2c15}'), ('\u{2c46}', '\u{2c16}'), ('\u{2c47}',
-        '\u{2c17}'), ('\u{2c48}', '\u{2c18}'), ('\u{2c49}', '\u{2c19}'), ('\u{2c4a}', '\u{2c1a}'),
-        ('\u{2c4b}', '\u{2c1b}'), ('\u{2c4c}', '\u{2c1c}'), ('\u{2c4d}', '\u{2c1d}'), ('\u{2c4e}',
-        '\u{2c1e}'), ('\u{2c4f}', '\u{2c1f}'), ('\u{2c50}', '\u{2c20}'), ('\u{2c51}', '\u{2c21}'),
-        ('\u{2c52}', '\u{2c22}'), ('\u{2c53}', '\u{2c23}'), ('\u{2c54}', '\u{2c24}'), ('\u{2c55}',
-        '\u{2c25}'), ('\u{2c56}', '\u{2c26}'), ('\u{2c57}', '\u{2c27}'), ('\u{2c58}', '\u{2c28}'),
-        ('\u{2c59}', '\u{2c29}'), ('\u{2c5a}', '\u{2c2a}'), ('\u{2c5b}', '\u{2c2b}'), ('\u{2c5c}',
-        '\u{2c2c}'), ('\u{2c5d}', '\u{2c2d}'), ('\u{2c5e}', '\u{2c2e}'), ('\u{2c61}', '\u{2c60}'),
-        ('\u{2c65}', '\u{23a}'), ('\u{2c66}', '\u{23e}'), ('\u{2c68}', '\u{2c67}'), ('\u{2c6a}',
-        '\u{2c69}'), ('\u{2c6c}', '\u{2c6b}'), ('\u{2c73}', '\u{2c72}'), ('\u{2c76}', '\u{2c75}'),
-        ('\u{2c81}', '\u{2c80}'), ('\u{2c83}', '\u{2c82}'), ('\u{2c85}', '\u{2c84}'), ('\u{2c87}',
-        '\u{2c86}'), ('\u{2c89}', '\u{2c88}'), ('\u{2c8b}', '\u{2c8a}'), ('\u{2c8d}', '\u{2c8c}'),
-        ('\u{2c8f}', '\u{2c8e}'), ('\u{2c91}', '\u{2c90}'), ('\u{2c93}', '\u{2c92}'), ('\u{2c95}',
-        '\u{2c94}'), ('\u{2c97}', '\u{2c96}'), ('\u{2c99}', '\u{2c98}'), ('\u{2c9b}', '\u{2c9a}'),
-        ('\u{2c9d}', '\u{2c9c}'), ('\u{2c9f}', '\u{2c9e}'), ('\u{2ca1}', '\u{2ca0}'), ('\u{2ca3}',
-        '\u{2ca2}'), ('\u{2ca5}', '\u{2ca4}'), ('\u{2ca7}', '\u{2ca6}'), ('\u{2ca9}', '\u{2ca8}'),
-        ('\u{2cab}', '\u{2caa}'), ('\u{2cad}', '\u{2cac}'), ('\u{2caf}', '\u{2cae}'), ('\u{2cb1}',
-        '\u{2cb0}'), ('\u{2cb3}', '\u{2cb2}'), ('\u{2cb5}', '\u{2cb4}'), ('\u{2cb7}', '\u{2cb6}'),
-        ('\u{2cb9}', '\u{2cb8}'), ('\u{2cbb}', '\u{2cba}'), ('\u{2cbd}', '\u{2cbc}'), ('\u{2cbf}',
-        '\u{2cbe}'), ('\u{2cc1}', '\u{2cc0}'), ('\u{2cc3}', '\u{2cc2}'), ('\u{2cc5}', '\u{2cc4}'),
-        ('\u{2cc7}', '\u{2cc6}'), ('\u{2cc9}', '\u{2cc8}'), ('\u{2ccb}', '\u{2cca}'), ('\u{2ccd}',
-        '\u{2ccc}'), ('\u{2ccf}', '\u{2cce}'), ('\u{2cd1}', '\u{2cd0}'), ('\u{2cd3}', '\u{2cd2}'),
-        ('\u{2cd5}', '\u{2cd4}'), ('\u{2cd7}', '\u{2cd6}'), ('\u{2cd9}', '\u{2cd8}'), ('\u{2cdb}',
-        '\u{2cda}'), ('\u{2cdd}', '\u{2cdc}'), ('\u{2cdf}', '\u{2cde}'), ('\u{2ce1}', '\u{2ce0}'),
-        ('\u{2ce3}', '\u{2ce2}'), ('\u{2cec}', '\u{2ceb}'), ('\u{2cee}', '\u{2ced}'), ('\u{2cf3}',
-        '\u{2cf2}'), ('\u{2d00}', '\u{10a0}'), ('\u{2d01}', '\u{10a1}'), ('\u{2d02}', '\u{10a2}'),
-        ('\u{2d03}', '\u{10a3}'), ('\u{2d04}', '\u{10a4}'), ('\u{2d05}', '\u{10a5}'), ('\u{2d06}',
-        '\u{10a6}'), ('\u{2d07}', '\u{10a7}'), ('\u{2d08}', '\u{10a8}'), ('\u{2d09}', '\u{10a9}'),
-        ('\u{2d0a}', '\u{10aa}'), ('\u{2d0b}', '\u{10ab}'), ('\u{2d0c}', '\u{10ac}'), ('\u{2d0d}',
-        '\u{10ad}'), ('\u{2d0e}', '\u{10ae}'), ('\u{2d0f}', '\u{10af}'), ('\u{2d10}', '\u{10b0}'),
-        ('\u{2d11}', '\u{10b1}'), ('\u{2d12}', '\u{10b2}'), ('\u{2d13}', '\u{10b3}'), ('\u{2d14}',
-        '\u{10b4}'), ('\u{2d15}', '\u{10b5}'), ('\u{2d16}', '\u{10b6}'), ('\u{2d17}', '\u{10b7}'),
-        ('\u{2d18}', '\u{10b8}'), ('\u{2d19}', '\u{10b9}'), ('\u{2d1a}', '\u{10ba}'), ('\u{2d1b}',
-        '\u{10bb}'), ('\u{2d1c}', '\u{10bc}'), ('\u{2d1d}', '\u{10bd}'), ('\u{2d1e}', '\u{10be}'),
-        ('\u{2d1f}', '\u{10bf}'), ('\u{2d20}', '\u{10c0}'), ('\u{2d21}', '\u{10c1}'), ('\u{2d22}',
-        '\u{10c2}'), ('\u{2d23}', '\u{10c3}'), ('\u{2d24}', '\u{10c4}'), ('\u{2d25}', '\u{10c5}'),
-        ('\u{2d27}', '\u{10c7}'), ('\u{2d2d}', '\u{10cd}'), ('\u{a641}', '\u{a640}'), ('\u{a643}',
-        '\u{a642}'), ('\u{a645}', '\u{a644}'), ('\u{a647}', '\u{a646}'), ('\u{a649}', '\u{a648}'),
-        ('\u{a64b}', '\u{a64a}'), ('\u{a64d}', '\u{a64c}'), ('\u{a64f}', '\u{a64e}'), ('\u{a651}',
-        '\u{a650}'), ('\u{a653}', '\u{a652}'), ('\u{a655}', '\u{a654}'), ('\u{a657}', '\u{a656}'),
-        ('\u{a659}', '\u{a658}'), ('\u{a65b}', '\u{a65a}'), ('\u{a65d}', '\u{a65c}'), ('\u{a65f}',
-        '\u{a65e}'), ('\u{a661}', '\u{a660}'), ('\u{a663}', '\u{a662}'), ('\u{a665}', '\u{a664}'),
-        ('\u{a667}', '\u{a666}'), ('\u{a669}', '\u{a668}'), ('\u{a66b}', '\u{a66a}'), ('\u{a66d}',
-        '\u{a66c}'), ('\u{a681}', '\u{a680}'), ('\u{a683}', '\u{a682}'), ('\u{a685}', '\u{a684}'),
-        ('\u{a687}', '\u{a686}'), ('\u{a689}', '\u{a688}'), ('\u{a68b}', '\u{a68a}'), ('\u{a68d}',
-        '\u{a68c}'), ('\u{a68f}', '\u{a68e}'), ('\u{a691}', '\u{a690}'), ('\u{a693}', '\u{a692}'),
-        ('\u{a695}', '\u{a694}'), ('\u{a697}', '\u{a696}'), ('\u{a699}', '\u{a698}'), ('\u{a69b}',
-        '\u{a69a}'), ('\u{a723}', '\u{a722}'), ('\u{a725}', '\u{a724}'), ('\u{a727}', '\u{a726}'),
-        ('\u{a729}', '\u{a728}'), ('\u{a72b}', '\u{a72a}'), ('\u{a72d}', '\u{a72c}'), ('\u{a72f}',
-        '\u{a72e}'), ('\u{a733}', '\u{a732}'), ('\u{a735}', '\u{a734}'), ('\u{a737}', '\u{a736}'),
-        ('\u{a739}', '\u{a738}'), ('\u{a73b}', '\u{a73a}'), ('\u{a73d}', '\u{a73c}'), ('\u{a73f}',
-        '\u{a73e}'), ('\u{a741}', '\u{a740}'), ('\u{a743}', '\u{a742}'), ('\u{a745}', '\u{a744}'),
-        ('\u{a747}', '\u{a746}'), ('\u{a749}', '\u{a748}'), ('\u{a74b}', '\u{a74a}'), ('\u{a74d}',
-        '\u{a74c}'), ('\u{a74f}', '\u{a74e}'), ('\u{a751}', '\u{a750}'), ('\u{a753}', '\u{a752}'),
-        ('\u{a755}', '\u{a754}'), ('\u{a757}', '\u{a756}'), ('\u{a759}', '\u{a758}'), ('\u{a75b}',
-        '\u{a75a}'), ('\u{a75d}', '\u{a75c}'), ('\u{a75f}', '\u{a75e}'), ('\u{a761}', '\u{a760}'),
-        ('\u{a763}', '\u{a762}'), ('\u{a765}', '\u{a764}'), ('\u{a767}', '\u{a766}'), ('\u{a769}',
-        '\u{a768}'), ('\u{a76b}', '\u{a76a}'), ('\u{a76d}', '\u{a76c}'), ('\u{a76f}', '\u{a76e}'),
-        ('\u{a77a}', '\u{a779}'), ('\u{a77c}', '\u{a77b}'), ('\u{a77f}', '\u{a77e}'), ('\u{a781}',
-        '\u{a780}'), ('\u{a783}', '\u{a782}'), ('\u{a785}', '\u{a784}'), ('\u{a787}', '\u{a786}'),
-        ('\u{a78c}', '\u{a78b}'), ('\u{a791}', '\u{a790}'), ('\u{a793}', '\u{a792}'), ('\u{a797}',
-        '\u{a796}'), ('\u{a799}', '\u{a798}'), ('\u{a79b}', '\u{a79a}'), ('\u{a79d}', '\u{a79c}'),
-        ('\u{a79f}', '\u{a79e}'), ('\u{a7a1}', '\u{a7a0}'), ('\u{a7a3}', '\u{a7a2}'), ('\u{a7a5}',
-        '\u{a7a4}'), ('\u{a7a7}', '\u{a7a6}'), ('\u{a7a9}', '\u{a7a8}'), ('\u{ff41}', '\u{ff21}'),
-        ('\u{ff42}', '\u{ff22}'), ('\u{ff43}', '\u{ff23}'), ('\u{ff44}', '\u{ff24}'), ('\u{ff45}',
-        '\u{ff25}'), ('\u{ff46}', '\u{ff26}'), ('\u{ff47}', '\u{ff27}'), ('\u{ff48}', '\u{ff28}'),
-        ('\u{ff49}', '\u{ff29}'), ('\u{ff4a}', '\u{ff2a}'), ('\u{ff4b}', '\u{ff2b}'), ('\u{ff4c}',
-        '\u{ff2c}'), ('\u{ff4d}', '\u{ff2d}'), ('\u{ff4e}', '\u{ff2e}'), ('\u{ff4f}', '\u{ff2f}'),
-        ('\u{ff50}', '\u{ff30}'), ('\u{ff51}', '\u{ff31}'), ('\u{ff52}', '\u{ff32}'), ('\u{ff53}',
-        '\u{ff33}'), ('\u{ff54}', '\u{ff34}'), ('\u{ff55}', '\u{ff35}'), ('\u{ff56}', '\u{ff36}'),
-        ('\u{ff57}', '\u{ff37}'), ('\u{ff58}', '\u{ff38}'), ('\u{ff59}', '\u{ff39}'), ('\u{ff5a}',
-        '\u{ff3a}'), ('\u{10428}', '\u{10400}'), ('\u{10429}', '\u{10401}'), ('\u{1042a}',
-        '\u{10402}'), ('\u{1042b}', '\u{10403}'), ('\u{1042c}', '\u{10404}'), ('\u{1042d}',
-        '\u{10405}'), ('\u{1042e}', '\u{10406}'), ('\u{1042f}', '\u{10407}'), ('\u{10430}',
-        '\u{10408}'), ('\u{10431}', '\u{10409}'), ('\u{10432}', '\u{1040a}'), ('\u{10433}',
-        '\u{1040b}'), ('\u{10434}', '\u{1040c}'), ('\u{10435}', '\u{1040d}'), ('\u{10436}',
-        '\u{1040e}'), ('\u{10437}', '\u{1040f}'), ('\u{10438}', '\u{10410}'), ('\u{10439}',
-        '\u{10411}'), ('\u{1043a}', '\u{10412}'), ('\u{1043b}', '\u{10413}'), ('\u{1043c}',
-        '\u{10414}'), ('\u{1043d}', '\u{10415}'), ('\u{1043e}', '\u{10416}'), ('\u{1043f}',
-        '\u{10417}'), ('\u{10440}', '\u{10418}'), ('\u{10441}', '\u{10419}'), ('\u{10442}',
-        '\u{1041a}'), ('\u{10443}', '\u{1041b}'), ('\u{10444}', '\u{1041c}'), ('\u{10445}',
-        '\u{1041d}'), ('\u{10446}', '\u{1041e}'), ('\u{10447}', '\u{1041f}'), ('\u{10448}',
-        '\u{10420}'), ('\u{10449}', '\u{10421}'), ('\u{1044a}', '\u{10422}'), ('\u{1044b}',
-        '\u{10423}'), ('\u{1044c}', '\u{10424}'), ('\u{1044d}', '\u{10425}'), ('\u{1044e}',
-        '\u{10426}'), ('\u{1044f}', '\u{10427}'), ('\u{118c0}', '\u{118a0}'), ('\u{118c1}',
-        '\u{118a1}'), ('\u{118c2}', '\u{118a2}'), ('\u{118c3}', '\u{118a3}'), ('\u{118c4}',
-        '\u{118a4}'), ('\u{118c5}', '\u{118a5}'), ('\u{118c6}', '\u{118a6}'), ('\u{118c7}',
-        '\u{118a7}'), ('\u{118c8}', '\u{118a8}'), ('\u{118c9}', '\u{118a9}'), ('\u{118ca}',
-        '\u{118aa}'), ('\u{118cb}', '\u{118ab}'), ('\u{118cc}', '\u{118ac}'), ('\u{118cd}',
-        '\u{118ad}'), ('\u{118ce}', '\u{118ae}'), ('\u{118cf}', '\u{118af}'), ('\u{118d0}',
-        '\u{118b0}'), ('\u{118d1}', '\u{118b1}'), ('\u{118d2}', '\u{118b2}'), ('\u{118d3}',
-        '\u{118b3}'), ('\u{118d4}', '\u{118b4}'), ('\u{118d5}', '\u{118b5}'), ('\u{118d6}',
-        '\u{118b6}'), ('\u{118d7}', '\u{118b7}'), ('\u{118d8}', '\u{118b8}'), ('\u{118d9}',
-        '\u{118b9}'), ('\u{118da}', '\u{118ba}'), ('\u{118db}', '\u{118bb}'), ('\u{118dc}',
-        '\u{118bc}'), ('\u{118dd}', '\u{118bd}'), ('\u{118de}', '\u{118be}'), ('\u{118df}',
-        '\u{118bf}')
+    const to_titlecase_table: &'static [(char, [char; 3])] = &[
+        ('\u{61}', ['\u{41}', '\0', '\0']), ('\u{62}', ['\u{42}', '\0', '\0']), ('\u{63}',
+        ['\u{43}', '\0', '\0']), ('\u{64}', ['\u{44}', '\0', '\0']), ('\u{65}', ['\u{45}', '\0',
+        '\0']), ('\u{66}', ['\u{46}', '\0', '\0']), ('\u{67}', ['\u{47}', '\0', '\0']), ('\u{68}',
+        ['\u{48}', '\0', '\0']), ('\u{69}', ['\u{49}', '\0', '\0']), ('\u{6a}', ['\u{4a}', '\0',
+        '\0']), ('\u{6b}', ['\u{4b}', '\0', '\0']), ('\u{6c}', ['\u{4c}', '\0', '\0']), ('\u{6d}',
+        ['\u{4d}', '\0', '\0']), ('\u{6e}', ['\u{4e}', '\0', '\0']), ('\u{6f}', ['\u{4f}', '\0',
+        '\0']), ('\u{70}', ['\u{50}', '\0', '\0']), ('\u{71}', ['\u{51}', '\0', '\0']), ('\u{72}',
+        ['\u{52}', '\0', '\0']), ('\u{73}', ['\u{53}', '\0', '\0']), ('\u{74}', ['\u{54}', '\0',
+        '\0']), ('\u{75}', ['\u{55}', '\0', '\0']), ('\u{76}', ['\u{56}', '\0', '\0']), ('\u{77}',
+        ['\u{57}', '\0', '\0']), ('\u{78}', ['\u{58}', '\0', '\0']), ('\u{79}', ['\u{59}', '\0',
+        '\0']), ('\u{7a}', ['\u{5a}', '\0', '\0']), ('\u{b5}', ['\u{39c}', '\0', '\0']), ('\u{df}',
+        ['\u{53}', '\u{73}', '\0']), ('\u{e0}', ['\u{c0}', '\0', '\0']), ('\u{e1}', ['\u{c1}', '\0',
+        '\0']), ('\u{e2}', ['\u{c2}', '\0', '\0']), ('\u{e3}', ['\u{c3}', '\0', '\0']), ('\u{e4}',
+        ['\u{c4}', '\0', '\0']), ('\u{e5}', ['\u{c5}', '\0', '\0']), ('\u{e6}', ['\u{c6}', '\0',
+        '\0']), ('\u{e7}', ['\u{c7}', '\0', '\0']), ('\u{e8}', ['\u{c8}', '\0', '\0']), ('\u{e9}',
+        ['\u{c9}', '\0', '\0']), ('\u{ea}', ['\u{ca}', '\0', '\0']), ('\u{eb}', ['\u{cb}', '\0',
+        '\0']), ('\u{ec}', ['\u{cc}', '\0', '\0']), ('\u{ed}', ['\u{cd}', '\0', '\0']), ('\u{ee}',
+        ['\u{ce}', '\0', '\0']), ('\u{ef}', ['\u{cf}', '\0', '\0']), ('\u{f0}', ['\u{d0}', '\0',
+        '\0']), ('\u{f1}', ['\u{d1}', '\0', '\0']), ('\u{f2}', ['\u{d2}', '\0', '\0']), ('\u{f3}',
+        ['\u{d3}', '\0', '\0']), ('\u{f4}', ['\u{d4}', '\0', '\0']), ('\u{f5}', ['\u{d5}', '\0',
+        '\0']), ('\u{f6}', ['\u{d6}', '\0', '\0']), ('\u{f8}', ['\u{d8}', '\0', '\0']), ('\u{f9}',
+        ['\u{d9}', '\0', '\0']), ('\u{fa}', ['\u{da}', '\0', '\0']), ('\u{fb}', ['\u{db}', '\0',
+        '\0']), ('\u{fc}', ['\u{dc}', '\0', '\0']), ('\u{fd}', ['\u{dd}', '\0', '\0']), ('\u{fe}',
+        ['\u{de}', '\0', '\0']), ('\u{ff}', ['\u{178}', '\0', '\0']), ('\u{101}', ['\u{100}', '\0',
+        '\0']), ('\u{103}', ['\u{102}', '\0', '\0']), ('\u{105}', ['\u{104}', '\0', '\0']),
+        ('\u{107}', ['\u{106}', '\0', '\0']), ('\u{109}', ['\u{108}', '\0', '\0']), ('\u{10b}',
+        ['\u{10a}', '\0', '\0']), ('\u{10d}', ['\u{10c}', '\0', '\0']), ('\u{10f}', ['\u{10e}',
+        '\0', '\0']), ('\u{111}', ['\u{110}', '\0', '\0']), ('\u{113}', ['\u{112}', '\0', '\0']),
+        ('\u{115}', ['\u{114}', '\0', '\0']), ('\u{117}', ['\u{116}', '\0', '\0']), ('\u{119}',
+        ['\u{118}', '\0', '\0']), ('\u{11b}', ['\u{11a}', '\0', '\0']), ('\u{11d}', ['\u{11c}',
+        '\0', '\0']), ('\u{11f}', ['\u{11e}', '\0', '\0']), ('\u{121}', ['\u{120}', '\0', '\0']),
+        ('\u{123}', ['\u{122}', '\0', '\0']), ('\u{125}', ['\u{124}', '\0', '\0']), ('\u{127}',
+        ['\u{126}', '\0', '\0']), ('\u{129}', ['\u{128}', '\0', '\0']), ('\u{12b}', ['\u{12a}',
+        '\0', '\0']), ('\u{12d}', ['\u{12c}', '\0', '\0']), ('\u{12f}', ['\u{12e}', '\0', '\0']),
+        ('\u{131}', ['\u{49}', '\0', '\0']), ('\u{133}', ['\u{132}', '\0', '\0']), ('\u{135}',
+        ['\u{134}', '\0', '\0']), ('\u{137}', ['\u{136}', '\0', '\0']), ('\u{13a}', ['\u{139}',
+        '\0', '\0']), ('\u{13c}', ['\u{13b}', '\0', '\0']), ('\u{13e}', ['\u{13d}', '\0', '\0']),
+        ('\u{140}', ['\u{13f}', '\0', '\0']), ('\u{142}', ['\u{141}', '\0', '\0']), ('\u{144}',
+        ['\u{143}', '\0', '\0']), ('\u{146}', ['\u{145}', '\0', '\0']), ('\u{148}', ['\u{147}',
+        '\0', '\0']), ('\u{149}', ['\u{2bc}', '\u{4e}', '\0']), ('\u{14b}', ['\u{14a}', '\0',
+        '\0']), ('\u{14d}', ['\u{14c}', '\0', '\0']), ('\u{14f}', ['\u{14e}', '\0', '\0']),
+        ('\u{151}', ['\u{150}', '\0', '\0']), ('\u{153}', ['\u{152}', '\0', '\0']), ('\u{155}',
+        ['\u{154}', '\0', '\0']), ('\u{157}', ['\u{156}', '\0', '\0']), ('\u{159}', ['\u{158}',
+        '\0', '\0']), ('\u{15b}', ['\u{15a}', '\0', '\0']), ('\u{15d}', ['\u{15c}', '\0', '\0']),
+        ('\u{15f}', ['\u{15e}', '\0', '\0']), ('\u{161}', ['\u{160}', '\0', '\0']), ('\u{163}',
+        ['\u{162}', '\0', '\0']), ('\u{165}', ['\u{164}', '\0', '\0']), ('\u{167}', ['\u{166}',
+        '\0', '\0']), ('\u{169}', ['\u{168}', '\0', '\0']), ('\u{16b}', ['\u{16a}', '\0', '\0']),
+        ('\u{16d}', ['\u{16c}', '\0', '\0']), ('\u{16f}', ['\u{16e}', '\0', '\0']), ('\u{171}',
+        ['\u{170}', '\0', '\0']), ('\u{173}', ['\u{172}', '\0', '\0']), ('\u{175}', ['\u{174}',
+        '\0', '\0']), ('\u{177}', ['\u{176}', '\0', '\0']), ('\u{17a}', ['\u{179}', '\0', '\0']),
+        ('\u{17c}', ['\u{17b}', '\0', '\0']), ('\u{17e}', ['\u{17d}', '\0', '\0']), ('\u{17f}',
+        ['\u{53}', '\0', '\0']), ('\u{180}', ['\u{243}', '\0', '\0']), ('\u{183}', ['\u{182}', '\0',
+        '\0']), ('\u{185}', ['\u{184}', '\0', '\0']), ('\u{188}', ['\u{187}', '\0', '\0']),
+        ('\u{18c}', ['\u{18b}', '\0', '\0']), ('\u{192}', ['\u{191}', '\0', '\0']), ('\u{195}',
+        ['\u{1f6}', '\0', '\0']), ('\u{199}', ['\u{198}', '\0', '\0']), ('\u{19a}', ['\u{23d}',
+        '\0', '\0']), ('\u{19e}', ['\u{220}', '\0', '\0']), ('\u{1a1}', ['\u{1a0}', '\0', '\0']),
+        ('\u{1a3}', ['\u{1a2}', '\0', '\0']), ('\u{1a5}', ['\u{1a4}', '\0', '\0']), ('\u{1a8}',
+        ['\u{1a7}', '\0', '\0']), ('\u{1ad}', ['\u{1ac}', '\0', '\0']), ('\u{1b0}', ['\u{1af}',
+        '\0', '\0']), ('\u{1b4}', ['\u{1b3}', '\0', '\0']), ('\u{1b6}', ['\u{1b5}', '\0', '\0']),
+        ('\u{1b9}', ['\u{1b8}', '\0', '\0']), ('\u{1bd}', ['\u{1bc}', '\0', '\0']), ('\u{1bf}',
+        ['\u{1f7}', '\0', '\0']), ('\u{1c4}', ['\u{1c5}', '\0', '\0']), ('\u{1c5}', ['\u{1c5}',
+        '\0', '\0']), ('\u{1c6}', ['\u{1c5}', '\0', '\0']), ('\u{1c7}', ['\u{1c8}', '\0', '\0']),
+        ('\u{1c8}', ['\u{1c8}', '\0', '\0']), ('\u{1c9}', ['\u{1c8}', '\0', '\0']), ('\u{1ca}',
+        ['\u{1cb}', '\0', '\0']), ('\u{1cb}', ['\u{1cb}', '\0', '\0']), ('\u{1cc}', ['\u{1cb}',
+        '\0', '\0']), ('\u{1ce}', ['\u{1cd}', '\0', '\0']), ('\u{1d0}', ['\u{1cf}', '\0', '\0']),
+        ('\u{1d2}', ['\u{1d1}', '\0', '\0']), ('\u{1d4}', ['\u{1d3}', '\0', '\0']), ('\u{1d6}',
+        ['\u{1d5}', '\0', '\0']), ('\u{1d8}', ['\u{1d7}', '\0', '\0']), ('\u{1da}', ['\u{1d9}',
+        '\0', '\0']), ('\u{1dc}', ['\u{1db}', '\0', '\0']), ('\u{1dd}', ['\u{18e}', '\0', '\0']),
+        ('\u{1df}', ['\u{1de}', '\0', '\0']), ('\u{1e1}', ['\u{1e0}', '\0', '\0']), ('\u{1e3}',
+        ['\u{1e2}', '\0', '\0']), ('\u{1e5}', ['\u{1e4}', '\0', '\0']), ('\u{1e7}', ['\u{1e6}',
+        '\0', '\0']), ('\u{1e9}', ['\u{1e8}', '\0', '\0']), ('\u{1eb}', ['\u{1ea}', '\0', '\0']),
+        ('\u{1ed}', ['\u{1ec}', '\0', '\0']), ('\u{1ef}', ['\u{1ee}', '\0', '\0']), ('\u{1f0}',
+        ['\u{4a}', '\u{30c}', '\0']), ('\u{1f1}', ['\u{1f2}', '\0', '\0']), ('\u{1f2}', ['\u{1f2}',
+        '\0', '\0']), ('\u{1f3}', ['\u{1f2}', '\0', '\0']), ('\u{1f5}', ['\u{1f4}', '\0', '\0']),
+        ('\u{1f9}', ['\u{1f8}', '\0', '\0']), ('\u{1fb}', ['\u{1fa}', '\0', '\0']), ('\u{1fd}',
+        ['\u{1fc}', '\0', '\0']), ('\u{1ff}', ['\u{1fe}', '\0', '\0']), ('\u{201}', ['\u{200}',
+        '\0', '\0']), ('\u{203}', ['\u{202}', '\0', '\0']), ('\u{205}', ['\u{204}', '\0', '\0']),
+        ('\u{207}', ['\u{206}', '\0', '\0']), ('\u{209}', ['\u{208}', '\0', '\0']), ('\u{20b}',
+        ['\u{20a}', '\0', '\0']), ('\u{20d}', ['\u{20c}', '\0', '\0']), ('\u{20f}', ['\u{20e}',
+        '\0', '\0']), ('\u{211}', ['\u{210}', '\0', '\0']), ('\u{213}', ['\u{212}', '\0', '\0']),
+        ('\u{215}', ['\u{214}', '\0', '\0']), ('\u{217}', ['\u{216}', '\0', '\0']), ('\u{219}',
+        ['\u{218}', '\0', '\0']), ('\u{21b}', ['\u{21a}', '\0', '\0']), ('\u{21d}', ['\u{21c}',
+        '\0', '\0']), ('\u{21f}', ['\u{21e}', '\0', '\0']), ('\u{223}', ['\u{222}', '\0', '\0']),
+        ('\u{225}', ['\u{224}', '\0', '\0']), ('\u{227}', ['\u{226}', '\0', '\0']), ('\u{229}',
+        ['\u{228}', '\0', '\0']), ('\u{22b}', ['\u{22a}', '\0', '\0']), ('\u{22d}', ['\u{22c}',
+        '\0', '\0']), ('\u{22f}', ['\u{22e}', '\0', '\0']), ('\u{231}', ['\u{230}', '\0', '\0']),
+        ('\u{233}', ['\u{232}', '\0', '\0']), ('\u{23c}', ['\u{23b}', '\0', '\0']), ('\u{23f}',
+        ['\u{2c7e}', '\0', '\0']), ('\u{240}', ['\u{2c7f}', '\0', '\0']), ('\u{242}', ['\u{241}',
+        '\0', '\0']), ('\u{247}', ['\u{246}', '\0', '\0']), ('\u{249}', ['\u{248}', '\0', '\0']),
+        ('\u{24b}', ['\u{24a}', '\0', '\0']), ('\u{24d}', ['\u{24c}', '\0', '\0']), ('\u{24f}',
+        ['\u{24e}', '\0', '\0']), ('\u{250}', ['\u{2c6f}', '\0', '\0']), ('\u{251}', ['\u{2c6d}',
+        '\0', '\0']), ('\u{252}', ['\u{2c70}', '\0', '\0']), ('\u{253}', ['\u{181}', '\0', '\0']),
+        ('\u{254}', ['\u{186}', '\0', '\0']), ('\u{256}', ['\u{189}', '\0', '\0']), ('\u{257}',
+        ['\u{18a}', '\0', '\0']), ('\u{259}', ['\u{18f}', '\0', '\0']), ('\u{25b}', ['\u{190}',
+        '\0', '\0']), ('\u{25c}', ['\u{a7ab}', '\0', '\0']), ('\u{260}', ['\u{193}', '\0', '\0']),
+        ('\u{261}', ['\u{a7ac}', '\0', '\0']), ('\u{263}', ['\u{194}', '\0', '\0']), ('\u{265}',
+        ['\u{a78d}', '\0', '\0']), ('\u{266}', ['\u{a7aa}', '\0', '\0']), ('\u{268}', ['\u{197}',
+        '\0', '\0']), ('\u{269}', ['\u{196}', '\0', '\0']), ('\u{26b}', ['\u{2c62}', '\0', '\0']),
+        ('\u{26c}', ['\u{a7ad}', '\0', '\0']), ('\u{26f}', ['\u{19c}', '\0', '\0']), ('\u{271}',
+        ['\u{2c6e}', '\0', '\0']), ('\u{272}', ['\u{19d}', '\0', '\0']), ('\u{275}', ['\u{19f}',
+        '\0', '\0']), ('\u{27d}', ['\u{2c64}', '\0', '\0']), ('\u{280}', ['\u{1a6}', '\0', '\0']),
+        ('\u{283}', ['\u{1a9}', '\0', '\0']), ('\u{287}', ['\u{a7b1}', '\0', '\0']), ('\u{288}',
+        ['\u{1ae}', '\0', '\0']), ('\u{289}', ['\u{244}', '\0', '\0']), ('\u{28a}', ['\u{1b1}',
+        '\0', '\0']), ('\u{28b}', ['\u{1b2}', '\0', '\0']), ('\u{28c}', ['\u{245}', '\0', '\0']),
+        ('\u{292}', ['\u{1b7}', '\0', '\0']), ('\u{29e}', ['\u{a7b0}', '\0', '\0']), ('\u{345}',
+        ['\u{399}', '\0', '\0']), ('\u{371}', ['\u{370}', '\0', '\0']), ('\u{373}', ['\u{372}',
+        '\0', '\0']), ('\u{377}', ['\u{376}', '\0', '\0']), ('\u{37b}', ['\u{3fd}', '\0', '\0']),
+        ('\u{37c}', ['\u{3fe}', '\0', '\0']), ('\u{37d}', ['\u{3ff}', '\0', '\0']), ('\u{390}',
+        ['\u{399}', '\u{308}', '\u{301}']), ('\u{3ac}', ['\u{386}', '\0', '\0']), ('\u{3ad}',
+        ['\u{388}', '\0', '\0']), ('\u{3ae}', ['\u{389}', '\0', '\0']), ('\u{3af}', ['\u{38a}',
+        '\0', '\0']), ('\u{3b0}', ['\u{3a5}', '\u{308}', '\u{301}']), ('\u{3b1}', ['\u{391}', '\0',
+        '\0']), ('\u{3b2}', ['\u{392}', '\0', '\0']), ('\u{3b3}', ['\u{393}', '\0', '\0']),
+        ('\u{3b4}', ['\u{394}', '\0', '\0']), ('\u{3b5}', ['\u{395}', '\0', '\0']), ('\u{3b6}',
+        ['\u{396}', '\0', '\0']), ('\u{3b7}', ['\u{397}', '\0', '\0']), ('\u{3b8}', ['\u{398}',
+        '\0', '\0']), ('\u{3b9}', ['\u{399}', '\0', '\0']), ('\u{3ba}', ['\u{39a}', '\0', '\0']),
+        ('\u{3bb}', ['\u{39b}', '\0', '\0']), ('\u{3bc}', ['\u{39c}', '\0', '\0']), ('\u{3bd}',
+        ['\u{39d}', '\0', '\0']), ('\u{3be}', ['\u{39e}', '\0', '\0']), ('\u{3bf}', ['\u{39f}',
+        '\0', '\0']), ('\u{3c0}', ['\u{3a0}', '\0', '\0']), ('\u{3c1}', ['\u{3a1}', '\0', '\0']),
+        ('\u{3c2}', ['\u{3a3}', '\0', '\0']), ('\u{3c3}', ['\u{3a3}', '\0', '\0']), ('\u{3c4}',
+        ['\u{3a4}', '\0', '\0']), ('\u{3c5}', ['\u{3a5}', '\0', '\0']), ('\u{3c6}', ['\u{3a6}',
+        '\0', '\0']), ('\u{3c7}', ['\u{3a7}', '\0', '\0']), ('\u{3c8}', ['\u{3a8}', '\0', '\0']),
+        ('\u{3c9}', ['\u{3a9}', '\0', '\0']), ('\u{3ca}', ['\u{3aa}', '\0', '\0']), ('\u{3cb}',
+        ['\u{3ab}', '\0', '\0']), ('\u{3cc}', ['\u{38c}', '\0', '\0']), ('\u{3cd}', ['\u{38e}',
+        '\0', '\0']), ('\u{3ce}', ['\u{38f}', '\0', '\0']), ('\u{3d0}', ['\u{392}', '\0', '\0']),
+        ('\u{3d1}', ['\u{398}', '\0', '\0']), ('\u{3d5}', ['\u{3a6}', '\0', '\0']), ('\u{3d6}',
+        ['\u{3a0}', '\0', '\0']), ('\u{3d7}', ['\u{3cf}', '\0', '\0']), ('\u{3d9}', ['\u{3d8}',
+        '\0', '\0']), ('\u{3db}', ['\u{3da}', '\0', '\0']), ('\u{3dd}', ['\u{3dc}', '\0', '\0']),
+        ('\u{3df}', ['\u{3de}', '\0', '\0']), ('\u{3e1}', ['\u{3e0}', '\0', '\0']), ('\u{3e3}',
+        ['\u{3e2}', '\0', '\0']), ('\u{3e5}', ['\u{3e4}', '\0', '\0']), ('\u{3e7}', ['\u{3e6}',
+        '\0', '\0']), ('\u{3e9}', ['\u{3e8}', '\0', '\0']), ('\u{3eb}', ['\u{3ea}', '\0', '\0']),
+        ('\u{3ed}', ['\u{3ec}', '\0', '\0']), ('\u{3ef}', ['\u{3ee}', '\0', '\0']), ('\u{3f0}',
+        ['\u{39a}', '\0', '\0']), ('\u{3f1}', ['\u{3a1}', '\0', '\0']), ('\u{3f2}', ['\u{3f9}',
+        '\0', '\0']), ('\u{3f3}', ['\u{37f}', '\0', '\0']), ('\u{3f5}', ['\u{395}', '\0', '\0']),
+        ('\u{3f8}', ['\u{3f7}', '\0', '\0']), ('\u{3fb}', ['\u{3fa}', '\0', '\0']), ('\u{430}',
+        ['\u{410}', '\0', '\0']), ('\u{431}', ['\u{411}', '\0', '\0']), ('\u{432}', ['\u{412}',
+        '\0', '\0']), ('\u{433}', ['\u{413}', '\0', '\0']), ('\u{434}', ['\u{414}', '\0', '\0']),
+        ('\u{435}', ['\u{415}', '\0', '\0']), ('\u{436}', ['\u{416}', '\0', '\0']), ('\u{437}',
+        ['\u{417}', '\0', '\0']), ('\u{438}', ['\u{418}', '\0', '\0']), ('\u{439}', ['\u{419}',
+        '\0', '\0']), ('\u{43a}', ['\u{41a}', '\0', '\0']), ('\u{43b}', ['\u{41b}', '\0', '\0']),
+        ('\u{43c}', ['\u{41c}', '\0', '\0']), ('\u{43d}', ['\u{41d}', '\0', '\0']), ('\u{43e}',
+        ['\u{41e}', '\0', '\0']), ('\u{43f}', ['\u{41f}', '\0', '\0']), ('\u{440}', ['\u{420}',
+        '\0', '\0']), ('\u{441}', ['\u{421}', '\0', '\0']), ('\u{442}', ['\u{422}', '\0', '\0']),
+        ('\u{443}', ['\u{423}', '\0', '\0']), ('\u{444}', ['\u{424}', '\0', '\0']), ('\u{445}',
+        ['\u{425}', '\0', '\0']), ('\u{446}', ['\u{426}', '\0', '\0']), ('\u{447}', ['\u{427}',
+        '\0', '\0']), ('\u{448}', ['\u{428}', '\0', '\0']), ('\u{449}', ['\u{429}', '\0', '\0']),
+        ('\u{44a}', ['\u{42a}', '\0', '\0']), ('\u{44b}', ['\u{42b}', '\0', '\0']), ('\u{44c}',
+        ['\u{42c}', '\0', '\0']), ('\u{44d}', ['\u{42d}', '\0', '\0']), ('\u{44e}', ['\u{42e}',
+        '\0', '\0']), ('\u{44f}', ['\u{42f}', '\0', '\0']), ('\u{450}', ['\u{400}', '\0', '\0']),
+        ('\u{451}', ['\u{401}', '\0', '\0']), ('\u{452}', ['\u{402}', '\0', '\0']), ('\u{453}',
+        ['\u{403}', '\0', '\0']), ('\u{454}', ['\u{404}', '\0', '\0']), ('\u{455}', ['\u{405}',
+        '\0', '\0']), ('\u{456}', ['\u{406}', '\0', '\0']), ('\u{457}', ['\u{407}', '\0', '\0']),
+        ('\u{458}', ['\u{408}', '\0', '\0']), ('\u{459}', ['\u{409}', '\0', '\0']), ('\u{45a}',
+        ['\u{40a}', '\0', '\0']), ('\u{45b}', ['\u{40b}', '\0', '\0']), ('\u{45c}', ['\u{40c}',
+        '\0', '\0']), ('\u{45d}', ['\u{40d}', '\0', '\0']), ('\u{45e}', ['\u{40e}', '\0', '\0']),
+        ('\u{45f}', ['\u{40f}', '\0', '\0']), ('\u{461}', ['\u{460}', '\0', '\0']), ('\u{463}',
+        ['\u{462}', '\0', '\0']), ('\u{465}', ['\u{464}', '\0', '\0']), ('\u{467}', ['\u{466}',
+        '\0', '\0']), ('\u{469}', ['\u{468}', '\0', '\0']), ('\u{46b}', ['\u{46a}', '\0', '\0']),
+        ('\u{46d}', ['\u{46c}', '\0', '\0']), ('\u{46f}', ['\u{46e}', '\0', '\0']), ('\u{471}',
+        ['\u{470}', '\0', '\0']), ('\u{473}', ['\u{472}', '\0', '\0']), ('\u{475}', ['\u{474}',
+        '\0', '\0']), ('\u{477}', ['\u{476}', '\0', '\0']), ('\u{479}', ['\u{478}', '\0', '\0']),
+        ('\u{47b}', ['\u{47a}', '\0', '\0']), ('\u{47d}', ['\u{47c}', '\0', '\0']), ('\u{47f}',
+        ['\u{47e}', '\0', '\0']), ('\u{481}', ['\u{480}', '\0', '\0']), ('\u{48b}', ['\u{48a}',
+        '\0', '\0']), ('\u{48d}', ['\u{48c}', '\0', '\0']), ('\u{48f}', ['\u{48e}', '\0', '\0']),
+        ('\u{491}', ['\u{490}', '\0', '\0']), ('\u{493}', ['\u{492}', '\0', '\0']), ('\u{495}',
+        ['\u{494}', '\0', '\0']), ('\u{497}', ['\u{496}', '\0', '\0']), ('\u{499}', ['\u{498}',
+        '\0', '\0']), ('\u{49b}', ['\u{49a}', '\0', '\0']), ('\u{49d}', ['\u{49c}', '\0', '\0']),
+        ('\u{49f}', ['\u{49e}', '\0', '\0']), ('\u{4a1}', ['\u{4a0}', '\0', '\0']), ('\u{4a3}',
+        ['\u{4a2}', '\0', '\0']), ('\u{4a5}', ['\u{4a4}', '\0', '\0']), ('\u{4a7}', ['\u{4a6}',
+        '\0', '\0']), ('\u{4a9}', ['\u{4a8}', '\0', '\0']), ('\u{4ab}', ['\u{4aa}', '\0', '\0']),
+        ('\u{4ad}', ['\u{4ac}', '\0', '\0']), ('\u{4af}', ['\u{4ae}', '\0', '\0']), ('\u{4b1}',
+        ['\u{4b0}', '\0', '\0']), ('\u{4b3}', ['\u{4b2}', '\0', '\0']), ('\u{4b5}', ['\u{4b4}',
+        '\0', '\0']), ('\u{4b7}', ['\u{4b6}', '\0', '\0']), ('\u{4b9}', ['\u{4b8}', '\0', '\0']),
+        ('\u{4bb}', ['\u{4ba}', '\0', '\0']), ('\u{4bd}', ['\u{4bc}', '\0', '\0']), ('\u{4bf}',
+        ['\u{4be}', '\0', '\0']), ('\u{4c2}', ['\u{4c1}', '\0', '\0']), ('\u{4c4}', ['\u{4c3}',
+        '\0', '\0']), ('\u{4c6}', ['\u{4c5}', '\0', '\0']), ('\u{4c8}', ['\u{4c7}', '\0', '\0']),
+        ('\u{4ca}', ['\u{4c9}', '\0', '\0']), ('\u{4cc}', ['\u{4cb}', '\0', '\0']), ('\u{4ce}',
+        ['\u{4cd}', '\0', '\0']), ('\u{4cf}', ['\u{4c0}', '\0', '\0']), ('\u{4d1}', ['\u{4d0}',
+        '\0', '\0']), ('\u{4d3}', ['\u{4d2}', '\0', '\0']), ('\u{4d5}', ['\u{4d4}', '\0', '\0']),
+        ('\u{4d7}', ['\u{4d6}', '\0', '\0']), ('\u{4d9}', ['\u{4d8}', '\0', '\0']), ('\u{4db}',
+        ['\u{4da}', '\0', '\0']), ('\u{4dd}', ['\u{4dc}', '\0', '\0']), ('\u{4df}', ['\u{4de}',
+        '\0', '\0']), ('\u{4e1}', ['\u{4e0}', '\0', '\0']), ('\u{4e3}', ['\u{4e2}', '\0', '\0']),
+        ('\u{4e5}', ['\u{4e4}', '\0', '\0']), ('\u{4e7}', ['\u{4e6}', '\0', '\0']), ('\u{4e9}',
+        ['\u{4e8}', '\0', '\0']), ('\u{4eb}', ['\u{4ea}', '\0', '\0']), ('\u{4ed}', ['\u{4ec}',
+        '\0', '\0']), ('\u{4ef}', ['\u{4ee}', '\0', '\0']), ('\u{4f1}', ['\u{4f0}', '\0', '\0']),
+        ('\u{4f3}', ['\u{4f2}', '\0', '\0']), ('\u{4f5}', ['\u{4f4}', '\0', '\0']), ('\u{4f7}',
+        ['\u{4f6}', '\0', '\0']), ('\u{4f9}', ['\u{4f8}', '\0', '\0']), ('\u{4fb}', ['\u{4fa}',
+        '\0', '\0']), ('\u{4fd}', ['\u{4fc}', '\0', '\0']), ('\u{4ff}', ['\u{4fe}', '\0', '\0']),
+        ('\u{501}', ['\u{500}', '\0', '\0']), ('\u{503}', ['\u{502}', '\0', '\0']), ('\u{505}',
+        ['\u{504}', '\0', '\0']), ('\u{507}', ['\u{506}', '\0', '\0']), ('\u{509}', ['\u{508}',
+        '\0', '\0']), ('\u{50b}', ['\u{50a}', '\0', '\0']), ('\u{50d}', ['\u{50c}', '\0', '\0']),
+        ('\u{50f}', ['\u{50e}', '\0', '\0']), ('\u{511}', ['\u{510}', '\0', '\0']), ('\u{513}',
+        ['\u{512}', '\0', '\0']), ('\u{515}', ['\u{514}', '\0', '\0']), ('\u{517}', ['\u{516}',
+        '\0', '\0']), ('\u{519}', ['\u{518}', '\0', '\0']), ('\u{51b}', ['\u{51a}', '\0', '\0']),
+        ('\u{51d}', ['\u{51c}', '\0', '\0']), ('\u{51f}', ['\u{51e}', '\0', '\0']), ('\u{521}',
+        ['\u{520}', '\0', '\0']), ('\u{523}', ['\u{522}', '\0', '\0']), ('\u{525}', ['\u{524}',
+        '\0', '\0']), ('\u{527}', ['\u{526}', '\0', '\0']), ('\u{529}', ['\u{528}', '\0', '\0']),
+        ('\u{52b}', ['\u{52a}', '\0', '\0']), ('\u{52d}', ['\u{52c}', '\0', '\0']), ('\u{52f}',
+        ['\u{52e}', '\0', '\0']), ('\u{561}', ['\u{531}', '\0', '\0']), ('\u{562}', ['\u{532}',
+        '\0', '\0']), ('\u{563}', ['\u{533}', '\0', '\0']), ('\u{564}', ['\u{534}', '\0', '\0']),
+        ('\u{565}', ['\u{535}', '\0', '\0']), ('\u{566}', ['\u{536}', '\0', '\0']), ('\u{567}',
+        ['\u{537}', '\0', '\0']), ('\u{568}', ['\u{538}', '\0', '\0']), ('\u{569}', ['\u{539}',
+        '\0', '\0']), ('\u{56a}', ['\u{53a}', '\0', '\0']), ('\u{56b}', ['\u{53b}', '\0', '\0']),
+        ('\u{56c}', ['\u{53c}', '\0', '\0']), ('\u{56d}', ['\u{53d}', '\0', '\0']), ('\u{56e}',
+        ['\u{53e}', '\0', '\0']), ('\u{56f}', ['\u{53f}', '\0', '\0']), ('\u{570}', ['\u{540}',
+        '\0', '\0']), ('\u{571}', ['\u{541}', '\0', '\0']), ('\u{572}', ['\u{542}', '\0', '\0']),
+        ('\u{573}', ['\u{543}', '\0', '\0']), ('\u{574}', ['\u{544}', '\0', '\0']), ('\u{575}',
+        ['\u{545}', '\0', '\0']), ('\u{576}', ['\u{546}', '\0', '\0']), ('\u{577}', ['\u{547}',
+        '\0', '\0']), ('\u{578}', ['\u{548}', '\0', '\0']), ('\u{579}', ['\u{549}', '\0', '\0']),
+        ('\u{57a}', ['\u{54a}', '\0', '\0']), ('\u{57b}', ['\u{54b}', '\0', '\0']), ('\u{57c}',
+        ['\u{54c}', '\0', '\0']), ('\u{57d}', ['\u{54d}', '\0', '\0']), ('\u{57e}', ['\u{54e}',
+        '\0', '\0']), ('\u{57f}', ['\u{54f}', '\0', '\0']), ('\u{580}', ['\u{550}', '\0', '\0']),
+        ('\u{581}', ['\u{551}', '\0', '\0']), ('\u{582}', ['\u{552}', '\0', '\0']), ('\u{583}',
+        ['\u{553}', '\0', '\0']), ('\u{584}', ['\u{554}', '\0', '\0']), ('\u{585}', ['\u{555}',
+        '\0', '\0']), ('\u{586}', ['\u{556}', '\0', '\0']), ('\u{587}', ['\u{535}', '\u{582}',
+        '\0']), ('\u{1d79}', ['\u{a77d}', '\0', '\0']), ('\u{1d7d}', ['\u{2c63}', '\0', '\0']),
+        ('\u{1e01}', ['\u{1e00}', '\0', '\0']), ('\u{1e03}', ['\u{1e02}', '\0', '\0']), ('\u{1e05}',
+        ['\u{1e04}', '\0', '\0']), ('\u{1e07}', ['\u{1e06}', '\0', '\0']), ('\u{1e09}', ['\u{1e08}',
+        '\0', '\0']), ('\u{1e0b}', ['\u{1e0a}', '\0', '\0']), ('\u{1e0d}', ['\u{1e0c}', '\0',
+        '\0']), ('\u{1e0f}', ['\u{1e0e}', '\0', '\0']), ('\u{1e11}', ['\u{1e10}', '\0', '\0']),
+        ('\u{1e13}', ['\u{1e12}', '\0', '\0']), ('\u{1e15}', ['\u{1e14}', '\0', '\0']), ('\u{1e17}',
+        ['\u{1e16}', '\0', '\0']), ('\u{1e19}', ['\u{1e18}', '\0', '\0']), ('\u{1e1b}', ['\u{1e1a}',
+        '\0', '\0']), ('\u{1e1d}', ['\u{1e1c}', '\0', '\0']), ('\u{1e1f}', ['\u{1e1e}', '\0',
+        '\0']), ('\u{1e21}', ['\u{1e20}', '\0', '\0']), ('\u{1e23}', ['\u{1e22}', '\0', '\0']),
+        ('\u{1e25}', ['\u{1e24}', '\0', '\0']), ('\u{1e27}', ['\u{1e26}', '\0', '\0']), ('\u{1e29}',
+        ['\u{1e28}', '\0', '\0']), ('\u{1e2b}', ['\u{1e2a}', '\0', '\0']), ('\u{1e2d}', ['\u{1e2c}',
+        '\0', '\0']), ('\u{1e2f}', ['\u{1e2e}', '\0', '\0']), ('\u{1e31}', ['\u{1e30}', '\0',
+        '\0']), ('\u{1e33}', ['\u{1e32}', '\0', '\0']), ('\u{1e35}', ['\u{1e34}', '\0', '\0']),
+        ('\u{1e37}', ['\u{1e36}', '\0', '\0']), ('\u{1e39}', ['\u{1e38}', '\0', '\0']), ('\u{1e3b}',
+        ['\u{1e3a}', '\0', '\0']), ('\u{1e3d}', ['\u{1e3c}', '\0', '\0']), ('\u{1e3f}', ['\u{1e3e}',
+        '\0', '\0']), ('\u{1e41}', ['\u{1e40}', '\0', '\0']), ('\u{1e43}', ['\u{1e42}', '\0',
+        '\0']), ('\u{1e45}', ['\u{1e44}', '\0', '\0']), ('\u{1e47}', ['\u{1e46}', '\0', '\0']),
+        ('\u{1e49}', ['\u{1e48}', '\0', '\0']), ('\u{1e4b}', ['\u{1e4a}', '\0', '\0']), ('\u{1e4d}',
+        ['\u{1e4c}', '\0', '\0']), ('\u{1e4f}', ['\u{1e4e}', '\0', '\0']), ('\u{1e51}', ['\u{1e50}',
+        '\0', '\0']), ('\u{1e53}', ['\u{1e52}', '\0', '\0']), ('\u{1e55}', ['\u{1e54}', '\0',
+        '\0']), ('\u{1e57}', ['\u{1e56}', '\0', '\0']), ('\u{1e59}', ['\u{1e58}', '\0', '\0']),
+        ('\u{1e5b}', ['\u{1e5a}', '\0', '\0']), ('\u{1e5d}', ['\u{1e5c}', '\0', '\0']), ('\u{1e5f}',
+        ['\u{1e5e}', '\0', '\0']), ('\u{1e61}', ['\u{1e60}', '\0', '\0']), ('\u{1e63}', ['\u{1e62}',
+        '\0', '\0']), ('\u{1e65}', ['\u{1e64}', '\0', '\0']), ('\u{1e67}', ['\u{1e66}', '\0',
+        '\0']), ('\u{1e69}', ['\u{1e68}', '\0', '\0']), ('\u{1e6b}', ['\u{1e6a}', '\0', '\0']),
+        ('\u{1e6d}', ['\u{1e6c}', '\0', '\0']), ('\u{1e6f}', ['\u{1e6e}', '\0', '\0']), ('\u{1e71}',
+        ['\u{1e70}', '\0', '\0']), ('\u{1e73}', ['\u{1e72}', '\0', '\0']), ('\u{1e75}', ['\u{1e74}',
+        '\0', '\0']), ('\u{1e77}', ['\u{1e76}', '\0', '\0']), ('\u{1e79}', ['\u{1e78}', '\0',
+        '\0']), ('\u{1e7b}', ['\u{1e7a}', '\0', '\0']), ('\u{1e7d}', ['\u{1e7c}', '\0', '\0']),
+        ('\u{1e7f}', ['\u{1e7e}', '\0', '\0']), ('\u{1e81}', ['\u{1e80}', '\0', '\0']), ('\u{1e83}',
+        ['\u{1e82}', '\0', '\0']), ('\u{1e85}', ['\u{1e84}', '\0', '\0']), ('\u{1e87}', ['\u{1e86}',
+        '\0', '\0']), ('\u{1e89}', ['\u{1e88}', '\0', '\0']), ('\u{1e8b}', ['\u{1e8a}', '\0',
+        '\0']), ('\u{1e8d}', ['\u{1e8c}', '\0', '\0']), ('\u{1e8f}', ['\u{1e8e}', '\0', '\0']),
+        ('\u{1e91}', ['\u{1e90}', '\0', '\0']), ('\u{1e93}', ['\u{1e92}', '\0', '\0']), ('\u{1e95}',
+        ['\u{1e94}', '\0', '\0']), ('\u{1e96}', ['\u{48}', '\u{331}', '\0']), ('\u{1e97}',
+        ['\u{54}', '\u{308}', '\0']), ('\u{1e98}', ['\u{57}', '\u{30a}', '\0']), ('\u{1e99}',
+        ['\u{59}', '\u{30a}', '\0']), ('\u{1e9a}', ['\u{41}', '\u{2be}', '\0']), ('\u{1e9b}',
+        ['\u{1e60}', '\0', '\0']), ('\u{1ea1}', ['\u{1ea0}', '\0', '\0']), ('\u{1ea3}', ['\u{1ea2}',
+        '\0', '\0']), ('\u{1ea5}', ['\u{1ea4}', '\0', '\0']), ('\u{1ea7}', ['\u{1ea6}', '\0',
+        '\0']), ('\u{1ea9}', ['\u{1ea8}', '\0', '\0']), ('\u{1eab}', ['\u{1eaa}', '\0', '\0']),
+        ('\u{1ead}', ['\u{1eac}', '\0', '\0']), ('\u{1eaf}', ['\u{1eae}', '\0', '\0']), ('\u{1eb1}',
+        ['\u{1eb0}', '\0', '\0']), ('\u{1eb3}', ['\u{1eb2}', '\0', '\0']), ('\u{1eb5}', ['\u{1eb4}',
+        '\0', '\0']), ('\u{1eb7}', ['\u{1eb6}', '\0', '\0']), ('\u{1eb9}', ['\u{1eb8}', '\0',
+        '\0']), ('\u{1ebb}', ['\u{1eba}', '\0', '\0']), ('\u{1ebd}', ['\u{1ebc}', '\0', '\0']),
+        ('\u{1ebf}', ['\u{1ebe}', '\0', '\0']), ('\u{1ec1}', ['\u{1ec0}', '\0', '\0']), ('\u{1ec3}',
+        ['\u{1ec2}', '\0', '\0']), ('\u{1ec5}', ['\u{1ec4}', '\0', '\0']), ('\u{1ec7}', ['\u{1ec6}',
+        '\0', '\0']), ('\u{1ec9}', ['\u{1ec8}', '\0', '\0']), ('\u{1ecb}', ['\u{1eca}', '\0',
+        '\0']), ('\u{1ecd}', ['\u{1ecc}', '\0', '\0']), ('\u{1ecf}', ['\u{1ece}', '\0', '\0']),
+        ('\u{1ed1}', ['\u{1ed0}', '\0', '\0']), ('\u{1ed3}', ['\u{1ed2}', '\0', '\0']), ('\u{1ed5}',
+        ['\u{1ed4}', '\0', '\0']), ('\u{1ed7}', ['\u{1ed6}', '\0', '\0']), ('\u{1ed9}', ['\u{1ed8}',
+        '\0', '\0']), ('\u{1edb}', ['\u{1eda}', '\0', '\0']), ('\u{1edd}', ['\u{1edc}', '\0',
+        '\0']), ('\u{1edf}', ['\u{1ede}', '\0', '\0']), ('\u{1ee1}', ['\u{1ee0}', '\0', '\0']),
+        ('\u{1ee3}', ['\u{1ee2}', '\0', '\0']), ('\u{1ee5}', ['\u{1ee4}', '\0', '\0']), ('\u{1ee7}',
+        ['\u{1ee6}', '\0', '\0']), ('\u{1ee9}', ['\u{1ee8}', '\0', '\0']), ('\u{1eeb}', ['\u{1eea}',
+        '\0', '\0']), ('\u{1eed}', ['\u{1eec}', '\0', '\0']), ('\u{1eef}', ['\u{1eee}', '\0',
+        '\0']), ('\u{1ef1}', ['\u{1ef0}', '\0', '\0']), ('\u{1ef3}', ['\u{1ef2}', '\0', '\0']),
+        ('\u{1ef5}', ['\u{1ef4}', '\0', '\0']), ('\u{1ef7}', ['\u{1ef6}', '\0', '\0']), ('\u{1ef9}',
+        ['\u{1ef8}', '\0', '\0']), ('\u{1efb}', ['\u{1efa}', '\0', '\0']), ('\u{1efd}', ['\u{1efc}',
+        '\0', '\0']), ('\u{1eff}', ['\u{1efe}', '\0', '\0']), ('\u{1f00}', ['\u{1f08}', '\0',
+        '\0']), ('\u{1f01}', ['\u{1f09}', '\0', '\0']), ('\u{1f02}', ['\u{1f0a}', '\0', '\0']),
+        ('\u{1f03}', ['\u{1f0b}', '\0', '\0']), ('\u{1f04}', ['\u{1f0c}', '\0', '\0']), ('\u{1f05}',
+        ['\u{1f0d}', '\0', '\0']), ('\u{1f06}', ['\u{1f0e}', '\0', '\0']), ('\u{1f07}', ['\u{1f0f}',
+        '\0', '\0']), ('\u{1f10}', ['\u{1f18}', '\0', '\0']), ('\u{1f11}', ['\u{1f19}', '\0',
+        '\0']), ('\u{1f12}', ['\u{1f1a}', '\0', '\0']), ('\u{1f13}', ['\u{1f1b}', '\0', '\0']),
+        ('\u{1f14}', ['\u{1f1c}', '\0', '\0']), ('\u{1f15}', ['\u{1f1d}', '\0', '\0']), ('\u{1f20}',
+        ['\u{1f28}', '\0', '\0']), ('\u{1f21}', ['\u{1f29}', '\0', '\0']), ('\u{1f22}', ['\u{1f2a}',
+        '\0', '\0']), ('\u{1f23}', ['\u{1f2b}', '\0', '\0']), ('\u{1f24}', ['\u{1f2c}', '\0',
+        '\0']), ('\u{1f25}', ['\u{1f2d}', '\0', '\0']), ('\u{1f26}', ['\u{1f2e}', '\0', '\0']),
+        ('\u{1f27}', ['\u{1f2f}', '\0', '\0']), ('\u{1f30}', ['\u{1f38}', '\0', '\0']), ('\u{1f31}',
+        ['\u{1f39}', '\0', '\0']), ('\u{1f32}', ['\u{1f3a}', '\0', '\0']), ('\u{1f33}', ['\u{1f3b}',
+        '\0', '\0']), ('\u{1f34}', ['\u{1f3c}', '\0', '\0']), ('\u{1f35}', ['\u{1f3d}', '\0',
+        '\0']), ('\u{1f36}', ['\u{1f3e}', '\0', '\0']), ('\u{1f37}', ['\u{1f3f}', '\0', '\0']),
+        ('\u{1f40}', ['\u{1f48}', '\0', '\0']), ('\u{1f41}', ['\u{1f49}', '\0', '\0']), ('\u{1f42}',
+        ['\u{1f4a}', '\0', '\0']), ('\u{1f43}', ['\u{1f4b}', '\0', '\0']), ('\u{1f44}', ['\u{1f4c}',
+        '\0', '\0']), ('\u{1f45}', ['\u{1f4d}', '\0', '\0']), ('\u{1f50}', ['\u{3a5}', '\u{313}',
+        '\0']), ('\u{1f51}', ['\u{1f59}', '\0', '\0']), ('\u{1f52}', ['\u{3a5}', '\u{313}',
+        '\u{300}']), ('\u{1f53}', ['\u{1f5b}', '\0', '\0']), ('\u{1f54}', ['\u{3a5}', '\u{313}',
+        '\u{301}']), ('\u{1f55}', ['\u{1f5d}', '\0', '\0']), ('\u{1f56}', ['\u{3a5}', '\u{313}',
+        '\u{342}']), ('\u{1f57}', ['\u{1f5f}', '\0', '\0']), ('\u{1f60}', ['\u{1f68}', '\0', '\0']),
+        ('\u{1f61}', ['\u{1f69}', '\0', '\0']), ('\u{1f62}', ['\u{1f6a}', '\0', '\0']), ('\u{1f63}',
+        ['\u{1f6b}', '\0', '\0']), ('\u{1f64}', ['\u{1f6c}', '\0', '\0']), ('\u{1f65}', ['\u{1f6d}',
+        '\0', '\0']), ('\u{1f66}', ['\u{1f6e}', '\0', '\0']), ('\u{1f67}', ['\u{1f6f}', '\0',
+        '\0']), ('\u{1f70}', ['\u{1fba}', '\0', '\0']), ('\u{1f71}', ['\u{1fbb}', '\0', '\0']),
+        ('\u{1f72}', ['\u{1fc8}', '\0', '\0']), ('\u{1f73}', ['\u{1fc9}', '\0', '\0']), ('\u{1f74}',
+        ['\u{1fca}', '\0', '\0']), ('\u{1f75}', ['\u{1fcb}', '\0', '\0']), ('\u{1f76}', ['\u{1fda}',
+        '\0', '\0']), ('\u{1f77}', ['\u{1fdb}', '\0', '\0']), ('\u{1f78}', ['\u{1ff8}', '\0',
+        '\0']), ('\u{1f79}', ['\u{1ff9}', '\0', '\0']), ('\u{1f7a}', ['\u{1fea}', '\0', '\0']),
+        ('\u{1f7b}', ['\u{1feb}', '\0', '\0']), ('\u{1f7c}', ['\u{1ffa}', '\0', '\0']), ('\u{1f7d}',
+        ['\u{1ffb}', '\0', '\0']), ('\u{1f80}', ['\u{1f88}', '\0', '\0']), ('\u{1f81}', ['\u{1f89}',
+        '\0', '\0']), ('\u{1f82}', ['\u{1f8a}', '\0', '\0']), ('\u{1f83}', ['\u{1f8b}', '\0',
+        '\0']), ('\u{1f84}', ['\u{1f8c}', '\0', '\0']), ('\u{1f85}', ['\u{1f8d}', '\0', '\0']),
+        ('\u{1f86}', ['\u{1f8e}', '\0', '\0']), ('\u{1f87}', ['\u{1f8f}', '\0', '\0']), ('\u{1f90}',
+        ['\u{1f98}', '\0', '\0']), ('\u{1f91}', ['\u{1f99}', '\0', '\0']), ('\u{1f92}', ['\u{1f9a}',
+        '\0', '\0']), ('\u{1f93}', ['\u{1f9b}', '\0', '\0']), ('\u{1f94}', ['\u{1f9c}', '\0',
+        '\0']), ('\u{1f95}', ['\u{1f9d}', '\0', '\0']), ('\u{1f96}', ['\u{1f9e}', '\0', '\0']),
+        ('\u{1f97}', ['\u{1f9f}', '\0', '\0']), ('\u{1fa0}', ['\u{1fa8}', '\0', '\0']), ('\u{1fa1}',
+        ['\u{1fa9}', '\0', '\0']), ('\u{1fa2}', ['\u{1faa}', '\0', '\0']), ('\u{1fa3}', ['\u{1fab}',
+        '\0', '\0']), ('\u{1fa4}', ['\u{1fac}', '\0', '\0']), ('\u{1fa5}', ['\u{1fad}', '\0',
+        '\0']), ('\u{1fa6}', ['\u{1fae}', '\0', '\0']), ('\u{1fa7}', ['\u{1faf}', '\0', '\0']),
+        ('\u{1fb0}', ['\u{1fb8}', '\0', '\0']), ('\u{1fb1}', ['\u{1fb9}', '\0', '\0']), ('\u{1fb2}',
+        ['\u{1fba}', '\u{345}', '\0']), ('\u{1fb3}', ['\u{1fbc}', '\0', '\0']), ('\u{1fb4}',
+        ['\u{386}', '\u{345}', '\0']), ('\u{1fb6}', ['\u{391}', '\u{342}', '\0']), ('\u{1fb7}',
+        ['\u{391}', '\u{342}', '\u{345}']), ('\u{1fbe}', ['\u{399}', '\0', '\0']), ('\u{1fc2}',
+        ['\u{1fca}', '\u{345}', '\0']), ('\u{1fc3}', ['\u{1fcc}', '\0', '\0']), ('\u{1fc4}',
+        ['\u{389}', '\u{345}', '\0']), ('\u{1fc6}', ['\u{397}', '\u{342}', '\0']), ('\u{1fc7}',
+        ['\u{397}', '\u{342}', '\u{345}']), ('\u{1fd0}', ['\u{1fd8}', '\0', '\0']), ('\u{1fd1}',
+        ['\u{1fd9}', '\0', '\0']), ('\u{1fd2}', ['\u{399}', '\u{308}', '\u{300}']), ('\u{1fd3}',
+        ['\u{399}', '\u{308}', '\u{301}']), ('\u{1fd6}', ['\u{399}', '\u{342}', '\0']), ('\u{1fd7}',
+        ['\u{399}', '\u{308}', '\u{342}']), ('\u{1fe0}', ['\u{1fe8}', '\0', '\0']), ('\u{1fe1}',
+        ['\u{1fe9}', '\0', '\0']), ('\u{1fe2}', ['\u{3a5}', '\u{308}', '\u{300}']), ('\u{1fe3}',
+        ['\u{3a5}', '\u{308}', '\u{301}']), ('\u{1fe4}', ['\u{3a1}', '\u{313}', '\0']), ('\u{1fe5}',
+        ['\u{1fec}', '\0', '\0']), ('\u{1fe6}', ['\u{3a5}', '\u{342}', '\0']), ('\u{1fe7}',
+        ['\u{3a5}', '\u{308}', '\u{342}']), ('\u{1ff2}', ['\u{1ffa}', '\u{345}', '\0']),
+        ('\u{1ff3}', ['\u{1ffc}', '\0', '\0']), ('\u{1ff4}', ['\u{38f}', '\u{345}', '\0']),
+        ('\u{1ff6}', ['\u{3a9}', '\u{342}', '\0']), ('\u{1ff7}', ['\u{3a9}', '\u{342}', '\u{345}']),
+        ('\u{214e}', ['\u{2132}', '\0', '\0']), ('\u{2170}', ['\u{2160}', '\0', '\0']), ('\u{2171}',
+        ['\u{2161}', '\0', '\0']), ('\u{2172}', ['\u{2162}', '\0', '\0']), ('\u{2173}', ['\u{2163}',
+        '\0', '\0']), ('\u{2174}', ['\u{2164}', '\0', '\0']), ('\u{2175}', ['\u{2165}', '\0',
+        '\0']), ('\u{2176}', ['\u{2166}', '\0', '\0']), ('\u{2177}', ['\u{2167}', '\0', '\0']),
+        ('\u{2178}', ['\u{2168}', '\0', '\0']), ('\u{2179}', ['\u{2169}', '\0', '\0']), ('\u{217a}',
+        ['\u{216a}', '\0', '\0']), ('\u{217b}', ['\u{216b}', '\0', '\0']), ('\u{217c}', ['\u{216c}',
+        '\0', '\0']), ('\u{217d}', ['\u{216d}', '\0', '\0']), ('\u{217e}', ['\u{216e}', '\0',
+        '\0']), ('\u{217f}', ['\u{216f}', '\0', '\0']), ('\u{2184}', ['\u{2183}', '\0', '\0']),
+        ('\u{24d0}', ['\u{24b6}', '\0', '\0']), ('\u{24d1}', ['\u{24b7}', '\0', '\0']), ('\u{24d2}',
+        ['\u{24b8}', '\0', '\0']), ('\u{24d3}', ['\u{24b9}', '\0', '\0']), ('\u{24d4}', ['\u{24ba}',
+        '\0', '\0']), ('\u{24d5}', ['\u{24bb}', '\0', '\0']), ('\u{24d6}', ['\u{24bc}', '\0',
+        '\0']), ('\u{24d7}', ['\u{24bd}', '\0', '\0']), ('\u{24d8}', ['\u{24be}', '\0', '\0']),
+        ('\u{24d9}', ['\u{24bf}', '\0', '\0']), ('\u{24da}', ['\u{24c0}', '\0', '\0']), ('\u{24db}',
+        ['\u{24c1}', '\0', '\0']), ('\u{24dc}', ['\u{24c2}', '\0', '\0']), ('\u{24dd}', ['\u{24c3}',
+        '\0', '\0']), ('\u{24de}', ['\u{24c4}', '\0', '\0']), ('\u{24df}', ['\u{24c5}', '\0',
+        '\0']), ('\u{24e0}', ['\u{24c6}', '\0', '\0']), ('\u{24e1}', ['\u{24c7}', '\0', '\0']),
+        ('\u{24e2}', ['\u{24c8}', '\0', '\0']), ('\u{24e3}', ['\u{24c9}', '\0', '\0']), ('\u{24e4}',
+        ['\u{24ca}', '\0', '\0']), ('\u{24e5}', ['\u{24cb}', '\0', '\0']), ('\u{24e6}', ['\u{24cc}',
+        '\0', '\0']), ('\u{24e7}', ['\u{24cd}', '\0', '\0']), ('\u{24e8}', ['\u{24ce}', '\0',
+        '\0']), ('\u{24e9}', ['\u{24cf}', '\0', '\0']), ('\u{2c30}', ['\u{2c00}', '\0', '\0']),
+        ('\u{2c31}', ['\u{2c01}', '\0', '\0']), ('\u{2c32}', ['\u{2c02}', '\0', '\0']), ('\u{2c33}',
+        ['\u{2c03}', '\0', '\0']), ('\u{2c34}', ['\u{2c04}', '\0', '\0']), ('\u{2c35}', ['\u{2c05}',
+        '\0', '\0']), ('\u{2c36}', ['\u{2c06}', '\0', '\0']), ('\u{2c37}', ['\u{2c07}', '\0',
+        '\0']), ('\u{2c38}', ['\u{2c08}', '\0', '\0']), ('\u{2c39}', ['\u{2c09}', '\0', '\0']),
+        ('\u{2c3a}', ['\u{2c0a}', '\0', '\0']), ('\u{2c3b}', ['\u{2c0b}', '\0', '\0']), ('\u{2c3c}',
+        ['\u{2c0c}', '\0', '\0']), ('\u{2c3d}', ['\u{2c0d}', '\0', '\0']), ('\u{2c3e}', ['\u{2c0e}',
+        '\0', '\0']), ('\u{2c3f}', ['\u{2c0f}', '\0', '\0']), ('\u{2c40}', ['\u{2c10}', '\0',
+        '\0']), ('\u{2c41}', ['\u{2c11}', '\0', '\0']), ('\u{2c42}', ['\u{2c12}', '\0', '\0']),
+        ('\u{2c43}', ['\u{2c13}', '\0', '\0']), ('\u{2c44}', ['\u{2c14}', '\0', '\0']), ('\u{2c45}',
+        ['\u{2c15}', '\0', '\0']), ('\u{2c46}', ['\u{2c16}', '\0', '\0']), ('\u{2c47}', ['\u{2c17}',
+        '\0', '\0']), ('\u{2c48}', ['\u{2c18}', '\0', '\0']), ('\u{2c49}', ['\u{2c19}', '\0',
+        '\0']), ('\u{2c4a}', ['\u{2c1a}', '\0', '\0']), ('\u{2c4b}', ['\u{2c1b}', '\0', '\0']),
+        ('\u{2c4c}', ['\u{2c1c}', '\0', '\0']), ('\u{2c4d}', ['\u{2c1d}', '\0', '\0']), ('\u{2c4e}',
+        ['\u{2c1e}', '\0', '\0']), ('\u{2c4f}', ['\u{2c1f}', '\0', '\0']), ('\u{2c50}', ['\u{2c20}',
+        '\0', '\0']), ('\u{2c51}', ['\u{2c21}', '\0', '\0']), ('\u{2c52}', ['\u{2c22}', '\0',
+        '\0']), ('\u{2c53}', ['\u{2c23}', '\0', '\0']), ('\u{2c54}', ['\u{2c24}', '\0', '\0']),
+        ('\u{2c55}', ['\u{2c25}', '\0', '\0']), ('\u{2c56}', ['\u{2c26}', '\0', '\0']), ('\u{2c57}',
+        ['\u{2c27}', '\0', '\0']), ('\u{2c58}', ['\u{2c28}', '\0', '\0']), ('\u{2c59}', ['\u{2c29}',
+        '\0', '\0']), ('\u{2c5a}', ['\u{2c2a}', '\0', '\0']), ('\u{2c5b}', ['\u{2c2b}', '\0',
+        '\0']), ('\u{2c5c}', ['\u{2c2c}', '\0', '\0']), ('\u{2c5d}', ['\u{2c2d}', '\0', '\0']),
+        ('\u{2c5e}', ['\u{2c2e}', '\0', '\0']), ('\u{2c61}', ['\u{2c60}', '\0', '\0']), ('\u{2c65}',
+        ['\u{23a}', '\0', '\0']), ('\u{2c66}', ['\u{23e}', '\0', '\0']), ('\u{2c68}', ['\u{2c67}',
+        '\0', '\0']), ('\u{2c6a}', ['\u{2c69}', '\0', '\0']), ('\u{2c6c}', ['\u{2c6b}', '\0',
+        '\0']), ('\u{2c73}', ['\u{2c72}', '\0', '\0']), ('\u{2c76}', ['\u{2c75}', '\0', '\0']),
+        ('\u{2c81}', ['\u{2c80}', '\0', '\0']), ('\u{2c83}', ['\u{2c82}', '\0', '\0']), ('\u{2c85}',
+        ['\u{2c84}', '\0', '\0']), ('\u{2c87}', ['\u{2c86}', '\0', '\0']), ('\u{2c89}', ['\u{2c88}',
+        '\0', '\0']), ('\u{2c8b}', ['\u{2c8a}', '\0', '\0']), ('\u{2c8d}', ['\u{2c8c}', '\0',
+        '\0']), ('\u{2c8f}', ['\u{2c8e}', '\0', '\0']), ('\u{2c91}', ['\u{2c90}', '\0', '\0']),
+        ('\u{2c93}', ['\u{2c92}', '\0', '\0']), ('\u{2c95}', ['\u{2c94}', '\0', '\0']), ('\u{2c97}',
+        ['\u{2c96}', '\0', '\0']), ('\u{2c99}', ['\u{2c98}', '\0', '\0']), ('\u{2c9b}', ['\u{2c9a}',
+        '\0', '\0']), ('\u{2c9d}', ['\u{2c9c}', '\0', '\0']), ('\u{2c9f}', ['\u{2c9e}', '\0',
+        '\0']), ('\u{2ca1}', ['\u{2ca0}', '\0', '\0']), ('\u{2ca3}', ['\u{2ca2}', '\0', '\0']),
+        ('\u{2ca5}', ['\u{2ca4}', '\0', '\0']), ('\u{2ca7}', ['\u{2ca6}', '\0', '\0']), ('\u{2ca9}',
+        ['\u{2ca8}', '\0', '\0']), ('\u{2cab}', ['\u{2caa}', '\0', '\0']), ('\u{2cad}', ['\u{2cac}',
+        '\0', '\0']), ('\u{2caf}', ['\u{2cae}', '\0', '\0']), ('\u{2cb1}', ['\u{2cb0}', '\0',
+        '\0']), ('\u{2cb3}', ['\u{2cb2}', '\0', '\0']), ('\u{2cb5}', ['\u{2cb4}', '\0', '\0']),
+        ('\u{2cb7}', ['\u{2cb6}', '\0', '\0']), ('\u{2cb9}', ['\u{2cb8}', '\0', '\0']), ('\u{2cbb}',
+        ['\u{2cba}', '\0', '\0']), ('\u{2cbd}', ['\u{2cbc}', '\0', '\0']), ('\u{2cbf}', ['\u{2cbe}',
+        '\0', '\0']), ('\u{2cc1}', ['\u{2cc0}', '\0', '\0']), ('\u{2cc3}', ['\u{2cc2}', '\0',
+        '\0']), ('\u{2cc5}', ['\u{2cc4}', '\0', '\0']), ('\u{2cc7}', ['\u{2cc6}', '\0', '\0']),
+        ('\u{2cc9}', ['\u{2cc8}', '\0', '\0']), ('\u{2ccb}', ['\u{2cca}', '\0', '\0']), ('\u{2ccd}',
+        ['\u{2ccc}', '\0', '\0']), ('\u{2ccf}', ['\u{2cce}', '\0', '\0']), ('\u{2cd1}', ['\u{2cd0}',
+        '\0', '\0']), ('\u{2cd3}', ['\u{2cd2}', '\0', '\0']), ('\u{2cd5}', ['\u{2cd4}', '\0',
+        '\0']), ('\u{2cd7}', ['\u{2cd6}', '\0', '\0']), ('\u{2cd9}', ['\u{2cd8}', '\0', '\0']),
+        ('\u{2cdb}', ['\u{2cda}', '\0', '\0']), ('\u{2cdd}', ['\u{2cdc}', '\0', '\0']), ('\u{2cdf}',
+        ['\u{2cde}', '\0', '\0']), ('\u{2ce1}', ['\u{2ce0}', '\0', '\0']), ('\u{2ce3}', ['\u{2ce2}',
+        '\0', '\0']), ('\u{2cec}', ['\u{2ceb}', '\0', '\0']), ('\u{2cee}', ['\u{2ced}', '\0',
+        '\0']), ('\u{2cf3}', ['\u{2cf2}', '\0', '\0']), ('\u{2d00}', ['\u{10a0}', '\0', '\0']),
+        ('\u{2d01}', ['\u{10a1}', '\0', '\0']), ('\u{2d02}', ['\u{10a2}', '\0', '\0']), ('\u{2d03}',
+        ['\u{10a3}', '\0', '\0']), ('\u{2d04}', ['\u{10a4}', '\0', '\0']), ('\u{2d05}', ['\u{10a5}',
+        '\0', '\0']), ('\u{2d06}', ['\u{10a6}', '\0', '\0']), ('\u{2d07}', ['\u{10a7}', '\0',
+        '\0']), ('\u{2d08}', ['\u{10a8}', '\0', '\0']), ('\u{2d09}', ['\u{10a9}', '\0', '\0']),
+        ('\u{2d0a}', ['\u{10aa}', '\0', '\0']), ('\u{2d0b}', ['\u{10ab}', '\0', '\0']), ('\u{2d0c}',
+        ['\u{10ac}', '\0', '\0']), ('\u{2d0d}', ['\u{10ad}', '\0', '\0']), ('\u{2d0e}', ['\u{10ae}',
+        '\0', '\0']), ('\u{2d0f}', ['\u{10af}', '\0', '\0']), ('\u{2d10}', ['\u{10b0}', '\0',
+        '\0']), ('\u{2d11}', ['\u{10b1}', '\0', '\0']), ('\u{2d12}', ['\u{10b2}', '\0', '\0']),
+        ('\u{2d13}', ['\u{10b3}', '\0', '\0']), ('\u{2d14}', ['\u{10b4}', '\0', '\0']), ('\u{2d15}',
+        ['\u{10b5}', '\0', '\0']), ('\u{2d16}', ['\u{10b6}', '\0', '\0']), ('\u{2d17}', ['\u{10b7}',
+        '\0', '\0']), ('\u{2d18}', ['\u{10b8}', '\0', '\0']), ('\u{2d19}', ['\u{10b9}', '\0',
+        '\0']), ('\u{2d1a}', ['\u{10ba}', '\0', '\0']), ('\u{2d1b}', ['\u{10bb}', '\0', '\0']),
+        ('\u{2d1c}', ['\u{10bc}', '\0', '\0']), ('\u{2d1d}', ['\u{10bd}', '\0', '\0']), ('\u{2d1e}',
+        ['\u{10be}', '\0', '\0']), ('\u{2d1f}', ['\u{10bf}', '\0', '\0']), ('\u{2d20}', ['\u{10c0}',
+        '\0', '\0']), ('\u{2d21}', ['\u{10c1}', '\0', '\0']), ('\u{2d22}', ['\u{10c2}', '\0',
+        '\0']), ('\u{2d23}', ['\u{10c3}', '\0', '\0']), ('\u{2d24}', ['\u{10c4}', '\0', '\0']),
+        ('\u{2d25}', ['\u{10c5}', '\0', '\0']), ('\u{2d27}', ['\u{10c7}', '\0', '\0']), ('\u{2d2d}',
+        ['\u{10cd}', '\0', '\0']), ('\u{a641}', ['\u{a640}', '\0', '\0']), ('\u{a643}', ['\u{a642}',
+        '\0', '\0']), ('\u{a645}', ['\u{a644}', '\0', '\0']), ('\u{a647}', ['\u{a646}', '\0',
+        '\0']), ('\u{a649}', ['\u{a648}', '\0', '\0']), ('\u{a64b}', ['\u{a64a}', '\0', '\0']),
+        ('\u{a64d}', ['\u{a64c}', '\0', '\0']), ('\u{a64f}', ['\u{a64e}', '\0', '\0']), ('\u{a651}',
+        ['\u{a650}', '\0', '\0']), ('\u{a653}', ['\u{a652}', '\0', '\0']), ('\u{a655}', ['\u{a654}',
+        '\0', '\0']), ('\u{a657}', ['\u{a656}', '\0', '\0']), ('\u{a659}', ['\u{a658}', '\0',
+        '\0']), ('\u{a65b}', ['\u{a65a}', '\0', '\0']), ('\u{a65d}', ['\u{a65c}', '\0', '\0']),
+        ('\u{a65f}', ['\u{a65e}', '\0', '\0']), ('\u{a661}', ['\u{a660}', '\0', '\0']), ('\u{a663}',
+        ['\u{a662}', '\0', '\0']), ('\u{a665}', ['\u{a664}', '\0', '\0']), ('\u{a667}', ['\u{a666}',
+        '\0', '\0']), ('\u{a669}', ['\u{a668}', '\0', '\0']), ('\u{a66b}', ['\u{a66a}', '\0',
+        '\0']), ('\u{a66d}', ['\u{a66c}', '\0', '\0']), ('\u{a681}', ['\u{a680}', '\0', '\0']),
+        ('\u{a683}', ['\u{a682}', '\0', '\0']), ('\u{a685}', ['\u{a684}', '\0', '\0']), ('\u{a687}',
+        ['\u{a686}', '\0', '\0']), ('\u{a689}', ['\u{a688}', '\0', '\0']), ('\u{a68b}', ['\u{a68a}',
+        '\0', '\0']), ('\u{a68d}', ['\u{a68c}', '\0', '\0']), ('\u{a68f}', ['\u{a68e}', '\0',
+        '\0']), ('\u{a691}', ['\u{a690}', '\0', '\0']), ('\u{a693}', ['\u{a692}', '\0', '\0']),
+        ('\u{a695}', ['\u{a694}', '\0', '\0']), ('\u{a697}', ['\u{a696}', '\0', '\0']), ('\u{a699}',
+        ['\u{a698}', '\0', '\0']), ('\u{a69b}', ['\u{a69a}', '\0', '\0']), ('\u{a723}', ['\u{a722}',
+        '\0', '\0']), ('\u{a725}', ['\u{a724}', '\0', '\0']), ('\u{a727}', ['\u{a726}', '\0',
+        '\0']), ('\u{a729}', ['\u{a728}', '\0', '\0']), ('\u{a72b}', ['\u{a72a}', '\0', '\0']),
+        ('\u{a72d}', ['\u{a72c}', '\0', '\0']), ('\u{a72f}', ['\u{a72e}', '\0', '\0']), ('\u{a733}',
+        ['\u{a732}', '\0', '\0']), ('\u{a735}', ['\u{a734}', '\0', '\0']), ('\u{a737}', ['\u{a736}',
+        '\0', '\0']), ('\u{a739}', ['\u{a738}', '\0', '\0']), ('\u{a73b}', ['\u{a73a}', '\0',
+        '\0']), ('\u{a73d}', ['\u{a73c}', '\0', '\0']), ('\u{a73f}', ['\u{a73e}', '\0', '\0']),
+        ('\u{a741}', ['\u{a740}', '\0', '\0']), ('\u{a743}', ['\u{a742}', '\0', '\0']), ('\u{a745}',
+        ['\u{a744}', '\0', '\0']), ('\u{a747}', ['\u{a746}', '\0', '\0']), ('\u{a749}', ['\u{a748}',
+        '\0', '\0']), ('\u{a74b}', ['\u{a74a}', '\0', '\0']), ('\u{a74d}', ['\u{a74c}', '\0',
+        '\0']), ('\u{a74f}', ['\u{a74e}', '\0', '\0']), ('\u{a751}', ['\u{a750}', '\0', '\0']),
+        ('\u{a753}', ['\u{a752}', '\0', '\0']), ('\u{a755}', ['\u{a754}', '\0', '\0']), ('\u{a757}',
+        ['\u{a756}', '\0', '\0']), ('\u{a759}', ['\u{a758}', '\0', '\0']), ('\u{a75b}', ['\u{a75a}',
+        '\0', '\0']), ('\u{a75d}', ['\u{a75c}', '\0', '\0']), ('\u{a75f}', ['\u{a75e}', '\0',
+        '\0']), ('\u{a761}', ['\u{a760}', '\0', '\0']), ('\u{a763}', ['\u{a762}', '\0', '\0']),
+        ('\u{a765}', ['\u{a764}', '\0', '\0']), ('\u{a767}', ['\u{a766}', '\0', '\0']), ('\u{a769}',
+        ['\u{a768}', '\0', '\0']), ('\u{a76b}', ['\u{a76a}', '\0', '\0']), ('\u{a76d}', ['\u{a76c}',
+        '\0', '\0']), ('\u{a76f}', ['\u{a76e}', '\0', '\0']), ('\u{a77a}', ['\u{a779}', '\0',
+        '\0']), ('\u{a77c}', ['\u{a77b}', '\0', '\0']), ('\u{a77f}', ['\u{a77e}', '\0', '\0']),
+        ('\u{a781}', ['\u{a780}', '\0', '\0']), ('\u{a783}', ['\u{a782}', '\0', '\0']), ('\u{a785}',
+        ['\u{a784}', '\0', '\0']), ('\u{a787}', ['\u{a786}', '\0', '\0']), ('\u{a78c}', ['\u{a78b}',
+        '\0', '\0']), ('\u{a791}', ['\u{a790}', '\0', '\0']), ('\u{a793}', ['\u{a792}', '\0',
+        '\0']), ('\u{a797}', ['\u{a796}', '\0', '\0']), ('\u{a799}', ['\u{a798}', '\0', '\0']),
+        ('\u{a79b}', ['\u{a79a}', '\0', '\0']), ('\u{a79d}', ['\u{a79c}', '\0', '\0']), ('\u{a79f}',
+        ['\u{a79e}', '\0', '\0']), ('\u{a7a1}', ['\u{a7a0}', '\0', '\0']), ('\u{a7a3}', ['\u{a7a2}',
+        '\0', '\0']), ('\u{a7a5}', ['\u{a7a4}', '\0', '\0']), ('\u{a7a7}', ['\u{a7a6}', '\0',
+        '\0']), ('\u{a7a9}', ['\u{a7a8}', '\0', '\0']), ('\u{fb00}', ['\u{46}', '\u{66}', '\0']),
+        ('\u{fb01}', ['\u{46}', '\u{69}', '\0']), ('\u{fb02}', ['\u{46}', '\u{6c}', '\0']),
+        ('\u{fb03}', ['\u{46}', '\u{66}', '\u{69}']), ('\u{fb04}', ['\u{46}', '\u{66}', '\u{6c}']),
+        ('\u{fb05}', ['\u{53}', '\u{74}', '\0']), ('\u{fb06}', ['\u{53}', '\u{74}', '\0']),
+        ('\u{fb13}', ['\u{544}', '\u{576}', '\0']), ('\u{fb14}', ['\u{544}', '\u{565}', '\0']),
+        ('\u{fb15}', ['\u{544}', '\u{56b}', '\0']), ('\u{fb16}', ['\u{54e}', '\u{576}', '\0']),
+        ('\u{fb17}', ['\u{544}', '\u{56d}', '\0']), ('\u{ff41}', ['\u{ff21}', '\0', '\0']),
+        ('\u{ff42}', ['\u{ff22}', '\0', '\0']), ('\u{ff43}', ['\u{ff23}', '\0', '\0']), ('\u{ff44}',
+        ['\u{ff24}', '\0', '\0']), ('\u{ff45}', ['\u{ff25}', '\0', '\0']), ('\u{ff46}', ['\u{ff26}',
+        '\0', '\0']), ('\u{ff47}', ['\u{ff27}', '\0', '\0']), ('\u{ff48}', ['\u{ff28}', '\0',
+        '\0']), ('\u{ff49}', ['\u{ff29}', '\0', '\0']), ('\u{ff4a}', ['\u{ff2a}', '\0', '\0']),
+        ('\u{ff4b}', ['\u{ff2b}', '\0', '\0']), ('\u{ff4c}', ['\u{ff2c}', '\0', '\0']), ('\u{ff4d}',
+        ['\u{ff2d}', '\0', '\0']), ('\u{ff4e}', ['\u{ff2e}', '\0', '\0']), ('\u{ff4f}', ['\u{ff2f}',
+        '\0', '\0']), ('\u{ff50}', ['\u{ff30}', '\0', '\0']), ('\u{ff51}', ['\u{ff31}', '\0',
+        '\0']), ('\u{ff52}', ['\u{ff32}', '\0', '\0']), ('\u{ff53}', ['\u{ff33}', '\0', '\0']),
+        ('\u{ff54}', ['\u{ff34}', '\0', '\0']), ('\u{ff55}', ['\u{ff35}', '\0', '\0']), ('\u{ff56}',
+        ['\u{ff36}', '\0', '\0']), ('\u{ff57}', ['\u{ff37}', '\0', '\0']), ('\u{ff58}', ['\u{ff38}',
+        '\0', '\0']), ('\u{ff59}', ['\u{ff39}', '\0', '\0']), ('\u{ff5a}', ['\u{ff3a}', '\0',
+        '\0']), ('\u{10428}', ['\u{10400}', '\0', '\0']), ('\u{10429}', ['\u{10401}', '\0', '\0']),
+        ('\u{1042a}', ['\u{10402}', '\0', '\0']), ('\u{1042b}', ['\u{10403}', '\0', '\0']),
+        ('\u{1042c}', ['\u{10404}', '\0', '\0']), ('\u{1042d}', ['\u{10405}', '\0', '\0']),
+        ('\u{1042e}', ['\u{10406}', '\0', '\0']), ('\u{1042f}', ['\u{10407}', '\0', '\0']),
+        ('\u{10430}', ['\u{10408}', '\0', '\0']), ('\u{10431}', ['\u{10409}', '\0', '\0']),
+        ('\u{10432}', ['\u{1040a}', '\0', '\0']), ('\u{10433}', ['\u{1040b}', '\0', '\0']),
+        ('\u{10434}', ['\u{1040c}', '\0', '\0']), ('\u{10435}', ['\u{1040d}', '\0', '\0']),
+        ('\u{10436}', ['\u{1040e}', '\0', '\0']), ('\u{10437}', ['\u{1040f}', '\0', '\0']),
+        ('\u{10438}', ['\u{10410}', '\0', '\0']), ('\u{10439}', ['\u{10411}', '\0', '\0']),
+        ('\u{1043a}', ['\u{10412}', '\0', '\0']), ('\u{1043b}', ['\u{10413}', '\0', '\0']),
+        ('\u{1043c}', ['\u{10414}', '\0', '\0']), ('\u{1043d}', ['\u{10415}', '\0', '\0']),
+        ('\u{1043e}', ['\u{10416}', '\0', '\0']), ('\u{1043f}', ['\u{10417}', '\0', '\0']),
+        ('\u{10440}', ['\u{10418}', '\0', '\0']), ('\u{10441}', ['\u{10419}', '\0', '\0']),
+        ('\u{10442}', ['\u{1041a}', '\0', '\0']), ('\u{10443}', ['\u{1041b}', '\0', '\0']),
+        ('\u{10444}', ['\u{1041c}', '\0', '\0']), ('\u{10445}', ['\u{1041d}', '\0', '\0']),
+        ('\u{10446}', ['\u{1041e}', '\0', '\0']), ('\u{10447}', ['\u{1041f}', '\0', '\0']),
+        ('\u{10448}', ['\u{10420}', '\0', '\0']), ('\u{10449}', ['\u{10421}', '\0', '\0']),
+        ('\u{1044a}', ['\u{10422}', '\0', '\0']), ('\u{1044b}', ['\u{10423}', '\0', '\0']),
+        ('\u{1044c}', ['\u{10424}', '\0', '\0']), ('\u{1044d}', ['\u{10425}', '\0', '\0']),
+        ('\u{1044e}', ['\u{10426}', '\0', '\0']), ('\u{1044f}', ['\u{10427}', '\0', '\0']),
+        ('\u{118c0}', ['\u{118a0}', '\0', '\0']), ('\u{118c1}', ['\u{118a1}', '\0', '\0']),
+        ('\u{118c2}', ['\u{118a2}', '\0', '\0']), ('\u{118c3}', ['\u{118a3}', '\0', '\0']),
+        ('\u{118c4}', ['\u{118a4}', '\0', '\0']), ('\u{118c5}', ['\u{118a5}', '\0', '\0']),
+        ('\u{118c6}', ['\u{118a6}', '\0', '\0']), ('\u{118c7}', ['\u{118a7}', '\0', '\0']),
+        ('\u{118c8}', ['\u{118a8}', '\0', '\0']), ('\u{118c9}', ['\u{118a9}', '\0', '\0']),
+        ('\u{118ca}', ['\u{118aa}', '\0', '\0']), ('\u{118cb}', ['\u{118ab}', '\0', '\0']),
+        ('\u{118cc}', ['\u{118ac}', '\0', '\0']), ('\u{118cd}', ['\u{118ad}', '\0', '\0']),
+        ('\u{118ce}', ['\u{118ae}', '\0', '\0']), ('\u{118cf}', ['\u{118af}', '\0', '\0']),
+        ('\u{118d0}', ['\u{118b0}', '\0', '\0']), ('\u{118d1}', ['\u{118b1}', '\0', '\0']),
+        ('\u{118d2}', ['\u{118b2}', '\0', '\0']), ('\u{118d3}', ['\u{118b3}', '\0', '\0']),
+        ('\u{118d4}', ['\u{118b4}', '\0', '\0']), ('\u{118d5}', ['\u{118b5}', '\0', '\0']),
+        ('\u{118d6}', ['\u{118b6}', '\0', '\0']), ('\u{118d7}', ['\u{118b7}', '\0', '\0']),
+        ('\u{118d8}', ['\u{118b8}', '\0', '\0']), ('\u{118d9}', ['\u{118b9}', '\0', '\0']),
+        ('\u{118da}', ['\u{118ba}', '\0', '\0']), ('\u{118db}', ['\u{118bb}', '\0', '\0']),
+        ('\u{118dc}', ['\u{118bc}', '\0', '\0']), ('\u{118dd}', ['\u{118bd}', '\0', '\0']),
+        ('\u{118de}', ['\u{118be}', '\0', '\0']), ('\u{118df}', ['\u{118bf}', '\0', '\0'])
     ];
 
 }
@@ -4603,7 +5682,7 @@ pub fn grapheme_category(c: char) -> GraphemeCat {
     }
 
     const grapheme_cat_table: &'static [(char, char, GraphemeCat)] = &[
-        ('\u{0}', '\u{1f}', GC_Control), ('\u{7f}', '\u{9f}', GC_Control), ('\u{ad}', '\u{ad}',
+        ('\0', '\u{1f}', GC_Control), ('\u{7f}', '\u{9f}', GC_Control), ('\u{ad}', '\u{ad}',
         GC_Control), ('\u{300}', '\u{36f}', GC_Extend), ('\u{483}', '\u{489}', GC_Extend),
         ('\u{591}', '\u{5bd}', GC_Extend), ('\u{5bf}', '\u{5bf}', GC_Extend), ('\u{5c1}', '\u{5c2}',
         GC_Extend), ('\u{5c4}', '\u{5c5}', GC_Extend), ('\u{5c7}', '\u{5c7}', GC_Extend),
index 0be8570f904835875ba883c47360f12bf6d37c93..af0c3a1c02aa1fee2574c763c863a10c084f87bb 100644 (file)
@@ -55,7 +55,7 @@
 
 /// A stable identifier to the particular version of JSON output.
 /// Increment this when the `Crate` and related structures change.
-pub static SCHEMA_VERSION: &'static str = "0.8.3";
+pub const SCHEMA_VERSION: &'static str = "0.8.3";
 
 mod inline;
 mod simplify;
@@ -2521,7 +2521,7 @@ fn lit_to_string(lit: &ast::Lit) -> String {
         ast::LitStr(ref st, _) => st.to_string(),
         ast::LitBinary(ref data) => format!("{:?}", data),
         ast::LitByte(b) => {
-            let mut res = String::from_str("b'");
+            let mut res = String::from("b'");
             for c in (b as char).escape_default() {
                 res.push(c);
             }
index 3929630267ac1469513dd543d23377e421dd4c0d..9439fc3c5f405ffedf729376462f0dc3f5c491e6 100644 (file)
@@ -335,8 +335,7 @@ fn resolved_path(w: &mut fmt::Formatter, did: ast::DefId, path: &clean::Path,
     if print_all {
         let amt = path.segments.len() - 1;
         match rel_root {
-            Some(root) => {
-                let mut root = String::from_str(&root);
+            Some(mut root) => {
                 for seg in &path.segments[..amt] {
                     if "super" == seg.name || "self" == seg.name {
                         try!(write!(w, "{}::", seg.name));
index c4f2c7207ac39520aa2aa72da7db49df88812572..cbf521840ae2788e7bef9cc593a3fae3048637f7 100644 (file)
@@ -817,7 +817,7 @@ fn emit_source(&mut self, filename: &str) -> io::Result<()> {
 
         // Create the intermediate directories
         let mut cur = self.dst.clone();
-        let mut root_path = String::from_str("../../");
+        let mut root_path = String::from("../../");
         clean_srcpath(&self.cx.src_root, &p, false, |component| {
             cur.push(component);
             mkdir(&cur).unwrap();
@@ -2284,7 +2284,7 @@ fn render_assoc_items(w: &mut fmt::Formatter,
         }
         try!(write!(w, "<h2 id='implementations'>Trait \
                           Implementations</h2>"));
-        let (derived, manual): (Vec<_>, _) = traits.iter().partition(|i| {
+        let (derived, manual): (Vec<_>, Vec<&Impl>) = traits.iter().partition(|i| {
             i.impl_.derived
         });
         for i in &manual {
index 93aa74d7005f6d8989cbae865218d8d421165596..8f3e63820dac9ca30382c143a562278539b9e0b8 100644 (file)
@@ -145,7 +145,7 @@ pub fn push<'a>(&'a mut self, level: u32, name: String, id: String) -> &'a str {
                     (0, &self.top_level)
                 }
                 Some(entry) => {
-                    sec_number = String::from_str(&entry.sec_number);
+                    sec_number = entry.sec_number.clone();
                     sec_number.push_str(".");
                     (entry.level, &entry.children)
                 }
index d4d214f449d5921733ca9c2c9c9140e23b02fd9b..e48651a154eb067ecbfb7990c1c04c6b0ac17484 100644 (file)
@@ -90,7 +90,7 @@ fn libname(mut n: String) -> String {
 
 #[cfg(all(not(target_os="windows"), not(target_os="macos")))]
 fn libname(n: String) -> String {
-    let mut i = String::from_str("lib");
+    let mut i = String::from("lib");
     i.push_str(&n);
     i.push_str(".so");
     i
index 24cc7fe878af471ff13af8c73e9127175bce8402..0096d8d22ae8a1827f43d558713873e86f281976 100644 (file)
@@ -457,7 +457,7 @@ fn spaces(wr: &mut fmt::Write, mut n: usize) -> EncodeResult {
 
 fn fmt_number_or_null(v: f64) -> string::String {
     match v.classify() {
-        Fp::Nan | Fp::Infinite => string::String::from_str("null"),
+        Fp::Nan | Fp::Infinite => string::String::from("null"),
         _ if v.fract() != 0f64 => v.to_string(),
         _ => v.to_string() + ".0",
     }
index 6d23df970000cab16ce5dbfa8473788abcb16875..328c75b6d9e20b92097a1f8af038b7242ab99f08 100644 (file)
@@ -121,7 +121,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, 'b> From<&'b str> for Box<Error + Send + Sync + 'a> {
     fn from(err: &'b str) -> Box<Error + Send + Sync + 'a> {
-        From::from(String::from_str(err))
+        From::from(String::from(err))
     }
 }
 
index cffccab7e09d00b57dda169e8c009d54b5c13e81..36854db63a303ca21b28081e9816a69ecd5c8498 100644 (file)
@@ -483,7 +483,7 @@ fn multiple_connect_serial_ip4() {
 
     #[test]
     fn multiple_connect_interleaved_greedy_schedule() {
-        static MAX: usize = 10;
+        const MAX: usize = 10;
         each_ip(&mut |addr| {
             let acceptor = t!(TcpListener::bind(&addr));
 
@@ -890,7 +890,7 @@ fn debug() {
                               socket_addr, name, listener_inner);
         assert_eq!(format!("{:?}", listener), compare);
 
-        let mut stream = t!(TcpStream::connect(&("localhost",
+        let stream = t!(TcpStream::connect(&("localhost",
                                                  socket_addr.port())));
         let stream_inner = stream.0.socket().as_inner();
         let compare = format!("TcpStream {{ addr: {:?}, \
index 42d9ad81b598aac8cdd23d6afd2cac1a75901b35..ee7cf009fc4d94b7266dcf4de462a4beaf8359cb 100644 (file)
@@ -268,7 +268,7 @@ fn spawn_inner(&self, default_io: StdioImp) -> io::Result<Child> {
 
     /// Executes the command as a child process, returning a handle to it.
     ///
-    /// By default, stdin, stdout and stderr are inherited by the parent.
+    /// By default, stdin, stdout and stderr are inherited from the parent.
     #[stable(feature = "process", since = "1.0.0")]
     pub fn spawn(&mut self) -> io::Result<Child> {
         self.spawn_inner(StdioImp::Raw(imp::Stdio::Inherit))
@@ -300,7 +300,7 @@ pub fn output(&mut self) -> io::Result<Output> {
     /// Executes a command as a child process, waiting for it to finish and
     /// collecting its exit status.
     ///
-    /// By default, stdin, stdout and stderr are inherited by the parent.
+    /// By default, stdin, stdout and stderr are inherited from the parent.
     ///
     /// # Examples
     ///
index 580d970af0c3da3d77a1a484da9c7497ea085e93..00932712a07a436c2526c75ced2ea6931944054c 100644 (file)
@@ -27,7 +27,7 @@
 // 2. For each element of the path, emit the length plus the element
 // 3. End the path with "E"
 //
-// For example, "_ZN4testE" => "test" and "_ZN3foo3bar" => "foo::bar".
+// For example, "_ZN4testE" => "test" and "_ZN3foo3barE" => "foo::bar".
 //
 // We're the ones printing our backtraces, so we can't rely on anything else to
 // demangle our symbols. It's *much* nicer to look at demangled symbols, so
index 72f8453233a4108ffffca4d6dfa0eb4b3bf754dc..8f41646417367632637c6fa9798b39968ebee271 100644 (file)
@@ -187,7 +187,7 @@ fn is_mutex() {
             assert_eq!(*lock.borrow(), 4950);
         });
         for i in 0..100 {
-            let mut lock = m.lock().unwrap();
+            let lock = m.lock().unwrap();
             *lock.borrow_mut() += i;
         }
         drop(lock);
index cb9239ed7ba57032fb320a6614d68adac27ee1b3..b2dc01e3ccb199a52c0af28ee8052f66f0fc70e8 100644 (file)
@@ -906,8 +906,8 @@ fn wtf8buf_from_str() {
 
     #[test]
     fn wtf8buf_from_string() {
-        assert_eq!(Wtf8Buf::from_string(String::from_str("")).bytes, b"");
-        assert_eq!(Wtf8Buf::from_string(String::from_str("aé 💩")).bytes,
+        assert_eq!(Wtf8Buf::from_string(String::from("")).bytes, b"");
+        assert_eq!(Wtf8Buf::from_string(String::from("aé 💩")).bytes,
                    b"a\xC3\xA9 \xF0\x9F\x92\xA9");
     }
 
@@ -1049,7 +1049,7 @@ fn wtf8buf_truncate_fail_longer() {
     #[test]
     fn wtf8buf_into_string() {
         let mut string = Wtf8Buf::from_str("aé 💩");
-        assert_eq!(string.clone().into_string(), Ok(String::from_str("aé 💩")));
+        assert_eq!(string.clone().into_string(), Ok(String::from("aé 💩")));
         string.push(CodePoint::from_u32(0xD800).unwrap());
         assert_eq!(string.clone().into_string(), Err(string));
     }
@@ -1057,9 +1057,9 @@ fn wtf8buf_into_string() {
     #[test]
     fn wtf8buf_into_string_lossy() {
         let mut string = Wtf8Buf::from_str("aé 💩");
-        assert_eq!(string.clone().into_string_lossy(), String::from_str("aé 💩"));
+        assert_eq!(string.clone().into_string_lossy(), String::from("aé 💩"));
         string.push(CodePoint::from_u32(0xD800).unwrap());
-        assert_eq!(string.clone().into_string_lossy(), String::from_str("aé 💩�"));
+        assert_eq!(string.clone().into_string_lossy(), String::from("aé 💩�"));
     }
 
     #[test]
@@ -1226,7 +1226,7 @@ fn wtf8_to_string_lossy() {
         assert_eq!(Wtf8::from_str("aé 💩").to_string_lossy(), Cow::Borrowed("aé 💩"));
         let mut string = Wtf8Buf::from_str("aé 💩");
         string.push(CodePoint::from_u32(0xD800).unwrap());
-        let expected: Cow<str> = Cow::Owned(String::from_str("aé 💩�"));
+        let expected: Cow<str> = Cow::Owned(String::from("aé 💩�"));
         assert_eq!(string.to_string_lossy(), expected);
     }
 
index aaffe8dadf87298e760c4ee7610e0a1ee7a082fb..28d9b3e047633fd53c83d0a2b78d529a200cbc37 100644 (file)
 pub trait OpenOptionsExt {
     /// Overrides the `dwDesiredAccess` argument to the call to `CreateFile`
     /// with the specified value.
-    fn desired_access(&mut self, access: i32) -> &mut Self;
+    fn desired_access(&mut self, access: u32) -> &mut Self;
 
     /// Overrides the `dwCreationDisposition` argument to the call to
     /// `CreateFile` with the specified value.
     ///
     /// This will override any values of the standard `create` flags, for
     /// example.
-    fn creation_disposition(&mut self, val: i32) -> &mut Self;
+    fn creation_disposition(&mut self, val: u32) -> &mut Self;
 
     /// Overrides the `dwFlagsAndAttributes` argument to the call to
     /// `CreateFile` with the specified value.
     ///
     /// This will override any values of the standard flags on the
     /// `OpenOptions` structure.
-    fn flags_and_attributes(&mut self, val: i32) -> &mut Self;
+    fn flags_and_attributes(&mut self, val: u32) -> &mut Self;
 
     /// Overrides the `dwShareMode` argument to the call to `CreateFile` with
     /// the specified value.
     ///
     /// This will override any values of the standard flags on the
     /// `OpenOptions` structure.
-    fn share_mode(&mut self, val: i32) -> &mut Self;
+    fn share_mode(&mut self, val: u32) -> &mut Self;
 }
 
 impl OpenOptionsExt for OpenOptions {
-    fn desired_access(&mut self, access: i32) -> &mut OpenOptions {
+    fn desired_access(&mut self, access: u32) -> &mut OpenOptions {
         self.as_inner_mut().desired_access(access); self
     }
-    fn creation_disposition(&mut self, access: i32) -> &mut OpenOptions {
+    fn creation_disposition(&mut self, access: u32) -> &mut OpenOptions {
         self.as_inner_mut().creation_disposition(access); self
     }
-    fn flags_and_attributes(&mut self, access: i32) -> &mut OpenOptions {
+    fn flags_and_attributes(&mut self, access: u32) -> &mut OpenOptions {
         self.as_inner_mut().flags_and_attributes(access); self
     }
-    fn share_mode(&mut self, access: i32) -> &mut OpenOptions {
+    fn share_mode(&mut self, access: u32) -> &mut OpenOptions {
         self.as_inner_mut().share_mode(access); self
     }
 }
index 03a56e2958a6e9f485b050323ac42274b744b9eb..4401a52d71fff3c119c148706282c540bcad614e 100644 (file)
@@ -158,17 +158,17 @@ pub fn new() -> OpenOptions { Default::default() }
     pub fn append(&mut self, append: bool) { self.append = append; }
     pub fn create(&mut self, create: bool) { self.create = create; }
     pub fn truncate(&mut self, truncate: bool) { self.truncate = truncate; }
-    pub fn creation_disposition(&mut self, val: i32) {
-        self.creation_disposition = Some(val as libc::DWORD);
+    pub fn creation_disposition(&mut self, val: u32) {
+        self.creation_disposition = Some(val);
     }
-    pub fn flags_and_attributes(&mut self, val: i32) {
-        self.flags_and_attributes = Some(val as libc::DWORD);
+    pub fn flags_and_attributes(&mut self, val: u32) {
+        self.flags_and_attributes = Some(val);
     }
-    pub fn desired_access(&mut self, val: i32) {
-        self.desired_access = Some(val as libc::DWORD);
+    pub fn desired_access(&mut self, val: u32) {
+        self.desired_access = Some(val);
     }
-    pub fn share_mode(&mut self, val: i32) {
-        self.share_mode = Some(val as libc::DWORD);
+    pub fn share_mode(&mut self, val: u32) {
+        self.share_mode = Some(val);
     }
     pub fn security_attributes(&mut self, attrs: libc::LPSECURITY_ATTRIBUTES) {
         self.security_attributes = attrs as usize;
@@ -221,7 +221,7 @@ impl File {
     fn open_reparse_point(path: &Path) -> io::Result<File> {
         let mut opts = OpenOptions::new();
         opts.read(true);
-        opts.flags_and_attributes(c::FILE_FLAG_OPEN_REPARSE_POINT as i32);
+        opts.flags_and_attributes(c::FILE_FLAG_OPEN_REPARSE_POINT);
         File::open(path, &opts)
     }
 
index 620ac1280f48c3f037307eec668cd78b2f4bdadd..54b09d863a33aad15265b72a190f28bce7ff973d 100644 (file)
@@ -200,9 +200,8 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
             ident: name.clone(),
             attrs: Vec::new(),
             id: ast::DUMMY_NODE_ID,
-            node: ast::ItemStatic(
+            node: ast::ItemConst(
                 ty,
-                ast::MutImmutable,
                 expr,
             ),
             vis: ast::Public,
index 4fe5ab1554500877aa1e2f99e00b62d93d65ebab..86e72d4ef03de4350d46ac4f95e49a01fcf65aaf 100644 (file)
@@ -452,6 +452,7 @@ fn static_array(ecx: &mut ExtCtxt,
             Some(ecx.lifetime(sp, special_idents::static_lifetime.name)),
             ast::MutImmutable);
         let slice = ecx.expr_vec_slice(sp, pieces);
+        // static instead of const to speed up codegen by not requiring this to be inlined
         let st = ast::ItemStatic(ty, ast::MutImmutable, slice);
 
         let name = ecx.ident_of(name);
index 420b27b83957b57c7606050d5ccc178cf6a0c455..dcf6667b606440f14538db9bf20249c5db3f731a 100644 (file)
@@ -3394,7 +3394,10 @@ fn parse_let(&mut self) -> PResult<P<Decl>> {
     /// Parse a structure field
     fn parse_name_and_ty(&mut self, pr: Visibility,
                          attrs: Vec<Attribute> ) -> PResult<StructField> {
-        let lo = self.span.lo;
+        let lo = match pr {
+            Inherited => self.span.lo,
+            Public => self.last_span.lo,
+        };
         if !self.token.is_plain_ident() {
             return Err(self.fatal("expected ident"));
         }
index da86e727c6874bb028e9de02c705462fbf88a708..5ea843918be5f1a4c495d60dea0a6cefbd7dbc5b 100644 (file)
@@ -127,7 +127,7 @@ enum NamePadding {
 
 impl TestDesc {
     fn padded_name(&self, column_count: usize, align: NamePadding) -> String {
-        let mut name = String::from_str(self.name.as_slice());
+        let mut name = String::from(self.name.as_slice());
         let fill = column_count.saturating_sub(name.len());
         let pad = repeat(" ").take(fill).collect::<String>();
         match align {
@@ -625,17 +625,44 @@ pub fn write_run_finish(&mut self) -> io::Result<bool> {
     }
 }
 
+// Format a number with thousands separators
+fn fmt_thousands_sep(mut n: usize, sep: char) -> String {
+    use std::fmt::Write;
+    let mut output = String::new();
+    let mut first = true;
+    for &pow in &[9, 6, 3, 0] {
+        let base = 10_usize.pow(pow);
+        if pow == 0 || n / base != 0 {
+            if first {
+                output.write_fmt(format_args!("{}", n / base)).unwrap();
+            } else {
+                output.write_fmt(format_args!("{:03}", n / base)).unwrap();
+            }
+            if pow != 0 {
+                output.push(sep);
+            }
+            first = false;
+        }
+        n %= base;
+    }
+
+    output
+}
+
 pub fn fmt_bench_samples(bs: &BenchSamples) -> String {
+    use std::fmt::Write;
+    let mut output = String::new();
+
+    let median = bs.ns_iter_summ.median as usize;
+    let deviation = (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as usize;
+
+    output.write_fmt(format_args!("{:>11} ns/iter (+/- {})",
+                     fmt_thousands_sep(median, ','),
+                     fmt_thousands_sep(deviation, ','))).unwrap();
     if bs.mb_s != 0 {
-        format!("{:>9} ns/iter (+/- {}) = {} MB/s",
-             bs.ns_iter_summ.median as usize,
-             (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as usize,
-             bs.mb_s)
-    } else {
-        format!("{:>9} ns/iter (+/- {})",
-             bs.ns_iter_summ.median as usize,
-             (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as usize)
+        output.write_fmt(format_args!(" = {} MB/s", bs.mb_s)).unwrap();
     }
+    output
 }
 
 // A simple console test runner
index 31c973214a1c944aac7d567dd312eb2fe693e45c..5ffb9b007d041394789b684228afeada4c46116c 100644 (file)
@@ -59,7 +59,7 @@ fn walk_item(item: &BookItem,
 
         try!(writeln!(out, "<li><a {} href='{}'><b>{}</b> {}</a>",
                  class_string,
-                 item.path_to_root.join(&item.path.with_extension("html")).display(),
+                 current_page.path_to_root.join(&item.path).with_extension("html").display(),
                  section,
                  item.title));
         if !item.children.is_empty() {
index 7e0630fd242d39c83dfff871136a8d0118950208..e37ede82bb5604b623cd5accee0468915b22ae42 100644 (file)
@@ -16,22 +16,31 @@ using namespace llvm;
 using namespace llvm::sys;
 using namespace llvm::object;
 
+// libmorestack is not used on Windows
+#ifndef _WIN32
+extern "C" void __morestack(void);
+
+static void* morestack_addr() {
+    return reinterpret_cast<void*>(__morestack);
+}
+#endif
+
 class RustJITMemoryManager : public SectionMemoryManager
 {
     typedef SectionMemoryManager Base;
 
-    const void *morestack;
-
     public:
 
-    RustJITMemoryManager(const void *morestack_ptr)
-        : morestack(morestack_ptr)
-        {}
+    RustJITMemoryManager() {}
 
     uint64_t getSymbolAddress(const std::string &Name) override
     {
+#ifndef _WIN32
         if (Name == "__morestack" || Name == "___morestack")
-            return reinterpret_cast<uint64_t>(morestack);
+            return reinterpret_cast<uint64_t>(__morestack);
+        if (Name == "__morestack_addr" || Name == "___morestack_addr")
+            return reinterpret_cast<uint64_t>(morestack_addr);
+#endif
 
         return Base::getSymbolAddress(Name);
     }
@@ -39,11 +48,6 @@ class RustJITMemoryManager : public SectionMemoryManager
 
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(RustJITMemoryManager, LLVMRustJITMemoryManagerRef)
 
-extern "C" LLVMRustJITMemoryManagerRef LLVMRustCreateJITMemoryManager(void *morestack)
-{
-    return wrap(new RustJITMemoryManager(morestack));
-}
-
 extern "C" LLVMBool LLVMRustLoadDynamicLibrary(const char *path)
 {
     std::string err;
@@ -60,6 +64,13 @@ extern "C" LLVMBool LLVMRustLoadDynamicLibrary(const char *path)
 extern "C" void LLVMExecutionEngineAddModule(
     LLVMExecutionEngineRef eeref, LLVMModuleRef mref)
 {
+#ifdef _WIN32
+    // On Windows, MCJIT must generate ELF objects
+    std::string target = getProcessTriple();
+    target += "-elf";
+    target = Triple::normalize(target);
+    unwrap(mref)->setTargetTriple(target);
+#endif
     LLVMAddModule(eeref, mref);
 }
 
@@ -74,27 +85,36 @@ extern "C" LLVMBool LLVMExecutionEngineRemoveModule(
     return ee->removeModule(m);
 }
 
-extern "C" LLVMExecutionEngineRef LLVMBuildExecutionEngine(
-    LLVMModuleRef mod, LLVMRustJITMemoryManagerRef mref)
+extern "C" LLVMExecutionEngineRef LLVMBuildExecutionEngine(LLVMModuleRef mod)
 {
     // These are necessary for code generation to work properly.
     InitializeNativeTarget();
     InitializeNativeTargetAsmPrinter();
     InitializeNativeTargetAsmParser();
 
+#ifdef _WIN32
+    // On Windows, MCJIT must generate ELF objects
+    std::string target = getProcessTriple();
+    target += "-elf";
+    target = Triple::normalize(target);
+    unwrap(mod)->setTargetTriple(target);
+#endif
+
     std::string error_str;
     TargetOptions options;
 
     options.JITEmitDebugInfo = true;
     options.NoFramePointerElim = true;
 
+    RustJITMemoryManager *mm = new RustJITMemoryManager;
+
     ExecutionEngine *ee =
     #if LLVM_VERSION_MINOR >= 6
         EngineBuilder(std::unique_ptr<Module>(unwrap(mod)))
-            .setMCJITMemoryManager(std::unique_ptr<RustJITMemoryManager>(unwrap(mref)))
+            .setMCJITMemoryManager(std::unique_ptr<RustJITMemoryManager>(mm))
     #else
         EngineBuilder(unwrap(mod))
-            .setMCJITMemoryManager(unwrap(mref))
+            .setMCJITMemoryManager(mm)
     #endif
             .setEngineKind(EngineKind::JIT)
             .setErrorStr(&error_str)
index 66db7326d21bf45c94d586cb7f4cd94998365e32..ad6533e5480b1f349794a1c77859ca135db60e7a 100644 (file)
@@ -233,10 +233,18 @@ DIT unwrapDI(LLVMMetadataRef ref) {
     return DIT(ref ? unwrap<MDNode>(ref) : NULL);
 }
 
-extern "C" const uint32_t LLVMRustDebugMetadataVersion() {
+extern "C" uint32_t LLVMRustDebugMetadataVersion() {
     return DEBUG_METADATA_VERSION;
 }
 
+extern "C" uint32_t LLVMVersionMinor() {
+  return LLVM_VERSION_MINOR;
+}
+
+extern "C" uint32_t LLVMVersionMajor() {
+  return LLVM_VERSION_MAJOR;
+}
+
 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M,
                                       const char *name,
                                       uint32_t value) {
index 8a4330acf43417e831690e9f564207685de03e5e..bb82c0c818677607252355e6e119cdccec3bf383 100644 (file)
 #include "llvm/IR/DIBuilder.h"
 #include "llvm/Linker/Linker.h"
 
-// Used by RustMCJITMemoryManager::getPointerToNamedFunction()
-// to get around glibc issues. See the function for more information.
-#ifdef __linux__
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#endif
-
 void LLVMRustSetLastError(const char*);
 
 typedef struct OpaqueRustString *RustStringRef;
index 38ba652f53bc3931678e33b31ec1b92b8bafbd11..c35c9255ed28e8353928d9d1a92e348578166ec3 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: unresolved name `m1::a`. Did you mean `args`?
+// error-pattern: unresolved name `m1::arguments`. Did you mean `arguments`?
 
 mod m1 {}
 
-fn main(args: Vec<String>) { log(debug, m1::a); }
+fn main(arguments: Vec<String>) { log(debug, m1::arguments); }
index f397d0b387da5d4fa538d53983de57ab621aeba6..af34887dec954fda455c740c5d55984cad3a586e 100644 (file)
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: unresolved name `m1::a`. Did you mean `args`?
+// error-pattern: unresolved name `m1::arguments`. Did you mean `arguments`?
 
 mod m1 {
-    pub mod a {}
+    pub mod arguments {}
 }
 
-fn main(args: Vec<String>) {
-    log(debug, m1::a);
+fn main(arguments: Vec<String>) {
+    log(debug, m1::arguments);
 }
diff --git a/src/test/compile-fail/pub-struct-field-span-26083.rs b/src/test/compile-fail/pub-struct-field-span-26083.rs
new file mode 100644 (file)
index 0000000..0dc7e09
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 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.
+
+// Regression test for issue #26083
+// Test that span for public struct fields start at `pub` instead of the identifier
+
+struct Foo {
+    pub bar: u8,
+
+    pub
+    //~^ error: field `bar` is already declared [E0124]
+    bar: u8,
+
+    pub bar:
+    //~^ error: field `bar` is already declared [E0124]
+    u8,
+
+    bar:
+    //~^ error: field `bar` is already declared [E0124]
+    u8,
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/typo-suggestion.rs b/src/test/compile-fail/typo-suggestion.rs
new file mode 100644 (file)
index 0000000..d5cf6a2
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2014 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.
+
+fn main() {
+    let foo = 1;
+
+    // `foo` shouldn't be suggested, it is too dissimilar from `bar`.
+    println!("Hello {}", bar);
+    //~^ ERROR: unresolved name `bar`
+
+    // But this is close enough.
+    println!("Hello {}", fob);
+    //~^ ERROR: unresolved name `fob`. Did you mean `foo`?
+}
index 56a973fa59f668398eff78903937e9d810046630..fbf28259949c06bbb415ee2d8e85dbd5c3c57ef7 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-test also broken on nightly linux distcheck. it's just broken!
 // ignore-windows failing on win32 bot
 // ignore-freebsd: output doesn't match
 // ignore-tidy-linelength
diff --git a/src/test/run-make/execution-engine/Makefile b/src/test/run-make/execution-engine/Makefile
new file mode 100644 (file)
index 0000000..387905f
--- /dev/null
@@ -0,0 +1,8 @@
+-include ../tools.mk
+
+# This is a basic test of LLVM ExecutionEngine functionality using compiled
+# Rust code built using the `rustc` crate.
+
+all:
+       $(RUSTC) test.rs
+       $(call RUN,test $(RUSTC))
diff --git a/src/test/run-make/execution-engine/test.rs b/src/test/run-make/execution-engine/test.rs
new file mode 100644 (file)
index 0000000..ba6d0d2
--- /dev/null
@@ -0,0 +1,249 @@
+// Copyright 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.
+
+#![feature(rustc_private)]
+
+extern crate rustc;
+extern crate rustc_driver;
+extern crate rustc_lint;
+extern crate rustc_resolve;
+extern crate syntax;
+
+use std::ffi::{CStr, CString};
+use std::mem::transmute;
+use std::path::PathBuf;
+use std::thread::Builder;
+
+use rustc::llvm;
+use rustc::metadata::cstore::RequireDynamic;
+use rustc::middle::ty;
+use rustc::session::config::{self, basic_options, build_configuration, Input, Options};
+use rustc::session::build_session;
+use rustc_driver::driver;
+use rustc_resolve::MakeGlobMap;
+
+use syntax::ast_map;
+use syntax::diagnostics::registry::Registry;
+
+fn main() {
+    let program = r#"
+    #[no_mangle]
+    pub static TEST_STATIC: i32 = 42;
+    "#;
+
+    let program2 = r#"
+    #[no_mangle]
+    pub fn test_add(a: i32, b: i32) -> i32 { a + b }
+    "#;
+
+    let mut path = match std::env::args().nth(2) {
+        Some(path) => PathBuf::from(&path),
+        None => panic!("missing rustc path")
+    };
+
+    // Remove two segments from rustc path to get sysroot.
+    path.pop();
+    path.pop();
+
+    let mut ee = ExecutionEngine::new(program, path);
+
+    let test_static = match ee.get_global("TEST_STATIC") {
+        Some(g) => g as *const i32,
+        None => panic!("failed to get global")
+    };
+
+    assert_eq!(unsafe { *test_static }, 42);
+
+    ee.add_module(program2);
+
+    let test_add: fn(i32, i32) -> i32;
+
+    test_add = match ee.get_function("test_add") {
+        Some(f) => unsafe { transmute(f) },
+        None => panic!("failed to get function")
+    };
+
+    assert_eq!(test_add(1, 2), 3);
+}
+
+struct ExecutionEngine {
+    ee: llvm::ExecutionEngineRef,
+    modules: Vec<llvm::ModuleRef>,
+    sysroot: PathBuf,
+}
+
+impl ExecutionEngine {
+    pub fn new(program: &str, sysroot: PathBuf) -> ExecutionEngine {
+        let (llmod, deps) = compile_program(program, sysroot.clone())
+            .expect("failed to compile program");
+
+        let ee = unsafe { llvm::LLVMBuildExecutionEngine(llmod) };
+
+        if ee.is_null() {
+            panic!("Failed to create ExecutionEngine: {}", llvm_error());
+        }
+
+        let ee = ExecutionEngine{
+            ee: ee,
+            modules: vec![llmod],
+            sysroot: sysroot,
+        };
+
+        ee.load_deps(&deps);
+        ee
+    }
+
+    pub fn add_module(&mut self, program: &str) {
+        let (llmod, deps) = compile_program(program, self.sysroot.clone())
+            .expect("failed to compile program in add_module");
+
+        unsafe { llvm::LLVMExecutionEngineAddModule(self.ee, llmod); }
+
+        self.modules.push(llmod);
+        self.load_deps(&deps);
+    }
+
+    /// Returns a raw pointer to the named function.
+    pub fn get_function(&mut self, name: &str) -> Option<*const ()> {
+        let s = CString::new(name.as_bytes()).unwrap();
+
+        for &m in &self.modules {
+            let fv = unsafe { llvm::LLVMGetNamedFunction(m, s.as_ptr()) };
+
+            if !fv.is_null() {
+                let fp = unsafe { llvm::LLVMGetPointerToGlobal(self.ee, fv) };
+
+                assert!(!fp.is_null());
+                return Some(fp);
+            }
+        }
+        None
+    }
+
+    /// Returns a raw pointer to the named global item.
+    pub fn get_global(&mut self, name: &str) -> Option<*const ()> {
+        let s = CString::new(name.as_bytes()).unwrap();
+
+        for &m in &self.modules {
+            let gv = unsafe { llvm::LLVMGetNamedGlobal(m, s.as_ptr()) };
+
+            if !gv.is_null() {
+                let gp = unsafe { llvm::LLVMGetPointerToGlobal(self.ee, gv) };
+
+                assert!(!gp.is_null());
+                return Some(gp);
+            }
+        }
+        None
+    }
+
+    /// Loads all dependencies of compiled code.
+    /// Expects a series of paths to dynamic library files.
+    fn load_deps(&self, deps: &[PathBuf]) {
+        for path in deps {
+            let s = match path.as_os_str().to_str() {
+                Some(s) => s,
+                None => panic!(
+                    "Could not convert crate path to UTF-8 string: {:?}", path)
+            };
+            let cs = CString::new(s).unwrap();
+
+            let res = unsafe { llvm::LLVMRustLoadDynamicLibrary(cs.as_ptr()) };
+
+            if res == 0 {
+                panic!("Failed to load crate {:?}: {}",
+                    path.display(), llvm_error());
+            }
+        }
+    }
+}
+
+impl Drop for ExecutionEngine {
+    fn drop(&mut self) {
+        unsafe { llvm::LLVMDisposeExecutionEngine(self.ee) };
+    }
+}
+
+/// Returns last error from LLVM wrapper code.
+fn llvm_error() -> String {
+    String::from_utf8_lossy(
+        unsafe { CStr::from_ptr(llvm::LLVMRustGetLastError()).to_bytes() })
+        .into_owned()
+}
+
+fn build_exec_options(sysroot: PathBuf) -> Options {
+    let mut opts = basic_options();
+
+    // librustc derives sysroot from the executable name.
+    // Since we are not rustc, we must specify it.
+    opts.maybe_sysroot = Some(sysroot);
+
+    // Prefer faster build time
+    opts.optimize = config::No;
+
+    // Don't require a `main` function
+    opts.crate_types = vec![config::CrateTypeDylib];
+
+    opts
+}
+
+/// Compiles input up to phase 4, translation to LLVM.
+///
+/// Returns the LLVM `ModuleRef` and a series of paths to dynamic libraries
+/// for crates used in the given input.
+fn compile_program(input: &str, sysroot: PathBuf)
+                   -> Option<(llvm::ModuleRef, Vec<PathBuf>)> {
+    let input = Input::Str(input.to_string());
+    let thread = Builder::new().name("compile_program".to_string());
+
+    let handle = thread.spawn(move || {
+        let opts = build_exec_options(sysroot);
+        let sess = build_session(opts, None, Registry::new(&rustc::DIAGNOSTICS));
+        rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
+
+        let cfg = build_configuration(&sess);
+
+        let id = "input".to_string();
+
+        let krate = driver::phase_1_parse_input(&sess, cfg, &input);
+
+        let krate = driver::phase_2_configure_and_expand(&sess, krate, &id, None)
+            .expect("phase_2 returned `None`");
+
+        let mut forest = ast_map::Forest::new(krate);
+        let arenas = ty::CtxtArenas::new();
+        let ast_map = driver::assign_node_ids_and_map(&sess, &mut forest);
+
+        let analysis = driver::phase_3_run_analysis_passes(
+            sess, ast_map, &arenas, id, MakeGlobMap::No);
+
+        let (tcx, trans) = driver::phase_4_translate_to_llvm(analysis);
+
+        let crates = tcx.sess.cstore.get_used_crates(RequireDynamic);
+
+        // Collect crates used in the session.
+        // Reverse order finds dependencies first.
+        let deps = crates.into_iter().rev()
+            .filter_map(|(_, p)| p).collect();
+
+        assert_eq!(trans.modules.len(), 1);
+        let llmod = trans.modules[0].llmod;
+
+        // Workaround because raw pointers do not impl Send
+        let modp = llmod as usize;
+
+        (modp, deps)
+    }).unwrap();
+
+    match handle.join() {
+        Ok((llmod, deps)) => Some((llmod as llvm::ModuleRef, deps)),
+        Err(_) => None
+    }
+}
diff --git a/src/test/run-make/issue-26006/Makefile b/src/test/run-make/issue-26006/Makefile
new file mode 100644 (file)
index 0000000..10c789d
--- /dev/null
@@ -0,0 +1,16 @@
+-include ../tools.mk
+
+ifndef IS_WINDOWS
+all: time
+
+time: libc
+       mkdir -p out/time out/time/deps
+       ln -sf out/libc/liblibc.rlib out/time/deps/
+       $(RUSTC) in/time/lib.rs -Ldependency=out/time/deps/
+
+libc:
+       mkdir -p out/libc
+       $(RUSTC) in/libc/lib.rs --crate-name=libc -o out/libc/liblibc.rlib
+else
+all:
+endif
diff --git a/src/test/run-make/issue-26006/in/libc/lib.rs b/src/test/run-make/issue-26006/in/libc/lib.rs
new file mode 100644 (file)
index 0000000..177ffdc
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 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.
+#![crate_type="rlib"]
+
+pub fn something(){}
diff --git a/src/test/run-make/issue-26006/in/time/lib.rs b/src/test/run-make/issue-26006/in/time/lib.rs
new file mode 100644 (file)
index 0000000..b1d07d5
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 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.
+#![feature(libc)]
+extern crate libc;
+
+fn main(){}
index 32e7a6279c858a197970d9c7b6310094d25bf796..67dd4021cb5c8dd65ae347ec635c2858c4bbc6a6 100644 (file)
@@ -12,6 +12,7 @@
 
 #![feature(core)]
 
+use std::cell::RefCell;
 use std::rc::Rc;
 
 trait Baz {
@@ -36,4 +37,8 @@ fn main() {
     assert_eq!(b.get(), 42);
 
     let _c = b.clone();
+
+    let a: Rc<RefCell<i32>> = Rc::new(RefCell::new(42));
+    let b: Rc<RefCell<Baz>> = a.clone();
+    assert_eq!(b.borrow().get(), 42);
 }
index e6e9bf6e6367fabf04e5340592982b3938824b3d..cff431065ffedc951206df31122a9355b17a4043 100644 (file)
@@ -12,7 +12,7 @@
 #![feature(collections)]
 
 fn main() {
-    let mut escaped = String::from_str("");
+    let mut escaped = String::from("");
     for c in '\u{10401}'.escape_unicode() {
         escaped.push(c);
     }
diff --git a/src/test/run-pass/issue-24779.rs b/src/test/run-pass/issue-24779.rs
new file mode 100644 (file)
index 0000000..4f13b91
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 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.
+
+fn main() {
+    assert_eq!((||||42)()(), 42);
+}
index 0013cb292e1c7d87c4914b711910be61dfc55d52..6cc8751c554ca6ce01b6990f745258621e4e8b22 100644 (file)
@@ -41,12 +41,12 @@ fn test_append() {
     s.push_str("a");
     assert_eq!(s, "a");
 
-    let mut s = String::from_str("a");
+    let mut s = String::from("a");
     s.push_str("b");
     println!("{}", s.clone());
     assert_eq!(s, "ab");
 
-    let mut s = String::from_str("c");
+    let mut s = String::from("c");
     s.push_str("offee");
     assert!(s == "coffee");
 
index bfad79e92d2c2c71eb38343ae66d8e83ead6afba..83c2dadcd2f7c35a5d6772c7b3c3ca242c32709b 100644 (file)
@@ -19,7 +19,7 @@ pub fn main() {
     assert_eq!(s, "⨐⨁⪠");
 
     let s = "\\{20}";
-    let mut correct_s = String::from_str("\\");
+    let mut correct_s = String::from("\\");
     correct_s.push_str("{20}");
     assert_eq!(s, correct_s);
 }
index 5e924d015b619ca712aa6101f2c89794d21199a5..ed3ddb43b261734b1911d838e6d68cdde2cccfc2 100644 (file)
@@ -34,7 +34,7 @@ pub fn main() {
     let s = Rc::new("foo".to_string());
     assert_eq!(&**s, "foo");
 
-    let mut_s = Rc::new(RefCell::new(String::from_str("foo")));
+    let mut_s = Rc::new(RefCell::new(String::from("foo")));
     mut_s.borrow_mut().push_str("bar");
     // HACK assert_eq! would panic here because it stores the LHS and RHS in two locals.
     assert!(&**mut_s.borrow() == "foobar");
index 6d8bb30c83755ffd37a5928d6f4ee5ec61ec53d2..3590b7c616cffe37d899e93502300162afecb57b 100644 (file)
@@ -34,7 +34,7 @@ pub fn main() {
     assert_eq!(*s, "foo".to_string());
     assert_eq!((*s), "foo");
 
-    let mut_s = Rc::new(RefCell::new(String::from_str("foo")));
+    let mut_s = Rc::new(RefCell::new(String::from("foo")));
     (*(*mut_s).borrow_mut()).push_str("bar");
     // assert_eq! would panic here because it stores the LHS and RHS in two locals.
     assert!((*(*mut_s).borrow()) == "foobar");
index 7ff770327742baaf8c36e0d24126dda278073581..e4ca5515653cbb5035b19489d385f023a3888a71 100644 (file)
@@ -17,7 +17,7 @@ enum t { a, b(String), }
 
 fn make(i: isize) -> t {
     if i > 10 { return t::a; }
-    let mut s = String::from_str("hello");
+    let mut s = String::from("hello");
     // Ensure s is non-const.
 
     s.push_str("there");