Snap for 10453563 from c42c4eaf61c61127a4c1907f0171b453780fade4 to mainline-os-statsd-release

Change-Id: Ie21f88381692f335501c2842d231d1779e1d2e9a
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 8da2e20..4917a0e 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,6 @@
 {
   "git": {
-    "sha1": "de247d6ac25d2e62d4cbd195f064ed4af35fd4eb"
-  }
-}
+    "sha1": "ef4faeda61024dfb38b3897e46aeda8140828dc6"
+  },
+  "path_in_vcs": ""
+}
\ No newline at end of file
diff --git a/.clippy.toml b/.clippy.toml
index 8e17d80..0a54853 100644
--- a/.clippy.toml
+++ b/.clippy.toml
@@ -1 +1 @@
-msrv = "1.0.0"
+msrv = "1.36.0"
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e0f8585..d16faca 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -5,6 +5,12 @@
   pull_request:
   schedule: [cron: "40 1 * * *"]
 
+permissions:
+  contents: read
+
+env:
+  RUSTFLAGS: -Dwarnings
+
 jobs:
   test:
     name: Rust ${{matrix.rust}}
@@ -12,42 +18,62 @@
     strategy:
       fail-fast: false
       matrix:
-        rust: [nightly, beta, stable, 1.26.0]
+        rust: [nightly, beta, stable, 1.36.0]
+    timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - uses: dtolnay/rust-toolchain@master
         with:
           toolchain: ${{matrix.rust}}
       - run: cargo build
-      - run: cargo build --features i128
-      - run: cargo test --features i128
-      - run: cargo test --features i128 --release
-      - run: cargo build --no-default-features --features i128
-      - run: cargo test --tests --no-default-features --features i128
-      - run: cargo test --tests --no-default-features --features i128 --release
-      - run: cargo bench --no-run --features i128
+      - run: cargo test
+      - run: cargo test --release
+      - run: cargo build --no-default-features
+      - run: cargo test --tests --no-default-features
+      - run: cargo test --tests --no-default-features --release
+      - run: cargo build --tests --features no-panic --release
+        if: matrix.rust == 'nightly'
+      - run: cargo bench --no-run
         if: matrix.rust == 'nightly'
 
-  mintest:
-    name: Rust 1.20.0
+  miri:
+    name: Miri
     runs-on: ubuntu-latest
+    timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v2
-      - uses: dtolnay/rust-toolchain@1.20.0
-      - run: cargo test
-
-  msrv:
-    name: Rust 1.0.0
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v2
-      - uses: dtolnay/rust-toolchain@1.0.0
-      - run: cargo build
+      - uses: actions/checkout@v3
+      - uses: dtolnay/rust-toolchain@miri
+      - run: cargo miri test
+        env:
+          MIRIFLAGS: -Zmiri-strict-provenance
 
   clippy:
     name: Clippy
     runs-on: ubuntu-latest
+    if: github.event_name != 'pull_request'
+    timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - uses: dtolnay/rust-toolchain@clippy
-      - run: cargo clippy -- -Dclippy::all -Dclippy::pedantic
+      - run: cargo clippy --tests --benches -- -Dclippy::all -Dclippy::pedantic
+
+  fuzz:
+    name: Fuzz
+    runs-on: ubuntu-latest
+    timeout-minutes: 45
+    steps:
+      - uses: actions/checkout@v3
+      - uses: dtolnay/rust-toolchain@nightly
+      - uses: dtolnay/install@cargo-fuzz
+      - run: cargo fuzz build -O
+
+  outdated:
+    name: Outdated
+    runs-on: ubuntu-latest
+    if: github.event_name != 'pull_request'
+    timeout-minutes: 45
+    steps:
+      - uses: actions/checkout@v3
+      - uses: dtolnay/install@cargo-outdated
+      - run: cargo outdated --workspace --exit-code 1
+      - run: cargo outdated --manifest-path fuzz/Cargo.toml --exit-code 1
diff --git a/Android.bp b/Android.bp
index 6027693..da9aca2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -43,18 +43,14 @@
     host_supported: true,
     crate_name: "test",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.4.8",
+    cargo_pkg_version: "1.0.5",
     srcs: ["tests/test.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
     test_options: {
         unit_test: true,
     },
-    edition: "2015",
-    features: [
-        "default",
-        "std",
-    ],
+    edition: "2018",
     rustlibs: [
         "libitoa",
     ],
@@ -65,15 +61,13 @@
     host_supported: true,
     crate_name: "itoa",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.4.8",
+    cargo_pkg_version: "1.0.5",
     srcs: ["src/lib.rs"],
-    edition: "2015",
-    features: [
-        "default",
-        "std",
-    ],
+    edition: "2018",
     apex_available: [
         "//apex_available:platform",
         "com.android.virt",
     ],
+    product_available: true,
+    vendor_available: true,
 }
diff --git a/Cargo.toml b/Cargo.toml
index 02b4382..86c10b6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,20 +10,29 @@
 # See Cargo.toml.orig for the original contents.
 
 [package]
+edition = "2018"
+rust-version = "1.36"
 name = "itoa"
-version = "0.4.8"
+version = "1.0.5"
 authors = ["David Tolnay <dtolnay@gmail.com>"]
-exclude = ["performance.png"]
-description = "Fast functions for printing integer primitives to an io::Write"
+exclude = [
+    "performance.png",
+    "chart/**",
+]
+description = "Fast integer primitive to string conversion"
 documentation = "https://docs.rs/itoa"
 readme = "README.md"
-categories = ["value-formatting"]
+keywords = ["integer"]
+categories = [
+    "value-formatting",
+    "no-std",
+]
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/dtolnay/itoa"
+
 [package.metadata.docs.rs]
 targets = ["x86_64-unknown-linux-gnu"]
 
-[features]
-default = ["std"]
-i128 = []
-std = []
+[dependencies.no-panic]
+version = "0.1"
+optional = true
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 2781d7c..a24b8e4 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,19 +1,19 @@
 [package]
 name = "itoa"
-version = "0.4.8" # remember to update html_root_url
+version = "1.0.5" # remember to update html_root_url
 authors = ["David Tolnay <dtolnay@gmail.com>"]
-license = "MIT OR Apache-2.0"
-description = "Fast functions for printing integer primitives to an io::Write"
-repository = "https://github.com/dtolnay/itoa"
+categories = ["value-formatting", "no-std"]
+description = "Fast integer primitive to string conversion"
 documentation = "https://docs.rs/itoa"
-categories = ["value-formatting"]
-readme = "README.md"
-exclude = ["performance.png"]
+edition = "2018"
+exclude = ["performance.png", "chart/**"]
+keywords = ["integer"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/dtolnay/itoa"
+rust-version = "1.36"
 
-[features]
-default = ["std"]
-i128 = []
-std = []
+[dependencies]
+no-panic = { version = "0.1", optional = true }
 
 [package.metadata.docs.rs]
 targets = ["x86_64-unknown-linux-gnu"]
diff --git a/METADATA b/METADATA
index e9cdb68..84449ae 100644
--- a/METADATA
+++ b/METADATA
@@ -1,5 +1,9 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update rust/crates/itoa
+# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+
 name: "itoa"
-description: "Fast functions for printing integer primitives to an io::Write"
+description: "Fast integer primitive to string conversion"
 third_party {
   url {
     type: HOMEPAGE
@@ -7,13 +11,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/itoa/itoa-0.4.8.crate"
+    value: "https://static.crates.io/crates/itoa/itoa-1.0.5.crate"
   }
-  version: "0.4.8"
+  version: "1.0.5"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2021
-    month: 9
-    day: 22
+    year: 2023
+    month: 2
+    day: 2
   }
 }
diff --git a/README.md b/README.md
index cff3bb3..5728fb7 100644
--- a/README.md
+++ b/README.md
@@ -3,27 +3,36 @@
 
 [<img alt="github" src="https://img.shields.io/badge/github-dtolnay/itoa-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/itoa)
 [<img alt="crates.io" src="https://img.shields.io/crates/v/itoa.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/itoa)
-[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-itoa-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/itoa)
-[<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/itoa/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/itoa/actions?query=branch%3Amaster)
+[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-itoa-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/itoa)
+[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/dtolnay/itoa/ci.yml?branch=master&style=for-the-badge" height="20">](https://github.com/dtolnay/itoa/actions?query=branch%3Amaster)
 
-This crate provides fast functions for printing integer primitives to an
-[`io::Write`] or a [`fmt::Write`]. The implementation comes straight from
-[libcore] but avoids the performance penalty of going through
-[`fmt::Formatter`].
+This crate provides a fast conversion of integer primitives to decimal strings.
+The implementation comes straight from [libcore] but avoids the performance
+penalty of going through [`core::fmt::Formatter`].
 
-See also [`dtoa`] for printing floating point primitives.
+See also [`ryu`] for printing floating point primitives.
 
-*Version requirement: rustc 1.0+*
+*Version requirement: rustc 1.36+*
 
-[`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
-[`fmt::Write`]: https://doc.rust-lang.org/core/fmt/trait.Write.html
 [libcore]: https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L201-L254
-[`fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html
-[`dtoa`]: https://github.com/dtolnay/dtoa
+[`core::fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html
+[`ryu`]: https://github.com/dtolnay/ryu
 
 ```toml
 [dependencies]
-itoa = "0.4"
+itoa = "1.0"
+```
+
+<br>
+
+## Example
+
+```rust
+fn main() {
+    let mut buffer = itoa::Buffer::new();
+    let printed = buffer.format(128u64);
+    assert_eq!(printed, "128");
+}
 ```
 
 <br>
@@ -34,52 +43,6 @@
 
 <br>
 
-## Examples
-
-```rust
-use std::{fmt, io};
-
-fn demo_itoa_write() -> io::Result<()> {
-    // Write to a vector or other io::Write.
-    let mut buf = Vec::new();
-    itoa::write(&mut buf, 128u64)?;
-    println!("{:?}", buf);
-
-    // Write to a stack buffer.
-    let mut bytes = [0u8; 20];
-    let n = itoa::write(&mut bytes[..], 128u64)?;
-    println!("{:?}", &bytes[..n]);
-
-    Ok(())
-}
-
-fn demo_itoa_fmt() -> fmt::Result {
-    // Write to a string.
-    let mut s = String::new();
-    itoa::fmt(&mut s, 128u64)?;
-    println!("{}", s);
-
-    Ok(())
-}
-```
-
-The function signatures are:
-
-```rust
-fn write<W: io::Write, V: itoa::Integer>(writer: W, value: V) -> io::Result<usize>;
-
-fn fmt<W: fmt::Write, V: itoa::Integer>(writer: W, value: V) -> fmt::Result;
-```
-
-where `itoa::Integer` is implemented for i8, u8, i16, u16, i32, u32, i64, u64,
-i128, u128, isize and usize. 128-bit integer support requires rustc 1.26+ and
-the `i128` feature of this crate enabled.
-
-The `write` function is only available when the `std` feature is enabled
-(default is enabled). The return value gives the number of bytes written.
-
-<br>
-
 #### License
 
 <sup>
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 9095ded..c57fb45 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -24,40 +24,31 @@
     },
     {
       "path": "external/rust/crates/url"
+    },
+    {
+      "path": "packages/modules/Virtualization/authfs"
+    },
+    {
+      "path": "packages/modules/Virtualization/microdroid_manager"
+    },
+    {
+      "path": "packages/modules/Virtualization/virtualizationmanager"
+    },
+    {
+      "path": "packages/modules/Virtualization/vm"
+    },
+    {
+      "path": "packages/modules/Virtualization/zipfuse"
     }
   ],
   "presubmit": [
     {
-      "name": "ZipFuseTest"
-    },
-    {
-      "name": "authfs_device_test_src_lib"
-    },
-    {
       "name": "itoa_test_tests_test"
-    },
-    {
-      "name": "microdroid_manager_test"
-    },
-    {
-      "name": "virtualizationservice_device_test"
     }
   ],
   "presubmit-rust": [
     {
-      "name": "ZipFuseTest"
-    },
-    {
-      "name": "authfs_device_test_src_lib"
-    },
-    {
       "name": "itoa_test_tests_test"
-    },
-    {
-      "name": "microdroid_manager_test"
-    },
-    {
-      "name": "virtualizationservice_device_test"
     }
   ]
 }
diff --git a/benches/bench.rs b/benches/bench.rs
index a9ed517..acd2a0c 100644
--- a/benches/bench.rs
+++ b/benches/bench.rs
@@ -1,66 +1,40 @@
-#![cfg_attr(feature = "cargo-clippy", allow(cast_lossless))]
 #![feature(test)]
 #![allow(non_snake_case)]
+#![allow(clippy::cast_lossless)]
 
-extern crate itoa;
 extern crate test;
 
 macro_rules! benches {
-    (
-        $(
-            $(#[$attr:meta])*
-            $name:ident($value:expr)
-        ),*
-    ) => {
-        mod bench_itoa_write {
+    ($($name:ident($value:expr))*) => {
+        mod bench_itoa_format {
             use test::{Bencher, black_box};
+
             $(
-                $(#[$attr])*
                 #[bench]
                 fn $name(b: &mut Bencher) {
-                    use itoa;
-
-                    let mut buf = Vec::with_capacity(40);
+                    let mut buffer = itoa::Buffer::new();
 
                     b.iter(|| {
-                        buf.clear();
-                        itoa::write(&mut buf, black_box($value)).unwrap()
-                    });
-                }
-            )*
-        }
-
-        mod bench_itoa_fmt {
-            use test::{Bencher, black_box};
-            $(
-                $(#[$attr])*
-                #[bench]
-                fn $name(b: &mut Bencher) {
-                    use itoa;
-
-                    let mut buf = String::with_capacity(40);
-
-                    b.iter(|| {
-                        buf.clear();
-                        itoa::fmt(&mut buf, black_box($value)).unwrap()
+                        let printed = buffer.format(black_box($value));
+                        black_box(printed);
                     });
                 }
             )*
         }
 
         mod bench_std_fmt {
+            use std::io::Write;
             use test::{Bencher, black_box};
+
             $(
-                $(#[$attr])*
                 #[bench]
                 fn $name(b: &mut Bencher) {
-                    use std::io::Write;
-
                     let mut buf = Vec::with_capacity(40);
 
                     b.iter(|| {
                         buf.clear();
-                        write!(&mut buf, "{}", black_box($value)).unwrap()
+                        write!(&mut buf, "{}", black_box($value)).unwrap();
+                        black_box(&buf);
                     });
                 }
             )*
@@ -69,15 +43,13 @@
 }
 
 benches! {
-    bench_u64_0(0u64),
-    bench_u64_half(<u32>::max_value() as u64),
-    bench_u64_max(<u64>::max_value()),
+    bench_u64_0(0u64)
+    bench_u64_half(u32::max_value() as u64)
+    bench_u64_max(u64::max_value())
 
-    bench_i16_0(0i16),
-    bench_i16_min(<i16>::min_value()),
+    bench_i16_0(0i16)
+    bench_i16_min(i16::min_value())
 
-    #[cfg(feature = "i128")]
-    bench_u128_0(0u128),
-    #[cfg(feature = "i128")]
-    bench_u128_max(<u128>::max_value())
+    bench_u128_0(0u128)
+    bench_u128_max(u128::max_value())
 }
diff --git a/patches/std.diff b/patches/std.diff
new file mode 100644
index 0000000..e335aef
--- /dev/null
+++ b/patches/std.diff
@@ -0,0 +1,15 @@
+diff --git a/src/lib.rs b/src/lib.rs
+index 7c3616e..cbcd374 100644
+--- a/src/lib.rs
++++ b/src/lib.rs
+@@ -46,6 +46,10 @@ use core::{ptr, slice, str};
+ #[cfg(feature = "no-panic")]
+ use no_panic::no_panic;
+ 
++/// Local Android change: Use std to allow building as a dylib.
++#[cfg(android_dylib)]
++extern crate std;
++
+ /// A correctly sized stack allocation for the formatted integer to be written
+ /// into.
+ ///
diff --git a/src/lib.rs b/src/lib.rs
index 8d4582e..c03064f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,102 +2,56 @@
 //!
 //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
 //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
-//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
+//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
 //!
 //! <br>
 //!
-//! This crate provides fast functions for printing integer primitives to an
-//! [`io::Write`] or a [`fmt::Write`]. The implementation comes straight from
-//! [libcore] but avoids the performance penalty of going through
-//! [`fmt::Formatter`].
+//! This crate provides a fast conversion of integer primitives to decimal
+//! strings. The implementation comes straight from [libcore] but avoids the
+//! performance penalty of going through [`core::fmt::Formatter`].
 //!
-//! See also [`dtoa`] for printing floating point primitives.
+//! See also [`ryu`] for printing floating point primitives.
 //!
-//! [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
-//! [`fmt::Write`]: https://doc.rust-lang.org/core/fmt/trait.Write.html
 //! [libcore]: https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L201-L254
-//! [`fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html
-//! [`dtoa`]: https://github.com/dtolnay/dtoa
+//! [`core::fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html
+//! [`ryu`]: https://github.com/dtolnay/ryu
 //!
-//! <br>
+//! # Example
+//!
+//! ```
+//! fn main() {
+//!     let mut buffer = itoa::Buffer::new();
+//!     let printed = buffer.format(128u64);
+//!     assert_eq!(printed, "128");
+//! }
+//! ```
 //!
 //! # Performance (lower is better)
 //!
 //! ![performance](https://raw.githubusercontent.com/dtolnay/itoa/master/performance.png)
-//!
-//! <br>
-//!
-//! # Examples
-//!
-//! ```edition2018
-//! use std::{fmt, io};
-//!
-//! fn demo_itoa_write() -> io::Result<()> {
-//!     // Write to a vector or other io::Write.
-//!     let mut buf = Vec::new();
-//!     itoa::write(&mut buf, 128u64)?;
-//!     println!("{:?}", buf);
-//!
-//!     // Write to a stack buffer.
-//!     let mut bytes = [0u8; 20];
-//!     let n = itoa::write(&mut bytes[..], 128u64)?;
-//!     println!("{:?}", &bytes[..n]);
-//!
-//!     Ok(())
-//! }
-//!
-//! fn demo_itoa_fmt() -> fmt::Result {
-//!     // Write to a string.
-//!     let mut s = String::new();
-//!     itoa::fmt(&mut s, 128u64)?;
-//!     println!("{}", s);
-//!
-//!     Ok(())
-//! }
-//! ```
 
-#![doc(html_root_url = "https://docs.rs/itoa/0.4.8")]
-#![cfg_attr(not(feature = "std"), no_std)]
-#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
-#![cfg_attr(
-    feature = "cargo-clippy",
-    allow(
-        expl_impl_clone_on_copy,
-        missing_errors_doc,
-        must_use_candidate,
-        transmute_ptr_to_ptr
-    )
+#![doc(html_root_url = "https://docs.rs/itoa/1.0.5")]
+#![no_std]
+#![allow(
+    clippy::cast_lossless,
+    clippy::cast_possible_truncation,
+    clippy::must_use_candidate,
+    clippy::unreadable_literal
 )]
 
-#[cfg(feature = "i128")]
 mod udiv128;
 
-#[cfg(feature = "std")]
-use std::{fmt, io, mem, ptr, slice, str};
+use core::mem::{self, MaybeUninit};
+use core::{ptr, slice, str};
+#[cfg(feature = "no-panic")]
+use no_panic::no_panic;
 
-#[cfg(not(feature = "std"))]
-use core::{fmt, mem, ptr, slice, str};
+/// Local Android change: Use std to allow building as a dylib.
+#[cfg(android_dylib)]
+extern crate std;
 
-/// Write integer to an `io::Write`.
-#[cfg(feature = "std")]
-#[inline]
-pub fn write<W: io::Write, V: Integer>(mut wr: W, value: V) -> io::Result<usize> {
-    let mut buf = Buffer::new();
-    let s = buf.format(value);
-    match wr.write_all(s.as_bytes()) {
-        Ok(()) => Ok(s.len()),
-        Err(e) => Err(e),
-    }
-}
-
-/// Write integer to an `fmt::Write`.
-#[inline]
-pub fn fmt<W: fmt::Write, V: Integer>(mut wr: W, value: V) -> fmt::Result {
-    let mut buf = Buffer::new();
-    wr.write_str(buf.format(value))
-}
-
-/// A safe API for formatting integers to text.
+/// A correctly sized stack allocation for the formatted integer to be written
+/// into.
 ///
 /// # Example
 ///
@@ -106,9 +60,8 @@
 /// let printed = buffer.format(1234);
 /// assert_eq!(printed, "1234");
 /// ```
-#[derive(Copy)]
 pub struct Buffer {
-    bytes: [u8; I128_MAX_LEN],
+    bytes: [MaybeUninit<u8>; I128_MAX_LEN],
 }
 
 impl Default for Buffer {
@@ -129,39 +82,37 @@
     /// This is a cheap operation; you don't need to worry about reusing buffers
     /// for efficiency.
     #[inline]
-    #[allow(deprecated)]
+    #[cfg_attr(feature = "no-panic", no_panic)]
     pub fn new() -> Buffer {
-        Buffer {
-            bytes: unsafe { mem::uninitialized() },
-        }
+        let bytes = [MaybeUninit::<u8>::uninit(); I128_MAX_LEN];
+        Buffer { bytes }
     }
 
-    /// Print an integer into this buffer and return a reference to its string representation
-    /// within the buffer.
+    /// Print an integer into this buffer and return a reference to its string
+    /// representation within the buffer.
+    #[cfg_attr(feature = "no-panic", no_panic)]
     pub fn format<I: Integer>(&mut self, i: I) -> &str {
-        i.write(self)
+        i.write(unsafe {
+            &mut *(&mut self.bytes as *mut [MaybeUninit<u8>; I128_MAX_LEN]
+                as *mut <I as private::Sealed>::Buffer)
+        })
     }
 }
 
+/// An integer that can be written into an [`itoa::Buffer`][Buffer].
+///
+/// This trait is sealed and cannot be implemented for types outside of itoa.
+pub trait Integer: private::Sealed {}
+
 // Seal to prevent downstream implementations of the Integer trait.
 mod private {
-    pub trait Sealed {}
+    pub trait Sealed: Copy {
+        type Buffer: 'static;
+        fn write(self, buf: &mut Self::Buffer) -> &str;
+    }
 }
 
-/// An integer that can be formatted by `itoa::write` and `itoa::fmt`.
-///
-/// This trait is sealed and cannot be implemented for types outside of itoa.
-pub trait Integer: private::Sealed {
-    // Not public API.
-    #[doc(hidden)]
-    fn write(self, buf: &mut Buffer) -> &str;
-}
-
-trait IntegerPrivate<B> {
-    fn write_to(self, buf: &mut B) -> &[u8];
-}
-
-const DEC_DIGITS_LUT: &'static [u8] = b"\
+const DEC_DIGITS_LUT: &[u8] = b"\
       0001020304050607080910111213141516171819\
       2021222324252627282930313233343536373839\
       4041424344454647484950515253545556575859\
@@ -170,34 +121,17 @@
 
 // Adaptation of the original implementation at
 // https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L188-L266
-macro_rules! impl_IntegerCommon {
-    ($max_len:expr, $t:ident) => {
-        impl Integer for $t {
-            #[inline]
-            fn write(self, buf: &mut Buffer) -> &str {
-                unsafe {
-                    debug_assert!($max_len <= I128_MAX_LEN);
-                    let buf = mem::transmute::<&mut [u8; I128_MAX_LEN], &mut [u8; $max_len]>(
-                        &mut buf.bytes,
-                    );
-                    let bytes = self.write_to(buf);
-                    str::from_utf8_unchecked(bytes)
-                }
-            }
-        }
-
-        impl private::Sealed for $t {}
-    };
-}
-
 macro_rules! impl_Integer {
     ($($max_len:expr => $t:ident),* as $conv_fn:ident) => {$(
-        impl_IntegerCommon!($max_len, $t);
+        impl Integer for $t {}
 
-        impl IntegerPrivate<[u8; $max_len]> for $t {
+        impl private::Sealed for $t {
+            type Buffer = [MaybeUninit<u8>; $max_len];
+
             #[allow(unused_comparisons)]
             #[inline]
-            fn write_to(self, buf: &mut [u8; $max_len]) -> &[u8] {
+            #[cfg_attr(feature = "no-panic", no_panic)]
+            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
                 let is_nonnegative = self >= 0;
                 let mut n = if is_nonnegative {
                     self as $conv_fn
@@ -206,7 +140,7 @@
                     (!(self as $conv_fn)).wrapping_add(1)
                 };
                 let mut curr = buf.len() as isize;
-                let buf_ptr = buf.as_mut_ptr();
+                let buf_ptr = buf.as_mut_ptr() as *mut u8;
                 let lut_ptr = DEC_DIGITS_LUT.as_ptr();
 
                 unsafe {
@@ -253,7 +187,8 @@
                 }
 
                 let len = buf.len() - curr as usize;
-                unsafe { slice::from_raw_parts(buf_ptr.offset(curr), len) }
+                let bytes = unsafe { slice::from_raw_parts(buf_ptr.offset(curr), len) };
+                unsafe { str::from_utf8_unchecked(bytes) }
             }
         }
     )*};
@@ -288,15 +223,17 @@
 #[cfg(target_pointer_width = "64")]
 impl_Integer!(I64_MAX_LEN => isize, U64_MAX_LEN => usize as u64);
 
-#[cfg(all(feature = "i128"))]
 macro_rules! impl_Integer128 {
     ($($max_len:expr => $t:ident),*) => {$(
-        impl_IntegerCommon!($max_len, $t);
+        impl Integer for $t {}
 
-        impl IntegerPrivate<[u8; $max_len]> for $t {
+        impl private::Sealed for $t {
+            type Buffer = [MaybeUninit<u8>; $max_len];
+
             #[allow(unused_comparisons)]
             #[inline]
-            fn write_to(self, buf: &mut [u8; $max_len]) -> &[u8] {
+            #[cfg_attr(feature = "no-panic", no_panic)]
+            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
                 let is_nonnegative = self >= 0;
                 let n = if is_nonnegative {
                     self as u128
@@ -305,13 +242,13 @@
                     (!(self as u128)).wrapping_add(1)
                 };
                 let mut curr = buf.len() as isize;
-                let buf_ptr = buf.as_mut_ptr();
+                let buf_ptr = buf.as_mut_ptr() as *mut u8;
 
                 unsafe {
                     // Divide by 10^19 which is the highest power less than 2^64.
                     let (n, rem) = udiv128::udivmod_1e19(n);
-                    let buf1 = buf_ptr.offset(curr - U64_MAX_LEN as isize) as *mut [u8; U64_MAX_LEN];
-                    curr -= rem.write_to(&mut *buf1).len() as isize;
+                    let buf1 = buf_ptr.offset(curr - U64_MAX_LEN as isize) as *mut [MaybeUninit<u8>; U64_MAX_LEN];
+                    curr -= rem.write(&mut *buf1).len() as isize;
 
                     if n != 0 {
                         // Memset the base10 leading zeros of rem.
@@ -321,8 +258,8 @@
 
                         // Divide by 10^19 again.
                         let (n, rem) = udiv128::udivmod_1e19(n);
-                        let buf2 = buf_ptr.offset(curr - U64_MAX_LEN as isize) as *mut [u8; U64_MAX_LEN];
-                        curr -= rem.write_to(&mut *buf2).len() as isize;
+                        let buf2 = buf_ptr.offset(curr - U64_MAX_LEN as isize) as *mut [MaybeUninit<u8>; U64_MAX_LEN];
+                        curr -= rem.write(&mut *buf2).len() as isize;
 
                         if n != 0 {
                             // Memset the leading zeros.
@@ -343,16 +280,15 @@
                     }
 
                     let len = buf.len() - curr as usize;
-                    slice::from_raw_parts(buf_ptr.offset(curr), len)
+                    let bytes = slice::from_raw_parts(buf_ptr.offset(curr), len);
+                    str::from_utf8_unchecked(bytes)
                 }
             }
         }
     )*};
 }
 
-#[cfg(all(feature = "i128"))]
 const U128_MAX_LEN: usize = 39;
 const I128_MAX_LEN: usize = 40;
 
-#[cfg(all(feature = "i128"))]
 impl_Integer128!(I128_MAX_LEN => i128, U128_MAX_LEN => u128);
diff --git a/src/udiv128.rs b/src/udiv128.rs
index 617c1c1..0587047 100644
--- a/src/udiv128.rs
+++ b/src/udiv128.rs
@@ -1,5 +1,9 @@
+#[cfg(feature = "no-panic")]
+use no_panic::no_panic;
+
 /// Multiply unsigned 128 bit integers, return upper 128 bits of the result
 #[inline]
+#[cfg_attr(feature = "no-panic", no_panic)]
 fn u128_mulhi(x: u128, y: u128) -> u128 {
     let x_lo = x as u64;
     let x_hi = (x >> 64) as u64;
@@ -12,7 +16,7 @@
     let high1 = m >> 64;
 
     let m_lo = m as u64;
-    let high2 = x_hi as u128 * y_lo as u128 + m_lo as u128 >> 64;
+    let high2 = (x_hi as u128 * y_lo as u128 + m_lo as u128) >> 64;
 
     x_hi as u128 * y_hi as u128 + high1 + high2
 }
@@ -26,15 +30,14 @@
 ///   Implementation, 1994, pp. 61–72
 ///
 #[inline]
+#[cfg_attr(feature = "no-panic", no_panic)]
 pub fn udivmod_1e19(n: u128) -> (u128, u64) {
     let d = 10_000_000_000_000_000_000_u64; // 10^19
 
     let quot = if n < 1 << 83 {
         ((n >> 19) as u64 / (d >> 19)) as u128
     } else {
-        let factor =
-            (8507059173023461586_u64 as u128) << 64 | 10779635027931437427 as u128;
-        u128_mulhi(n, factor) >> 62
+        u128_mulhi(n, 156927543384667019095894735580191660403) >> 62
     };
 
     let rem = (n - quot * d as u128) as u64;
diff --git a/tests/test.rs b/tests/test.rs
index 5355868..1d7e8cb 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -1,28 +1,13 @@
-#![cfg_attr(feature = "cargo-clippy", allow(cast_lossless, string_lit_as_bytes))]
 #![allow(non_snake_case)]
-
-extern crate itoa;
+#![allow(clippy::cast_lossless)]
 
 macro_rules! test {
-    (
+    ($($name:ident($value:expr, $expected:expr))*) => {
         $(
-            $(#[$attr:meta])*
-            $name:ident($value:expr, $expected:expr)
-        ),*
-    ) => {
-        $(
-            $(#[$attr])*
             #[test]
             fn $name() {
-                #[cfg(feature = "std")]
-                {
-                    let mut buf = [b'\0'; 40];
-                    let len = itoa::write(&mut buf[..], $value).unwrap();
-                    assert_eq!(&buf[0..len], $expected.as_bytes());
-                }
-
-                let mut s = String::new();
-                itoa::fmt(&mut s, $value).unwrap();
+                let mut buffer = itoa::Buffer::new();
+                let s = buffer.format($value);
                 assert_eq!(s, $expected);
             }
         )*
@@ -30,18 +15,15 @@
 }
 
 test! {
-    test_u64_0(0u64, "0"),
-    test_u64_half(<u32>::max_value() as u64, "4294967295"),
-    test_u64_max(<u64>::max_value(), "18446744073709551615"),
-    test_i64_min(<i64>::min_value(), "-9223372036854775808"),
+    test_u64_0(0u64, "0")
+    test_u64_half(u32::max_value() as u64, "4294967295")
+    test_u64_max(u64::max_value(), "18446744073709551615")
+    test_i64_min(i64::min_value(), "-9223372036854775808")
 
-    test_i16_0(0i16, "0"),
-    test_i16_min(<i16>::min_value(), "-32768"),
+    test_i16_0(0i16, "0")
+    test_i16_min(i16::min_value(), "-32768")
 
-    #[cfg(feature = "i128")]
-    test_u128_0(0u128, "0"),
-    #[cfg(feature = "i128")]
-    test_u128_max(<u128>::max_value(), "340282366920938463463374607431768211455"),
-    #[cfg(feature = "i128")]
-    test_i128_min(<i128>::min_value(), "-170141183460469231731687303715884105728")
+    test_u128_0(0u128, "0")
+    test_u128_max(u128::max_value(), "340282366920938463463374607431768211455")
+    test_i128_min(i128::min_value(), "-170141183460469231731687303715884105728")
 }