sp-im 0.3.0

Immutable datatypes for no_std use within Substrate
Documentation
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

// use metrohash::MetroHash64;
use core::{
  hash::Hasher,
  marker::PhantomData,
};
use typenum::{
  Unsigned,
  U64,
};

pub(crate) fn is_sorted<A, I>(l: I) -> bool
where
  I: IntoIterator<Item = A>,
  A: Ord, {
  let mut it = l.into_iter().peekable();
  loop {
    match (it.next(), it.peek()) {
      (_, None) => return true,
      (Some(ref a), Some(b)) if a > b => return false,
      _ => (),
    }
  }
}

pub(crate) struct LolHasher<N: Unsigned = U64> {
  state: u64,
  shift: usize,
  size: PhantomData<N>,
}

impl<N: Unsigned> LolHasher<N> {
  fn feed_me(&mut self, byte: u8) {
    self.state ^= u64::from(byte) << self.shift;
    self.shift += 8;
    if self.shift >= 64 {
      self.shift = 0;
    }
  }
}

impl<N: Unsigned> Hasher for LolHasher<N> {
  fn write(&mut self, bytes: &[u8]) {
    for byte in bytes {
      self.feed_me(*byte)
    }
  }

  fn finish(&self) -> u64 {
    if N::USIZE == 64 { self.state } else { self.state & ((1 << N::USIZE) - 1) }
  }
}

impl<N: Unsigned> Default for LolHasher<N> {
  fn default() -> Self { LolHasher { state: 0, shift: 0, size: PhantomData } }
}

// pub(crate) struct MetroHashBuilder {
//   seed: u64,
// }

// impl MetroHashBuilder {
//   pub(crate) fn new(seed: u64) -> Self { MetroHashBuilder { seed } }

//   pub(crate) fn seed(&self) -> u64 { self.seed }
// }

// impl BuildHasher for MetroHashBuilder {
//   type Hasher = MetroHash64;

//   fn build_hasher(&self) -> Self::Hasher { MetroHash64::with_seed(self.seed)
// } }