Merge remote-tracking branch 'aosp/upstream-master' into mymerge am: 6b8a5a7461
am: 2eea9b9b1a

Change-Id: I8b259c74ed28d7fb73f530a200691227f45863ef
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1fec0ef
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+.*.swp
+doc
+tags
+build
+target
+Cargo.lock
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..082c5cc
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,15 @@
+language: rust
+matrix:
+  include:
+    - rust: 1.12.0
+    - rust: stable
+    - rust: beta
+    - rust: nightly
+    - env: CROSS_TARGET=mips64-unknown-linux-gnuabi64
+      rust: stable
+      services: docker
+      sudo: required
+script: ci/script.sh
+branches:
+  only:
+    - master
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..020beb4
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,114 @@
+1.3.0
+=====
+This new minor release now enables `i128` support automatically on Rust
+compilers that support 128-bit integers. The `i128` feature is now a no-op, but
+continues to exist for backward compatibility purposes. The crate continues to
+maintain compatibility with Rust 1.12.0.
+
+This release also deprecates the `ByteOrder` trait methods
+`read_f32_into_unchecked` and `read_f64_into_unchecked` in favor of
+`read_f32_into` and `read_f64_into`. This was an oversight from the 1.2 release
+where the corresponding methods on `ReadBytesExt` were deprecated.
+
+`quickcheck` and `rand` were bumped to `0.8` and `0.6`, respectively.
+
+A few small documentation related bugs have been fixed.
+
+
+1.2.7
+=====
+This patch release excludes some CI files from the crate release and updates
+the license field to use `OR` instead of `/`.
+
+
+1.2.6
+=====
+This patch release fixes some test compilation errors introduced by an
+over-eager release of 1.2.5.
+
+
+1.2.5
+=====
+This patch release fixes some typos in the docs, adds doc tests to methods on
+`WriteByteExt` and bumps the quickcheck dependency to `0.7`.
+
+
+1.2.4
+=====
+This patch release adds support for 48-bit integers by adding the following
+methods to the `ByteOrder` trait: `read_u48`, `read_i48`, `write_u48` and
+`write_i48`. Corresponding methods have been added to the `ReadBytesExt` and
+`WriteBytesExt` traits as well.
+
+
+1.2.3
+=====
+This patch release removes the use of `feature(i128_type)` from byteorder,
+since it has been stabilized. We leave byteorder's `i128` feature in place
+in order to continue supporting compilation on older versions of Rust.
+
+
+1.2.2
+=====
+This patch release only consists of internal improvements and refactorings.
+Notably, this removes all uses of `transmute` and instead uses pointer casts.
+
+
+1.2.1
+=====
+This patch release removes more unnecessary uses of `unsafe` that
+were overlooked in the prior `1.2.0` release. In particular, the
+`ReadBytesExt::read_{f32,f64}_into_checked` methods have been deprecated and
+replaced by more appropriately named `read_{f32,f64}_into` methods.
+
+
+1.2.0
+=====
+The most prominent change in this release of `byteorder` is the removal of
+unnecessary signaling NaN masking, and in turn, the `unsafe` annotations
+associated with methods that didn't do masking. See
+[#103](https://github.com/BurntSushi/byteorder/issues/103)
+for more details.
+
+* [BUG #102](https://github.com/BurntSushi/byteorder/issues/102):
+  Fix big endian tests.
+* [BUG #103](https://github.com/BurntSushi/byteorder/issues/103):
+  Remove sNaN masking.
+
+
+1.1.0
+=====
+This release of `byteorder` features a number of fixes and improvements, mostly
+as a result of the
+[Litz Blitz evaluation](https://public.etherpad-mozilla.org/p/rust-crate-eval-byteorder).
+
+Feature enhancements:
+
+* [FEATURE #63](https://github.com/BurntSushi/byteorder/issues/63):
+  Add methods for reading/writing slices of numbers for a specific
+  endianness.
+* [FEATURE #65](https://github.com/BurntSushi/byteorder/issues/65):
+  Add support for `u128`/`i128` types. (Behind the nightly only `i128`
+  feature.)
+* [FEATURE #72](https://github.com/BurntSushi/byteorder/issues/72):
+  Add "panics" and "errors" sections for each relevant public API item.
+* [FEATURE #74](https://github.com/BurntSushi/byteorder/issues/74):
+  Add CI badges to Cargo.toml.
+* [FEATURE #75](https://github.com/BurntSushi/byteorder/issues/75):
+  Add more examples to public API items.
+* Add 24-bit read/write methods.
+* Add `BE` and `LE` type aliases for `BigEndian` and `LittleEndian`,
+  respectively.
+
+Bug fixes:
+
+* [BUG #68](https://github.com/BurntSushi/byteorder/issues/68):
+  Panic in {BigEndian,LittleEndian}::default.
+* [BUG #69](https://github.com/BurntSushi/byteorder/issues/69):
+  Seal the `ByteOrder` trait to prevent out-of-crate implementations.
+* [BUG #71](https://github.com/BurntSushi/byteorder/issues/71):
+  Guarantee that the results of `read_f32`/`read_f64` are always defined.
+* [BUG #73](https://github.com/BurntSushi/byteorder/issues/73):
+  Add crates.io categories.
+* [BUG #77](https://github.com/BurntSushi/byteorder/issues/77):
+  Add `html_root` doc attribute.
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..bb9c20a
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,3 @@
+This project is dual-licensed under the Unlicense and MIT licenses.
+
+You may use this code under the terms of either license.
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..91f2aa3
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,38 @@
+[package]
+name = "byteorder"
+version = "1.3.2"  #:version
+authors = ["Andrew Gallant <jamslam@gmail.com>"]
+description = "Library for reading/writing numbers in big-endian and little-endian."
+documentation = "https://docs.rs/byteorder"
+homepage = "https://github.com/BurntSushi/byteorder"
+repository = "https://github.com/BurntSushi/byteorder"
+readme = "README.md"
+categories = ["encoding", "parsing"]
+keywords = ["byte", "endian", "big-endian", "little-endian", "binary"]
+license = "Unlicense OR MIT"
+exclude = ["/ci/*"]
+build = "build.rs"
+
+[lib]
+name = "byteorder"
+bench = false
+
+[dev-dependencies]
+quickcheck = { version = "0.8", default-features = false }
+rand = "0.6"
+doc-comment = "0.3"
+
+[features]
+default = ["std"]
+std = []
+
+# This feature is no longer used and is DEPRECATED. This crate now
+# automatically enables i128 support for Rust compilers that support it. The
+# feature will be removed if and when a new major version is released.
+i128 = []
+
+[profile.bench]
+opt-level = 3
+
+[badges]
+travis-ci = { repository = "BurntSushi/byteorder" }
diff --git a/LICENSE-MIT b/LICENSE-MIT
new file mode 100644
index 0000000..3b0a5dc
--- /dev/null
+++ b/LICENSE-MIT
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Andrew Gallant
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8940b29
--- /dev/null
+++ b/README.md
@@ -0,0 +1,63 @@
+This crate provides convenience methods for encoding and decoding
+numbers in either big-endian or little-endian order.
+
+[![Build status](https://api.travis-ci.org/BurntSushi/byteorder.svg)](https://travis-ci.org/BurntSushi/byteorder)
+[![](http://meritbadge.herokuapp.com/byteorder)](https://crates.io/crates/byteorder)
+
+Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org).
+
+
+### Documentation
+
+https://docs.rs/byteorder
+
+
+### Installation
+
+This crate works with Cargo and is on
+[crates.io](https://crates.io/crates/byteorder). Add it to your `Cargo.toml`
+like so:
+
+```toml
+[dependencies]
+byteorder = "1"
+```
+
+If you want to augment existing `Read` and `Write` traits, then import the
+extension methods like so:
+
+```rust
+extern crate byteorder;
+
+use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian, LittleEndian};
+```
+
+For example:
+
+```rust
+use std::io::Cursor;
+use byteorder::{BigEndian, ReadBytesExt};
+
+let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
+// Note that we use type parameters to indicate which kind of byte order
+// we want!
+assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
+assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
+```
+
+### `no_std` crates
+
+This crate has a feature, `std`, that is enabled by default. To use this crate
+in a `no_std` context, add the following to your `Cargo.toml`:
+
+```toml
+[dependencies]
+byteorder = { version = "1", default-features = false }
+```
+
+
+### Alternatives
+
+Note that as of Rust 1.32, the standard numeric types provide built-in methods
+like `to_le_bytes` and `from_le_bytes`, which support some of the same use
+cases.
diff --git a/UNLICENSE b/UNLICENSE
new file mode 100644
index 0000000..68a49da
--- /dev/null
+++ b/UNLICENSE
@@ -0,0 +1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <http://unlicense.org/>
diff --git a/benches/bench.rs b/benches/bench.rs
new file mode 100644
index 0000000..d53d25e
--- /dev/null
+++ b/benches/bench.rs
@@ -0,0 +1,328 @@
+#![feature(test)]
+
+extern crate byteorder;
+extern crate rand;
+extern crate test;
+
+macro_rules! bench_num {
+    ($name:ident, $read:ident, $bytes:expr, $data:expr) => (
+        mod $name {
+            use byteorder::{ByteOrder, BigEndian, NativeEndian, LittleEndian};
+            use super::test::Bencher;
+            use super::test::black_box as bb;
+
+            const NITER: usize = 100_000;
+
+            #[bench]
+            fn read_big_endian(b: &mut Bencher) {
+                let buf = $data;
+                b.iter(|| {
+                    for _ in 0..NITER {
+                        bb(BigEndian::$read(&buf, $bytes));
+                    }
+                });
+            }
+
+            #[bench]
+            fn read_little_endian(b: &mut Bencher) {
+                let buf = $data;
+                b.iter(|| {
+                    for _ in 0..NITER {
+                        bb(LittleEndian::$read(&buf, $bytes));
+                    }
+                });
+            }
+
+            #[bench]
+            fn read_native_endian(b: &mut Bencher) {
+                let buf = $data;
+                b.iter(|| {
+                    for _ in 0..NITER {
+                        bb(NativeEndian::$read(&buf, $bytes));
+                    }
+                });
+            }
+        }
+    );
+    ($ty:ident, $max:ident,
+     $read:ident, $write:ident, $size:expr, $data:expr) => (
+        mod $ty {
+            use std::$ty;
+            use byteorder::{ByteOrder, BigEndian, NativeEndian, LittleEndian};
+            use super::test::Bencher;
+            use super::test::black_box as bb;
+
+            const NITER: usize = 100_000;
+
+            #[bench]
+            fn read_big_endian(b: &mut Bencher) {
+                let buf = $data;
+                b.iter(|| {
+                    for _ in 0..NITER {
+                        bb(BigEndian::$read(&buf));
+                    }
+                });
+            }
+
+            #[bench]
+            fn read_little_endian(b: &mut Bencher) {
+                let buf = $data;
+                b.iter(|| {
+                    for _ in 0..NITER {
+                        bb(LittleEndian::$read(&buf));
+                    }
+                });
+            }
+
+            #[bench]
+            fn read_native_endian(b: &mut Bencher) {
+                let buf = $data;
+                b.iter(|| {
+                    for _ in 0..NITER {
+                        bb(NativeEndian::$read(&buf));
+                    }
+                });
+            }
+
+            #[bench]
+            fn write_big_endian(b: &mut Bencher) {
+                let mut buf = $data;
+                let n = $ty::$max;
+                b.iter(|| {
+                    for _ in 0..NITER {
+                        bb(BigEndian::$write(&mut buf, n));
+                    }
+                });
+            }
+
+            #[bench]
+            fn write_little_endian(b: &mut Bencher) {
+                let mut buf = $data;
+                let n = $ty::$max;
+                b.iter(|| {
+                    for _ in 0..NITER {
+                        bb(LittleEndian::$write(&mut buf, n));
+                    }
+                });
+            }
+
+            #[bench]
+            fn write_native_endian(b: &mut Bencher) {
+                let mut buf = $data;
+                let n = $ty::$max;
+                b.iter(|| {
+                    for _ in 0..NITER {
+                        bb(NativeEndian::$write(&mut buf, n));
+                    }
+                });
+            }
+        }
+    );
+}
+
+bench_num!(u16, MAX, read_u16, write_u16, 2, [1, 2]);
+bench_num!(i16, MAX, read_i16, write_i16, 2, [1, 2]);
+bench_num!(u32, MAX, read_u32, write_u32, 4, [1, 2, 3, 4]);
+bench_num!(i32, MAX, read_i32, write_i32, 4, [1, 2, 3, 4]);
+bench_num!(u64, MAX, read_u64, write_u64, 8, [1, 2, 3, 4, 5, 6, 7, 8]);
+bench_num!(i64, MAX, read_i64, write_i64, 8, [1, 2, 3, 4, 5, 6, 7, 8]);
+bench_num!(f32, MAX, read_f32, write_f32, 4, [1, 2, 3, 4]);
+bench_num!(f64, MAX, read_f64, write_f64, 8,
+           [1, 2, 3, 4, 5, 6, 7, 8]);
+
+bench_num!(uint_1, read_uint, 1, [1]);
+bench_num!(uint_2, read_uint, 2, [1, 2]);
+bench_num!(uint_3, read_uint, 3, [1, 2, 3]);
+bench_num!(uint_4, read_uint, 4, [1, 2, 3, 4]);
+bench_num!(uint_5, read_uint, 5, [1, 2, 3, 4, 5]);
+bench_num!(uint_6, read_uint, 6, [1, 2, 3, 4, 5, 6]);
+bench_num!(uint_7, read_uint, 7, [1, 2, 3, 4, 5, 6, 7]);
+bench_num!(uint_8, read_uint, 8, [1, 2, 3, 4, 5, 6, 7, 8]);
+
+bench_num!(int_1, read_int, 1, [1]);
+bench_num!(int_2, read_int, 2, [1, 2]);
+bench_num!(int_3, read_int, 3, [1, 2, 3]);
+bench_num!(int_4, read_int, 4, [1, 2, 3, 4]);
+bench_num!(int_5, read_int, 5, [1, 2, 3, 4, 5]);
+bench_num!(int_6, read_int, 6, [1, 2, 3, 4, 5, 6]);
+bench_num!(int_7, read_int, 7, [1, 2, 3, 4, 5, 6, 7]);
+bench_num!(int_8, read_int, 8, [1, 2, 3, 4, 5, 6, 7, 8]);
+
+#[cfg(byteorder_i128)]
+bench_num!(u128, MAX, read_u128, write_u128,
+    16, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
+#[cfg(byteorder_i128)]
+bench_num!(i128, MAX, read_i128, write_i128,
+    16, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
+
+#[cfg(byteorder_i128)]
+bench_num!(uint128_1, read_uint128,
+    1, [1]);
+#[cfg(byteorder_i128)]
+bench_num!(uint128_2, read_uint128,
+    2, [1, 2]);
+#[cfg(byteorder_i128)]
+bench_num!(uint128_3, read_uint128,
+    3, [1, 2, 3]);
+#[cfg(byteorder_i128)]
+bench_num!(uint128_4, read_uint128,
+    4, [1, 2, 3, 4]);
+#[cfg(byteorder_i128)]
+bench_num!(uint128_5, read_uint128,
+    5, [1, 2, 3, 4, 5]);
+#[cfg(byteorder_i128)]
+bench_num!(uint128_6, read_uint128,
+    6, [1, 2, 3, 4, 5, 6]);
+#[cfg(byteorder_i128)]
+bench_num!(uint128_7, read_uint128,
+    7, [1, 2, 3, 4, 5, 6, 7]);
+#[cfg(byteorder_i128)]
+bench_num!(uint128_8, read_uint128,
+    8, [1, 2, 3, 4, 5, 6, 7, 8]);
+#[cfg(byteorder_i128)]
+bench_num!(uint128_9, read_uint128,
+    9, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
+#[cfg(byteorder_i128)]
+bench_num!(uint128_10, read_uint128,
+    10, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
+#[cfg(byteorder_i128)]
+bench_num!(uint128_11, read_uint128,
+    11, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
+#[cfg(byteorder_i128)]
+bench_num!(uint128_12, read_uint128,
+    12, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
+#[cfg(byteorder_i128)]
+bench_num!(uint128_13, read_uint128,
+    13, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
+#[cfg(byteorder_i128)]
+bench_num!(uint128_14, read_uint128,
+    14, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]);
+#[cfg(byteorder_i128)]
+bench_num!(uint128_15, read_uint128,
+    15, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
+#[cfg(byteorder_i128)]
+bench_num!(uint128_16, read_uint128,
+    16, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
+
+#[cfg(byteorder_i128)]
+bench_num!(int128_1, read_int128,
+    1, [1]);
+#[cfg(byteorder_i128)]
+bench_num!(int128_2, read_int128,
+    2, [1, 2]);
+#[cfg(byteorder_i128)]
+bench_num!(int128_3, read_int128,
+    3, [1, 2, 3]);
+#[cfg(byteorder_i128)]
+bench_num!(int128_4, read_int128,
+    4, [1, 2, 3, 4]);
+#[cfg(byteorder_i128)]
+bench_num!(int128_5, read_int128,
+    5, [1, 2, 3, 4, 5]);
+#[cfg(byteorder_i128)]
+bench_num!(int128_6, read_int128,
+    6, [1, 2, 3, 4, 5, 6]);
+#[cfg(byteorder_i128)]
+bench_num!(int128_7, read_int128,
+    7, [1, 2, 3, 4, 5, 6, 7]);
+#[cfg(byteorder_i128)]
+bench_num!(int128_8, read_int128,
+    8, [1, 2, 3, 4, 5, 6, 7, 8]);
+#[cfg(byteorder_i128)]
+bench_num!(int128_9, read_int128,
+    9, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
+#[cfg(byteorder_i128)]
+bench_num!(int128_10, read_int128,
+    10, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
+#[cfg(byteorder_i128)]
+bench_num!(int128_11, read_int128,
+    11, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
+#[cfg(byteorder_i128)]
+bench_num!(int128_12, read_int128,
+    12, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
+#[cfg(byteorder_i128)]
+bench_num!(int128_13, read_int128,
+    13, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
+#[cfg(byteorder_i128)]
+bench_num!(int128_14, read_int128,
+    14, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]);
+#[cfg(byteorder_i128)]
+bench_num!(int128_15, read_int128,
+    15, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
+#[cfg(byteorder_i128)]
+bench_num!(int128_16, read_int128,
+    16, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
+
+
+macro_rules! bench_slice {
+    ($name:ident, $numty:ty, $read:ident, $write:ident) => {
+        mod $name {
+            use std::mem::size_of;
+
+            use byteorder::{ByteOrder, BigEndian, LittleEndian};
+            use rand::{self, Rng};
+            use rand::distributions;
+            use test::Bencher;
+
+            #[bench]
+            fn read_big_endian(b: &mut Bencher) {
+                let mut numbers: Vec<$numty> = rand::thread_rng()
+                    .sample_iter(&distributions::Standard)
+                    .take(100000)
+                    .collect();
+                let mut bytes = vec![0; numbers.len() * size_of::<$numty>()];
+                BigEndian::$write(&numbers, &mut bytes);
+
+                b.bytes = bytes.len() as u64;
+                b.iter(|| {
+                    BigEndian::$read(&bytes, &mut numbers);
+                });
+            }
+
+            #[bench]
+            fn read_little_endian(b: &mut Bencher) {
+                let mut numbers: Vec<$numty> = rand::thread_rng()
+                    .sample_iter(&distributions::Standard)
+                    .take(100000)
+                    .collect();
+                let mut bytes = vec![0; numbers.len() * size_of::<$numty>()];
+                LittleEndian::$write(&numbers, &mut bytes);
+
+                b.bytes = bytes.len() as u64;
+                b.iter(|| {
+                    LittleEndian::$read(&bytes, &mut numbers);
+                });
+            }
+
+            #[bench]
+            fn write_big_endian(b: &mut Bencher) {
+                let numbers: Vec<$numty> = rand::thread_rng()
+                    .sample_iter(&distributions::Standard)
+                    .take(100000)
+                    .collect();
+                let mut bytes = vec![0; numbers.len() * size_of::<$numty>()];
+
+                b.bytes = bytes.len() as u64;
+                b.iter(|| {
+                    BigEndian::$write(&numbers, &mut bytes);
+                });
+            }
+
+            #[bench]
+            fn write_little_endian(b: &mut Bencher) {
+                let numbers: Vec<$numty> = rand::thread_rng()
+                    .sample_iter(&distributions::Standard)
+                    .take(100000)
+                    .collect();
+                let mut bytes = vec![0; numbers.len() * size_of::<$numty>()];
+
+                b.bytes = bytes.len() as u64;
+                b.iter(|| {
+                    LittleEndian::$write(&numbers, &mut bytes);
+                });
+            }
+        }
+    }
+}
+
+bench_slice!(slice_u64, u64, read_u64_into, write_u64_into);
diff --git a/build.rs b/build.rs
new file mode 100644
index 0000000..002135b
--- /dev/null
+++ b/build.rs
@@ -0,0 +1,87 @@
+use std::env;
+use std::ffi::OsString;
+use std::io::{self, Write};
+use std::process::Command;
+
+fn main() {
+    let version = match Version::read() {
+        Ok(version) => version,
+        Err(err) => {
+            writeln!(
+                &mut io::stderr(),
+                "failed to parse `rustc --version`: {}",
+                err
+            ).unwrap();
+            return;
+        }
+    };
+    enable_i128(version);
+}
+
+fn enable_i128(version: Version) {
+    if version < (Version { major: 1, minor: 26, patch: 0 }) {
+        return;
+    }
+
+    println!("cargo:rustc-cfg=byteorder_i128");
+}
+
+#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)]
+struct Version {
+    major: u32,
+    minor: u32,
+    patch: u32,
+}
+
+impl Version {
+    fn read() -> Result<Version, String> {
+        let rustc = env::var_os("RUSTC").unwrap_or(OsString::from("rustc"));
+        let output = Command::new(&rustc)
+            .arg("--version")
+            .output()
+            .unwrap()
+            .stdout;
+        Version::parse(&String::from_utf8(output).unwrap())
+    }
+
+    fn parse(mut s: &str) -> Result<Version, String> {
+        if !s.starts_with("rustc ") {
+            return Err(format!("unrecognized version string: {}", s));
+        }
+        s = &s["rustc ".len()..];
+
+        let parts: Vec<&str> = s.split(".").collect();
+        if parts.len() < 3 {
+            return Err(format!("not enough version parts: {:?}", parts));
+        }
+
+        let mut num = String::new();
+        for c in parts[0].chars() {
+            if !c.is_digit(10) {
+                break;
+            }
+            num.push(c);
+        }
+        let major = try!(num.parse::<u32>().map_err(|e| e.to_string()));
+
+        num.clear();
+        for c in parts[1].chars() {
+            if !c.is_digit(10) {
+                break;
+            }
+            num.push(c);
+        }
+        let minor = try!(num.parse::<u32>().map_err(|e| e.to_string()));
+
+        num.clear();
+        for c in parts[2].chars() {
+            if !c.is_digit(10) {
+                break;
+            }
+            num.push(c);
+        }
+        let patch = try!(num.parse::<u32>().map_err(|e| e.to_string()));
+
+        Ok(Version { major: major, minor: minor, patch: patch })
+    }
+}
diff --git a/ci/script.sh b/ci/script.sh
new file mode 100755
index 0000000..596e2d5
--- /dev/null
+++ b/ci/script.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+set -ex
+
+# Setup some variables for executing cargo commands.
+# Things are a little different if we're testing with cross.
+if [ ! -z "$CROSS_TARGET" ]; then
+  rustup target add "$CROSS_TARGET"
+  cargo install cross --force
+  export CARGO_CMD="cross"
+  export TARGET_PARAM="--target $CROSS_TARGET"
+else
+  export CARGO_CMD="cargo"
+  export TARGET_PARAM=""
+fi
+
+# Test the build and docs.
+"$CARGO_CMD" build --verbose $TARGET_PARAM
+"$CARGO_CMD" doc --verbose $TARGET_PARAM
+
+# If we're testing on an older version of Rust, then only check that we
+# can build the crate. This is because the dev dependencies might be updated
+# more frequently, and therefore might require a newer version of Rust.
+#
+# This isn't ideal. It's a compromise.
+if [ "$TRAVIS_RUST_VERSION" = "1.12.0" ]; then
+  exit
+fi
+
+"$CARGO_CMD" test --verbose $TARGET_PARAM
+"$CARGO_CMD" test --verbose --no-default-features --lib $TARGET_PARAM
+if [ "$TRAVIS_RUST_VERSION" = "nightly" ]; then
+  "$CARGO_CMD" test \
+    --verbose --features i128 $TARGET_PARAM
+  "$CARGO_CMD" test \
+    --verbose --no-default-features --features i128 --lib $TARGET_PARAM
+  "$CARGO_CMD" bench \
+    --verbose --no-run $TARGET_PARAM
+  "$CARGO_CMD" bench \
+    --verbose --no-run --no-default-features $TARGET_PARAM
+  "$CARGO_CMD" bench \
+    --verbose --no-run --features i128 $TARGET_PARAM
+  "$CARGO_CMD" bench \
+    --verbose --no-run --no-default-features --features i128 $TARGET_PARAM
+fi
diff --git a/src/io.rs b/src/io.rs
new file mode 100644
index 0000000..ed6a848
--- /dev/null
+++ b/src/io.rs
@@ -0,0 +1,1605 @@
+use std::io::{self, Result};
+use std::slice;
+
+use ByteOrder;
+
+/// Extends [`Read`] with methods for reading numbers. (For `std::io`.)
+///
+/// Most of the methods defined here have an unconstrained type parameter that
+/// must be explicitly instantiated. Typically, it is instantiated with either
+/// the [`BigEndian`] or [`LittleEndian`] types defined in this crate.
+///
+/// # Examples
+///
+/// Read unsigned 16 bit big-endian integers from a [`Read`]:
+///
+/// ```rust
+/// use std::io::Cursor;
+/// use byteorder::{BigEndian, ReadBytesExt};
+///
+/// let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
+/// assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
+/// assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
+/// ```
+///
+/// [`BigEndian`]: enum.BigEndian.html
+/// [`LittleEndian`]: enum.LittleEndian.html
+/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
+pub trait ReadBytesExt: io::Read {
+    /// Reads an unsigned 8 bit integer from the underlying reader.
+    ///
+    /// Note that since this reads a single byte, no byte order conversions
+    /// are used. It is included for completeness.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read unsigned 8 bit integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::ReadBytesExt;
+    ///
+    /// let mut rdr = Cursor::new(vec![2, 5]);
+    /// assert_eq!(2, rdr.read_u8().unwrap());
+    /// assert_eq!(5, rdr.read_u8().unwrap());
+    /// ```
+    #[inline]
+    fn read_u8(&mut self) -> Result<u8> {
+        let mut buf = [0; 1];
+        try!(self.read_exact(&mut buf));
+        Ok(buf[0])
+    }
+
+    /// Reads a signed 8 bit integer from the underlying reader.
+    ///
+    /// Note that since this reads a single byte, no byte order conversions
+    /// are used. It is included for completeness.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read signed 8 bit integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::ReadBytesExt;
+    ///
+    /// let mut rdr = Cursor::new(vec![0x02, 0xfb]);
+    /// assert_eq!(2, rdr.read_i8().unwrap());
+    /// assert_eq!(-5, rdr.read_i8().unwrap());
+    /// ```
+    #[inline]
+    fn read_i8(&mut self) -> Result<i8> {
+        let mut buf = [0; 1];
+        try!(self.read_exact(&mut buf));
+        Ok(buf[0] as i8)
+    }
+
+    /// Reads an unsigned 16 bit integer from the underlying reader.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read unsigned 16 bit big-endian integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
+    /// assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
+    /// assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
+    /// ```
+    #[inline]
+    fn read_u16<T: ByteOrder>(&mut self) -> Result<u16> {
+        let mut buf = [0; 2];
+        try!(self.read_exact(&mut buf));
+        Ok(T::read_u16(&buf))
+    }
+
+    /// Reads a signed 16 bit integer from the underlying reader.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read signed 16 bit big-endian integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![0x00, 0xc1, 0xff, 0x7c]);
+    /// assert_eq!(193, rdr.read_i16::<BigEndian>().unwrap());
+    /// assert_eq!(-132, rdr.read_i16::<BigEndian>().unwrap());
+    /// ```
+    #[inline]
+    fn read_i16<T: ByteOrder>(&mut self) -> Result<i16> {
+        let mut buf = [0; 2];
+        try!(self.read_exact(&mut buf));
+        Ok(T::read_i16(&buf))
+    }
+
+    /// Reads an unsigned 24 bit integer from the underlying reader.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read unsigned 24 bit big-endian integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![0x00, 0x01, 0x0b]);
+    /// assert_eq!(267, rdr.read_u24::<BigEndian>().unwrap());
+    /// ```
+    #[inline]
+    fn read_u24<T: ByteOrder>(&mut self) -> Result<u32> {
+        let mut buf = [0; 3];
+        try!(self.read_exact(&mut buf));
+        Ok(T::read_u24(&buf))
+    }
+
+    /// Reads a signed 24 bit integer from the underlying reader.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read signed 24 bit big-endian integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![0xff, 0x7a, 0x33]);
+    /// assert_eq!(-34253, rdr.read_i24::<BigEndian>().unwrap());
+    /// ```
+    #[inline]
+    fn read_i24<T: ByteOrder>(&mut self) -> Result<i32> {
+        let mut buf = [0; 3];
+        try!(self.read_exact(&mut buf));
+        Ok(T::read_i24(&buf))
+    }
+
+    /// Reads an unsigned 32 bit integer from the underlying reader.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read unsigned 32 bit big-endian integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![0x00, 0x00, 0x01, 0x0b]);
+    /// assert_eq!(267, rdr.read_u32::<BigEndian>().unwrap());
+    /// ```
+    #[inline]
+    fn read_u32<T: ByteOrder>(&mut self) -> Result<u32> {
+        let mut buf = [0; 4];
+        try!(self.read_exact(&mut buf));
+        Ok(T::read_u32(&buf))
+    }
+
+    /// Reads a signed 32 bit integer from the underlying reader.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read signed 32 bit big-endian integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![0xff, 0xff, 0x7a, 0x33]);
+    /// assert_eq!(-34253, rdr.read_i32::<BigEndian>().unwrap());
+    /// ```
+    #[inline]
+    fn read_i32<T: ByteOrder>(&mut self) -> Result<i32> {
+        let mut buf = [0; 4];
+        try!(self.read_exact(&mut buf));
+        Ok(T::read_i32(&buf))
+    }
+
+    /// Reads an unsigned 48 bit integer from the underlying reader.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read unsigned 48 bit big-endian integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![0xb6, 0x71, 0x6b, 0xdc, 0x2b, 0x31]);
+    /// assert_eq!(200598257150769, rdr.read_u48::<BigEndian>().unwrap());
+    /// ```
+    #[inline]
+    fn read_u48<T: ByteOrder>(&mut self) -> Result<u64> {
+        let mut buf = [0; 6];
+        try!(self.read_exact(&mut buf));
+        Ok(T::read_u48(&buf))
+    }
+
+    /// Reads a signed 48 bit integer from the underlying reader.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read signed 48 bit big-endian integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![0x9d, 0x71, 0xab, 0xe7, 0x97, 0x8f]);
+    /// assert_eq!(-108363435763825, rdr.read_i48::<BigEndian>().unwrap());
+    /// ```
+    #[inline]
+    fn read_i48<T: ByteOrder>(&mut self) -> Result<i64> {
+        let mut buf = [0; 6];
+        try!(self.read_exact(&mut buf));
+        Ok(T::read_i48(&buf))
+    }
+
+    /// Reads an unsigned 64 bit integer from the underlying reader.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read an unsigned 64 bit big-endian integer from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83]);
+    /// assert_eq!(918733457491587, rdr.read_u64::<BigEndian>().unwrap());
+    /// ```
+    #[inline]
+    fn read_u64<T: ByteOrder>(&mut self) -> Result<u64> {
+        let mut buf = [0; 8];
+        try!(self.read_exact(&mut buf));
+        Ok(T::read_u64(&buf))
+    }
+
+    /// Reads a signed 64 bit integer from the underlying reader.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read a signed 64 bit big-endian integer from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![0x80, 0, 0, 0, 0, 0, 0, 0]);
+    /// assert_eq!(i64::min_value(), rdr.read_i64::<BigEndian>().unwrap());
+    /// ```
+    #[inline]
+    fn read_i64<T: ByteOrder>(&mut self) -> Result<i64> {
+        let mut buf = [0; 8];
+        try!(self.read_exact(&mut buf));
+        Ok(T::read_i64(&buf))
+    }
+
+    /// Reads an unsigned 128 bit integer from the underlying reader.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read an unsigned 128 bit big-endian integer from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![
+    ///     0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83,
+    ///     0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83
+    /// ]);
+    /// assert_eq!(16947640962301618749969007319746179, rdr.read_u128::<BigEndian>().unwrap());
+    /// ```
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn read_u128<T: ByteOrder>(&mut self) -> Result<u128> {
+        let mut buf = [0; 16];
+        try!(self.read_exact(&mut buf));
+        Ok(T::read_u128(&buf))
+    }
+
+    /// Reads a signed 128 bit integer from the underlying reader.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read a signed 128 bit big-endian integer from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
+    /// assert_eq!(i128::min_value(), rdr.read_i128::<BigEndian>().unwrap());
+    /// ```
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn read_i128<T: ByteOrder>(&mut self) -> Result<i128> {
+        let mut buf = [0; 16];
+        try!(self.read_exact(&mut buf));
+        Ok(T::read_i128(&buf))
+    }
+
+    /// Reads an unsigned n-bytes integer from the underlying reader.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read an unsigned n-byte big-endian integer from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![0x80, 0x74, 0xfa]);
+    /// assert_eq!(8418554, rdr.read_uint::<BigEndian>(3).unwrap());
+    #[inline]
+    fn read_uint<T: ByteOrder>(&mut self, nbytes: usize) -> Result<u64> {
+        let mut buf = [0; 8];
+        try!(self.read_exact(&mut buf[..nbytes]));
+        Ok(T::read_uint(&buf[..nbytes], nbytes))
+    }
+
+    /// Reads a signed n-bytes integer from the underlying reader.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read an unsigned n-byte big-endian integer from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![0xc1, 0xff, 0x7c]);
+    /// assert_eq!(-4063364, rdr.read_int::<BigEndian>(3).unwrap());
+    #[inline]
+    fn read_int<T: ByteOrder>(&mut self, nbytes: usize) -> Result<i64> {
+        let mut buf = [0; 8];
+        try!(self.read_exact(&mut buf[..nbytes]));
+        Ok(T::read_int(&buf[..nbytes], nbytes))
+    }
+
+    /// Reads an unsigned n-bytes integer from the underlying reader.
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn read_uint128<T: ByteOrder>(&mut self, nbytes: usize) -> Result<u128> {
+        let mut buf = [0; 16];
+        try!(self.read_exact(&mut buf[..nbytes]));
+        Ok(T::read_uint128(&buf[..nbytes], nbytes))
+    }
+
+    /// Reads a signed n-bytes integer from the underlying reader.
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn read_int128<T: ByteOrder>(&mut self, nbytes: usize) -> Result<i128> {
+        let mut buf = [0; 16];
+        try!(self.read_exact(&mut buf[..nbytes]));
+        Ok(T::read_int128(&buf[..nbytes], nbytes))
+    }
+
+    /// Reads a IEEE754 single-precision (4 bytes) floating point number from
+    /// the underlying reader.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read a big-endian single-precision floating point number from a `Read`:
+    ///
+    /// ```rust
+    /// use std::f32;
+    /// use std::io::Cursor;
+    ///
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![
+    ///     0x40, 0x49, 0x0f, 0xdb,
+    /// ]);
+    /// assert_eq!(f32::consts::PI, rdr.read_f32::<BigEndian>().unwrap());
+    /// ```
+    #[inline]
+    fn read_f32<T: ByteOrder>(&mut self) -> Result<f32> {
+        let mut buf = [0; 4];
+        try!(self.read_exact(&mut buf));
+        Ok(T::read_f32(&buf))
+    }
+
+    /// Reads a IEEE754 double-precision (8 bytes) floating point number from
+    /// the underlying reader.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read a big-endian double-precision floating point number from a `Read`:
+    ///
+    /// ```rust
+    /// use std::f64;
+    /// use std::io::Cursor;
+    ///
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![
+    ///     0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18,
+    /// ]);
+    /// assert_eq!(f64::consts::PI, rdr.read_f64::<BigEndian>().unwrap());
+    /// ```
+    #[inline]
+    fn read_f64<T: ByteOrder>(&mut self) -> Result<f64> {
+        let mut buf = [0; 8];
+        try!(self.read_exact(&mut buf));
+        Ok(T::read_f64(&buf))
+    }
+
+    /// Reads a sequence of unsigned 16 bit integers from the underlying
+    /// reader.
+    ///
+    /// The given buffer is either filled completely or an error is returned.
+    /// If an error is returned, the contents of `dst` are unspecified.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read a sequence of unsigned 16 bit big-endian integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
+    /// let mut dst = [0; 2];
+    /// rdr.read_u16_into::<BigEndian>(&mut dst).unwrap();
+    /// assert_eq!([517, 768], dst);
+    /// ```
+    #[inline]
+    fn read_u16_into<T: ByteOrder>(&mut self, dst: &mut [u16]) -> Result<()> {
+        {
+            let buf = unsafe { slice_to_u8_mut(dst) };
+            try!(self.read_exact(buf));
+        }
+        T::from_slice_u16(dst);
+        Ok(())
+    }
+
+    /// Reads a sequence of unsigned 32 bit integers from the underlying
+    /// reader.
+    ///
+    /// The given buffer is either filled completely or an error is returned.
+    /// If an error is returned, the contents of `dst` are unspecified.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read a sequence of unsigned 32 bit big-endian integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![0, 0, 2, 5, 0, 0, 3, 0]);
+    /// let mut dst = [0; 2];
+    /// rdr.read_u32_into::<BigEndian>(&mut dst).unwrap();
+    /// assert_eq!([517, 768], dst);
+    /// ```
+    #[inline]
+    fn read_u32_into<T: ByteOrder>(&mut self, dst: &mut [u32]) -> Result<()> {
+        {
+            let buf = unsafe { slice_to_u8_mut(dst) };
+            try!(self.read_exact(buf));
+        }
+        T::from_slice_u32(dst);
+        Ok(())
+    }
+
+    /// Reads a sequence of unsigned 64 bit integers from the underlying
+    /// reader.
+    ///
+    /// The given buffer is either filled completely or an error is returned.
+    /// If an error is returned, the contents of `dst` are unspecified.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read a sequence of unsigned 64 bit big-endian integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![
+    ///     0, 0, 0, 0, 0, 0, 2, 5,
+    ///     0, 0, 0, 0, 0, 0, 3, 0,
+    /// ]);
+    /// let mut dst = [0; 2];
+    /// rdr.read_u64_into::<BigEndian>(&mut dst).unwrap();
+    /// assert_eq!([517, 768], dst);
+    /// ```
+    #[inline]
+    fn read_u64_into<T: ByteOrder>(&mut self, dst: &mut [u64]) -> Result<()> {
+        {
+            let buf = unsafe { slice_to_u8_mut(dst) };
+            try!(self.read_exact(buf));
+        }
+        T::from_slice_u64(dst);
+        Ok(())
+    }
+
+    /// Reads a sequence of unsigned 128 bit integers from the underlying
+    /// reader.
+    ///
+    /// The given buffer is either filled completely or an error is returned.
+    /// If an error is returned, the contents of `dst` are unspecified.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read a sequence of unsigned 128 bit big-endian integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![
+    ///     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5,
+    ///     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,
+    /// ]);
+    /// let mut dst = [0; 2];
+    /// rdr.read_u128_into::<BigEndian>(&mut dst).unwrap();
+    /// assert_eq!([517, 768], dst);
+    /// ```
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn read_u128_into<T: ByteOrder>(
+        &mut self,
+        dst: &mut [u128],
+    ) -> Result<()> {
+        {
+            let buf = unsafe { slice_to_u8_mut(dst) };
+            try!(self.read_exact(buf));
+        }
+        T::from_slice_u128(dst);
+        Ok(())
+    }
+
+    /// Reads a sequence of signed 8 bit integers from the underlying reader.
+    ///
+    /// The given buffer is either filled completely or an error is returned.
+    /// If an error is returned, the contents of `dst` are unspecified.
+    ///
+    /// Note that since each `i8` is a single byte, no byte order conversions
+    /// are used. This method is included because it provides a safe, simple
+    /// way for the caller to read into a `&mut [i8]` buffer. (Without this
+    /// method, the caller would have to either use `unsafe` code or convert
+    /// each byte to `i8` individually.)
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read a sequence of signed 8 bit integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![2, 251, 3]);
+    /// let mut dst = [0; 3];
+    /// rdr.read_i8_into(&mut dst).unwrap();
+    /// assert_eq!([2, -5, 3], dst);
+    /// ```
+    #[inline]
+    fn read_i8_into(&mut self, dst: &mut [i8]) -> Result<()> {
+        let buf = unsafe { slice_to_u8_mut(dst) };
+        self.read_exact(buf)
+    }
+
+    /// Reads a sequence of signed 16 bit integers from the underlying
+    /// reader.
+    ///
+    /// The given buffer is either filled completely or an error is returned.
+    /// If an error is returned, the contents of `dst` are unspecified.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read a sequence of signed 16 bit big-endian integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
+    /// let mut dst = [0; 2];
+    /// rdr.read_i16_into::<BigEndian>(&mut dst).unwrap();
+    /// assert_eq!([517, 768], dst);
+    /// ```
+    #[inline]
+    fn read_i16_into<T: ByteOrder>(&mut self, dst: &mut [i16]) -> Result<()> {
+        {
+            let buf = unsafe { slice_to_u8_mut(dst) };
+            try!(self.read_exact(buf));
+        }
+        T::from_slice_i16(dst);
+        Ok(())
+    }
+
+    /// Reads a sequence of signed 32 bit integers from the underlying
+    /// reader.
+    ///
+    /// The given buffer is either filled completely or an error is returned.
+    /// If an error is returned, the contents of `dst` are unspecified.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read a sequence of signed 32 bit big-endian integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![0, 0, 2, 5, 0, 0, 3, 0]);
+    /// let mut dst = [0; 2];
+    /// rdr.read_i32_into::<BigEndian>(&mut dst).unwrap();
+    /// assert_eq!([517, 768], dst);
+    /// ```
+    #[inline]
+    fn read_i32_into<T: ByteOrder>(&mut self, dst: &mut [i32]) -> Result<()> {
+        {
+            let buf = unsafe { slice_to_u8_mut(dst) };
+            try!(self.read_exact(buf));
+        }
+        T::from_slice_i32(dst);
+        Ok(())
+    }
+
+    /// Reads a sequence of signed 64 bit integers from the underlying
+    /// reader.
+    ///
+    /// The given buffer is either filled completely or an error is returned.
+    /// If an error is returned, the contents of `dst` are unspecified.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read a sequence of signed 64 bit big-endian integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![
+    ///     0, 0, 0, 0, 0, 0, 2, 5,
+    ///     0, 0, 0, 0, 0, 0, 3, 0,
+    /// ]);
+    /// let mut dst = [0; 2];
+    /// rdr.read_i64_into::<BigEndian>(&mut dst).unwrap();
+    /// assert_eq!([517, 768], dst);
+    /// ```
+    #[inline]
+    fn read_i64_into<T: ByteOrder>(&mut self, dst: &mut [i64]) -> Result<()> {
+        {
+            let buf = unsafe { slice_to_u8_mut(dst) };
+            try!(self.read_exact(buf));
+        }
+        T::from_slice_i64(dst);
+        Ok(())
+    }
+
+    /// Reads a sequence of signed 128 bit integers from the underlying
+    /// reader.
+    ///
+    /// The given buffer is either filled completely or an error is returned.
+    /// If an error is returned, the contents of `dst` are unspecified.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read a sequence of signed 128 bit big-endian integers from a `Read`:
+    ///
+    /// ```rust
+    /// use std::io::Cursor;
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![
+    ///     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5,
+    ///     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,
+    /// ]);
+    /// let mut dst = [0; 2];
+    /// rdr.read_i128_into::<BigEndian>(&mut dst).unwrap();
+    /// assert_eq!([517, 768], dst);
+    /// ```
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn read_i128_into<T: ByteOrder>(
+        &mut self,
+        dst: &mut [i128],
+    ) -> Result<()> {
+        {
+            let buf = unsafe { slice_to_u8_mut(dst) };
+            try!(self.read_exact(buf));
+        }
+        T::from_slice_i128(dst);
+        Ok(())
+    }
+
+    /// Reads a sequence of IEEE754 single-precision (4 bytes) floating
+    /// point numbers from the underlying reader.
+    ///
+    /// The given buffer is either filled completely or an error is returned.
+    /// If an error is returned, the contents of `dst` are unspecified.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read a sequence of big-endian single-precision floating point number
+    /// from a `Read`:
+    ///
+    /// ```rust
+    /// use std::f32;
+    /// use std::io::Cursor;
+    ///
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![
+    ///     0x40, 0x49, 0x0f, 0xdb,
+    ///     0x3f, 0x80, 0x00, 0x00,
+    /// ]);
+    /// let mut dst = [0.0; 2];
+    /// rdr.read_f32_into::<BigEndian>(&mut dst).unwrap();
+    /// assert_eq!([f32::consts::PI, 1.0], dst);
+    /// ```
+    #[inline]
+    fn read_f32_into<T: ByteOrder>(
+        &mut self,
+        dst: &mut [f32],
+    ) -> Result<()> {
+        {
+            let buf = unsafe { slice_to_u8_mut(dst) };
+            try!(self.read_exact(buf));
+        }
+        T::from_slice_f32(dst);
+        Ok(())
+    }
+
+    /// **DEPRECATED**.
+    ///
+    /// This method is deprecated. Use `read_f32_into` instead.
+    ///
+    /// Reads a sequence of IEEE754 single-precision (4 bytes) floating
+    /// point numbers from the underlying reader.
+    ///
+    /// The given buffer is either filled completely or an error is returned.
+    /// If an error is returned, the contents of `dst` are unspecified.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read a sequence of big-endian single-precision floating point number
+    /// from a `Read`:
+    ///
+    /// ```rust
+    /// use std::f32;
+    /// use std::io::Cursor;
+    ///
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![
+    ///     0x40, 0x49, 0x0f, 0xdb,
+    ///     0x3f, 0x80, 0x00, 0x00,
+    /// ]);
+    /// let mut dst = [0.0; 2];
+    /// rdr.read_f32_into_unchecked::<BigEndian>(&mut dst).unwrap();
+    /// assert_eq!([f32::consts::PI, 1.0], dst);
+    /// ```
+    #[inline]
+    #[deprecated(since="1.2.0", note="please use `read_f32_into` instead")]
+    fn read_f32_into_unchecked<T: ByteOrder>(
+        &mut self,
+        dst: &mut [f32],
+    ) -> Result<()> {
+        self.read_f32_into::<T>(dst)
+    }
+
+    /// Reads a sequence of IEEE754 double-precision (8 bytes) floating
+    /// point numbers from the underlying reader.
+    ///
+    /// The given buffer is either filled completely or an error is returned.
+    /// If an error is returned, the contents of `dst` are unspecified.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read a sequence of big-endian single-precision floating point number
+    /// from a `Read`:
+    ///
+    /// ```rust
+    /// use std::f64;
+    /// use std::io::Cursor;
+    ///
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![
+    ///     0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18,
+    ///     0x3f, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    /// ]);
+    /// let mut dst = [0.0; 2];
+    /// rdr.read_f64_into::<BigEndian>(&mut dst).unwrap();
+    /// assert_eq!([f64::consts::PI, 1.0], dst);
+    /// ```
+    #[inline]
+    fn read_f64_into<T: ByteOrder>(
+        &mut self,
+        dst: &mut [f64],
+    ) -> Result<()> {
+        {
+            let buf = unsafe { slice_to_u8_mut(dst) };
+            try!(self.read_exact(buf));
+        }
+        T::from_slice_f64(dst);
+        Ok(())
+    }
+
+    /// **DEPRECATED**.
+    ///
+    /// This method is deprecated. Use `read_f64_into` instead.
+    ///
+    /// Reads a sequence of IEEE754 double-precision (8 bytes) floating
+    /// point numbers from the underlying reader.
+    ///
+    /// The given buffer is either filled completely or an error is returned.
+    /// If an error is returned, the contents of `dst` are unspecified.
+    ///
+    /// # Safety
+    ///
+    /// This method is unsafe because there are no guarantees made about the
+    /// floating point values. In particular, this method does not check for
+    /// signaling NaNs, which may result in undefined behavior.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Read::read_exact`].
+    ///
+    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
+    ///
+    /// # Examples
+    ///
+    /// Read a sequence of big-endian single-precision floating point number
+    /// from a `Read`:
+    ///
+    /// ```rust
+    /// use std::f64;
+    /// use std::io::Cursor;
+    ///
+    /// use byteorder::{BigEndian, ReadBytesExt};
+    ///
+    /// let mut rdr = Cursor::new(vec![
+    ///     0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18,
+    ///     0x3f, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    /// ]);
+    /// let mut dst = [0.0; 2];
+    /// rdr.read_f64_into_unchecked::<BigEndian>(&mut dst).unwrap();
+    /// assert_eq!([f64::consts::PI, 1.0], dst);
+    /// ```
+    #[inline]
+    #[deprecated(since="1.2.0", note="please use `read_f64_into` instead")]
+    fn read_f64_into_unchecked<T: ByteOrder>(
+        &mut self,
+        dst: &mut [f64],
+    ) -> Result<()> {
+        self.read_f64_into::<T>(dst)
+    }
+}
+
+/// All types that implement `Read` get methods defined in `ReadBytesExt`
+/// for free.
+impl<R: io::Read + ?Sized> ReadBytesExt for R {}
+
+/// Extends [`Write`] with methods for writing numbers. (For `std::io`.)
+///
+/// Most of the methods defined here have an unconstrained type parameter that
+/// must be explicitly instantiated. Typically, it is instantiated with either
+/// the [`BigEndian`] or [`LittleEndian`] types defined in this crate.
+///
+/// # Examples
+///
+/// Write unsigned 16 bit big-endian integers to a [`Write`]:
+///
+/// ```rust
+/// use byteorder::{BigEndian, WriteBytesExt};
+///
+/// let mut wtr = vec![];
+/// wtr.write_u16::<BigEndian>(517).unwrap();
+/// wtr.write_u16::<BigEndian>(768).unwrap();
+/// assert_eq!(wtr, vec![2, 5, 3, 0]);
+/// ```
+///
+/// [`BigEndian`]: enum.BigEndian.html
+/// [`LittleEndian`]: enum.LittleEndian.html
+/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
+pub trait WriteBytesExt: io::Write {
+    /// Writes an unsigned 8 bit integer to the underlying writer.
+    ///
+    /// Note that since this writes a single byte, no byte order conversions
+    /// are used. It is included for completeness.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Write::write_all`].
+    ///
+    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
+    ///
+    /// # Examples
+    ///
+    /// Write unsigned 8 bit integers to a `Write`:
+    ///
+    /// ```rust
+    /// use byteorder::WriteBytesExt;
+    ///
+    /// let mut wtr = Vec::new();
+    /// wtr.write_u8(2).unwrap();
+    /// wtr.write_u8(5).unwrap();
+    /// assert_eq!(wtr, b"\x02\x05");
+    /// ```
+    #[inline]
+    fn write_u8(&mut self, n: u8) -> Result<()> {
+        self.write_all(&[n])
+    }
+
+    /// Writes a signed 8 bit integer to the underlying writer.
+    ///
+    /// Note that since this writes a single byte, no byte order conversions
+    /// are used. It is included for completeness.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Write::write_all`].
+    ///
+    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
+    ///
+    /// # Examples
+    ///
+    /// Write signed 8 bit integers to a `Write`:
+    ///
+    /// ```rust
+    /// use byteorder::WriteBytesExt;
+    ///
+    /// let mut wtr = Vec::new();
+    /// wtr.write_i8(2).unwrap();
+    /// wtr.write_i8(-5).unwrap();
+    /// assert_eq!(wtr, b"\x02\xfb");
+    /// ```
+    #[inline]
+    fn write_i8(&mut self, n: i8) -> Result<()> {
+        self.write_all(&[n as u8])
+    }
+
+    /// Writes an unsigned 16 bit integer to the underlying writer.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Write::write_all`].
+    ///
+    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
+    ///
+    /// # Examples
+    ///
+    /// Write unsigned 16 bit big-endian integers to a `Write`:
+    ///
+    /// ```rust
+    /// use byteorder::{BigEndian, WriteBytesExt};
+    ///
+    /// let mut wtr = Vec::new();
+    /// wtr.write_u16::<BigEndian>(517).unwrap();
+    /// wtr.write_u16::<BigEndian>(768).unwrap();
+    /// assert_eq!(wtr, b"\x02\x05\x03\x00");
+    /// ```
+    #[inline]
+    fn write_u16<T: ByteOrder>(&mut self, n: u16) -> Result<()> {
+        let mut buf = [0; 2];
+        T::write_u16(&mut buf, n);
+        self.write_all(&buf)
+    }
+
+    /// Writes a signed 16 bit integer to the underlying writer.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Write::write_all`].
+    ///
+    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
+    ///
+    /// # Examples
+    ///
+    /// Write signed 16 bit big-endian integers to a `Write`:
+    ///
+    /// ```rust
+    /// use byteorder::{BigEndian, WriteBytesExt};
+    ///
+    /// let mut wtr = Vec::new();
+    /// wtr.write_i16::<BigEndian>(193).unwrap();
+    /// wtr.write_i16::<BigEndian>(-132).unwrap();
+    /// assert_eq!(wtr, b"\x00\xc1\xff\x7c");
+    /// ```
+    #[inline]
+    fn write_i16<T: ByteOrder>(&mut self, n: i16) -> Result<()> {
+        let mut buf = [0; 2];
+        T::write_i16(&mut buf, n);
+        self.write_all(&buf)
+    }
+
+    /// Writes an unsigned 24 bit integer to the underlying writer.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Write::write_all`].
+    ///
+    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
+    ///
+    /// # Examples
+    ///
+    /// Write unsigned 24 bit big-endian integers to a `Write`:
+    ///
+    /// ```rust
+    /// use byteorder::{BigEndian, WriteBytesExt};
+    ///
+    /// let mut wtr = Vec::new();
+    /// wtr.write_u24::<BigEndian>(267).unwrap();
+    /// wtr.write_u24::<BigEndian>(120111).unwrap();
+    /// assert_eq!(wtr, b"\x00\x01\x0b\x01\xd5\x2f");
+    /// ```
+    #[inline]
+    fn write_u24<T: ByteOrder>(&mut self, n: u32) -> Result<()> {
+        let mut buf = [0; 3];
+        T::write_u24(&mut buf, n);
+        self.write_all(&buf)
+    }
+
+    /// Writes a signed 24 bit integer to the underlying writer.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Write::write_all`].
+    ///
+    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
+    ///
+    /// # Examples
+    ///
+    /// Write signed 24 bit big-endian integers to a `Write`:
+    ///
+    /// ```rust
+    /// use byteorder::{BigEndian, WriteBytesExt};
+    ///
+    /// let mut wtr = Vec::new();
+    /// wtr.write_i24::<BigEndian>(-34253).unwrap();
+    /// wtr.write_i24::<BigEndian>(120111).unwrap();
+    /// assert_eq!(wtr, b"\xff\x7a\x33\x01\xd5\x2f");
+    /// ```
+    #[inline]
+    fn write_i24<T: ByteOrder>(&mut self, n: i32) -> Result<()> {
+        let mut buf = [0; 3];
+        T::write_i24(&mut buf, n);
+        self.write_all(&buf)
+    }
+
+    /// Writes an unsigned 32 bit integer to the underlying writer.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Write::write_all`].
+    ///
+    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
+    ///
+    /// # Examples
+    ///
+    /// Write unsigned 32 bit big-endian integers to a `Write`:
+    ///
+    /// ```rust
+    /// use byteorder::{BigEndian, WriteBytesExt};
+    ///
+    /// let mut wtr = Vec::new();
+    /// wtr.write_u32::<BigEndian>(267).unwrap();
+    /// wtr.write_u32::<BigEndian>(1205419366).unwrap();
+    /// assert_eq!(wtr, b"\x00\x00\x01\x0b\x47\xd9\x3d\x66");
+    /// ```
+    #[inline]
+    fn write_u32<T: ByteOrder>(&mut self, n: u32) -> Result<()> {
+        let mut buf = [0; 4];
+        T::write_u32(&mut buf, n);
+        self.write_all(&buf)
+    }
+
+    /// Writes a signed 32 bit integer to the underlying writer.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Write::write_all`].
+    ///
+    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
+    ///
+    /// # Examples
+    ///
+    /// Write signed 32 bit big-endian integers to a `Write`:
+    ///
+    /// ```rust
+    /// use byteorder::{BigEndian, WriteBytesExt};
+    ///
+    /// let mut wtr = Vec::new();
+    /// wtr.write_i32::<BigEndian>(-34253).unwrap();
+    /// wtr.write_i32::<BigEndian>(1205419366).unwrap();
+    /// assert_eq!(wtr, b"\xff\xff\x7a\x33\x47\xd9\x3d\x66");
+    /// ```
+    #[inline]
+    fn write_i32<T: ByteOrder>(&mut self, n: i32) -> Result<()> {
+        let mut buf = [0; 4];
+        T::write_i32(&mut buf, n);
+        self.write_all(&buf)
+    }
+
+    /// Writes an unsigned 48 bit integer to the underlying writer.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Write::write_all`].
+    ///
+    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
+    ///
+    /// # Examples
+    ///
+    /// Write unsigned 48 bit big-endian integers to a `Write`:
+    ///
+    /// ```rust
+    /// use byteorder::{BigEndian, WriteBytesExt};
+    ///
+    /// let mut wtr = Vec::new();
+    /// wtr.write_u48::<BigEndian>(52360336390828).unwrap();
+    /// wtr.write_u48::<BigEndian>(541).unwrap();
+    /// assert_eq!(wtr, b"\x2f\x9f\x17\x40\x3a\xac\x00\x00\x00\x00\x02\x1d");
+    /// ```
+    #[inline]
+    fn write_u48<T: ByteOrder>(&mut self, n: u64) -> Result<()> {
+        let mut buf = [0; 6];
+        T::write_u48(&mut buf, n);
+        self.write_all(&buf)
+    }
+
+    /// Writes a signed 48 bit integer to the underlying writer.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Write::write_all`].
+    ///
+    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
+    ///
+    /// # Examples
+    ///
+    /// Write signed 48 bit big-endian integers to a `Write`:
+    ///
+    /// ```rust
+    /// use byteorder::{BigEndian, WriteBytesExt};
+    ///
+    /// let mut wtr = Vec::new();
+    /// wtr.write_i48::<BigEndian>(-108363435763825).unwrap();
+    /// wtr.write_i48::<BigEndian>(77).unwrap();
+    /// assert_eq!(wtr, b"\x9d\x71\xab\xe7\x97\x8f\x00\x00\x00\x00\x00\x4d");
+    /// ```
+    #[inline]
+    fn write_i48<T: ByteOrder>(&mut self, n: i64) -> Result<()> {
+        let mut buf = [0; 6];
+        T::write_i48(&mut buf, n);
+        self.write_all(&buf)
+    }
+
+    /// Writes an unsigned 64 bit integer to the underlying writer.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Write::write_all`].
+    ///
+    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
+    ///
+    /// # Examples
+    ///
+    /// Write unsigned 64 bit big-endian integers to a `Write`:
+    ///
+    /// ```rust
+    /// use byteorder::{BigEndian, WriteBytesExt};
+    ///
+    /// let mut wtr = Vec::new();
+    /// wtr.write_u64::<BigEndian>(918733457491587).unwrap();
+    /// wtr.write_u64::<BigEndian>(143).unwrap();
+    /// assert_eq!(wtr, b"\x00\x03\x43\x95\x4d\x60\x86\x83\x00\x00\x00\x00\x00\x00\x00\x8f");
+    /// ```
+    #[inline]
+    fn write_u64<T: ByteOrder>(&mut self, n: u64) -> Result<()> {
+        let mut buf = [0; 8];
+        T::write_u64(&mut buf, n);
+        self.write_all(&buf)
+    }
+
+    /// Writes a signed 64 bit integer to the underlying writer.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Write::write_all`].
+    ///
+    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
+    ///
+    /// # Examples
+    ///
+    /// Write signed 64 bit big-endian integers to a `Write`:
+    ///
+    /// ```rust
+    /// use byteorder::{BigEndian, WriteBytesExt};
+    ///
+    /// let mut wtr = Vec::new();
+    /// wtr.write_i64::<BigEndian>(i64::min_value()).unwrap();
+    /// wtr.write_i64::<BigEndian>(i64::max_value()).unwrap();
+    /// assert_eq!(wtr, b"\x80\x00\x00\x00\x00\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff");
+    /// ```
+    #[inline]
+    fn write_i64<T: ByteOrder>(&mut self, n: i64) -> Result<()> {
+        let mut buf = [0; 8];
+        T::write_i64(&mut buf, n);
+        self.write_all(&buf)
+    }
+
+    /// Writes an unsigned 128 bit integer to the underlying writer.
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn write_u128<T: ByteOrder>(&mut self, n: u128) -> Result<()> {
+        let mut buf = [0; 16];
+        T::write_u128(&mut buf, n);
+        self.write_all(&buf)
+    }
+
+    /// Writes a signed 128 bit integer to the underlying writer.
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn write_i128<T: ByteOrder>(&mut self, n: i128) -> Result<()> {
+        let mut buf = [0; 16];
+        T::write_i128(&mut buf, n);
+        self.write_all(&buf)
+    }
+
+    /// Writes an unsigned n-bytes integer to the underlying writer.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Write::write_all`].
+    ///
+    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
+    ///
+    /// # Panics
+    ///
+    /// If the given integer is not representable in the given number of bytes,
+    /// this method panics. If `nbytes > 8`, this method panics.
+    ///
+    /// # Examples
+    ///
+    /// Write unsigned 40 bit big-endian integers to a `Write`:
+    ///
+    /// ```rust
+    /// use byteorder::{BigEndian, WriteBytesExt};
+    ///
+    /// let mut wtr = Vec::new();
+    /// wtr.write_uint::<BigEndian>(312550384361, 5).unwrap();
+    /// wtr.write_uint::<BigEndian>(43, 5).unwrap();
+    /// assert_eq!(wtr, b"\x48\xc5\x74\x62\xe9\x00\x00\x00\x00\x2b");
+    /// ```
+    #[inline]
+    fn write_uint<T: ByteOrder>(
+        &mut self,
+        n: u64,
+        nbytes: usize,
+    ) -> Result<()> {
+        let mut buf = [0; 8];
+        T::write_uint(&mut buf, n, nbytes);
+        self.write_all(&buf[0..nbytes])
+    }
+
+    /// Writes a signed n-bytes integer to the underlying writer.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Write::write_all`].
+    ///
+    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
+    ///
+    /// # Panics
+    ///
+    /// If the given integer is not representable in the given number of bytes,
+    /// this method panics. If `nbytes > 8`, this method panics.
+    ///
+    /// # Examples
+    ///
+    /// Write signed 56 bit big-endian integers to a `Write`:
+    ///
+    /// ```rust
+    /// use byteorder::{BigEndian, WriteBytesExt};
+    ///
+    /// let mut wtr = Vec::new();
+    /// wtr.write_int::<BigEndian>(-3548172039376767, 7).unwrap();
+    /// wtr.write_int::<BigEndian>(43, 7).unwrap();
+    /// assert_eq!(wtr, b"\xf3\x64\xf4\xd1\xfd\xb0\x81\x00\x00\x00\x00\x00\x00\x2b");
+    /// ```
+    #[inline]
+    fn write_int<T: ByteOrder>(
+        &mut self,
+        n: i64,
+        nbytes: usize,
+    ) -> Result<()> {
+        let mut buf = [0; 8];
+        T::write_int(&mut buf, n, nbytes);
+        self.write_all(&buf[0..nbytes])
+    }
+
+    /// Writes an unsigned n-bytes integer to the underlying writer.
+    ///
+    /// If the given integer is not representable in the given number of bytes,
+    /// this method panics. If `nbytes > 16`, this method panics.
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn write_uint128<T: ByteOrder>(
+        &mut self,
+        n: u128,
+        nbytes: usize,
+    ) -> Result<()> {
+        let mut buf = [0; 16];
+        T::write_uint128(&mut buf, n, nbytes);
+        self.write_all(&buf[0..nbytes])
+    }
+
+    /// Writes a signed n-bytes integer to the underlying writer.
+    ///
+    /// If the given integer is not representable in the given number of bytes,
+    /// this method panics. If `nbytes > 16`, this method panics.
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn write_int128<T: ByteOrder>(
+        &mut self,
+        n: i128,
+        nbytes: usize,
+    ) -> Result<()> {
+        let mut buf = [0; 16];
+        T::write_int128(&mut buf, n, nbytes);
+        self.write_all(&buf[0..nbytes])
+    }
+
+    /// Writes a IEEE754 single-precision (4 bytes) floating point number to
+    /// the underlying writer.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Write::write_all`].
+    ///
+    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
+    ///
+    /// # Examples
+    ///
+    /// Write a big-endian single-precision floating point number to a `Write`:
+    ///
+    /// ```rust
+    /// use std::f32;
+    ///
+    /// use byteorder::{BigEndian, WriteBytesExt};
+    ///
+    /// let mut wtr = Vec::new();
+    /// wtr.write_f32::<BigEndian>(f32::consts::PI).unwrap();
+    /// assert_eq!(wtr, b"\x40\x49\x0f\xdb");
+    /// ```
+    #[inline]
+    fn write_f32<T: ByteOrder>(&mut self, n: f32) -> Result<()> {
+        let mut buf = [0; 4];
+        T::write_f32(&mut buf, n);
+        self.write_all(&buf)
+    }
+
+    /// Writes a IEEE754 double-precision (8 bytes) floating point number to
+    /// the underlying writer.
+    ///
+    /// # Errors
+    ///
+    /// This method returns the same errors as [`Write::write_all`].
+    ///
+    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
+    ///
+    /// # Examples
+    ///
+    /// Write a big-endian double-precision floating point number to a `Write`:
+    ///
+    /// ```rust
+    /// use std::f64;
+    ///
+    /// use byteorder::{BigEndian, WriteBytesExt};
+    ///
+    /// let mut wtr = Vec::new();
+    /// wtr.write_f64::<BigEndian>(f64::consts::PI).unwrap();
+    /// assert_eq!(wtr, b"\x40\x09\x21\xfb\x54\x44\x2d\x18");
+    /// ```
+    #[inline]
+    fn write_f64<T: ByteOrder>(&mut self, n: f64) -> Result<()> {
+        let mut buf = [0; 8];
+        T::write_f64(&mut buf, n);
+        self.write_all(&buf)
+    }
+}
+
+/// All types that implement `Write` get methods defined in `WriteBytesExt`
+/// for free.
+impl<W: io::Write + ?Sized> WriteBytesExt for W {}
+
+/// Convert a slice of T (where T is plain old data) to its mutable binary
+/// representation.
+///
+/// This function is wildly unsafe because it permits arbitrary modification of
+/// the binary representation of any `Copy` type. Use with care.
+unsafe fn slice_to_u8_mut<T: Copy>(slice: &mut [T]) -> &mut [u8] {
+    use std::mem::size_of;
+
+    let len = size_of::<T>() * slice.len();
+    slice::from_raw_parts_mut(slice.as_mut_ptr() as *mut u8, len)
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..db4d24d
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,3328 @@
+/*!
+This crate provides convenience methods for encoding and decoding numbers in
+either [big-endian or little-endian order].
+
+The organization of the crate is pretty simple. A trait, [`ByteOrder`], specifies
+byte conversion methods for each type of number in Rust (sans numbers that have
+a platform dependent size like `usize` and `isize`). Two types, [`BigEndian`]
+and [`LittleEndian`] implement these methods. Finally, [`ReadBytesExt`] and
+[`WriteBytesExt`] provide convenience methods available to all types that
+implement [`Read`] and [`Write`].
+
+An alias, [`NetworkEndian`], for [`BigEndian`] is provided to help improve
+code clarity.
+
+An additional alias, [`NativeEndian`], is provided for the endianness of the
+local platform. This is convenient when serializing data for use and
+conversions are not desired.
+
+# Examples
+
+Read unsigned 16 bit big-endian integers from a [`Read`] type:
+
+```rust
+use std::io::Cursor;
+use byteorder::{BigEndian, ReadBytesExt};
+
+let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
+// Note that we use type parameters to indicate which kind of byte order
+// we want!
+assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
+assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
+```
+
+Write unsigned 16 bit little-endian integers to a [`Write`] type:
+
+```rust
+use byteorder::{LittleEndian, WriteBytesExt};
+
+let mut wtr = vec![];
+wtr.write_u16::<LittleEndian>(517).unwrap();
+wtr.write_u16::<LittleEndian>(768).unwrap();
+assert_eq!(wtr, vec![5, 2, 0, 3]);
+```
+
+# Optional Features
+
+This crate optionally provides support for 128 bit values (`i128` and `u128`)
+when built with the `i128` feature enabled.
+
+This crate can also be used without the standard library.
+
+# Alternatives
+
+Note that as of Rust 1.32, the standard numeric types provide built-in methods
+like `to_le_bytes` and `from_le_bytes`, which support some of the same use
+cases.
+
+[big-endian or little-endian order]: https://en.wikipedia.org/wiki/Endianness
+[`ByteOrder`]: trait.ByteOrder.html
+[`BigEndian`]: enum.BigEndian.html
+[`LittleEndian`]: enum.LittleEndian.html
+[`ReadBytesExt`]: trait.ReadBytesExt.html
+[`WriteBytesExt`]: trait.WriteBytesExt.html
+[`NetworkEndian`]: type.NetworkEndian.html
+[`NativeEndian`]: type.NativeEndian.html
+[`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
+[`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
+*/
+
+#![deny(missing_docs)]
+#![cfg_attr(not(feature = "std"), no_std)]
+
+#[cfg(feature = "std")]
+extern crate core;
+
+#[cfg(test)]
+#[macro_use]
+extern crate doc_comment;
+
+#[cfg(test)]
+doctest!("../README.md");
+
+use core::fmt::Debug;
+use core::hash::Hash;
+use core::ptr::copy_nonoverlapping;
+use core::slice;
+
+#[cfg(feature = "std")]
+pub use io::{ReadBytesExt, WriteBytesExt};
+
+#[cfg(feature = "std")]
+mod io;
+
+#[inline]
+fn extend_sign(val: u64, nbytes: usize) -> i64 {
+    let shift = (8 - nbytes) * 8;
+    (val << shift) as i64 >> shift
+}
+
+#[cfg(byteorder_i128)]
+#[inline]
+fn extend_sign128(val: u128, nbytes: usize) -> i128 {
+    let shift = (16 - nbytes) * 8;
+    (val << shift) as i128 >> shift
+}
+
+#[inline]
+fn unextend_sign(val: i64, nbytes: usize) -> u64 {
+    let shift = (8 - nbytes) * 8;
+    (val << shift) as u64 >> shift
+}
+
+#[cfg(byteorder_i128)]
+#[inline]
+fn unextend_sign128(val: i128, nbytes: usize) -> u128 {
+    let shift = (16 - nbytes) * 8;
+    (val << shift) as u128 >> shift
+}
+
+#[inline]
+fn pack_size(n: u64) -> usize {
+    if n < 1 << 8 {
+        1
+    } else if n < 1 << 16 {
+        2
+    } else if n < 1 << 24 {
+        3
+    } else if n < 1 << 32 {
+        4
+    } else if n < 1 << 40 {
+        5
+    } else if n < 1 << 48 {
+        6
+    } else if n < 1 << 56 {
+        7
+    } else {
+        8
+    }
+}
+
+#[cfg(byteorder_i128)]
+#[inline]
+fn pack_size128(n: u128) -> usize {
+    if n < 1 << 8 {
+        1
+    } else if n < 1 << 16 {
+        2
+    } else if n < 1 << 24 {
+        3
+    } else if n < 1 << 32 {
+        4
+    } else if n < 1 << 40 {
+        5
+    } else if n < 1 << 48 {
+        6
+    } else if n < 1 << 56 {
+        7
+    } else if n < 1 << 64 {
+        8
+    } else if n < 1 << 72 {
+        9
+    } else if n < 1 << 80 {
+        10
+    } else if n < 1 << 88 {
+        11
+    } else if n < 1 << 96 {
+        12
+    } else if n < 1 << 104 {
+        13
+    } else if n < 1 << 112 {
+        14
+    } else if n < 1 << 120 {
+        15
+    } else {
+        16
+    }
+}
+
+mod private {
+    /// Sealed stops crates other than byteorder from implementing any traits
+    /// that use it.
+    pub trait Sealed{}
+    impl Sealed for super::LittleEndian {}
+    impl Sealed for super::BigEndian {}
+}
+
+/// `ByteOrder` describes types that can serialize integers as bytes.
+///
+/// Note that `Self` does not appear anywhere in this trait's definition!
+/// Therefore, in order to use it, you'll need to use syntax like
+/// `T::read_u16(&[0, 1])` where `T` implements `ByteOrder`.
+///
+/// This crate provides two types that implement `ByteOrder`: [`BigEndian`]
+/// and [`LittleEndian`].
+/// This trait is sealed and cannot be implemented for callers to avoid
+/// breaking backwards compatibility when adding new derived traits.
+///
+/// # Examples
+///
+/// Write and read `u32` numbers in little endian order:
+///
+/// ```rust
+/// use byteorder::{ByteOrder, LittleEndian};
+///
+/// let mut buf = [0; 4];
+/// LittleEndian::write_u32(&mut buf, 1_000_000);
+/// assert_eq!(1_000_000, LittleEndian::read_u32(&buf));
+/// ```
+///
+/// Write and read `i16` numbers in big endian order:
+///
+/// ```rust
+/// use byteorder::{ByteOrder, BigEndian};
+///
+/// let mut buf = [0; 2];
+/// BigEndian::write_i16(&mut buf, -5_000);
+/// assert_eq!(-5_000, BigEndian::read_i16(&buf));
+/// ```
+///
+/// [`BigEndian`]: enum.BigEndian.html
+/// [`LittleEndian`]: enum.LittleEndian.html
+pub trait ByteOrder
+    : Clone + Copy + Debug + Default + Eq + Hash + Ord + PartialEq + PartialOrd
+    + private::Sealed
+{
+    /// Reads an unsigned 16 bit integer from `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 2`.
+    fn read_u16(buf: &[u8]) -> u16;
+
+    /// Reads an unsigned 24 bit integer from `buf`, stored in u32.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 3`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read 24 bit `u32` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 3];
+    /// LittleEndian::write_u24(&mut buf, 1_000_000);
+    /// assert_eq!(1_000_000, LittleEndian::read_u24(&buf));
+    /// ```
+    fn read_u24(buf: &[u8]) -> u32 {
+        Self::read_uint(buf, 3) as u32
+    }
+
+    /// Reads an unsigned 32 bit integer from `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 4`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `u32` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 4];
+    /// LittleEndian::write_u32(&mut buf, 1_000_000);
+    /// assert_eq!(1_000_000, LittleEndian::read_u32(&buf));
+    /// ```
+    fn read_u32(buf: &[u8]) -> u32;
+
+    /// Reads an unsigned 48 bit integer from `buf`, stored in u64.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 6`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read 48 bit `u64` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 6];
+    /// LittleEndian::write_u48(&mut buf, 1_000_000_000_000);
+    /// assert_eq!(1_000_000_000_000, LittleEndian::read_u48(&buf));
+    /// ```
+    fn read_u48(buf: &[u8]) -> u64 {
+        Self::read_uint(buf, 6) as u64
+    }
+
+    /// Reads an unsigned 64 bit integer from `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 8`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `u64` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 8];
+    /// LittleEndian::write_u64(&mut buf, 1_000_000);
+    /// assert_eq!(1_000_000, LittleEndian::read_u64(&buf));
+    /// ```
+    fn read_u64(buf: &[u8]) -> u64;
+
+    /// Reads an unsigned 128 bit integer from `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 16`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `u128` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 16];
+    /// LittleEndian::write_u128(&mut buf, 1_000_000);
+    /// assert_eq!(1_000_000, LittleEndian::read_u128(&buf));
+    /// ```
+    #[cfg(byteorder_i128)]
+    fn read_u128(buf: &[u8]) -> u128;
+
+    /// Reads an unsigned n-bytes integer from `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `nbytes < 1` or `nbytes > 8` or
+    /// `buf.len() < nbytes`
+    ///
+    /// # Examples
+    ///
+    /// Write and read an n-byte number in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 3];
+    /// LittleEndian::write_uint(&mut buf, 1_000_000, 3);
+    /// assert_eq!(1_000_000, LittleEndian::read_uint(&buf, 3));
+    /// ```
+    fn read_uint(buf: &[u8], nbytes: usize) -> u64;
+
+    /// Reads an unsigned n-bytes integer from `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `nbytes < 1` or `nbytes > 16` or
+    /// `buf.len() < nbytes`
+    ///
+    /// # Examples
+    ///
+    /// Write and read an n-byte number in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 3];
+    /// LittleEndian::write_uint128(&mut buf, 1_000_000, 3);
+    /// assert_eq!(1_000_000, LittleEndian::read_uint128(&buf, 3));
+    /// ```
+    #[cfg(byteorder_i128)]
+    fn read_uint128(buf: &[u8], nbytes: usize) -> u128;
+
+    /// Writes an unsigned 16 bit integer `n` to `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 2`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `u16` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 2];
+    /// LittleEndian::write_u16(&mut buf, 1_000);
+    /// assert_eq!(1_000, LittleEndian::read_u16(&buf));
+    /// ```
+    fn write_u16(buf: &mut [u8], n: u16);
+
+    /// Writes an unsigned 24 bit integer `n` to `buf`, stored in u32.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 3`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read 24 bit `u32` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 3];
+    /// LittleEndian::write_u24(&mut buf, 1_000_000);
+    /// assert_eq!(1_000_000, LittleEndian::read_u24(&buf));
+    /// ```
+    fn write_u24(buf: &mut [u8], n: u32) {
+        Self::write_uint(buf, n as u64, 3)
+    }
+
+    /// Writes an unsigned 32 bit integer `n` to `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 4`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `u32` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 4];
+    /// LittleEndian::write_u32(&mut buf, 1_000_000);
+    /// assert_eq!(1_000_000, LittleEndian::read_u32(&buf));
+    /// ```
+    fn write_u32(buf: &mut [u8], n: u32);
+
+    /// Writes an unsigned 48 bit integer `n` to `buf`, stored in u64.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 6`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read 48 bit `u64` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 6];
+    /// LittleEndian::write_u48(&mut buf, 1_000_000_000_000);
+    /// assert_eq!(1_000_000_000_000, LittleEndian::read_u48(&buf));
+    /// ```
+    fn write_u48(buf: &mut [u8], n: u64) {
+        Self::write_uint(buf, n as u64, 6)
+    }
+
+    /// Writes an unsigned 64 bit integer `n` to `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 8`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `u64` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 8];
+    /// LittleEndian::write_u64(&mut buf, 1_000_000);
+    /// assert_eq!(1_000_000, LittleEndian::read_u64(&buf));
+    /// ```
+    fn write_u64(buf: &mut [u8], n: u64);
+
+    /// Writes an unsigned 128 bit integer `n` to `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 16`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `u128` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 16];
+    /// LittleEndian::write_u128(&mut buf, 1_000_000);
+    /// assert_eq!(1_000_000, LittleEndian::read_u128(&buf));
+    /// ```
+    #[cfg(byteorder_i128)]
+    fn write_u128(buf: &mut [u8], n: u128);
+
+    /// Writes an unsigned integer `n` to `buf` using only `nbytes`.
+    ///
+    /// # Panics
+    ///
+    /// If `n` is not representable in `nbytes`, or if `nbytes` is `> 8`, then
+    /// this method panics.
+    ///
+    /// # Examples
+    ///
+    /// Write and read an n-byte number in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 3];
+    /// LittleEndian::write_uint(&mut buf, 1_000_000, 3);
+    /// assert_eq!(1_000_000, LittleEndian::read_uint(&buf, 3));
+    /// ```
+    fn write_uint(buf: &mut [u8], n: u64, nbytes: usize);
+
+    /// Writes an unsigned integer `n` to `buf` using only `nbytes`.
+    ///
+    /// # Panics
+    ///
+    /// If `n` is not representable in `nbytes`, or if `nbytes` is `> 16`, then
+    /// this method panics.
+    ///
+    /// # Examples
+    ///
+    /// Write and read an n-byte number in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 3];
+    /// LittleEndian::write_uint128(&mut buf, 1_000_000, 3);
+    /// assert_eq!(1_000_000, LittleEndian::read_uint128(&buf, 3));
+    /// ```
+    #[cfg(byteorder_i128)]
+    fn write_uint128(buf: &mut [u8], n: u128, nbytes: usize);
+
+    /// Reads a signed 16 bit integer from `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 2`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `i16` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 2];
+    /// LittleEndian::write_i16(&mut buf, -1_000);
+    /// assert_eq!(-1_000, LittleEndian::read_i16(&buf));
+    /// ```
+    #[inline]
+    fn read_i16(buf: &[u8]) -> i16 {
+        Self::read_u16(buf) as i16
+    }
+
+    /// Reads a signed 24 bit integer from `buf`, stored in i32.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 3`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read 24 bit `i32` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 3];
+    /// LittleEndian::write_i24(&mut buf, -1_000_000);
+    /// assert_eq!(-1_000_000, LittleEndian::read_i24(&buf));
+    /// ```
+    #[inline]
+    fn read_i24(buf: &[u8]) -> i32 {
+        Self::read_int(buf, 3) as i32
+    }
+
+    /// Reads a signed 32 bit integer from `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 4`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `i32` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 4];
+    /// LittleEndian::write_i32(&mut buf, -1_000_000);
+    /// assert_eq!(-1_000_000, LittleEndian::read_i32(&buf));
+    /// ```
+    #[inline]
+    fn read_i32(buf: &[u8]) -> i32 {
+        Self::read_u32(buf) as i32
+    }
+
+    /// Reads a signed 48 bit integer from `buf`, stored in i64.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 6`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read 48 bit `i64` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 6];
+    /// LittleEndian::write_i48(&mut buf, -1_000_000_000_000);
+    /// assert_eq!(-1_000_000_000_000, LittleEndian::read_i48(&buf));
+    /// ```
+    #[inline]
+    fn read_i48(buf: &[u8]) -> i64 {
+        Self::read_int(buf, 6) as i64
+    }
+
+    /// Reads a signed 64 bit integer from `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 8`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `i64` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 8];
+    /// LittleEndian::write_i64(&mut buf, -1_000_000_000);
+    /// assert_eq!(-1_000_000_000, LittleEndian::read_i64(&buf));
+    /// ```
+    #[inline]
+    fn read_i64(buf: &[u8]) -> i64 {
+        Self::read_u64(buf) as i64
+    }
+
+    /// Reads a signed 128 bit integer from `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 16`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `i128` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 16];
+    /// LittleEndian::write_i128(&mut buf, -1_000_000_000);
+    /// assert_eq!(-1_000_000_000, LittleEndian::read_i128(&buf));
+    /// ```
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn read_i128(buf: &[u8]) -> i128 {
+        Self::read_u128(buf) as i128
+    }
+
+    /// Reads a signed n-bytes integer from `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `nbytes < 1` or `nbytes > 8` or
+    /// `buf.len() < nbytes`
+    ///
+    /// # Examples
+    ///
+    /// Write and read n-length signed numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 3];
+    /// LittleEndian::write_int(&mut buf, -1_000, 3);
+    /// assert_eq!(-1_000, LittleEndian::read_int(&buf, 3));
+    /// ```
+    #[inline]
+    fn read_int(buf: &[u8], nbytes: usize) -> i64 {
+        extend_sign(Self::read_uint(buf, nbytes), nbytes)
+    }
+
+    /// Reads a signed n-bytes integer from `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `nbytes < 1` or `nbytes > 16` or
+    /// `buf.len() < nbytes`
+    ///
+    /// # Examples
+    ///
+    /// Write and read n-length signed numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 3];
+    /// LittleEndian::write_int128(&mut buf, -1_000, 3);
+    /// assert_eq!(-1_000, LittleEndian::read_int128(&buf, 3));
+    /// ```
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn read_int128(buf: &[u8], nbytes: usize) -> i128 {
+        extend_sign128(Self::read_uint128(buf, nbytes), nbytes)
+    }
+
+    /// Reads a IEEE754 single-precision (4 bytes) floating point number.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 4`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `f32` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let e = 2.71828;
+    /// let mut buf = [0; 4];
+    /// LittleEndian::write_f32(&mut buf, e);
+    /// assert_eq!(e, LittleEndian::read_f32(&buf));
+    /// ```
+    #[inline]
+    fn read_f32(buf: &[u8]) -> f32 {
+        unsafe { *(&Self::read_u32(buf) as *const u32 as *const f32) }
+    }
+
+    /// Reads a IEEE754 double-precision (8 bytes) floating point number.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 8`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `f64` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let phi = 1.6180339887;
+    /// let mut buf = [0; 8];
+    /// LittleEndian::write_f64(&mut buf, phi);
+    /// assert_eq!(phi, LittleEndian::read_f64(&buf));
+    /// ```
+    #[inline]
+    fn read_f64(buf: &[u8]) -> f64 {
+        unsafe { *(&Self::read_u64(buf) as *const u64 as *const f64) }
+    }
+
+    /// Writes a signed 16 bit integer `n` to `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 2`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `i16` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 2];
+    /// LittleEndian::write_i16(&mut buf, -1_000);
+    /// assert_eq!(-1_000, LittleEndian::read_i16(&buf));
+    /// ```
+    #[inline]
+    fn write_i16(buf: &mut [u8], n: i16) {
+        Self::write_u16(buf, n as u16)
+    }
+
+    /// Writes a signed 24 bit integer `n` to `buf`, stored in i32.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 3`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read 24 bit `i32` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 3];
+    /// LittleEndian::write_i24(&mut buf, -1_000_000);
+    /// assert_eq!(-1_000_000, LittleEndian::read_i24(&buf));
+    /// ```
+    #[inline]
+    fn write_i24(buf: &mut [u8], n: i32) {
+        Self::write_int(buf, n as i64, 3)
+    }
+
+    /// Writes a signed 32 bit integer `n` to `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 4`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `i32` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 4];
+    /// LittleEndian::write_i32(&mut buf, -1_000_000);
+    /// assert_eq!(-1_000_000, LittleEndian::read_i32(&buf));
+    /// ```
+    #[inline]
+    fn write_i32(buf: &mut [u8], n: i32) {
+        Self::write_u32(buf, n as u32)
+    }
+
+    /// Writes a signed 48 bit integer `n` to `buf`, stored in i64.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 6`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read 48 bit `i64` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 6];
+    /// LittleEndian::write_i48(&mut buf, -1_000_000_000_000);
+    /// assert_eq!(-1_000_000_000_000, LittleEndian::read_i48(&buf));
+    /// ```
+    #[inline]
+    fn write_i48(buf: &mut [u8], n: i64) {
+        Self::write_int(buf, n as i64, 6)
+    }
+
+    /// Writes a signed 64 bit integer `n` to `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 8`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `i64` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 8];
+    /// LittleEndian::write_i64(&mut buf, -1_000_000_000);
+    /// assert_eq!(-1_000_000_000, LittleEndian::read_i64(&buf));
+    /// ```
+    #[inline]
+    fn write_i64(buf: &mut [u8], n: i64) {
+        Self::write_u64(buf, n as u64)
+    }
+
+    /// Writes a signed 128 bit integer `n` to `buf`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 16`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read n-byte `i128` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 16];
+    /// LittleEndian::write_i128(&mut buf, -1_000_000_000);
+    /// assert_eq!(-1_000_000_000, LittleEndian::read_i128(&buf));
+    /// ```
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn write_i128(buf: &mut [u8], n: i128) {
+        Self::write_u128(buf, n as u128)
+    }
+
+    /// Writes a signed integer `n` to `buf` using only `nbytes`.
+    ///
+    /// # Panics
+    ///
+    /// If `n` is not representable in `nbytes`, or if `nbytes` is `> 8`, then
+    /// this method panics.
+    ///
+    /// # Examples
+    ///
+    /// Write and read an n-byte number in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 3];
+    /// LittleEndian::write_int(&mut buf, -1_000, 3);
+    /// assert_eq!(-1_000, LittleEndian::read_int(&buf, 3));
+    /// ```
+    #[inline]
+    fn write_int(buf: &mut [u8], n: i64, nbytes: usize) {
+        Self::write_uint(buf, unextend_sign(n, nbytes), nbytes)
+    }
+
+    /// Writes a signed integer `n` to `buf` using only `nbytes`.
+    ///
+    /// # Panics
+    ///
+    /// If `n` is not representable in `nbytes`, or if `nbytes` is `> 16`, then
+    /// this method panics.
+    ///
+    /// # Examples
+    ///
+    /// Write and read n-length signed numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut buf = [0; 3];
+    /// LittleEndian::write_int128(&mut buf, -1_000, 3);
+    /// assert_eq!(-1_000, LittleEndian::read_int128(&buf, 3));
+    /// ```
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn write_int128(buf: &mut [u8], n: i128, nbytes: usize) {
+        Self::write_uint128(buf, unextend_sign128(n, nbytes), nbytes)
+    }
+
+    /// Writes a IEEE754 single-precision (4 bytes) floating point number.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 4`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `f32` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let e = 2.71828;
+    /// let mut buf = [0; 4];
+    /// LittleEndian::write_f32(&mut buf, e);
+    /// assert_eq!(e, LittleEndian::read_f32(&buf));
+    /// ```
+    #[inline]
+    fn write_f32(buf: &mut [u8], n: f32) {
+        let n = unsafe { *(&n as *const f32 as *const u32) };
+        Self::write_u32(buf, n)
+    }
+
+    /// Writes a IEEE754 double-precision (8 bytes) floating point number.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() < 8`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `f64` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let phi = 1.6180339887;
+    /// let mut buf = [0; 8];
+    /// LittleEndian::write_f64(&mut buf, phi);
+    /// assert_eq!(phi, LittleEndian::read_f64(&buf));
+    /// ```
+    #[inline]
+    fn write_f64(buf: &mut [u8], n: f64) {
+        let n = unsafe { *(&n as *const f64 as *const u64) };
+        Self::write_u64(buf, n)
+    }
+
+    /// Reads unsigned 16 bit integers from `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `src.len() != 2*dst.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `u16` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 8];
+    /// let numbers_given = [1, 2, 0xf00f, 0xffee];
+    /// LittleEndian::write_u16_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0; 4];
+    /// LittleEndian::read_u16_into(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    fn read_u16_into(src: &[u8], dst: &mut [u16]);
+
+    /// Reads unsigned 32 bit integers from `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `src.len() != 4*dst.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `u32` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 16];
+    /// let numbers_given = [1, 2, 0xf00f, 0xffee];
+    /// LittleEndian::write_u32_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0; 4];
+    /// LittleEndian::read_u32_into(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    fn read_u32_into(src: &[u8], dst: &mut [u32]);
+
+    /// Reads unsigned 64 bit integers from `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `src.len() != 8*dst.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `u64` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 32];
+    /// let numbers_given = [1, 2, 0xf00f, 0xffee];
+    /// LittleEndian::write_u64_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0; 4];
+    /// LittleEndian::read_u64_into(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    fn read_u64_into(src: &[u8], dst: &mut [u64]);
+
+    /// Reads unsigned 128 bit integers from `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `src.len() != 16*dst.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `u128` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 64];
+    /// let numbers_given = [1, 2, 0xf00f, 0xffee];
+    /// LittleEndian::write_u128_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0; 4];
+    /// LittleEndian::read_u128_into(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    #[cfg(byteorder_i128)]
+    fn read_u128_into(src: &[u8], dst: &mut [u128]);
+
+    /// Reads signed 16 bit integers from `src` to `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() != 2*dst.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `i16` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 8];
+    /// let numbers_given = [1, 2, 0x0f, 0xee];
+    /// LittleEndian::write_i16_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0; 4];
+    /// LittleEndian::read_i16_into(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    #[inline]
+    fn read_i16_into(src: &[u8], dst: &mut [i16]) {
+        let dst = unsafe {
+            slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u16, dst.len())
+        };
+        Self::read_u16_into(src, dst)
+    }
+
+    /// Reads signed 32 bit integers from `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `src.len() != 4*dst.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `i32` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 16];
+    /// let numbers_given = [1, 2, 0xf00f, 0xffee];
+    /// LittleEndian::write_i32_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0; 4];
+    /// LittleEndian::read_i32_into(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    #[inline]
+    fn read_i32_into(src: &[u8], dst: &mut [i32]) {
+        let dst = unsafe {
+            slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u32, dst.len())
+        };
+        Self::read_u32_into(src, dst);
+    }
+
+    /// Reads signed 64 bit integers from `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `src.len() != 8*dst.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `i64` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 32];
+    /// let numbers_given = [1, 2, 0xf00f, 0xffee];
+    /// LittleEndian::write_i64_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0; 4];
+    /// LittleEndian::read_i64_into(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    #[inline]
+    fn read_i64_into(src: &[u8], dst: &mut [i64]) {
+        let dst = unsafe {
+            slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u64, dst.len())
+        };
+        Self::read_u64_into(src, dst);
+    }
+
+    /// Reads signed 128 bit integers from `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `src.len() != 16*dst.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `i128` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 64];
+    /// let numbers_given = [1, 2, 0xf00f, 0xffee];
+    /// LittleEndian::write_i128_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0; 4];
+    /// LittleEndian::read_i128_into(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn read_i128_into(src: &[u8], dst: &mut [i128]) {
+        let dst = unsafe {
+            slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u128, dst.len())
+        };
+        Self::read_u128_into(src, dst);
+    }
+
+    /// Reads IEEE754 single-precision (4 bytes) floating point numbers from
+    /// `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `src.len() != 4*dst.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `f32` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 16];
+    /// let numbers_given = [1.0, 2.0, 31.312e31, -11.32e19];
+    /// LittleEndian::write_f32_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0.0; 4];
+    /// LittleEndian::read_f32_into(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    #[inline]
+    fn read_f32_into(src: &[u8], dst: &mut [f32]) {
+        let dst = unsafe {
+            slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u32, dst.len())
+        };
+        Self::read_u32_into(src, dst);
+    }
+
+    /// **DEPRECATED**.
+    ///
+    /// This method is deprecated. Use `read_f32_into` instead.
+    /// Reads IEEE754 single-precision (4 bytes) floating point numbers from
+    /// `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `src.len() != 4*dst.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `f32` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 16];
+    /// let numbers_given = [1.0, 2.0, 31.312e31, -11.32e19];
+    /// LittleEndian::write_f32_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0.0; 4];
+    /// LittleEndian::read_f32_into_unchecked(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    #[inline]
+    #[deprecated(since="1.3.0", note="please use `read_f32_into` instead")]
+    fn read_f32_into_unchecked(src: &[u8], dst: &mut [f32]) {
+        Self::read_f32_into(src, dst);
+    }
+
+    /// Reads IEEE754 single-precision (4 bytes) floating point numbers from
+    /// `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `src.len() != 8*dst.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `f64` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 32];
+    /// let numbers_given = [1.0, 2.0, 31.312e211, -11.32e91];
+    /// LittleEndian::write_f64_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0.0; 4];
+    /// LittleEndian::read_f64_into(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    #[inline]
+    fn read_f64_into(src: &[u8], dst: &mut [f64]) {
+        let dst = unsafe {
+            slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u64, dst.len())
+        };
+        Self::read_u64_into(src, dst);
+    }
+
+    /// **DEPRECATED**.
+    ///
+    /// This method is deprecated. Use `read_f64_into` instead.
+    ///
+    /// Reads IEEE754 single-precision (4 bytes) floating point numbers from
+    /// `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `src.len() != 8*dst.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `f64` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 32];
+    /// let numbers_given = [1.0, 2.0, 31.312e211, -11.32e91];
+    /// LittleEndian::write_f64_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0.0; 4];
+    /// LittleEndian::read_f64_into_unchecked(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    #[inline]
+    #[deprecated(since="1.3.0", note="please use `read_f64_into` instead")]
+    fn read_f64_into_unchecked(src: &[u8], dst: &mut [f64]) {
+        Self::read_f64_into(src, dst);
+    }
+
+    /// Writes unsigned 16 bit integers from `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `dst.len() != 2*src.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `u16` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 8];
+    /// let numbers_given = [1, 2, 0xf00f, 0xffee];
+    /// LittleEndian::write_u16_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0; 4];
+    /// LittleEndian::read_u16_into(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    fn write_u16_into(src: &[u16], dst: &mut [u8]);
+
+    /// Writes unsigned 32 bit integers from `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `dst.len() != 4*src.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `u32` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 16];
+    /// let numbers_given = [1, 2, 0xf00f, 0xffee];
+    /// LittleEndian::write_u32_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0; 4];
+    /// LittleEndian::read_u32_into(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    fn write_u32_into(src: &[u32], dst: &mut [u8]);
+
+    /// Writes unsigned 64 bit integers from `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `dst.len() != 8*src.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `u64` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 32];
+    /// let numbers_given = [1, 2, 0xf00f, 0xffee];
+    /// LittleEndian::write_u64_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0; 4];
+    /// LittleEndian::read_u64_into(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    fn write_u64_into(src: &[u64], dst: &mut [u8]);
+
+    /// Writes unsigned 128 bit integers from `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `dst.len() != 16*src.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `u128` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 64];
+    /// let numbers_given = [1, 2, 0xf00f, 0xffee];
+    /// LittleEndian::write_u128_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0; 4];
+    /// LittleEndian::read_u128_into(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    #[cfg(byteorder_i128)]
+    fn write_u128_into(src: &[u128], dst: &mut [u8]);
+
+    /// Writes signed 16 bit integers from `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `buf.len() != 2*src.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `i16` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 8];
+    /// let numbers_given = [1, 2, 0x0f, 0xee];
+    /// LittleEndian::write_i16_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0; 4];
+    /// LittleEndian::read_i16_into(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    fn write_i16_into(src: &[i16], dst: &mut [u8]) {
+        let src = unsafe {
+            slice::from_raw_parts(src.as_ptr() as *const u16, src.len())
+        };
+        Self::write_u16_into(src, dst);
+    }
+
+    /// Writes signed 32 bit integers from `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `dst.len() != 4*src.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `i32` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 16];
+    /// let numbers_given = [1, 2, 0xf00f, 0xffee];
+    /// LittleEndian::write_i32_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0; 4];
+    /// LittleEndian::read_i32_into(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    fn write_i32_into(src: &[i32], dst: &mut [u8]) {
+        let src = unsafe {
+            slice::from_raw_parts(src.as_ptr() as *const u32, src.len())
+        };
+        Self::write_u32_into(src, dst);
+    }
+
+    /// Writes signed 64 bit integers from `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `dst.len() != 8*src.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `i64` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 32];
+    /// let numbers_given = [1, 2, 0xf00f, 0xffee];
+    /// LittleEndian::write_i64_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0; 4];
+    /// LittleEndian::read_i64_into(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    fn write_i64_into(src: &[i64], dst: &mut [u8]) {
+        let src = unsafe {
+            slice::from_raw_parts(src.as_ptr() as *const u64, src.len())
+        };
+        Self::write_u64_into(src, dst);
+    }
+
+    /// Writes signed 128 bit integers from `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `dst.len() != 16*src.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `i128` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 64];
+    /// let numbers_given = [1, 2, 0xf00f, 0xffee];
+    /// LittleEndian::write_i128_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0; 4];
+    /// LittleEndian::read_i128_into(&bytes, &mut numbers_got);
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    #[cfg(byteorder_i128)]
+    fn write_i128_into(src: &[i128], dst: &mut [u8]) {
+        let src = unsafe {
+            slice::from_raw_parts(src.as_ptr() as *const u128, src.len())
+        };
+        Self::write_u128_into(src, dst);
+    }
+
+    /// Writes IEEE754 single-precision (4 bytes) floating point numbers from
+    /// `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `src.len() != 4*dst.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `f32` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 16];
+    /// let numbers_given = [1.0, 2.0, 31.312e31, -11.32e19];
+    /// LittleEndian::write_f32_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0.0; 4];
+    /// unsafe {
+    ///     LittleEndian::read_f32_into(&bytes, &mut numbers_got);
+    /// }
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    fn write_f32_into(src: &[f32], dst: &mut [u8]) {
+        let src = unsafe {
+            slice::from_raw_parts(src.as_ptr() as *const u32, src.len())
+        };
+        Self::write_u32_into(src, dst);
+    }
+
+    /// Writes IEEE754 double-precision (8 bytes) floating point numbers from
+    /// `src` into `dst`.
+    ///
+    /// # Panics
+    ///
+    /// Panics when `src.len() != 8*dst.len()`.
+    ///
+    /// # Examples
+    ///
+    /// Write and read `f64` numbers in little endian order:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, LittleEndian};
+    ///
+    /// let mut bytes = [0; 32];
+    /// let numbers_given = [1.0, 2.0, 31.312e211, -11.32e91];
+    /// LittleEndian::write_f64_into(&numbers_given, &mut bytes);
+    ///
+    /// let mut numbers_got = [0.0; 4];
+    /// unsafe {
+    ///     LittleEndian::read_f64_into(&bytes, &mut numbers_got);
+    /// }
+    /// assert_eq!(numbers_given, numbers_got);
+    /// ```
+    fn write_f64_into(src: &[f64], dst: &mut [u8]) {
+        let src = unsafe {
+            slice::from_raw_parts(src.as_ptr() as *const u64, src.len())
+        };
+        Self::write_u64_into(src, dst);
+    }
+
+    /// Converts the given slice of unsigned 16 bit integers to a particular
+    /// endianness.
+    ///
+    /// If the endianness matches the endianness of the host platform, then
+    /// this is a no-op.
+    ///
+    /// # Examples
+    ///
+    /// Convert the host platform's endianness to big-endian:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, BigEndian};
+    ///
+    /// let mut numbers = [5, 65000];
+    /// BigEndian::from_slice_u16(&mut numbers);
+    /// assert_eq!(numbers, [5u16.to_be(), 65000u16.to_be()]);
+    /// ```
+    fn from_slice_u16(numbers: &mut [u16]);
+
+    /// Converts the given slice of unsigned 32 bit integers to a particular
+    /// endianness.
+    ///
+    /// If the endianness matches the endianness of the host platform, then
+    /// this is a no-op.
+    ///
+    /// # Examples
+    ///
+    /// Convert the host platform's endianness to big-endian:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, BigEndian};
+    ///
+    /// let mut numbers = [5, 65000];
+    /// BigEndian::from_slice_u32(&mut numbers);
+    /// assert_eq!(numbers, [5u32.to_be(), 65000u32.to_be()]);
+    /// ```
+    fn from_slice_u32(numbers: &mut [u32]);
+
+    /// Converts the given slice of unsigned 64 bit integers to a particular
+    /// endianness.
+    ///
+    /// If the endianness matches the endianness of the host platform, then
+    /// this is a no-op.
+    ///
+    /// # Examples
+    ///
+    /// Convert the host platform's endianness to big-endian:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, BigEndian};
+    ///
+    /// let mut numbers = [5, 65000];
+    /// BigEndian::from_slice_u64(&mut numbers);
+    /// assert_eq!(numbers, [5u64.to_be(), 65000u64.to_be()]);
+    /// ```
+    fn from_slice_u64(numbers: &mut [u64]);
+
+    /// Converts the given slice of unsigned 128 bit integers to a particular
+    /// endianness.
+    ///
+    /// If the endianness matches the endianness of the host platform, then
+    /// this is a no-op.
+    ///
+    /// # Examples
+    ///
+    /// Convert the host platform's endianness to big-endian:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, BigEndian};
+    ///
+    /// let mut numbers = [5, 65000];
+    /// BigEndian::from_slice_u128(&mut numbers);
+    /// assert_eq!(numbers, [5u128.to_be(), 65000u128.to_be()]);
+    /// ```
+    #[cfg(byteorder_i128)]
+    fn from_slice_u128(numbers: &mut [u128]);
+
+    /// Converts the given slice of signed 16 bit integers to a particular
+    /// endianness.
+    ///
+    /// If the endianness matches the endianness of the host platform, then
+    /// this is a no-op.
+    ///
+    /// # Examples
+    ///
+    /// Convert the host platform's endianness to big-endian:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, BigEndian};
+    ///
+    /// let mut numbers = [5, 6500];
+    /// BigEndian::from_slice_i16(&mut numbers);
+    /// assert_eq!(numbers, [5i16.to_be(), 6500i16.to_be()]);
+    /// ```
+    #[inline]
+    fn from_slice_i16(src: &mut [i16]) {
+        let src = unsafe {
+            slice::from_raw_parts_mut(src.as_ptr() as *mut u16, src.len())
+        };
+        Self::from_slice_u16(src);
+    }
+
+    /// Converts the given slice of signed 32 bit integers to a particular
+    /// endianness.
+    ///
+    /// If the endianness matches the endianness of the host platform, then
+    /// this is a no-op.
+    ///
+    /// # Examples
+    ///
+    /// Convert the host platform's endianness to big-endian:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, BigEndian};
+    ///
+    /// let mut numbers = [5, 65000];
+    /// BigEndian::from_slice_i32(&mut numbers);
+    /// assert_eq!(numbers, [5i32.to_be(), 65000i32.to_be()]);
+    /// ```
+    #[inline]
+    fn from_slice_i32(src: &mut [i32]) {
+        let src = unsafe {
+            slice::from_raw_parts_mut(src.as_ptr() as *mut u32, src.len())
+        };
+        Self::from_slice_u32(src);
+    }
+
+    /// Converts the given slice of signed 64 bit integers to a particular
+    /// endianness.
+    ///
+    /// If the endianness matches the endianness of the host platform, then
+    /// this is a no-op.
+    ///
+    /// # Examples
+    ///
+    /// Convert the host platform's endianness to big-endian:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, BigEndian};
+    ///
+    /// let mut numbers = [5, 65000];
+    /// BigEndian::from_slice_i64(&mut numbers);
+    /// assert_eq!(numbers, [5i64.to_be(), 65000i64.to_be()]);
+    /// ```
+    #[inline]
+    fn from_slice_i64(src: &mut [i64]) {
+        let src = unsafe {
+            slice::from_raw_parts_mut(src.as_ptr() as *mut u64, src.len())
+        };
+        Self::from_slice_u64(src);
+    }
+
+    /// Converts the given slice of signed 128 bit integers to a particular
+    /// endianness.
+    ///
+    /// If the endianness matches the endianness of the host platform, then
+    /// this is a no-op.
+    ///
+    /// # Examples
+    ///
+    /// Convert the host platform's endianness to big-endian:
+    ///
+    /// ```rust
+    /// use byteorder::{ByteOrder, BigEndian};
+    ///
+    /// let mut numbers = [5, 65000];
+    /// BigEndian::from_slice_i128(&mut numbers);
+    /// assert_eq!(numbers, [5i128.to_be(), 65000i128.to_be()]);
+    /// ```
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn from_slice_i128(src: &mut [i128]) {
+        let src = unsafe {
+            slice::from_raw_parts_mut(src.as_ptr() as *mut u128, src.len())
+        };
+        Self::from_slice_u128(src);
+    }
+
+    /// Converts the given slice of IEEE754 single-precision (4 bytes) floating
+    /// point numbers to a particular endianness.
+    ///
+    /// If the endianness matches the endianness of the host platform, then
+    /// this is a no-op.
+    fn from_slice_f32(numbers: &mut [f32]);
+
+    /// Converts the given slice of IEEE754 double-precision (8 bytes) floating
+    /// point numbers to a particular endianness.
+    ///
+    /// If the endianness matches the endianness of the host platform, then
+    /// this is a no-op.
+    fn from_slice_f64(numbers: &mut [f64]);
+}
+
+/// Defines big-endian serialization.
+///
+/// Note that this type has no value constructor. It is used purely at the
+/// type level.
+///
+/// # Examples
+///
+/// Write and read `u32` numbers in big endian order:
+///
+/// ```rust
+/// use byteorder::{ByteOrder, BigEndian};
+///
+/// let mut buf = [0; 4];
+/// BigEndian::write_u32(&mut buf, 1_000_000);
+/// assert_eq!(1_000_000, BigEndian::read_u32(&buf));
+/// ```
+#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub enum BigEndian {}
+
+impl Default for BigEndian {
+    fn default() -> BigEndian {
+        panic!("BigEndian default")
+    }
+}
+
+/// A type alias for [`BigEndian`].
+///
+/// [`BigEndian`]: enum.BigEndian.html
+pub type BE = BigEndian;
+
+/// Defines little-endian serialization.
+///
+/// Note that this type has no value constructor. It is used purely at the
+/// type level.
+///
+/// # Examples
+///
+/// Write and read `u32` numbers in little endian order:
+///
+/// ```rust
+/// use byteorder::{ByteOrder, LittleEndian};
+///
+/// let mut buf = [0; 4];
+/// LittleEndian::write_u32(&mut buf, 1_000_000);
+/// assert_eq!(1_000_000, LittleEndian::read_u32(&buf));
+/// ```
+#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub enum LittleEndian {}
+
+impl Default for LittleEndian {
+    fn default() -> LittleEndian {
+        panic!("LittleEndian default")
+    }
+}
+
+/// A type alias for [`LittleEndian`].
+///
+/// [`LittleEndian`]: enum.LittleEndian.html
+pub type LE = LittleEndian;
+
+/// Defines network byte order serialization.
+///
+/// Network byte order is defined by [RFC 1700][1] to be big-endian, and is
+/// referred to in several protocol specifications.  This type is an alias of
+/// [`BigEndian`].
+///
+/// [1]: https://tools.ietf.org/html/rfc1700
+///
+/// Note that this type has no value constructor. It is used purely at the
+/// type level.
+///
+/// # Examples
+///
+/// Write and read `i16` numbers in big endian order:
+///
+/// ```rust
+/// use byteorder::{ByteOrder, NetworkEndian, BigEndian};
+///
+/// let mut buf = [0; 2];
+/// BigEndian::write_i16(&mut buf, -5_000);
+/// assert_eq!(-5_000, NetworkEndian::read_i16(&buf));
+/// ```
+///
+/// [`BigEndian`]: enum.BigEndian.html
+pub type NetworkEndian = BigEndian;
+
+/// Defines system native-endian serialization.
+///
+/// Note that this type has no value constructor. It is used purely at the
+/// type level.
+///
+/// On this platform, this is an alias for [`LittleEndian`].
+///
+/// [`LittleEndian`]: enum.LittleEndian.html
+#[cfg(target_endian = "little")]
+pub type NativeEndian = LittleEndian;
+
+/// Defines system native-endian serialization.
+///
+/// Note that this type has no value constructor. It is used purely at the
+/// type level.
+///
+/// On this platform, this is an alias for [`BigEndian`].
+///
+/// [`BigEndian`]: enum.BigEndian.html
+#[cfg(target_endian = "big")]
+pub type NativeEndian = BigEndian;
+
+macro_rules! read_num_bytes {
+    ($ty:ty, $size:expr, $src:expr, $which:ident) => ({
+        assert!($size == ::core::mem::size_of::<$ty>());
+        assert!($size <= $src.len());
+        let mut data: $ty = 0;
+        unsafe {
+            copy_nonoverlapping(
+                $src.as_ptr(),
+                &mut data as *mut $ty as *mut u8,
+                $size);
+        }
+        data.$which()
+    });
+}
+
+macro_rules! write_num_bytes {
+    ($ty:ty, $size:expr, $n:expr, $dst:expr, $which:ident) => ({
+        assert!($size <= $dst.len());
+        unsafe {
+            // N.B. https://github.com/rust-lang/rust/issues/22776
+            let bytes = *(&$n.$which() as *const _ as *const [u8; $size]);
+            copy_nonoverlapping((&bytes).as_ptr(), $dst.as_mut_ptr(), $size);
+        }
+    });
+}
+
+macro_rules! read_slice {
+    ($src:expr, $dst:expr, $size:expr, $which:ident) => {{
+        assert_eq!($src.len(), $size * $dst.len());
+
+        unsafe {
+            copy_nonoverlapping(
+                $src.as_ptr(),
+                $dst.as_mut_ptr() as *mut u8,
+                $src.len());
+        }
+        for v in $dst.iter_mut() {
+            *v = v.$which();
+        }
+    }};
+}
+
+macro_rules! write_slice_native {
+    ($src:expr, $dst:expr, $ty:ty, $size:expr) => {{
+        assert!($size == ::core::mem::size_of::<$ty>());
+        assert_eq!($size * $src.len(), $dst.len());
+
+        unsafe {
+            copy_nonoverlapping(
+                $src.as_ptr() as *const u8,
+                $dst.as_mut_ptr(),
+                $dst.len());
+        }
+    }};
+}
+
+macro_rules! write_slice {
+    ($src:expr, $dst:expr, $ty:ty, $size:expr, $write:expr) => ({
+        assert!($size == ::core::mem::size_of::<$ty>());
+        assert_eq!($size * $src.len(), $dst.len());
+
+        for (&n, chunk) in $src.iter().zip($dst.chunks_mut($size)) {
+            $write(chunk, n);
+        }
+    });
+}
+
+impl ByteOrder for BigEndian {
+    #[inline]
+    fn read_u16(buf: &[u8]) -> u16 {
+        read_num_bytes!(u16, 2, buf, to_be)
+    }
+
+    #[inline]
+    fn read_u32(buf: &[u8]) -> u32 {
+        read_num_bytes!(u32, 4, buf, to_be)
+    }
+
+    #[inline]
+    fn read_u64(buf: &[u8]) -> u64 {
+        read_num_bytes!(u64, 8, buf, to_be)
+    }
+
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn read_u128(buf: &[u8]) -> u128 {
+        read_num_bytes!(u128, 16, buf, to_be)
+    }
+
+    #[inline]
+    fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
+        assert!(1 <= nbytes && nbytes <= 8 && nbytes <= buf.len());
+        let mut out = [0u8; 8];
+        let ptr_out = out.as_mut_ptr();
+        unsafe {
+            copy_nonoverlapping(
+                buf.as_ptr(), ptr_out.offset((8 - nbytes) as isize), nbytes);
+            (*(ptr_out as *const u64)).to_be()
+        }
+    }
+
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn read_uint128(buf: &[u8], nbytes: usize) -> u128 {
+        assert!(1 <= nbytes && nbytes <= 16 && nbytes <= buf.len());
+        let mut out = [0u8; 16];
+        let ptr_out = out.as_mut_ptr();
+        unsafe {
+            copy_nonoverlapping(
+                buf.as_ptr(), ptr_out.offset((16 - nbytes) as isize), nbytes);
+            (*(ptr_out as *const u128)).to_be()
+        }
+    }
+
+    #[inline]
+    fn write_u16(buf: &mut [u8], n: u16) {
+        write_num_bytes!(u16, 2, n, buf, to_be);
+    }
+
+    #[inline]
+    fn write_u32(buf: &mut [u8], n: u32) {
+        write_num_bytes!(u32, 4, n, buf, to_be);
+    }
+
+    #[inline]
+    fn write_u64(buf: &mut [u8], n: u64) {
+        write_num_bytes!(u64, 8, n, buf, to_be);
+    }
+
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn write_u128(buf: &mut [u8], n: u128) {
+        write_num_bytes!(u128, 16, n, buf, to_be);
+    }
+
+    #[inline]
+    fn write_uint(buf: &mut [u8], n: u64, nbytes: usize) {
+        assert!(pack_size(n) <= nbytes && nbytes <= 8);
+        assert!(nbytes <= buf.len());
+        unsafe {
+            let bytes = *(&n.to_be() as *const u64 as *const [u8; 8]);
+            copy_nonoverlapping(
+                bytes.as_ptr().offset((8 - nbytes) as isize),
+                buf.as_mut_ptr(),
+                nbytes);
+        }
+    }
+
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn write_uint128(buf: &mut [u8], n: u128, nbytes: usize) {
+        assert!(pack_size128(n) <= nbytes && nbytes <= 16);
+        assert!(nbytes <= buf.len());
+        unsafe {
+            let bytes = *(&n.to_be() as *const u128 as *const [u8; 16]);
+            copy_nonoverlapping(
+                bytes.as_ptr().offset((16 - nbytes) as isize),
+                buf.as_mut_ptr(),
+                nbytes);
+        }
+    }
+
+    #[inline]
+    fn read_u16_into(src: &[u8], dst: &mut [u16]) {
+        read_slice!(src, dst, 2, to_be);
+    }
+
+    #[inline]
+    fn read_u32_into(src: &[u8], dst: &mut [u32]) {
+        read_slice!(src, dst, 4, to_be);
+    }
+
+    #[inline]
+    fn read_u64_into(src: &[u8], dst: &mut [u64]) {
+        read_slice!(src, dst, 8, to_be);
+    }
+
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn read_u128_into(src: &[u8], dst: &mut [u128]) {
+        read_slice!(src, dst, 16, to_be);
+    }
+
+    #[inline]
+    fn write_u16_into(src: &[u16], dst: &mut [u8]) {
+        if cfg!(target_endian = "big") {
+            write_slice_native!(src, dst, u16, 2);
+        } else {
+            write_slice!(src, dst, u16, 2, Self::write_u16);
+        }
+    }
+
+    #[inline]
+    fn write_u32_into(src: &[u32], dst: &mut [u8]) {
+        if cfg!(target_endian = "big") {
+            write_slice_native!(src, dst, u32, 4);
+        } else {
+            write_slice!(src, dst, u32, 4, Self::write_u32);
+        }
+    }
+
+    #[inline]
+    fn write_u64_into(src: &[u64], dst: &mut [u8]) {
+        if cfg!(target_endian = "big") {
+            write_slice_native!(src, dst, u64, 8);
+        } else {
+            write_slice!(src, dst, u64, 8, Self::write_u64);
+        }
+    }
+
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn write_u128_into(src: &[u128], dst: &mut [u8]) {
+        if cfg!(target_endian = "big") {
+            write_slice_native!(src, dst, u128, 16);
+        } else {
+            write_slice!(src, dst, u128, 16, Self::write_u128);
+        }
+    }
+
+    #[inline]
+    fn from_slice_u16(numbers: &mut [u16]) {
+        if cfg!(target_endian = "little") {
+            for n in numbers {
+                *n = n.to_be();
+            }
+        }
+    }
+
+    #[inline]
+    fn from_slice_u32(numbers: &mut [u32]) {
+        if cfg!(target_endian = "little") {
+            for n in numbers {
+                *n = n.to_be();
+            }
+        }
+    }
+
+    #[inline]
+    fn from_slice_u64(numbers: &mut [u64]) {
+        if cfg!(target_endian = "little") {
+            for n in numbers {
+                *n = n.to_be();
+            }
+        }
+    }
+
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn from_slice_u128(numbers: &mut [u128]) {
+        if cfg!(target_endian = "little") {
+            for n in numbers {
+                *n = n.to_be();
+            }
+        }
+    }
+
+    #[inline]
+    fn from_slice_f32(numbers: &mut [f32]) {
+        if cfg!(target_endian = "little") {
+            for n in numbers {
+                unsafe {
+                    let int = *(n as *const f32 as *const u32);
+                    *n = *(&int.to_be() as *const u32 as *const f32);
+                }
+            }
+        }
+    }
+
+    #[inline]
+    fn from_slice_f64(numbers: &mut [f64]) {
+        if cfg!(target_endian = "little") {
+            for n in numbers {
+                unsafe {
+                    let int = *(n as *const f64 as *const u64);
+                    *n = *(&int.to_be() as *const u64 as *const f64);
+                }
+            }
+        }
+    }
+}
+
+impl ByteOrder for LittleEndian {
+    #[inline]
+    fn read_u16(buf: &[u8]) -> u16 {
+        read_num_bytes!(u16, 2, buf, to_le)
+    }
+
+    #[inline]
+    fn read_u32(buf: &[u8]) -> u32 {
+        read_num_bytes!(u32, 4, buf, to_le)
+    }
+
+    #[inline]
+    fn read_u64(buf: &[u8]) -> u64 {
+        read_num_bytes!(u64, 8, buf, to_le)
+    }
+
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn read_u128(buf: &[u8]) -> u128 {
+        read_num_bytes!(u128, 16, buf, to_le)
+    }
+
+    #[inline]
+    fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
+        assert!(1 <= nbytes && nbytes <= 8 && nbytes <= buf.len());
+        let mut out = [0u8; 8];
+        let ptr_out = out.as_mut_ptr();
+        unsafe {
+            copy_nonoverlapping(buf.as_ptr(), ptr_out, nbytes);
+            (*(ptr_out as *const u64)).to_le()
+        }
+    }
+
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn read_uint128(buf: &[u8], nbytes: usize) -> u128 {
+        assert!(1 <= nbytes && nbytes <= 16 && nbytes <= buf.len());
+        let mut out = [0u8; 16];
+        let ptr_out = out.as_mut_ptr();
+        unsafe {
+            copy_nonoverlapping(buf.as_ptr(), ptr_out, nbytes);
+            (*(ptr_out as *const u128)).to_le()
+        }
+    }
+
+    #[inline]
+    fn write_u16(buf: &mut [u8], n: u16) {
+        write_num_bytes!(u16, 2, n, buf, to_le);
+    }
+
+    #[inline]
+    fn write_u32(buf: &mut [u8], n: u32) {
+        write_num_bytes!(u32, 4, n, buf, to_le);
+    }
+
+    #[inline]
+    fn write_u64(buf: &mut [u8], n: u64) {
+        write_num_bytes!(u64, 8, n, buf, to_le);
+    }
+
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn write_u128(buf: &mut [u8], n: u128) {
+        write_num_bytes!(u128, 16, n, buf, to_le);
+    }
+
+    #[inline]
+    fn write_uint(buf: &mut [u8], n: u64, nbytes: usize) {
+        assert!(pack_size(n as u64) <= nbytes && nbytes <= 8);
+        assert!(nbytes <= buf.len());
+        unsafe {
+            let bytes = *(&n.to_le() as *const u64 as *const [u8; 8]);
+            copy_nonoverlapping(bytes.as_ptr(), buf.as_mut_ptr(), nbytes);
+        }
+    }
+
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn write_uint128(buf: &mut [u8], n: u128, nbytes: usize) {
+        assert!(pack_size128(n as u128) <= nbytes && nbytes <= 16);
+        assert!(nbytes <= buf.len());
+        unsafe {
+            let bytes = *(&n.to_le() as *const u128 as *const [u8; 16]);
+            copy_nonoverlapping(bytes.as_ptr(), buf.as_mut_ptr(), nbytes);
+        }
+    }
+
+    #[inline]
+    fn read_u16_into(src: &[u8], dst: &mut [u16]) {
+        read_slice!(src, dst, 2, to_le);
+    }
+
+    #[inline]
+    fn read_u32_into(src: &[u8], dst: &mut [u32]) {
+        read_slice!(src, dst, 4, to_le);
+    }
+
+    #[inline]
+    fn read_u64_into(src: &[u8], dst: &mut [u64]) {
+        read_slice!(src, dst, 8, to_le);
+    }
+
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn read_u128_into(src: &[u8], dst: &mut [u128]) {
+        read_slice!(src, dst, 16, to_le);
+    }
+
+    #[inline]
+    fn write_u16_into(src: &[u16], dst: &mut [u8]) {
+        if cfg!(target_endian = "little") {
+            write_slice_native!(src, dst, u16, 2);
+        } else {
+            write_slice!(src, dst, u16, 2, Self::write_u16);
+        }
+    }
+
+    #[inline]
+    fn write_u32_into(src: &[u32], dst: &mut [u8]) {
+        if cfg!(target_endian = "little") {
+            write_slice_native!(src, dst, u32, 4);
+        } else {
+            write_slice!(src, dst, u32, 4, Self::write_u32);
+        }
+    }
+
+    #[inline]
+    fn write_u64_into(src: &[u64], dst: &mut [u8]) {
+        if cfg!(target_endian = "little") {
+            write_slice_native!(src, dst, u64, 8);
+        } else {
+            write_slice!(src, dst, u64, 8, Self::write_u64);
+        }
+    }
+
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn write_u128_into(src: &[u128], dst: &mut [u8]) {
+        if cfg!(target_endian = "little") {
+            write_slice_native!(src, dst, u128, 16);
+        } else {
+            write_slice!(src, dst, u128, 16, Self::write_u128);
+        }
+    }
+
+    #[inline]
+    fn from_slice_u16(numbers: &mut [u16]) {
+        if cfg!(target_endian = "big") {
+            for n in numbers {
+                *n = n.to_le();
+            }
+        }
+    }
+
+    #[inline]
+    fn from_slice_u32(numbers: &mut [u32]) {
+        if cfg!(target_endian = "big") {
+            for n in numbers {
+                *n = n.to_le();
+            }
+        }
+    }
+
+    #[inline]
+    fn from_slice_u64(numbers: &mut [u64]) {
+        if cfg!(target_endian = "big") {
+            for n in numbers {
+                *n = n.to_le();
+            }
+        }
+    }
+
+    #[cfg(byteorder_i128)]
+    #[inline]
+    fn from_slice_u128(numbers: &mut [u128]) {
+        if cfg!(target_endian = "big") {
+            for n in numbers {
+                *n = n.to_le();
+            }
+        }
+    }
+
+    #[inline]
+    fn from_slice_f32(numbers: &mut [f32]) {
+        if cfg!(target_endian = "big") {
+            for n in numbers {
+                unsafe {
+                    let int = *(n as *const f32 as *const u32);
+                    *n = *(&int.to_le() as *const u32 as *const f32);
+                }
+            }
+        }
+    }
+
+    #[inline]
+    fn from_slice_f64(numbers: &mut [f64]) {
+        if cfg!(target_endian = "big") {
+            for n in numbers {
+                unsafe {
+                    let int = *(n as *const f64 as *const u64);
+                    *n = *(&int.to_le() as *const u64 as *const f64);
+                }
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    extern crate quickcheck;
+    extern crate rand;
+
+    use self::quickcheck::{QuickCheck, StdGen, Testable};
+    use self::rand::thread_rng;
+    #[cfg(byteorder_i128)]
+    use self::rand::Rng;
+    #[cfg(byteorder_i128)]
+    use self::quickcheck::{Arbitrary, Gen};
+
+    pub const U24_MAX: u32 = 16_777_215;
+    pub const I24_MAX: i32 = 8_388_607;
+    pub const U48_MAX: u64 = 281_474_976_710_655;
+    pub const I48_MAX: i64 = 140_737_488_355_327;
+
+    pub const U64_MAX: u64 = ::core::u64::MAX;
+    pub const I64_MAX: u64 = ::core::i64::MAX as u64;
+
+    macro_rules! calc_max {
+        ($max:expr, $bytes:expr) => { calc_max!($max, $bytes, 8) };
+        ($max:expr, $bytes:expr, $maxbytes:expr) => {
+            ($max - 1) >> (8 * ($maxbytes - $bytes))
+        };
+    }
+
+    #[derive(Clone, Debug)]
+    pub struct Wi128<T>(pub T);
+
+    #[cfg(byteorder_i128)]
+    impl<T: Clone> Wi128<T> {
+        pub fn clone(&self) -> T {
+            self.0.clone()
+        }
+    }
+
+    impl<T: PartialEq> PartialEq<T> for Wi128<T> {
+        fn eq(&self, other: &T) -> bool {
+            self.0.eq(other)
+        }
+    }
+
+    #[cfg(byteorder_i128)]
+    impl Arbitrary for Wi128<u128> {
+        fn arbitrary<G: Gen>(gen: &mut G) -> Wi128<u128> {
+            let max = calc_max!(::core::u128::MAX, gen.size(), 16);
+            let output =
+                (gen.gen::<u64>() as u128) |
+                ((gen.gen::<u64>() as u128) << 64);
+            Wi128(output & (max - 1))
+        }
+    }
+
+    #[cfg(byteorder_i128)]
+    impl Arbitrary for Wi128<i128> {
+        fn arbitrary<G: Gen>(gen: &mut G) -> Wi128<i128> {
+            let max = calc_max!(::core::i128::MAX, gen.size(), 16);
+            let output =
+                (gen.gen::<i64>() as i128) |
+                ((gen.gen::<i64>() as i128) << 64);
+            Wi128(output & (max - 1))
+        }
+    }
+
+    pub fn qc_sized<A: Testable>(f: A, size: u64) {
+        QuickCheck::new()
+            .gen(StdGen::new(thread_rng(), size as usize))
+            .tests(1_00)
+            .max_tests(10_000)
+            .quickcheck(f);
+    }
+
+    macro_rules! qc_byte_order {
+        ($name:ident, $ty_int:ty, $max:expr,
+         $bytes:expr, $read:ident, $write:ident) => (
+            mod $name {
+                use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
+                #[allow(unused_imports)] use super::{ qc_sized, Wi128 };
+
+                #[test]
+                fn big_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let mut buf = [0; 16];
+                        BigEndian::$write(&mut buf, n.clone(), $bytes);
+                        n == BigEndian::$read(&mut buf[..$bytes], $bytes)
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max);
+                }
+
+                #[test]
+                fn little_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let mut buf = [0; 16];
+                        LittleEndian::$write(&mut buf, n.clone(), $bytes);
+                        n == LittleEndian::$read(&mut buf[..$bytes], $bytes)
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max);
+                }
+
+                #[test]
+                fn native_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let mut buf = [0; 16];
+                        NativeEndian::$write(&mut buf, n.clone(), $bytes);
+                        n == NativeEndian::$read(&mut buf[..$bytes], $bytes)
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max);
+                }
+            }
+        );
+        ($name:ident, $ty_int:ty, $max:expr,
+         $read:ident, $write:ident) => (
+            mod $name {
+                use core::mem::size_of;
+                use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
+                #[allow(unused_imports)] use super::{ qc_sized, Wi128 };
+
+                #[test]
+                fn big_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let bytes = size_of::<$ty_int>();
+                        let mut buf = [0; 16];
+                        BigEndian::$write(&mut buf[16 - bytes..], n.clone());
+                        n == BigEndian::$read(&mut buf[16 - bytes..])
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max - 1);
+                }
+
+                #[test]
+                fn little_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let bytes = size_of::<$ty_int>();
+                        let mut buf = [0; 16];
+                        LittleEndian::$write(&mut buf[..bytes], n.clone());
+                        n == LittleEndian::$read(&mut buf[..bytes])
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max - 1);
+                }
+
+                #[test]
+                fn native_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let bytes = size_of::<$ty_int>();
+                        let mut buf = [0; 16];
+                        NativeEndian::$write(&mut buf[..bytes], n.clone());
+                        n == NativeEndian::$read(&mut buf[..bytes])
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max - 1);
+                }
+            }
+        );
+    }
+
+    qc_byte_order!(prop_u16, u16, ::core::u16::MAX as u64, read_u16, write_u16);
+    qc_byte_order!(prop_i16, i16, ::core::i16::MAX as u64, read_i16, write_i16);
+    qc_byte_order!(prop_u24, u32, ::test::U24_MAX as u64, read_u24, write_u24);
+    qc_byte_order!(prop_i24, i32, ::test::I24_MAX as u64, read_i24, write_i24);
+    qc_byte_order!(prop_u32, u32, ::core::u32::MAX as u64, read_u32, write_u32);
+    qc_byte_order!(prop_i32, i32, ::core::i32::MAX as u64, read_i32, write_i32);
+    qc_byte_order!(prop_u48, u64, ::test::U48_MAX as u64, read_u48, write_u48);
+    qc_byte_order!(prop_i48, i64, ::test::I48_MAX as u64, read_i48, write_i48);
+    qc_byte_order!(prop_u64, u64, ::core::u64::MAX as u64, read_u64, write_u64);
+    qc_byte_order!(prop_i64, i64, ::core::i64::MAX as u64, read_i64, write_i64);
+    qc_byte_order!(prop_f32, f32, ::core::u64::MAX as u64, read_f32, write_f32);
+    qc_byte_order!(prop_f64, f64, ::core::i64::MAX as u64, read_f64, write_f64);
+
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_u128, Wi128<u128>, 16 + 1, read_u128, write_u128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_i128, Wi128<i128>, 16 + 1, read_i128, write_i128);
+
+    qc_byte_order!(prop_uint_1,
+        u64, calc_max!(super::U64_MAX, 1), 1, read_uint, write_uint);
+    qc_byte_order!(prop_uint_2,
+        u64, calc_max!(super::U64_MAX, 2), 2, read_uint, write_uint);
+    qc_byte_order!(prop_uint_3,
+        u64, calc_max!(super::U64_MAX, 3), 3, read_uint, write_uint);
+    qc_byte_order!(prop_uint_4,
+        u64, calc_max!(super::U64_MAX, 4), 4, read_uint, write_uint);
+    qc_byte_order!(prop_uint_5,
+        u64, calc_max!(super::U64_MAX, 5), 5, read_uint, write_uint);
+    qc_byte_order!(prop_uint_6,
+        u64, calc_max!(super::U64_MAX, 6), 6, read_uint, write_uint);
+    qc_byte_order!(prop_uint_7,
+        u64, calc_max!(super::U64_MAX, 7), 7, read_uint, write_uint);
+    qc_byte_order!(prop_uint_8,
+        u64, calc_max!(super::U64_MAX, 8), 8, read_uint, write_uint);
+
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_uint128_1,
+        Wi128<u128>, 1, 1, read_uint128, write_uint128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_uint128_2,
+        Wi128<u128>, 2, 2, read_uint128, write_uint128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_uint128_3,
+        Wi128<u128>, 3, 3, read_uint128, write_uint128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_uint128_4,
+        Wi128<u128>, 4, 4, read_uint128, write_uint128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_uint128_5,
+        Wi128<u128>, 5, 5, read_uint128, write_uint128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_uint128_6,
+        Wi128<u128>, 6, 6, read_uint128, write_uint128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_uint128_7,
+        Wi128<u128>, 7, 7, read_uint128, write_uint128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_uint128_8,
+        Wi128<u128>, 8, 8, read_uint128, write_uint128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_uint128_9,
+        Wi128<u128>, 9, 9, read_uint128, write_uint128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_uint128_10,
+        Wi128<u128>, 10, 10, read_uint128, write_uint128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_uint128_11,
+        Wi128<u128>, 11, 11, read_uint128, write_uint128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_uint128_12,
+        Wi128<u128>, 12, 12, read_uint128, write_uint128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_uint128_13,
+        Wi128<u128>, 13, 13, read_uint128, write_uint128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_uint128_14,
+        Wi128<u128>, 14, 14, read_uint128, write_uint128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_uint128_15,
+        Wi128<u128>, 15, 15, read_uint128, write_uint128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_uint128_16,
+        Wi128<u128>, 16, 16, read_uint128, write_uint128);
+
+    qc_byte_order!(prop_int_1,
+        i64, calc_max!(super::I64_MAX, 1), 1, read_int, write_int);
+    qc_byte_order!(prop_int_2,
+        i64, calc_max!(super::I64_MAX, 2), 2, read_int, write_int);
+    qc_byte_order!(prop_int_3,
+        i64, calc_max!(super::I64_MAX, 3), 3, read_int, write_int);
+    qc_byte_order!(prop_int_4,
+        i64, calc_max!(super::I64_MAX, 4), 4, read_int, write_int);
+    qc_byte_order!(prop_int_5,
+        i64, calc_max!(super::I64_MAX, 5), 5, read_int, write_int);
+    qc_byte_order!(prop_int_6,
+        i64, calc_max!(super::I64_MAX, 6), 6, read_int, write_int);
+    qc_byte_order!(prop_int_7,
+        i64, calc_max!(super::I64_MAX, 7), 7, read_int, write_int);
+    qc_byte_order!(prop_int_8,
+        i64, calc_max!(super::I64_MAX, 8), 8, read_int, write_int);
+
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_int128_1,
+        Wi128<i128>, 1, 1, read_int128, write_int128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_int128_2,
+        Wi128<i128>, 2, 2, read_int128, write_int128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_int128_3,
+        Wi128<i128>, 3, 3, read_int128, write_int128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_int128_4,
+        Wi128<i128>, 4, 4, read_int128, write_int128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_int128_5,
+        Wi128<i128>, 5, 5, read_int128, write_int128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_int128_6,
+        Wi128<i128>, 6, 6, read_int128, write_int128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_int128_7,
+        Wi128<i128>, 7, 7, read_int128, write_int128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_int128_8,
+        Wi128<i128>, 8, 8, read_int128, write_int128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_int128_9,
+        Wi128<i128>, 9, 9, read_int128, write_int128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_int128_10,
+        Wi128<i128>, 10, 10, read_int128, write_int128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_int128_11,
+        Wi128<i128>, 11, 11, read_int128, write_int128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_int128_12,
+        Wi128<i128>, 12, 12, read_int128, write_int128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_int128_13,
+        Wi128<i128>, 13, 13, read_int128, write_int128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_int128_14,
+        Wi128<i128>, 14, 14, read_int128, write_int128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_int128_15,
+        Wi128<i128>, 15, 15, read_int128, write_int128);
+    #[cfg(byteorder_i128)]
+    qc_byte_order!(prop_int128_16,
+        Wi128<i128>, 16, 16, read_int128, write_int128);
+
+
+    // Test that all of the byte conversion functions panic when given a
+    // buffer that is too small.
+    //
+    // These tests are critical to ensure safety, otherwise we might end up
+    // with a buffer overflow.
+    macro_rules! too_small {
+        ($name:ident, $maximally_small:expr, $zero:expr,
+         $read:ident, $write:ident) => (
+            mod $name {
+                use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
+
+                #[test]
+                #[should_panic]
+                fn read_big_endian() {
+                    let buf = [0; $maximally_small];
+                    BigEndian::$read(&buf);
+                }
+
+                #[test]
+                #[should_panic]
+                fn read_little_endian() {
+                    let buf = [0; $maximally_small];
+                    LittleEndian::$read(&buf);
+                }
+
+                #[test]
+                #[should_panic]
+                fn read_native_endian() {
+                    let buf = [0; $maximally_small];
+                    NativeEndian::$read(&buf);
+                }
+
+                #[test]
+                #[should_panic]
+                fn write_big_endian() {
+                    let mut buf = [0; $maximally_small];
+                    BigEndian::$write(&mut buf, $zero);
+                }
+
+                #[test]
+                #[should_panic]
+                fn write_little_endian() {
+                    let mut buf = [0; $maximally_small];
+                    LittleEndian::$write(&mut buf, $zero);
+                }
+
+                #[test]
+                #[should_panic]
+                fn write_native_endian() {
+                    let mut buf = [0; $maximally_small];
+                    NativeEndian::$write(&mut buf, $zero);
+                }
+            }
+        );
+        ($name:ident, $maximally_small:expr, $read:ident) => (
+            mod $name {
+                use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
+
+                #[test]
+                #[should_panic]
+                fn read_big_endian() {
+                    let buf = [0; $maximally_small];
+                    BigEndian::$read(&buf, $maximally_small + 1);
+                }
+
+                #[test]
+                #[should_panic]
+                fn read_little_endian() {
+                    let buf = [0; $maximally_small];
+                    LittleEndian::$read(&buf, $maximally_small + 1);
+                }
+
+                #[test]
+                #[should_panic]
+                fn read_native_endian() {
+                    let buf = [0; $maximally_small];
+                    NativeEndian::$read(&buf, $maximally_small + 1);
+                }
+            }
+        );
+    }
+
+    too_small!(small_u16, 1, 0, read_u16, write_u16);
+    too_small!(small_i16, 1, 0, read_i16, write_i16);
+    too_small!(small_u32, 3, 0, read_u32, write_u32);
+    too_small!(small_i32, 3, 0, read_i32, write_i32);
+    too_small!(small_u64, 7, 0, read_u64, write_u64);
+    too_small!(small_i64, 7, 0, read_i64, write_i64);
+    too_small!(small_f32, 3, 0.0, read_f32, write_f32);
+    too_small!(small_f64, 7, 0.0, read_f64, write_f64);
+    #[cfg(byteorder_i128)]
+    too_small!(small_u128, 15, 0, read_u128, write_u128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_i128, 15, 0, read_i128, write_i128);
+
+    too_small!(small_uint_1, 1, read_uint);
+    too_small!(small_uint_2, 2, read_uint);
+    too_small!(small_uint_3, 3, read_uint);
+    too_small!(small_uint_4, 4, read_uint);
+    too_small!(small_uint_5, 5, read_uint);
+    too_small!(small_uint_6, 6, read_uint);
+    too_small!(small_uint_7, 7, read_uint);
+
+    #[cfg(byteorder_i128)]
+    too_small!(small_uint128_1, 1, read_uint128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_uint128_2, 2, read_uint128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_uint128_3, 3, read_uint128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_uint128_4, 4, read_uint128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_uint128_5, 5, read_uint128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_uint128_6, 6, read_uint128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_uint128_7, 7, read_uint128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_uint128_8, 8, read_uint128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_uint128_9, 9, read_uint128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_uint128_10, 10, read_uint128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_uint128_11, 11, read_uint128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_uint128_12, 12, read_uint128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_uint128_13, 13, read_uint128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_uint128_14, 14, read_uint128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_uint128_15, 15, read_uint128);
+
+    too_small!(small_int_1, 1, read_int);
+    too_small!(small_int_2, 2, read_int);
+    too_small!(small_int_3, 3, read_int);
+    too_small!(small_int_4, 4, read_int);
+    too_small!(small_int_5, 5, read_int);
+    too_small!(small_int_6, 6, read_int);
+    too_small!(small_int_7, 7, read_int);
+
+    #[cfg(byteorder_i128)]
+    too_small!(small_int128_1, 1, read_int128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_int128_2, 2, read_int128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_int128_3, 3, read_int128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_int128_4, 4, read_int128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_int128_5, 5, read_int128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_int128_6, 6, read_int128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_int128_7, 7, read_int128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_int128_8, 8, read_int128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_int128_9, 9, read_int128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_int128_10, 10, read_int128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_int128_11, 11, read_int128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_int128_12, 12, read_int128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_int128_13, 13, read_int128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_int128_14, 14, read_int128);
+    #[cfg(byteorder_i128)]
+    too_small!(small_int128_15, 15, read_int128);
+
+    // Test that reading/writing slices enforces the correct lengths.
+    macro_rules! slice_lengths {
+        ($name:ident, $read:ident, $write:ident,
+         $num_bytes:expr, $numbers:expr) => {
+            mod $name {
+                use {ByteOrder, BigEndian, NativeEndian, LittleEndian};
+
+                #[test]
+                #[should_panic]
+                fn read_big_endian() {
+                    let bytes = [0; $num_bytes];
+                    let mut numbers = $numbers;
+                    BigEndian::$read(&bytes, &mut numbers);
+                }
+
+                #[test]
+                #[should_panic]
+                fn read_little_endian() {
+                    let bytes = [0; $num_bytes];
+                    let mut numbers = $numbers;
+                    LittleEndian::$read(&bytes, &mut numbers);
+                }
+
+                #[test]
+                #[should_panic]
+                fn read_native_endian() {
+                    let bytes = [0; $num_bytes];
+                    let mut numbers = $numbers;
+                    NativeEndian::$read(&bytes, &mut numbers);
+                }
+
+                #[test]
+                #[should_panic]
+                fn write_big_endian() {
+                    let mut bytes = [0; $num_bytes];
+                    let numbers = $numbers;
+                    BigEndian::$write(&numbers, &mut bytes);
+                }
+
+                #[test]
+                #[should_panic]
+                fn write_little_endian() {
+                    let mut bytes = [0; $num_bytes];
+                    let numbers = $numbers;
+                    LittleEndian::$write(&numbers, &mut bytes);
+                }
+
+                #[test]
+                #[should_panic]
+                fn write_native_endian() {
+                    let mut bytes = [0; $num_bytes];
+                    let numbers = $numbers;
+                    NativeEndian::$write(&numbers, &mut bytes);
+                }
+            }
+        }
+    }
+
+    slice_lengths!(
+        slice_len_too_small_u16, read_u16_into, write_u16_into, 3, [0, 0]);
+    slice_lengths!(
+        slice_len_too_big_u16, read_u16_into, write_u16_into, 5, [0, 0]);
+    slice_lengths!(
+        slice_len_too_small_i16, read_i16_into, write_i16_into, 3, [0, 0]);
+    slice_lengths!(
+        slice_len_too_big_i16, read_i16_into, write_i16_into, 5, [0, 0]);
+
+    slice_lengths!(
+        slice_len_too_small_u32, read_u32_into, write_u32_into, 7, [0, 0]);
+    slice_lengths!(
+        slice_len_too_big_u32, read_u32_into, write_u32_into, 9, [0, 0]);
+    slice_lengths!(
+        slice_len_too_small_i32, read_i32_into, write_i32_into, 7, [0, 0]);
+    slice_lengths!(
+        slice_len_too_big_i32, read_i32_into, write_i32_into, 9, [0, 0]);
+
+    slice_lengths!(
+        slice_len_too_small_u64, read_u64_into, write_u64_into, 15, [0, 0]);
+    slice_lengths!(
+        slice_len_too_big_u64, read_u64_into, write_u64_into, 17, [0, 0]);
+    slice_lengths!(
+        slice_len_too_small_i64, read_i64_into, write_i64_into, 15, [0, 0]);
+    slice_lengths!(
+        slice_len_too_big_i64, read_i64_into, write_i64_into, 17, [0, 0]);
+
+    #[cfg(byteorder_i128)]
+    slice_lengths!(
+        slice_len_too_small_u128, read_u128_into, write_u128_into, 31, [0, 0]);
+    #[cfg(byteorder_i128)]
+    slice_lengths!(
+        slice_len_too_big_u128, read_u128_into, write_u128_into, 33, [0, 0]);
+    #[cfg(byteorder_i128)]
+    slice_lengths!(
+        slice_len_too_small_i128, read_i128_into, write_i128_into, 31, [0, 0]);
+    #[cfg(byteorder_i128)]
+    slice_lengths!(
+        slice_len_too_big_i128, read_i128_into, write_i128_into, 33, [0, 0]);
+
+    #[test]
+    fn uint_bigger_buffer() {
+        use {ByteOrder, LittleEndian};
+        let n = LittleEndian::read_uint(&[1, 2, 3, 4, 5, 6, 7, 8], 5);
+        assert_eq!(n, 0x0504030201);
+    }
+}
+
+#[cfg(test)]
+#[cfg(feature = "std")]
+mod stdtests {
+    extern crate quickcheck;
+    extern crate rand;
+
+    use self::quickcheck::{QuickCheck, StdGen, Testable};
+    use self::rand::thread_rng;
+
+    fn qc_unsized<A: Testable>(f: A) {
+
+        QuickCheck::new()
+            .gen(StdGen::new(thread_rng(), 16))
+            .tests(1_00)
+            .max_tests(10_000)
+            .quickcheck(f);
+    }
+
+    macro_rules! calc_max {
+        ($max:expr, $bytes:expr) => { ($max - 1) >> (8 * (8 - $bytes)) };
+    }
+
+    macro_rules! qc_bytes_ext {
+        ($name:ident, $ty_int:ty, $max:expr,
+         $bytes:expr, $read:ident, $write:ident) => (
+            mod $name {
+                use std::io::Cursor;
+                use {
+                    ReadBytesExt, WriteBytesExt,
+                    BigEndian, NativeEndian, LittleEndian,
+                };
+                #[allow(unused_imports)] use test::{qc_sized, Wi128};
+
+                #[test]
+                fn big_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let mut wtr = vec![];
+                        wtr.$write::<BigEndian>(n.clone()).unwrap();
+                        let offset = wtr.len() - $bytes;
+                        let mut rdr = Cursor::new(&mut wtr[offset..]);
+                        n == rdr.$read::<BigEndian>($bytes).unwrap()
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max);
+                }
+
+                #[test]
+                fn little_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let mut wtr = vec![];
+                        wtr.$write::<LittleEndian>(n.clone()).unwrap();
+                        let mut rdr = Cursor::new(wtr);
+                        n == rdr.$read::<LittleEndian>($bytes).unwrap()
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max);
+                }
+
+                #[test]
+                fn native_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let mut wtr = vec![];
+                        wtr.$write::<NativeEndian>(n.clone()).unwrap();
+                        let offset = if cfg!(target_endian = "big") {
+                            wtr.len() - $bytes
+                        } else {
+                            0
+                        };
+                        let mut rdr = Cursor::new(&mut wtr[offset..]);
+                        n == rdr.$read::<NativeEndian>($bytes).unwrap()
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max);
+                }
+            }
+        );
+        ($name:ident, $ty_int:ty, $max:expr, $read:ident, $write:ident) => (
+            mod $name {
+                use std::io::Cursor;
+                use {
+                    ReadBytesExt, WriteBytesExt,
+                    BigEndian, NativeEndian, LittleEndian,
+                };
+                #[allow(unused_imports)] use test::{qc_sized, Wi128};
+
+                #[test]
+                fn big_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let mut wtr = vec![];
+                        wtr.$write::<BigEndian>(n.clone()).unwrap();
+                        let mut rdr = Cursor::new(wtr);
+                        n == rdr.$read::<BigEndian>().unwrap()
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max - 1);
+                }
+
+                #[test]
+                fn little_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let mut wtr = vec![];
+                        wtr.$write::<LittleEndian>(n.clone()).unwrap();
+                        let mut rdr = Cursor::new(wtr);
+                        n == rdr.$read::<LittleEndian>().unwrap()
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max - 1);
+                }
+
+                #[test]
+                fn native_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let mut wtr = vec![];
+                        wtr.$write::<NativeEndian>(n.clone()).unwrap();
+                        let mut rdr = Cursor::new(wtr);
+                        n == rdr.$read::<NativeEndian>().unwrap()
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max - 1);
+                }
+            }
+        );
+    }
+
+    qc_bytes_ext!(prop_ext_u16,
+        u16, ::std::u16::MAX as u64, read_u16, write_u16);
+    qc_bytes_ext!(prop_ext_i16,
+        i16, ::std::i16::MAX as u64, read_i16, write_i16);
+    qc_bytes_ext!(prop_ext_u32,
+        u32, ::std::u32::MAX as u64, read_u32, write_u32);
+    qc_bytes_ext!(prop_ext_i32,
+        i32, ::std::i32::MAX as u64, read_i32, write_i32);
+    qc_bytes_ext!(prop_ext_u64,
+        u64, ::std::u64::MAX as u64, read_u64, write_u64);
+    qc_bytes_ext!(prop_ext_i64,
+        i64, ::std::i64::MAX as u64, read_i64, write_i64);
+    qc_bytes_ext!(prop_ext_f32,
+        f32, ::std::u64::MAX as u64, read_f32, write_f32);
+    qc_bytes_ext!(prop_ext_f64,
+        f64, ::std::i64::MAX as u64, read_f64, write_f64);
+
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_u128, Wi128<u128>, 16 + 1, read_u128, write_u128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_i128, Wi128<i128>, 16 + 1, read_i128, write_i128);
+
+    qc_bytes_ext!(prop_ext_uint_1,
+        u64, calc_max!(::test::U64_MAX, 1), 1, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_2,
+        u64, calc_max!(::test::U64_MAX, 2), 2, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_3,
+        u64, calc_max!(::test::U64_MAX, 3), 3, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_4,
+        u64, calc_max!(::test::U64_MAX, 4), 4, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_5,
+        u64, calc_max!(::test::U64_MAX, 5), 5, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_6,
+        u64, calc_max!(::test::U64_MAX, 6), 6, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_7,
+        u64, calc_max!(::test::U64_MAX, 7), 7, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_8,
+        u64, calc_max!(::test::U64_MAX, 8), 8, read_uint, write_u64);
+
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_uint128_1,
+        Wi128<u128>, 1, 1, read_uint128, write_u128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_uint128_2,
+        Wi128<u128>, 2, 2, read_uint128, write_u128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_uint128_3,
+        Wi128<u128>, 3, 3, read_uint128, write_u128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_uint128_4,
+        Wi128<u128>, 4, 4, read_uint128, write_u128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_uint128_5,
+        Wi128<u128>, 5, 5, read_uint128, write_u128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_uint128_6,
+        Wi128<u128>, 6, 6, read_uint128, write_u128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_uint128_7,
+        Wi128<u128>, 7, 7, read_uint128, write_u128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_uint128_8,
+        Wi128<u128>, 8, 8, read_uint128, write_u128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_uint128_9,
+        Wi128<u128>, 9, 9, read_uint128, write_u128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_uint128_10,
+        Wi128<u128>, 10, 10, read_uint128, write_u128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_uint128_11,
+        Wi128<u128>, 11, 11, read_uint128, write_u128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_uint128_12,
+        Wi128<u128>, 12, 12, read_uint128, write_u128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_uint128_13,
+        Wi128<u128>, 13, 13, read_uint128, write_u128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_uint128_14,
+        Wi128<u128>, 14, 14, read_uint128, write_u128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_uint128_15,
+        Wi128<u128>, 15, 15, read_uint128, write_u128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_uint128_16,
+        Wi128<u128>, 16, 16, read_uint128, write_u128);
+
+    qc_bytes_ext!(prop_ext_int_1,
+        i64, calc_max!(::test::I64_MAX, 1), 1, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_2,
+        i64, calc_max!(::test::I64_MAX, 2), 2, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_3,
+        i64, calc_max!(::test::I64_MAX, 3), 3, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_4,
+        i64, calc_max!(::test::I64_MAX, 4), 4, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_5,
+        i64, calc_max!(::test::I64_MAX, 5), 5, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_6,
+        i64, calc_max!(::test::I64_MAX, 6), 6, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_7,
+        i64, calc_max!(::test::I64_MAX, 1), 7, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_8,
+        i64, calc_max!(::test::I64_MAX, 8), 8, read_int, write_i64);
+
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_int128_1,
+        Wi128<i128>, 1, 1, read_int128, write_i128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_int128_2,
+        Wi128<i128>, 2, 2, read_int128, write_i128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_int128_3,
+        Wi128<i128>, 3, 3, read_int128, write_i128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_int128_4,
+        Wi128<i128>, 4, 4, read_int128, write_i128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_int128_5,
+        Wi128<i128>, 5, 5, read_int128, write_i128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_int128_6,
+        Wi128<i128>, 6, 6, read_int128, write_i128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_int128_7,
+        Wi128<i128>, 7, 7, read_int128, write_i128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_int128_8,
+        Wi128<i128>, 8, 8, read_int128, write_i128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_int128_9,
+        Wi128<i128>, 9, 9, read_int128, write_i128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_int128_10,
+        Wi128<i128>, 10, 10, read_int128, write_i128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_int128_11,
+        Wi128<i128>, 11, 11, read_int128, write_i128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_int128_12,
+        Wi128<i128>, 12, 12, read_int128, write_i128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_int128_13,
+        Wi128<i128>, 13, 13, read_int128, write_i128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_int128_14,
+        Wi128<i128>, 14, 14, read_int128, write_i128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_int128_15,
+        Wi128<i128>, 15, 15, read_int128, write_i128);
+    #[cfg(byteorder_i128)]
+    qc_bytes_ext!(prop_ext_int128_16,
+        Wi128<i128>, 16, 16, read_int128, write_i128);
+
+    // Test slice serialization/deserialization.
+    macro_rules! qc_slice {
+        ($name:ident, $ty_int:ty, $read:ident, $write:ident, $zero:expr) => {
+            mod $name {
+                use core::mem::size_of;
+                use {ByteOrder, BigEndian, NativeEndian, LittleEndian};
+                use super::qc_unsized;
+                #[allow(unused_imports)]
+                use test::Wi128;
+
+                #[test]
+                fn big_endian() {
+                    #[allow(unused_unsafe)]
+                    fn prop(numbers: Vec<$ty_int>) -> bool {
+                        let numbers: Vec<_> = numbers
+                            .into_iter()
+                            .map(|x| x.clone())
+                            .collect();
+                        let num_bytes = size_of::<$ty_int>() * numbers.len();
+                        let mut bytes = vec![0; num_bytes];
+
+                        BigEndian::$write(&numbers, &mut bytes);
+
+                        let mut got = vec![$zero; numbers.len()];
+                        unsafe { BigEndian::$read(&bytes, &mut got); }
+
+                        numbers == got
+                    }
+                    qc_unsized(prop as fn(_) -> bool);
+                }
+
+                #[test]
+                fn little_endian() {
+                    #[allow(unused_unsafe)]
+                    fn prop(numbers: Vec<$ty_int>) -> bool {
+                        let numbers: Vec<_> = numbers
+                            .into_iter()
+                            .map(|x| x.clone())
+                            .collect();
+                        let num_bytes = size_of::<$ty_int>() * numbers.len();
+                        let mut bytes = vec![0; num_bytes];
+
+                        LittleEndian::$write(&numbers, &mut bytes);
+
+                        let mut got = vec![$zero; numbers.len()];
+                        unsafe { LittleEndian::$read(&bytes, &mut got); }
+
+                        numbers == got
+                    }
+                    qc_unsized(prop as fn(_) -> bool);
+                }
+
+                #[test]
+                fn native_endian() {
+                    #[allow(unused_unsafe)]
+                    fn prop(numbers: Vec<$ty_int>) -> bool {
+                        let numbers: Vec<_> = numbers
+                            .into_iter()
+                            .map(|x| x.clone())
+                            .collect();
+                        let num_bytes = size_of::<$ty_int>() * numbers.len();
+                        let mut bytes = vec![0; num_bytes];
+
+                        NativeEndian::$write(&numbers, &mut bytes);
+
+                        let mut got = vec![$zero; numbers.len()];
+                        unsafe { NativeEndian::$read(&bytes, &mut got); }
+
+                        numbers == got
+                    }
+                    qc_unsized(prop as fn(_) -> bool);
+                }
+            }
+        }
+    }
+
+    qc_slice!(prop_slice_u16, u16, read_u16_into, write_u16_into, 0);
+    qc_slice!(prop_slice_i16, i16, read_i16_into, write_i16_into, 0);
+    qc_slice!(prop_slice_u32, u32, read_u32_into, write_u32_into, 0);
+    qc_slice!(prop_slice_i32, i32, read_i32_into, write_i32_into, 0);
+    qc_slice!(prop_slice_u64, u64, read_u64_into, write_u64_into, 0);
+    qc_slice!(prop_slice_i64, i64, read_i64_into, write_i64_into, 0);
+    #[cfg(byteorder_i128)]
+    qc_slice!(
+        prop_slice_u128, Wi128<u128>, read_u128_into, write_u128_into, 0);
+    #[cfg(byteorder_i128)]
+    qc_slice!(
+        prop_slice_i128, Wi128<i128>, read_i128_into, write_i128_into, 0);
+
+    qc_slice!(
+        prop_slice_f32, f32, read_f32_into, write_f32_into, 0.0);
+    qc_slice!(
+        prop_slice_f64, f64, read_f64_into, write_f64_into, 0.0);
+}