/* Copyright 2016 The encode_unicode Developers
 *
 * Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
 * http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
 * http://opensource.org/licenses/MIT>, at your option. This file may not be
 * copied, modified, or distributed except according to those terms.
 */

#![allow(unused_unsafe)]// explicit unsafe{} blocks in unsafe functions are a good thing.

use utf8_char::Utf8Char;
use utf16_char::Utf16Char;
use utf8_iterators::*;
use utf16_iterators::*;
use decoding_iterators::*;
use error::*;
extern crate core;
use self::core::{char, u32, mem};
use self::core::ops::{Not, Index, RangeFull};
use self::core::borrow::Borrow;
#[cfg(feature="ascii")]
extern crate ascii;
#[cfg(feature="ascii")]
use self::ascii::AsciiStr;

// TODO better docs and tests

/// Methods for working with `u8`s as UTF-8 bytes.
pub trait U8UtfExt {
    /// How many more bytes will you need to complete this codepoint?
    ///
    /// # Errors
    ///
    /// An error is returned if the byte is not a valid start of an UTF-8
    /// codepoint:
    ///
    /// * `128..192`: ContinuationByte
    /// * `248..`: TooLongSequence
    ///
    /// Values in 244..248 represent a too high codepoint, but do not cause an
    /// error.
    fn extra_utf8_bytes(self) -> Result<usize,InvalidUtf8FirstByte>;

    /// How many more bytes will you need to complete this codepoint?
    ///
    /// This function assumes that the byte is a valid UTF-8 start, and might
    /// return any value otherwise. (but the function is pure and safe to call
    /// with any value).
    fn extra_utf8_bytes_unchecked(self) -> usize;
}

impl U8UtfExt for u8 {
    #[inline]
    fn extra_utf8_bytes(self) -> Result<usize,InvalidUtf8FirstByte> {
        use error::InvalidUtf8FirstByte::{ContinuationByte,TooLongSeqence};
        // the bit twiddling is explained in extra_utf8_bytes_unchecked()
        if self < 128 {
            return Ok(0);
        }
        match ((self as u32)<<25).not().leading_zeros() {
            n @ 1...3 => Ok(n as usize),
            0 => Err(ContinuationByte),
            _ => Err(TooLongSeqence),
        }
    }
    #[inline]
    fn extra_utf8_bytes_unchecked(self) -> usize {
        // For fun I've optimized this function (for x86 instruction count):
        // The most straightforward implementation, that lets the compiler do
        // the optimizing:
        //match self {
        //    0b0000_0000...0b0111_1111 => 0,
        //    0b1100_0010...0b1101_1111 => 1,
        //    0b1110_0000...0b1110_1111 => 2,
        //    0b1111_0000...0b1111_0100 => 3,
        //                _             => whatever()
        //}
        // Using `unsafe{self::core::hint::unreachable_unchecked()}` for the
        // "don't care" case is a terrible idea: while having the function
        // non-deterministically return whatever happens to be in a register
        // MIGHT be acceptable, it permits the function to not `ret`urn at all,
        // but let execution fall through to whatever comes after it in the
        // binary! (in other words completely UB).
        // Currently unreachable_unchecked() might trap too,
        // which is certainly not what we want.
        // I also think `unsafe{mem::unitialized()}` is much more likely to
        // explicitly produce whatever happens to be in a register than tell
        // the compiler it can ignore this branch but needs to produce a value.
        //
        // From the bit patterns we see that for non-ASCII values the result is
        // (number of leading set bits) - 1
        // The standard library doesn't have a method for counting leading ones,
        // but it has leading_zeros(), which can be used after inverting.
        // This function can therefore be reduced to the one-liner
        //`self.not().leading_zeros().saturating_sub(1) as usize`, which would
        // be branchless for architectures with instructions for
        // leading_zeros() and saturating_sub().

        // Shortest version as long as ASCII-ness can be predicted: (especially
        // if the BSR instruction which leading_zeros() uses is microcoded or
        // doesn't exist)
        // u8.leading_zeros() would cast to a bigger type internally, so that's
        // free. compensating by shifting left by 24 before inverting lets the
        // compiler know that the value passed to leading_zeros() is not zero,
        // for which BSR's output is undefined and leading_zeros() normally has
        // special case with a branch.
        // Shifting one bit too many left acts as a saturating_sub(1).
        if self<128 {0} else {((self as u32)<<25).not().leading_zeros() as usize}

        // Branchless but longer version: (9 instructions)
        // It's tempting to try (self|0x80).not().leading_zeros().wrapping_sub(1),
        // but that produces high lengths for ASCII values 0b01xx_xxxx.
        // If we could somehow (branchlessy) clear that bit for ASCII values...
        // We can by masking with the value shifted right with sign extension!
        // (any nonzero number of bits in range works)
        //let extended = self as i8 as i32;
        //let ascii_cleared = (extended<<25) & (extended>>25);
        //ascii_cleared.not().leading_zeros() as usize

        // cmov version: (7 instructions)
        //(((self as u32)<<24).not().leading_zeros() as usize).saturating_sub(1)
    }
}


/// Methods for working with `u16`s as UTF-16 units.
pub trait U16UtfExt {
    /// Will you need an extra unit to complete this codepoint?
    ///
    /// Returns `Err` for trailing surrogates, `Ok(true)` for leading surrogates,
    /// and `Ok(false)` for others.
    fn utf16_needs_extra_unit(self) -> Result<bool,InvalidUtf16FirstUnit>;

    /// Does this `u16` need another `u16` to complete a codepoint?
    /// Returns `(self & 0xfc00) == 0xd800`
    ///
    /// Is basically an unchecked variant of `utf16_needs_extra_unit()`.
    fn is_utf16_leading_surrogate(self) -> bool;
}
impl U16UtfExt for u16 {
    #[inline]
    fn utf16_needs_extra_unit(self) -> Result<bool,InvalidUtf16FirstUnit> {
        match self {
            // https://en.wikipedia.org/wiki/UTF-16#U.2B10000_to_U.2B10FFFF
            0x00_00...0xd7_ff | 0xe0_00...0xff_ff => Ok(false),
            0xd8_00...0xdb_ff => Ok(true),
                    _         => Err(InvalidUtf16FirstUnit)
        }
    }
    #[inline]
    fn is_utf16_leading_surrogate(self) -> bool {
        (self & 0xfc00) == 0xd800// Clear the ten content bytes of a surrogate,
                                 // and see if it's a leading surrogate.
    }
}




/// Extension trait for `char` that adds methods for converting to and from UTF-8 or UTF-16.
pub trait CharExt: Sized {
    /// Get the UTF-8 representation of this codepoint.
    ///
    /// `Utf8Char` is to `[u8;4]` what `char` is to `u32`:
    /// a restricted type that cannot be mutated internally.
    fn to_utf8(self) -> Utf8Char;

    /// Get the UTF-16 representation of this codepoint.
    ///
    /// `Utf16Char` is to `[u16;2]` what `char` is to `u32`:
    /// a restricted type that cannot be mutated internally.
    fn to_utf16(self) -> Utf16Char;

    /// Iterate over or [read](https://doc.rust-lang.org/std/io/trait.Read.html)
    /// the one to four bytes in the UTF-8 representation of this codepoint.
    ///
    /// An identical alternative to the unstable `char.encode_utf8()`.
    /// That method somehow still exist on stable, so I have to use a different name.
    fn iter_utf8_bytes(self) -> Utf8Iterator;

    /// Iterate over the one or two units in the UTF-16 representation of this codepoint.
    ///
    /// An identical alternative to the unstable `char.encode_utf16()`.
    /// That method somehow still exist on stable, so I have to use a different name.
    fn iter_utf16_units(self) -> Utf16Iterator;


    /// Convert this char to an UTF-8 array, and also return how many bytes of
    /// the array are used,
    ///
    /// The returned array is left-aligned with unused bytes set to zero.
    fn to_utf8_array(self) -> ([u8; 4], usize);

    /// Convert this `char` to UTF-16.
    /// The second `u16` is `Some` if a surrogate pair is required.
    fn to_utf16_tuple(self) -> (u16, Option<u16>);



    /// Create a `char` from the start of an UTF-8 slice,
    /// and also return how many bytes were used.
    ///
    /// # Errors
    ///
    /// Returns an `Err` if the slice is empty, doesn't start with a valid
    /// UTF-8 sequence or is too short for the sequence.
    ///
    /// # Examples
    ///
    /// ```
    /// use encode_unicode::CharExt;
    /// use encode_unicode::error::InvalidUtf8Slice::*;
    /// use encode_unicode::error::InvalidUtf8::*;
    ///
    /// assert_eq!(char::from_utf8_slice_start(&[b'A', b'B', b'C']), Ok(('A',1)));
    /// assert_eq!(char::from_utf8_slice_start(&[0xdd, 0xbb]), Ok(('\u{77b}',2)));
    ///
    /// assert_eq!(char::from_utf8_slice_start(&[]), Err(TooShort(1)));
    /// assert_eq!(char::from_utf8_slice_start(&[0xf0, 0x99]), Err(TooShort(4)));
    /// assert_eq!(char::from_utf8_slice_start(&[0xee, b'F', 0x80]), Err(Utf8(NotAContinuationByte(1))));
    /// assert_eq!(char::from_utf8_slice_start(&[0xee, 0x99, 0x0f]), Err(Utf8(NotAContinuationByte(2))));
    /// ```
    fn from_utf8_slice_start(src: &[u8]) -> Result<(Self,usize),InvalidUtf8Slice>;

    /// Create a `char` from the start of an UTF-16 slice,
    /// and also return how many units were used.
    ///
    /// If you want to continue after an error, continue with the next `u16` unit.
    fn from_utf16_slice_start(src: &[u16]) -> Result<(Self,usize), InvalidUtf16Slice>;


    /// Convert an UTF-8 sequence as returned from `.to_utf8_array()` into a `char`
    ///
    /// The codepoint must start at the first byte, and leftover bytes are ignored.
    ///
    /// # Errors
    ///
    /// Returns an `Err` if the array doesn't start with a valid UTF-8 sequence.
    ///
    /// # Examples
    ///
    /// ```
    /// use encode_unicode::CharExt;
    /// use encode_unicode::error::InvalidUtf8Array::*;
    /// use encode_unicode::error::InvalidUtf8::*;
    /// use encode_unicode::error::InvalidCodepoint::*;
    ///
    /// assert_eq!(char::from_utf8_array([b'A', 0, 0, 0]), Ok('A'));
    /// assert_eq!(char::from_utf8_array([0xf4, 0x8b, 0xbb, 0xbb]), Ok('\u{10befb}'));
    /// assert_eq!(char::from_utf8_array([b'A', b'B', b'C', b'D']), Ok('A'));
    /// assert_eq!(char::from_utf8_array([0, 0, 0xcc, 0xbb]), Ok('\0'));
    ///
    /// assert_eq!(char::from_utf8_array([0xef, b'F', 0x80, 0x80]), Err(Utf8(NotAContinuationByte(1))));
    /// assert_eq!(char::from_utf8_array([0xc1, 0x80, 0, 0]), Err(Utf8(OverLong)));
    /// assert_eq!(char::from_utf8_array([0xf7, 0xaa, 0x99, 0x88]), Err(Codepoint(TooHigh)));
    /// ```
    fn from_utf8_array(utf8: [u8; 4]) -> Result<Self,InvalidUtf8Array>;

    /// Convert a UTF-16 pair as returned from `.to_utf16_tuple()` into a `char`.
    fn from_utf16_tuple(utf16: (u16, Option<u16>)) -> Result<Self, InvalidUtf16Tuple>;


    /// Convert an UTF-8 sequence into a char.
    ///
    /// The length of the slice is taken as length of the sequence;
    /// it should be 1,2,3 or 4.
    ///
    /// # Safety
    ///
    /// The slice must contain exactly one, valid, UTF-8 sequence.
    ///
    /// Passing a slice that produces an invalid codepoint is always undefined
    /// behavior; Later checks that the codepoint is valid can be removed
    /// by the compiler.
    ///
    /// # Panics
    ///
    /// If the slice is empty
    unsafe fn from_utf8_exact_slice_unchecked(src: &[u8]) -> Self;

    /// Convert a UTF-16 tuple as returned from `.to_utf16_tuple()` into a `char`.
    unsafe fn from_utf16_tuple_unchecked(utf16: (u16, Option<u16>)) -> Self;


    /// Perform some extra validations compared to `char::from_u32_unchecked()`
    ///
    /// # Errors
    ///
    /// This function will return an error if
    ///
    /// * the value is greater than 0x10ffff
    /// * the value is between 0xd800 and 0xdfff (inclusive)
    fn from_u32_detailed(c: u32) -> Result<Self,InvalidCodepoint>;
}



impl CharExt for char {
      /////////
     //UTF-8//
    /////////

    fn to_utf8(self) -> Utf8Char {
        self.into()
    }
    fn iter_utf8_bytes(self) -> Utf8Iterator {
        self.to_utf8().into_iter()
    }

    fn to_utf8_array(self) -> ([u8; 4], usize) {
        let len = self.len_utf8();
        let mut c = self as u32;
        if len == 1 {// ASCII, the common case
            ([c as u8, 0, 0, 0],  1)
        } else {
            let mut parts = 0;// convert to 6-bit bytes
                        parts |= c & 0x3f;  c>>=6;
            parts<<=8;  parts |= c & 0x3f;  c>>=6;
            parts<<=8;  parts |= c & 0x3f;  c>>=6;
            parts<<=8;  parts |= c & 0x3f;
            parts |= 0x80_80_80_80;// set the most significant bit
            parts >>= 8*(4-len);// right-align bytes
            // Now, unused bytes are zero, (which matters for Utf8Char.eq())
            // and the rest are 0b10xx_xxxx

            // set header on first byte
            parts |= (0xff_00u32 >> len)  &  0xff;// store length
            parts &= Not::not(1u32 << 7-len);// clear the next bit after it

            let bytes: [u8; 4] = unsafe{ mem::transmute(u32::from_le(parts)) };
            (bytes, len)
        }
    }


    fn from_utf8_slice_start(src: &[u8]) -> Result<(Self,usize),InvalidUtf8Slice> {
        use errors::InvalidUtf8::*;
        use errors::InvalidUtf8Slice::*;
        let first = match src.first() {
            Some(first) => *first,
            None => return Err(TooShort(1)),
        };
        let bytes = match first.extra_utf8_bytes() {
            Err(e)    => return Err(Utf8(FirstByte(e))),
            Ok(0)     => return Ok((first as char, 1)),
            Ok(extra) if extra >= src.len()
                      => return Err(TooShort(extra+1)),
            Ok(extra) => &src[..extra+1],
        };
        if let Some(i) = bytes.iter().skip(1).position(|&b| (b >> 6) != 0b10 ) {
            Err(Utf8(NotAContinuationByte(i+1)))
        } else if overlong(bytes[0], bytes[1]) {
            Err(Utf8(OverLong))
        } else {
            match char::from_u32_detailed(merge_nonascii_unchecked_utf8(bytes)) {
                Ok(c) => Ok((c, bytes.len())),
                Err(e) => Err(Codepoint(e)),
            }
        }
    }

    fn from_utf8_array(utf8: [u8; 4]) -> Result<Self,InvalidUtf8Array> {
        use errors::InvalidUtf8::*;
        use errors::InvalidUtf8Array::*;
        let src = match utf8[0].extra_utf8_bytes() {
            Err(error) => return Err(Utf8(FirstByte(error))),
            Ok(0)      => return Ok(utf8[0] as char),
            Ok(extra)  => &utf8[..extra+1],
        };
        if let Some(i) = src[1..].iter().position(|&b| (b >> 6) != 0b10 ) {
            Err(Utf8(NotAContinuationByte(i+1)))
        } else if overlong(utf8[0], utf8[1]) {
            Err(Utf8(OverLong))
        } else {
            char::from_u32_detailed(merge_nonascii_unchecked_utf8(src))
                 .map_err(|e| Codepoint(e) )
        }
    }

    unsafe fn from_utf8_exact_slice_unchecked(src: &[u8]) -> Self {
        if src.len() == 1 {
            src[0] as char
        } else {
            char::from_u32_unchecked(merge_nonascii_unchecked_utf8(src))
        }
    }



      //////////
     //UTF-16//
    //////////

    fn to_utf16(self) -> Utf16Char {
        Utf16Char::from(self)
    }
    fn iter_utf16_units(self) -> Utf16Iterator {
        self.to_utf16().into_iter()
    }

    fn to_utf16_tuple(self) -> (u16, Option<u16>) {
        let c = self as u32;
        if c <= 0x_ff_ff {// single (or reserved, which we ignore)
            (c as u16, None)
        } else {// double (or too high, which we ignore)
            let c = c - 0x_01_00_00;
            let high = 0x_d8_00 + (c >> 10);
            let low = 0x_dc_00 + (c & 0x_03_ff);
            (high as u16,  Some(low as u16))
        }
    }


    fn from_utf16_slice_start(src: &[u16]) -> Result<(Self,usize), InvalidUtf16Slice> {
        use errors::InvalidUtf16Slice::*;
        unsafe {match (src.get(0), src.get(1)) {
            (Some(&u @ 0x00_00...0xd7_ff), _) |
            (Some(&u @ 0xe0_00...0xff_ff), _)
                => Ok((char::from_u32_unchecked(u as u32), 1)),
            (Some(&0xdc_00...0xdf_ff), _) => Err(FirstLowSurrogate),
            (None, _) => Err(EmptySlice),
            (Some(&f @ 0xd8_00...0xdb_ff), Some(&s @ 0xdc_00...0xdf_ff))
                => Ok((char::from_utf16_tuple_unchecked((f, Some(s))), 2)),
            (Some(&0xd8_00...0xdb_ff), Some(_)) => Err(SecondNotLowSurrogate),
            (Some(&0xd8_00...0xdb_ff), None) => Err(MissingSecond),
            (Some(_), _) => unreachable!()
        }}
    }

    fn from_utf16_tuple(utf16: (u16, Option<u16>)) -> Result<Self, InvalidUtf16Tuple> {
        use errors::InvalidUtf16Tuple::*;
        unsafe{ match utf16 {
            (0x00_00...0xd7_ff, None) | // single
            (0xe0_00...0xff_ff, None) | // single
            (0xd8_00...0xdb_ff, Some(0xdc_00...0xdf_ff)) // correct surrogate
                => Ok(char::from_utf16_tuple_unchecked(utf16)),
            (0xd8_00...0xdb_ff, Some(_)) => Err(InvalidSecond),
            (0xd8_00...0xdb_ff, None   ) => Err(MissingSecond),
            (0xdc_00...0xdf_ff,    _   ) => Err(FirstIsTrailingSurrogate),
            (        _        , Some(_)) => Err(SuperfluousSecond),
            (        _        , None   ) => unreachable!()
        }}
    }

    unsafe fn from_utf16_tuple_unchecked(utf16: (u16, Option<u16>)) -> Self {
        match utf16.1 {
            Some(second) => combine_surrogates(utf16.0, second),
            None         => char::from_u32_unchecked(utf16.0 as u32)
        }
    }


    fn from_u32_detailed(c: u32) -> Result<Self,InvalidCodepoint> {
        match char::from_u32(c) {
            Some(c) => Ok(c),
            None if c > 0x10_ff_ff => Err(InvalidCodepoint::TooHigh),
            None => Err(InvalidCodepoint::Utf16Reserved),
        }
    }
}

// Adapted from https://www.cl.cam.ac.uk/~mgk25/ucs/utf8_check.c
fn overlong(first: u8, second: u8) -> bool {
    if first < 0x80 {
        false
    } else if (first & 0xe0) == 0xc0 {
        (first & 0xfe) == 0xc0
    } else if (first & 0xf0) == 0xe0 {
        first == 0xe0 && (second & 0xe0) == 0x80
    } else {
        first == 0xf0 && (second & 0xf0) == 0x80
    }
}

/// Decodes the codepoint represented by a multi-byte UTF-8 sequence.
///
/// Does not check that the codepoint is valid,
/// and returns `u32` because casting invalid codepoints to `char` is insta UB.
fn merge_nonascii_unchecked_utf8(src: &[u8]) -> u32 {
    let mut c = src[0] as u32 & (0x7f >> src.len());
    for b in &src[1..] {
        c = (c << 6)  |  (b & 0b0011_1111) as u32;
    }
    c
}

// Create a `char` from a leading and a trailing surrogate.
unsafe fn combine_surrogates(first: u16, second: u16) -> char {
    let high = (first & 0x_03_ff) as u32;
    let low = (second & 0x_03_ff) as u32;
    let c = ((high << 10) | low) + 0x_01_00_00; // no, the constant can't be or'd in
    char::from_u32_unchecked(c)
}



/// Adds `.utf8chars()` and `.utf16chars()` iterator constructors to `&str`.
pub trait StrExt: AsRef<str> {
    /// Equivalent to `.chars()` but produces `Utf8Char`s.
    fn utf8chars(&self) -> Utf8Chars;
    /// Equivalent to `.chars()` but produces `Utf16Char`s.
    fn utf16chars(&self) -> Utf16Chars;
    /// Equivalent to `.char_indices()` but produces `Utf8Char`s.
    fn utf8char_indices(&self) -> Utf8CharIndices;
    /// Equivalent to `.char_indices()` but produces `Utf16Char`s.
    fn utf16char_indices(&self) -> Utf16CharIndices;
}

impl StrExt for str {
    fn utf8chars(&self) -> Utf8Chars {
        Utf8Chars::from(self)
    }
    fn utf16chars(&self) -> Utf16Chars {
        Utf16Chars::from(self)
    }
    fn utf8char_indices(&self) -> Utf8CharIndices {
        Utf8CharIndices::from(self)
    }
    fn utf16char_indices(&self) -> Utf16CharIndices {
        Utf16CharIndices::from(self)
    }
}

#[cfg(feature="ascii")]
impl StrExt for AsciiStr {
    fn utf8chars(&self) -> Utf8Chars {
        Utf8Chars::from(self.as_str())
    }
    fn utf16chars(&self) -> Utf16Chars {
        Utf16Chars::from(self.as_str())
    }
    fn utf8char_indices(&self) -> Utf8CharIndices {
        Utf8CharIndices::from(self.as_str())
    }
    fn utf16char_indices(&self) -> Utf16CharIndices {
        Utf16CharIndices::from(self.as_str())
    }
}



/// Iterator methods that convert between `u8`s and `Utf8Char` or `u16`s and `Utf16Char`
///
/// All the iterator adapters also accept iterators that produce references of
/// the type they convert from.
pub trait IterExt: Iterator+Sized {
    /// Converts an iterator of `Utf8Char`s or `&Utf8Char`s to an iterator of
    /// `u8`s.
    ///
    /// Has the same effect as `.flat_map()` or `.flatten()`, but the returned
    /// iterator is ~40% faster.
    ///
    /// The iterator also implements `Read`
    /// (when the `std` feature isn't disabled).  
    /// Reading will never produce an error, and calls to `.read()` and `.next()`
    /// can be mixed.
    ///
    /// The exact number of bytes cannot be known in advance, but `size_hint()`
    /// gives the possible range.
    /// (min: all remaining characters are ASCII, max: all require four bytes)
    ///
    /// # Examples
    ///
    /// From iterator of values:
    ///
    /// ```
    /// use encode_unicode::{IterExt, StrExt};
    ///
    /// let iterator = "foo".utf8chars();
    /// let mut bytes = [0; 4];
    /// for (u,dst) in iterator.to_bytes().zip(&mut bytes) {*dst=u;}
    /// assert_eq!(&bytes, b"foo\0");
    /// ```
    ///
    /// From iterator of references:
    ///
    #[cfg_attr(feature="std", doc=" ```")]
    #[cfg_attr(not(feature="std"), doc=" ```no_compile")]
    /// use encode_unicode::{IterExt, StrExt, Utf8Char};
    ///
    /// let chars: Vec<Utf8Char> = "💣 bomb 💣".utf8chars().collect();
    /// let bytes: Vec<u8> = chars.iter().to_bytes().collect();
    /// let flat_map: Vec<u8> = chars.iter().flat_map(|u8c| *u8c ).collect();
    /// assert_eq!(bytes, flat_map);
    /// ```
    ///
    /// `Read`ing from it:
    ///
    #[cfg_attr(feature="std", doc=" ```")]
    #[cfg_attr(not(feature="std"), doc=" ```no_compile")]
    /// use encode_unicode::{IterExt, StrExt};
    /// use std::io::Read;
    ///
    /// let s = "Ååh‽";
    /// assert_eq!(s.len(), 8);
    /// let mut buf = [b'E'; 9];
    /// let mut reader = s.utf8chars().to_bytes();
    /// assert_eq!(reader.read(&mut buf[..]).unwrap(), 8);
    /// assert_eq!(reader.read(&mut buf[..]).unwrap(), 0);
    /// assert_eq!(&buf[..8], s.as_bytes());
    /// assert_eq!(buf[8], b'E');
    /// ```
    fn to_bytes(self) -> Utf8CharSplitter<Self::Item,Self> where Self::Item: Borrow<Utf8Char>;

    /// Converts an iterator of `Utf16Char` (or `&Utf16Char`) to an iterator of
    /// `u16`s.
    ///
    /// Has the same effect as `.flat_map()` or `.flatten()`, but the returned
    /// iterator is about twice as fast.
    ///
    /// The exact number of units cannot be known in advance, but `size_hint()`
    /// gives the possible range.
    ///
    /// # Examples
    ///
    /// From iterator of values:
    ///
    /// ```
    /// use encode_unicode::{IterExt, StrExt};
    ///
    /// let iterator = "foo".utf16chars();
    /// let mut units = [0; 4];
    /// for (u,dst) in iterator.to_units().zip(&mut units) {*dst=u;}
    ///
    /// assert_eq!(units, ['f' as u16, 'o' as u16, 'o' as u16, 0]);
    /// ```
    ///
    /// From iterator of references:
    ///
    #[cfg_attr(feature="std", doc=" ```")]
    #[cfg_attr(not(feature="std"), doc=" ```no_compile")]
    /// use encode_unicode::{IterExt, StrExt, Utf16Char};
    ///
    /// // (💣 takes two units)
    /// let chars: Vec<Utf16Char> = "💣 bomb 💣".utf16chars().collect();
    /// let units: Vec<u16> = chars.iter().to_units().collect();
    /// let flat_map: Vec<u16> = chars.iter().flat_map(|u16c| *u16c ).collect();
    ///
    /// assert_eq!(units, flat_map);
    /// ```
    fn to_units(self) -> Utf16CharSplitter<Self::Item,Self> where Self::Item: Borrow<Utf16Char>;

    /// Decodes bytes as UTF-8 and groups them into `Utf8Char`s
    ///
    /// When errors (invalid values or sequences) are encountered,
    /// it continues with the byte right after the start of the error sequence.  
    /// This is neither the most intelligent choiche (sometimes it is guaranteed to
    ///  produce another error), nor the easiest to implement, but I believe it to
    /// be the most predictable.
    /// It also means that ASCII characters are never hidden by errors.
    ///
    /// # Examples
    ///
    /// Replace all errors with u+FFFD REPLACEMENT_CHARACTER:
    /// ```
    /// use encode_unicode::{Utf8Char, IterExt};
    ///
    /// let mut buf = [b'\0'; 255];
    /// let len = b"foo\xCFbar".iter()
    ///     .to_utf8chars()
    ///     .flat_map(|r| r.unwrap_or(Utf8Char::from('\u{FFFD}')).into_iter() )
    ///     .zip(&mut buf[..])
    ///     .map(|(byte, dst)| *dst = byte )
    ///     .count();
    ///
    /// assert_eq!(&buf[..len], "foo\u{FFFD}bar".as_bytes());
    /// ```
    ///
    /// Collect everything up until the first error into a string:
    #[cfg_attr(feature="std", doc=" ```")]
    #[cfg_attr(not(feature="std"), doc=" ```no_compile")]
    /// use encode_unicode::iterator::Utf8CharMerger;
    /// let mut good = String::new();
    /// for r in Utf8CharMerger::from(b"foo\xcc\xbbbar\xcc\xddbaz") {
    ///     if let Ok(uc) = r {
    ///         good.push_str(uc.as_str());
    ///     } else {
    ///         break;
    ///     }
    /// }
    /// assert_eq!(good, "foo̻bar");
    /// ```
    ///
    /// Abort decoding on error:
    #[cfg_attr(feature="std", doc=" ```")]
    #[cfg_attr(not(feature="std"), doc=" ```no_compile")]
    /// use encode_unicode::{IterExt, Utf8Char};
    /// use encode_unicode::error::{InvalidUtf8Slice, InvalidUtf8};
    ///
    /// let result = b"ab\0\xe0\xbc\xa9 \xf3\x80\x77".iter()
    ///     .to_utf8chars()
    ///     .collect::<Result<String,InvalidUtf8Slice>>();
    ///
    /// assert_eq!(result, Err(InvalidUtf8Slice::Utf8(InvalidUtf8::NotAContinuationByte(2))));
    /// ```
    fn to_utf8chars(self) -> Utf8CharMerger<Self::Item,Self> where Self::Item: Borrow<u8>;

    /// Decodes bytes as UTF-16 and groups them into `Utf16Char`s
    ///
    /// When errors (unmatched leading surrogates or unexpected trailing surrogates)
    /// are encountered, an error is produced for every unit.
    ///
    /// # Examples
    ///
    /// Replace errors with '�':
    #[cfg_attr(feature="std", doc=" ```")]
    #[cfg_attr(not(feature="std"), doc=" ```no_compile")]
    /// use encode_unicode::{IterExt, Utf16Char};
    ///
    /// let slice = &['a' as u16, 0xdf00, 0xd83c, 0xdca0][..];
    /// let string = slice.iter()
    ///     .to_utf16chars()
    ///     .map(|r| r.unwrap_or(Utf16Char::from('\u{fffd}')) ) // REPLACEMENT_CHARACTER
    ///     .collect::<String>();
    ///
    /// assert_eq!(string, "a�🂠");
    /// ```
    ///
    /// ```
    /// use encode_unicode::{IterExt, Utf16Char};
    /// use encode_unicode::error::Utf16PairError::*;
    ///
    /// let slice = [0xdcba, 0xdeff, 0xd8be, 0xdeee, 'Y' as u16, 0xdab1, 0xdab1];
    /// let mut iter = slice.iter().to_utf16chars();
    /// assert_eq!(iter.size_hint(), (3, Some(7)));
    /// assert_eq!(iter.next(), Some(Err(UnexpectedTrailingSurrogate)));
    /// assert_eq!(iter.next(), Some(Err(UnexpectedTrailingSurrogate)));
    /// assert_eq!(iter.next(), Some(Ok(Utf16Char::from('\u{3faee}'))));
    /// assert_eq!(iter.next(), Some(Ok(Utf16Char::from('Y'))));
    /// assert_eq!(iter.next(), Some(Err(UnmatchedLeadingSurrogate)));
    /// assert_eq!(iter.next(), Some(Err(Incomplete)));
    /// assert_eq!(iter.into_remaining_units().next(), None);
    /// ```
    ///
    /// Search for a codepoint and return the codepoint index of the first match:
    /// ```
    /// use encode_unicode::{IterExt, Utf16Char};
    ///
    /// let position = [0xd875, 0xdd4f, '≈' as u16, '2' as u16].iter()
    ///     .to_utf16chars()
    ///     .position(|r| r == Ok(Utf16Char::from('≈')) );
    ///
    /// assert_eq!(position, Some(1));
    /// ```
    fn to_utf16chars(self) -> Utf16CharMerger<Self::Item,Self> where Self::Item: Borrow<u16>;
}

impl<I:Iterator> IterExt for I {
    fn to_bytes(self) -> Utf8CharSplitter<Self::Item,Self> where Self::Item: Borrow<Utf8Char> {
        iter_bytes(self)
    }
    fn to_units(self) -> Utf16CharSplitter<Self::Item,Self> where Self::Item: Borrow<Utf16Char> {
        iter_units(self)
    }
    fn to_utf8chars(self) -> Utf8CharMerger<Self::Item,Self> where Self::Item: Borrow<u8> {
        Utf8CharMerger::from(self)
    }
    fn to_utf16chars(self) -> Utf16CharMerger<Self::Item,Self> where Self::Item: Borrow<u16> {
        Utf16CharMerger::from(self)
    }
}


/// Methods for iterating over `u8` and `u16` slices as UTF-8 or UTF-16 characters.
///
/// The iterators are slightly faster than the similar methods in [`IterExt`](trait.IterExt.html)
/// because they con "push back" items for free after errors and don't need a
/// separate buffer that must be checked on every call to `.next()`.
pub trait SliceExt: Index<RangeFull> {
    /// Decode `u8` slices as UTF-8 and iterate over the codepoints as `Utf8Char`s,
    ///
    /// # Examples
    ///
    /// Get the index and error type of the first error:
    #[cfg_attr(feature="std", doc=" ```")]
    #[cfg_attr(not(feature="std"), doc=" ```no_compile")]
    /// use encode_unicode::{SliceExt, Utf8Char};
    /// use encode_unicode::error::InvalidUtf8Slice;
    ///
    /// let slice = b"ab\0\xe0\xbc\xa9 \xf3\x80\x77";
    /// let result = slice.utf8char_indices()
    ///     .map(|(offset,r,length)| r.map_err(|e| (offset,e,length) ) )
    ///     .collect::<Result<String,(usize,InvalidUtf8Slice,usize)>>();
    ///
    /// assert_eq!(result, Err((7, InvalidUtf8Slice::TooShort(4), 1)));
    /// ```
    ///
    /// ```
    /// use encode_unicode::{SliceExt, Utf8Char};
    /// use std::error::Error;
    ///
    /// let slice = b"\xf0\xbf\xbf\xbfXY\xdd\xbb\xe1\x80\x99quux123";
    /// let mut fixed_size = [Utf8Char::default(); 8];
    /// for (cp_i, (byte_index, r, _)) in slice.utf8char_indices().enumerate().take(8) {
    ///     match r {
    ///         Ok(u8c) => fixed_size[cp_i] = u8c,
    ///         Err(e) => panic!("Invalid codepoint at index {} ({})", cp_i, e.description()),
    ///     }
    /// }
    /// let chars = ['\u{3ffff}', 'X', 'Y', '\u{77b}', '\u{1019}', 'q', 'u', 'u'];
    /// assert_eq!(fixed_size, chars);
    /// ```
    ///
    #[cfg_attr(feature="std", doc=" ```")]
    #[cfg_attr(not(feature="std"), doc=" ```no_compile")]
    /// use encode_unicode::{SliceExt, Utf8Char};
    /// use encode_unicode::error::InvalidUtf8Slice::*;
    /// use encode_unicode::error::{InvalidUtf8, InvalidUtf8FirstByte, InvalidCodepoint};
    ///
    /// let bytes = b"\xfa-\xf4\x8f\xee\xa1\x8f-\xed\xa9\x87\xf0\xcc\xbb";
    /// let mut errors = Vec::new();
    /// let mut lengths = Vec::new();
    /// let mut string = String::new();
    /// for (offset,result,length) in bytes.utf8char_indices() {
    ///     lengths.push((offset,length));
    ///     let c = result.unwrap_or_else(|error| {
    ///         errors.push((offset,error));
    ///         Utf8Char::from('\u{fffd}') // replacement character
    ///     });
    ///     string.push_str(c.as_str());
    /// }
    ///
    /// assert_eq!(string, "�-��\u{e84f}-����\u{33b}");
    /// assert_eq!(lengths, [(0,1), (1,1), (2,1), (3,1), (4,3), (7,1),
    ///                      (8,1), (9,1), (10,1), (11,1), (12,2)]);
    /// assert_eq!(errors, [
    ///     ( 0, Utf8(InvalidUtf8::FirstByte(InvalidUtf8FirstByte::TooLongSeqence))),
    ///     ( 2, Utf8(InvalidUtf8::NotAContinuationByte(2))),
    ///     ( 3, Utf8(InvalidUtf8::FirstByte(InvalidUtf8FirstByte::ContinuationByte))),
    ///     ( 8, Codepoint(InvalidCodepoint::Utf16Reserved)),
    ///     ( 9, Utf8(InvalidUtf8::FirstByte(InvalidUtf8FirstByte::ContinuationByte))),
    ///     (10, Utf8(InvalidUtf8::FirstByte(InvalidUtf8FirstByte::ContinuationByte))),
    ///     (11, TooShort(4)), // (but it was not the last element returned!)
    /// ]);
    /// ```
    fn utf8char_indices(&self) -> Utf8CharDecoder where Self::Output: Borrow<[u8]>;


    /// Decode `u16` slices as UTF-16 and iterate over the codepoints as `Utf16Char`s,
    ///
    /// The iterator produces `(usize,Result<Utf16Char,Utf16Error>,usize)`,
    /// and the slice is validated as you go.
    ///
    /// The first `usize` contains the offset from the start of the slice and
    /// the last `usize` contains the length of the codepoint or error.
    /// The length is either 1 or 2, and always 1 for errors.
    ///
    /// # Examples
    ///
    #[cfg_attr(feature="std", doc=" ```")]
    #[cfg_attr(not(feature="std"), doc=" ```no_compile")]
    /// use encode_unicode::{SliceExt, Utf8Char};
    ///
    /// let slice = &['a' as u16, 0xdf00, 0xd83c, 0xdca0][..];
    /// let mut errors = Vec::new();
    /// let string = slice.utf16char_indices().map(|(offset,r,_)| match r {
    ///     Ok(u16c) => Utf8Char::from(u16c),
    ///     Err(_) => {
    ///         errors.push(offset);
    ///         Utf8Char::from('\u{fffd}') // REPLACEMENT_CHARACTER
    ///     }
    /// }).collect::<String>();
    ///
    /// assert_eq!(string, "a�🂠");
    /// assert_eq!(errors, [1]);
    /// ```
    ///
    /// Search for a codepoint and return its unit and codepoint index.
    /// ```
    /// use encode_unicode::{SliceExt, Utf16Char};
    ///
    /// let slice = [0xd875,/*'𝕏'*/ 0xdd4f, '≈' as u16, '2' as u16];
    /// let position = slice.utf16char_indices()
    ///     .enumerate()
    ///     .find(|&(_,(_,r,_))| r == Ok(Utf16Char::from('≈')) )
    ///     .map(|(codepoint, (offset, _, _))| (codepoint, offset) );
    ///
    /// assert_eq!(position, Some((1,2)));
    /// ```
    ///
    /// Error types:
    /// ```
    /// use encode_unicode::{SliceExt, Utf16Char};
    /// use encode_unicode::error::Utf16PairError::*;
    ///
    /// let slice = [0xdcba, 0xdeff, 0xd8be, 0xdeee, 'λ' as u16, 0xdab1, 0xdab1];
    /// let mut iter = slice.utf16char_indices();
    /// assert_eq!(iter.next(), Some((0, Err(UnexpectedTrailingSurrogate), 1)));
    /// assert_eq!(iter.next(), Some((1, Err(UnexpectedTrailingSurrogate), 1)));
    /// assert_eq!(iter.next(), Some((2, Ok(Utf16Char::from('\u{3faee}')), 2)));
    /// assert_eq!(iter.next(), Some((4, Ok(Utf16Char::from('λ')), 1)));
    /// assert_eq!(iter.next(), Some((5, Err(UnmatchedLeadingSurrogate), 1)));
    /// assert_eq!(iter.next(), Some((6, Err(Incomplete), 1)));
    /// assert_eq!(iter.next(), None);
    /// assert_eq!(iter.as_slice(), [])
    /// ```
    fn utf16char_indices(&self) -> Utf16CharDecoder where Self::Output: Borrow<[u16]>;
}

impl<S: ?Sized+Index<RangeFull>> SliceExt for S {
    fn utf8char_indices(&self) -> Utf8CharDecoder where Self::Output: Borrow<[u8]> {
        Utf8CharDecoder::from(self[..].borrow())
    }
    fn utf16char_indices(&self) -> Utf16CharDecoder where Self::Output: Borrow<[u16]> {
        Utf16CharDecoder::from(self[..].borrow())
    }
}
