From ee8b1082faea1095dbaa3940b401473f1187f183 Mon Sep 17 00:00:00 2001 From: leo60228 Date: Fri, 16 Aug 2019 16:10:45 +0000 Subject: [PATCH 1/5] no_std support (bumps MSRV to 1.36) --- .travis.yml | 7 +---- Cargo.toml | 6 ++-- README.rst | 4 +-- benches/bench.rs | 6 +--- benches/faststring.rs | 4 --- src/equivalent.rs | 2 +- src/lib.rs | 7 +++++ src/macros.rs | 4 ++- src/map.rs | 69 +++++++++++++++++++++++-------------------- src/mutable_keys.rs | 4 +-- src/serde.rs | 20 ++++++------- src/set.rs | 23 ++++++++------- src/util.rs | 4 +-- tests/quick.rs | 8 ++--- tests/serde.rs | 2 -- tests/tests.rs | 1 - 16 files changed, 83 insertions(+), 88 deletions(-) diff --git a/.travis.yml b/.travis.yml index c6ae7ef2..01bdc083 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,12 +2,7 @@ language: rust sudo: false matrix: include: - - rust: 1.18.0 - before_script: - # lazy_static 1.1 requires Rust 1.21+, so downgrade it. - # (we only use it in benchmarks anyway...) - - cargo generate-lockfile - - cargo update -p lazy_static --precise 1.0.2 + - rust: 1.36.0 - rust: stable env: - FEATURES='serde-1' diff --git a/Cargo.toml b/Cargo.toml index a0548389..79bad659 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "indexmap" version = "1.1.0" +edition = "2018" authors = [ "bluss", "Josh Stone " @@ -28,10 +29,11 @@ categories = ["data-structures"] bench = false [dependencies] -serde = { version = "1.0", optional = true } +serde = { version = "1.0", optional = true, default-features = false } +hashbrown = "0.6.0" [dev-dependencies] -itertools = "0.7.0" # 0.8 not compiles on Rust 1.18 +itertools = "0.8.0" rand = "0.4" quickcheck = { version = "0.6", default-features = false } fnv = "1.0" diff --git a/README.rst b/README.rst index 3792afe3..6ee60906 100644 --- a/README.rst +++ b/README.rst @@ -12,8 +12,8 @@ indexmap .. |docs| image:: https://docs.rs/indexmap/badge.svg .. _docs: https://docs.rs/indexmap -.. |rustc| image:: https://img.shields.io/badge/rust-1.18%2B-orange.svg -.. _rustc: https://img.shields.io/badge/rust-1.18%2B-orange.svg +.. |rustc| image:: https://img.shields.io/badge/rust-1.36%2B-orange.svg +.. _rustc: https://img.shields.io/badge/rust-1.36%2B-orange.svg A safe, pure-Rust hash table which preserves insertion order. diff --git a/benches/bench.rs b/benches/bench.rs index b3e9915f..8910ffd9 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -1,7 +1,5 @@ #![feature(test)] extern crate test; -extern crate rand; -extern crate fnv; #[macro_use] extern crate lazy_static; @@ -13,8 +11,6 @@ type FnvBuilder = BuildHasherDefault; use test::Bencher; use test::black_box; -extern crate indexmap; - use indexmap::IndexMap; use std::collections::HashMap; @@ -580,7 +576,7 @@ fn remove_ordermap_100_000(b: &mut Bencher) { b.iter(|| { let mut map = map.clone(); for key in &keys { - map.remove(key).is_some(); + let _ = map.remove(key).is_some(); } assert_eq!(map.len(), 0); map diff --git a/benches/faststring.rs b/benches/faststring.rs index 65e78013..5d7f21a8 100644 --- a/benches/faststring.rs +++ b/benches/faststring.rs @@ -1,12 +1,8 @@ #![feature(test)] extern crate test; -extern crate rand; -extern crate lazy_static; use test::Bencher; -extern crate indexmap; - use indexmap::IndexMap; use std::collections::HashMap; diff --git a/src/equivalent.rs b/src/equivalent.rs index d72b2ef3..12b1f0b4 100644 --- a/src/equivalent.rs +++ b/src/equivalent.rs @@ -1,5 +1,5 @@ -use std::borrow::Borrow; +use core::borrow::Borrow; /// Key equivalence trait. /// diff --git a/src/lib.rs b/src/lib.rs index 1a0655e3..884dda3a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,6 +20,13 @@ //! upgrade policy, where in a later 1.x version, we will raise the minimum //! required Rust version. +#![cfg_attr(not(test), no_std)] + +#[cfg(test)] +extern crate core; + +extern crate alloc; + #[macro_use] mod macros; #[cfg(feature = "serde-1")] diff --git a/src/macros.rs b/src/macros.rs index b8c6f9b1..b7188278 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,10 +1,11 @@ - #[macro_export] /// Create an `IndexMap` from a list of key-value pairs /// /// ## Example /// /// ``` +/// # extern crate std; +/// /// #[macro_use] extern crate indexmap; /// # fn main() { /// @@ -43,6 +44,7 @@ macro_rules! indexmap { /// ## Example /// /// ``` +/// # extern crate std; /// #[macro_use] extern crate indexmap; /// # fn main() { /// diff --git a/src/map.rs b/src/map.rs index a52d3d88..4af7a122 100644 --- a/src/map.rs +++ b/src/map.rs @@ -1,23 +1,27 @@ //! `IndexMap` is a hash table where the iteration order of the key-value //! pairs is independent of the hash values of the keys. -pub use mutable_keys::MutableKeys; - -use std::hash::Hash; -use std::hash::BuildHasher; -use std::hash::Hasher; -use std::iter::FromIterator; -use std::collections::hash_map::RandomState; -use std::ops::RangeFull; - -use std::cmp::{max, Ordering}; -use std::fmt; -use std::mem::{replace}; -use std::marker::PhantomData; - -use util::{third, ptrdistance, enumerate}; -use equivalent::Equivalent; -use { +pub use crate::mutable_keys::MutableKeys; + +use core::hash::Hash; +use core::hash::BuildHasher; +use core::hash::Hasher; +use core::iter::FromIterator; +use hashbrown::hash_map::DefaultHashBuilder; +use core::ops::RangeFull; + +use core::cmp::{max, Ordering}; +use core::fmt; +use core::mem::{replace}; +use core::marker::PhantomData; + +use alloc::vec::Vec; +use alloc::boxed::Box; +use alloc::vec; + +use crate::util::{third, ptrdistance, enumerate}; +use crate::equivalent::Equivalent; +use crate::{ Bucket, HashValue, }; @@ -246,6 +250,7 @@ impl ShortHashProxy /// # Examples /// /// ``` +/// # extern crate std; /// use indexmap::IndexMap; /// /// // count the frequency of each letter in a sentence. @@ -260,7 +265,7 @@ impl ShortHashProxy /// assert_eq!(letters.get(&'y'), None); /// ``` #[derive(Clone)] -pub struct IndexMap { +pub struct IndexMap { core: OrderMapCore, hash_builder: S, } @@ -301,28 +306,28 @@ impl fmt::Debug for IndexMap S: BuildHasher, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(f.debug_map().entries(self.iter()).finish()); + f.debug_map().entries(self.iter()).finish()?; if cfg!(not(feature = "test_debug")) { return Ok(()); } - try!(writeln!(f, "")); + writeln!(f, "")?; for (i, index) in enumerate(&*self.core.indices) { - try!(write!(f, "{}: {:?}", i, index)); + write!(f, "{}: {:?}", i, index)?; if let Some(pos) = index.pos() { let hash = self.core.entries[pos].hash; let key = &self.core.entries[pos].key; let desire = desired_pos(self.core.mask, hash); - try!(write!(f, ", desired={}, probe_distance={}, key={:?}", + write!(f, ", desired={}, probe_distance={}, key={:?}", desire, probe_distance(self.core.mask, hash, i), - key)); + key)?; } - try!(writeln!(f, "")); + writeln!(f, "")?; } - try!(writeln!(f, "cap={}, raw_cap={}, entries.cap={}", + writeln!(f, "cap={}, raw_cap={}, entries.cap={}", self.capacity(), self.raw_capacity(), - self.core.entries.capacity())); + self.core.entries.capacity())?; Ok(()) } } @@ -1492,9 +1497,9 @@ fn find_existing_entry_at(indices: &[Pos], hash: HashValue, }); } -use std::slice::Iter as SliceIter; -use std::slice::IterMut as SliceIterMut; -use std::vec::IntoIter as VecIntoIter; +use core::slice::Iter as SliceIter; +use core::slice::IterMut as SliceIterMut; +use alloc::vec::IntoIter as VecIntoIter; /// An iterator over the keys of a `IndexMap`. /// @@ -1730,7 +1735,7 @@ impl fmt::Debug for IntoIter { /// [`drain`]: struct.IndexMap.html#method.drain /// [`IndexMap`]: struct.IndexMap.html pub struct Drain<'a, K, V> where K: 'a, V: 'a { - pub(crate) iter: ::std::vec::Drain<'a, Bucket> + pub(crate) iter: ::alloc::vec::Drain<'a, Bucket> } impl<'a, K, V> Iterator for Drain<'a, K, V> { @@ -1779,7 +1784,7 @@ impl IntoIterator for IndexMap } } -use std::ops::{Index, IndexMut}; +use core::ops::{Index, IndexMut}; impl<'a, K, V, Q: ?Sized, S> Index<&'a Q> for IndexMap where Q: Hash + Equivalent, @@ -1900,7 +1905,7 @@ impl Eq for IndexMap #[cfg(test)] mod tests { use super::*; - use util::enumerate; + use crate::util::enumerate; #[test] fn it_works() { diff --git a/src/mutable_keys.rs b/src/mutable_keys.rs index 9291f96f..fc1f16f0 100644 --- a/src/mutable_keys.rs +++ b/src/mutable_keys.rs @@ -1,6 +1,6 @@ -use std::hash::Hash; -use std::hash::BuildHasher; +use core::hash::Hash; +use core::hash::BuildHasher; use super::{IndexMap, Equivalent}; diff --git a/src/serde.rs b/src/serde.rs index eb54e01f..0ee20733 100644 --- a/src/serde.rs +++ b/src/serde.rs @@ -1,13 +1,11 @@ -extern crate serde; - use self::serde::ser::{Serialize, Serializer, SerializeMap, SerializeSeq}; use self::serde::de::{Deserialize, Deserializer, Error, IntoDeserializer, MapAccess, SeqAccess, Visitor}; use self::serde::de::value::{MapDeserializer, SeqDeserializer}; -use std::fmt::{self, Formatter}; -use std::hash::{BuildHasher, Hash}; -use std::marker::PhantomData; +use core::fmt::{self, Formatter}; +use core::hash::{BuildHasher, Hash}; +use core::marker::PhantomData; use IndexMap; @@ -20,9 +18,9 @@ impl Serialize for IndexMap fn serialize(&self, serializer: T) -> Result where T: Serializer { - let mut map_serializer = try!(serializer.serialize_map(Some(self.len()))); + let mut map_serializer = serializer.serialize_map(Some(self.len()))?; for (key, value) in self { - try!(map_serializer.serialize_entry(key, value)); + map_serializer.serialize_entry(key, value)?; } map_serializer.end() } @@ -46,7 +44,7 @@ impl<'de, K, V, S> Visitor<'de> for OrderMapVisitor { let mut values = IndexMap::with_capacity_and_hasher(map.size_hint().unwrap_or(0), S::default()); - while let Some((key, value)) = try!(map.next_entry()) { + while let Some((key, value)) = map.next_entry()? { values.insert(key, value); } @@ -91,9 +89,9 @@ impl Serialize for IndexSet fn serialize(&self, serializer: Se) -> Result where Se: Serializer { - let mut set_serializer = try!(serializer.serialize_seq(Some(self.len()))); + let mut set_serializer = serializer.serialize_seq(Some(self.len())); for value in self { - try!(set_serializer.serialize_element(value)); + set_serializer.serialize_element(value); } set_serializer.end() } @@ -116,7 +114,7 @@ impl<'de, T, S> Visitor<'de> for OrderSetVisitor { let mut values = IndexSet::with_capacity_and_hasher(seq.size_hint().unwrap_or(0), S::default()); - while let Some(value) = try!(seq.next_element()) { + while let Some(value) = seq.next_element() { values.insert(value); } diff --git a/src/set.rs b/src/set.rs index 7d1a956a..27b6bfbb 100644 --- a/src/set.rs +++ b/src/set.rs @@ -1,14 +1,14 @@ //! A hash set implemented using `IndexMap` -use std::cmp::Ordering; -use std::collections::hash_map::RandomState; -use std::fmt; -use std::iter::{FromIterator, Chain}; -use std::hash::{Hash, BuildHasher}; -use std::ops::RangeFull; -use std::ops::{BitAnd, BitOr, BitXor, Sub}; -use std::slice; -use std::vec; +use core::cmp::Ordering; +use hashbrown::hash_map::DefaultHashBuilder; +use core::fmt; +use core::iter::{FromIterator, Chain}; +use core::hash::{Hash, BuildHasher}; +use core::ops::RangeFull; +use core::ops::{BitAnd, BitOr, BitXor, Sub}; +use core::slice; +use alloc::vec; use super::{IndexMap, Equivalent}; @@ -45,6 +45,7 @@ type Bucket = super::Bucket; /// # Examples /// /// ``` +/// # extern crate std; /// use indexmap::IndexSet; /// /// // Collects which letters appear in a sentence. @@ -56,7 +57,7 @@ type Bucket = super::Bucket; /// assert!(!letters.contains(&'y')); /// ``` #[derive(Clone)] -pub struct IndexSet { +pub struct IndexSet { map: IndexMap, } @@ -942,7 +943,7 @@ impl<'a, 'b, T, S1, S2> Sub<&'b IndexSet> for &'a IndexSet #[cfg(test)] mod tests { use super::*; - use util::enumerate; + use crate::util::enumerate; #[test] fn it_works() { diff --git a/src/util.rs b/src/util.rs index 90d3e7e3..6d36971c 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,6 +1,6 @@ -use std::iter::Enumerate; -use std::mem::size_of; +use core::iter::Enumerate; +use core::mem::size_of; pub fn third(t: (A, B, C)) -> C { t.2 } diff --git a/tests/quick.rs b/tests/quick.rs index 14f267cf..a6efa5d4 100644 --- a/tests/quick.rs +++ b/tests/quick.rs @@ -1,11 +1,7 @@ -extern crate indexmap; -extern crate itertools; #[macro_use] extern crate quickcheck; -extern crate fnv; - use indexmap::IndexMap; use itertools::Itertools; @@ -337,7 +333,7 @@ impl Arbitrary for Alpha { }).collect()) } - fn shrink(&self) -> Box> { + fn shrink(&self) -> Box> { Box::new((**self).shrink().map(Alpha)) } } @@ -359,7 +355,7 @@ impl Arbitrary for Large> Large((0..len).map(|_| T::arbitrary(g)).collect()) } - fn shrink(&self) -> Box> { + fn shrink(&self) -> Box> { Box::new((**self).shrink().map(Large)) } } diff --git a/tests/serde.rs b/tests/serde.rs index dbb23573..09edba61 100644 --- a/tests/serde.rs +++ b/tests/serde.rs @@ -2,8 +2,6 @@ #[macro_use] extern crate indexmap; -extern crate serde_test; -extern crate fnv; use serde_test::{Token, assert_tokens}; diff --git a/tests/tests.rs b/tests/tests.rs index 4a7f4db7..dbb9f658 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1,7 +1,6 @@ #[macro_use] extern crate indexmap; -extern crate itertools; #[test] From 1f778b208187f55e1bf5d97ac6d48f864b5940c4 Mon Sep 17 00:00:00 2001 From: leo60228 Date: Fri, 16 Aug 2019 16:22:34 +0000 Subject: [PATCH 2/5] Fix serde --- src/serde.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/serde.rs b/src/serde.rs index 0ee20733..4c78e989 100644 --- a/src/serde.rs +++ b/src/serde.rs @@ -1,13 +1,13 @@ -use self::serde::ser::{Serialize, Serializer, SerializeMap, SerializeSeq}; -use self::serde::de::{Deserialize, Deserializer, Error, IntoDeserializer, MapAccess, SeqAccess, Visitor}; -use self::serde::de::value::{MapDeserializer, SeqDeserializer}; +use serde::ser::{Serialize, Serializer, SerializeMap, SerializeSeq}; +use serde::de::{Deserialize, Deserializer, Error, IntoDeserializer, MapAccess, SeqAccess, Visitor}; +use serde::de::value::{MapDeserializer, SeqDeserializer}; use core::fmt::{self, Formatter}; use core::hash::{BuildHasher, Hash}; use core::marker::PhantomData; -use IndexMap; +use crate::IndexMap; /// Requires crate feature `"serde-1"` impl Serialize for IndexMap @@ -79,7 +79,7 @@ impl<'de, K, V, S, E> IntoDeserializer<'de, E> for IndexMap } -use IndexSet; +use crate::IndexSet; /// Requires crate feature `"serde-1"` impl Serialize for IndexSet @@ -89,9 +89,9 @@ impl Serialize for IndexSet fn serialize(&self, serializer: Se) -> Result where Se: Serializer { - let mut set_serializer = serializer.serialize_seq(Some(self.len())); + let mut set_serializer = serializer.serialize_seq(Some(self.len()))?; for value in self { - set_serializer.serialize_element(value); + set_serializer.serialize_element(value)?; } set_serializer.end() } @@ -114,7 +114,7 @@ impl<'de, T, S> Visitor<'de> for OrderSetVisitor { let mut values = IndexSet::with_capacity_and_hasher(seq.size_hint().unwrap_or(0), S::default()); - while let Some(value) = seq.next_element() { + while let Some(value) = seq.next_element()? { values.insert(value); } From dd1bea31cbac2334bd7b5d0e47dfc26423868946 Mon Sep 17 00:00:00 2001 From: leo60228 Date: Fri, 16 Aug 2019 16:22:51 +0000 Subject: [PATCH 3/5] Update docs --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 884dda3a..39a0a2c6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,7 +14,7 @@ //! //! ## Rust Version //! -//! This version of indexmap requires Rust 1.18 or later. +//! This version of indexmap requires Rust 1.36 or later. //! //! The indexmap 1.x release series will use a carefully considered version //! upgrade policy, where in a later 1.x version, we will raise the minimum From dd041c0344a72194d5211b58b16712c21a9f1c82 Mon Sep 17 00:00:00 2001 From: leo60228 Date: Fri, 16 Aug 2019 19:54:16 +0000 Subject: [PATCH 4/5] Use autocfg to avoid breaking change --- .travis.yml | 11 ++++++++--- Cargo.toml | 37 +++++++++++++++++++++++++++++++++---- README.rst | 4 ++-- build.rs | 5 +++++ src/lib.rs | 11 +++++++++-- src/macros.rs | 4 +++- src/map.rs | 14 +++++++++++--- src/set.rs | 11 +++++++++-- tests/equivalent_trait.rs | 1 - tests/quick.rs | 1 - tests/tests.rs | 1 - 11 files changed, 80 insertions(+), 20 deletions(-) create mode 100644 build.rs diff --git a/.travis.yml b/.travis.yml index 01bdc083..75b7b19c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,12 @@ language: rust sudo: false matrix: include: - - rust: 1.36.0 + - rust: 1.18.0 + before_script: + # lazy_static 1.1 requires Rust 1.21+, so downgrade it. + # (we only use it in benchmarks anyway...) + - cargo generate-lockfile + - cargo update -p lazy_static --precise 1.0.2 - rust: stable env: - FEATURES='serde-1' @@ -17,6 +22,6 @@ branches: script: - | cargo build --verbose --features "$FEATURES" && - cargo test --verbose --features "$FEATURES" && - cargo test --release --verbose --features "$FEATURES" && + cargo test --verbose --features "$FEATURES",force_std && + cargo test --release --verbose --features "$FEATURES",force_std && cargo doc --verbose --features "$FEATURES" diff --git a/Cargo.toml b/Cargo.toml index 79bad659..8138fcbe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,12 @@ indexmap. keywords = ["hashmap"] categories = ["data-structures"] +[package.metadata.release] +no-dev-version = true + +[package.metadata.docs.rs] +features = ["serde-1"] + [lib] bench = false @@ -48,11 +54,34 @@ serde-1 = ["serde"] test_low_transition_point = [] test_debug = [] +force_std = [] + [profile.bench] debug = true -[package.metadata.release] -no-dev-version = true +[build-dependencies] +autocfg = "0.1.5" -[package.metadata.docs.rs] -features = ["serde-1"] +[[test]] +name = "tests" +required-features = [ "force_std" ] + +[[test]] +name = "serde" +required-features = [ "force_std" ] + +[[test]] +name = "quick" +required-features = [ "force_std" ] + +[[test]] +name = "equivalent_trait" +required-features = [ "force_std" ] + +[[bench]] +name = "bench" +required-features = [ "force_std" ] + +[[bench]] +name = "faststring" +required-features = [ "force_std" ] \ No newline at end of file diff --git a/README.rst b/README.rst index 6ee60906..3792afe3 100644 --- a/README.rst +++ b/README.rst @@ -12,8 +12,8 @@ indexmap .. |docs| image:: https://docs.rs/indexmap/badge.svg .. _docs: https://docs.rs/indexmap -.. |rustc| image:: https://img.shields.io/badge/rust-1.36%2B-orange.svg -.. _rustc: https://img.shields.io/badge/rust-1.36%2B-orange.svg +.. |rustc| image:: https://img.shields.io/badge/rust-1.18%2B-orange.svg +.. _rustc: https://img.shields.io/badge/rust-1.18%2B-orange.svg A safe, pure-Rust hash table which preserves insertion order. diff --git a/build.rs b/build.rs new file mode 100644 index 00000000..964cbe27 --- /dev/null +++ b/build.rs @@ -0,0 +1,5 @@ +fn main() { + let ac = autocfg::new(); + ac.emit_has_path("std"); + ac.emit_has_path("alloc"); +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 39a0a2c6..f94d1595 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,19 +14,26 @@ //! //! ## Rust Version //! -//! This version of indexmap requires Rust 1.36 or later. +//! This version of indexmap requires Rust 1.18 or later. //! //! The indexmap 1.x release series will use a carefully considered version //! upgrade policy, where in a later 1.x version, we will raise the minimum //! required Rust version. -#![cfg_attr(not(test), no_std)] +#![cfg_attr(all(not(test), has_alloc, not(feature = "force_std")), no_std)] #[cfg(test)] extern crate core; +#[cfg(all(has_alloc, not(feature = "force_std")))] extern crate alloc; +#[cfg(all(has_alloc, has_std))] +extern crate std; + +#[cfg(any(not(has_alloc), feature = "force_std"))] +extern crate std as alloc; + #[macro_use] mod macros; #[cfg(feature = "serde-1")] diff --git a/src/macros.rs b/src/macros.rs index b7188278..0186958b 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,5 +1,5 @@ #[macro_export] -/// Create an `IndexMap` from a list of key-value pairs +/// Create an `IndexMap` from a list of key-value pairs. Requires `std` to be available. /// /// ## Example /// @@ -21,6 +21,7 @@ /// assert_eq!(map.keys().next(), Some(&"a")); /// # } /// ``` +#[cfg(any(has_std, feature = "force_std", test))] macro_rules! indexmap { (@single $($x:tt)*) => (()); (@count $($rest:expr),*) => (<[()]>::len(&[$(indexmap!(@single $rest)),*])); @@ -60,6 +61,7 @@ macro_rules! indexmap { /// assert_eq!(set.iter().next(), Some(&"a")); /// # } /// ``` +#[cfg(any(has_std, feature = "force_std", test))] macro_rules! indexset { (@single $($x:tt)*) => (()); (@count $($rest:expr),*) => (<[()]>::len(&[$(indexset!(@single $rest)),*])); diff --git a/src/map.rs b/src/map.rs index 4af7a122..e7c77f6e 100644 --- a/src/map.rs +++ b/src/map.rs @@ -7,7 +7,6 @@ use core::hash::Hash; use core::hash::BuildHasher; use core::hash::Hasher; use core::iter::FromIterator; -use hashbrown::hash_map::DefaultHashBuilder; use core::ops::RangeFull; use core::cmp::{max, Ordering}; @@ -265,7 +264,15 @@ impl ShortHashProxy /// assert_eq!(letters.get(&'y'), None); /// ``` #[derive(Clone)] -pub struct IndexMap { +#[cfg(any(has_std, feature = "force_std", test))] +pub struct IndexMap { + core: OrderMapCore, + hash_builder: S, +} + +#[derive(Clone)] +#[cfg(not(any(has_std, feature = "force_std", test)))] +pub struct IndexMap { core: OrderMapCore, hash_builder: S, } @@ -356,7 +363,8 @@ macro_rules! probe_loop { } } -impl IndexMap { +#[cfg(any(has_std, feature = "force_std", test))] +impl IndexMap { /// Create a new map. (Does not allocate.) pub fn new() -> Self { Self::with_capacity(0) diff --git a/src/set.rs b/src/set.rs index 27b6bfbb..6b4209af 100644 --- a/src/set.rs +++ b/src/set.rs @@ -1,7 +1,6 @@ //! A hash set implemented using `IndexMap` use core::cmp::Ordering; -use hashbrown::hash_map::DefaultHashBuilder; use core::fmt; use core::iter::{FromIterator, Chain}; use core::hash::{Hash, BuildHasher}; @@ -57,7 +56,14 @@ type Bucket = super::Bucket; /// assert!(!letters.contains(&'y')); /// ``` #[derive(Clone)] -pub struct IndexSet { +#[cfg(any(has_std, feature = "force_std", test))] +pub struct IndexSet { + map: IndexMap, +} + +#[derive(Clone)] +#[cfg(not(any(has_std, feature = "force_std", test)))] +pub struct IndexSet { map: IndexMap, } @@ -75,6 +81,7 @@ impl fmt::Debug for IndexSet } } +#[cfg(any(has_std, feature = "force_std", test))] impl IndexSet { /// Create a new set. (Does not allocate.) pub fn new() -> Self { diff --git a/tests/equivalent_trait.rs b/tests/equivalent_trait.rs index 8b79e20a..18c861b3 100644 --- a/tests/equivalent_trait.rs +++ b/tests/equivalent_trait.rs @@ -1,4 +1,3 @@ - #[macro_use] extern crate indexmap; use indexmap::Equivalent; diff --git a/tests/quick.rs b/tests/quick.rs index a6efa5d4..95bddfe9 100644 --- a/tests/quick.rs +++ b/tests/quick.rs @@ -1,4 +1,3 @@ - #[macro_use] extern crate quickcheck; diff --git a/tests/tests.rs b/tests/tests.rs index dbb9f658..e2c3ecc0 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1,4 +1,3 @@ - #[macro_use] extern crate indexmap; From 521acc85b68e4a8c17117ee71c3e742c34174700 Mon Sep 17 00:00:00 2001 From: leo60228 Date: Mon, 19 Aug 2019 08:00:59 -0400 Subject: [PATCH 5/5] Revert to Rust 2015 (oops) --- .travis.yml | 12 ++++++++++-- Cargo.toml | 8 +++----- benches/bench.rs | 4 ++++ benches/faststring.rs | 4 ++++ build.rs | 12 ++++++++---- src/lib.rs | 1 - src/macros.rs | 2 -- src/map.rs | 28 ++++++++++++++-------------- src/serde.rs | 30 ++++++++++++++++-------------- src/set.rs | 4 ++-- tests/equivalent_trait.rs | 1 + tests/quick.rs | 9 +++++++-- tests/serde.rs | 2 ++ tests/tests.rs | 2 ++ 14 files changed, 73 insertions(+), 46 deletions(-) diff --git a/.travis.yml b/.travis.yml index 75b7b19c..462920d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,20 +8,28 @@ matrix: # (we only use it in benchmarks anyway...) - cargo generate-lockfile - cargo update -p lazy_static --precise 1.0.2 + env: + - FEATURES='force_std' - rust: stable env: - FEATURES='serde-1' + - TEST_FEATURES='force_std' - rust: beta + env: + - TEST_FEATURES='force_std' - rust: nightly + env: + - TEST_FEATURES='force_std' - rust: nightly env: - FEATURES='test_low_transition_point' + - TEST_FEATURES='force_std' branches: only: - master script: - | cargo build --verbose --features "$FEATURES" && - cargo test --verbose --features "$FEATURES",force_std && - cargo test --release --verbose --features "$FEATURES",force_std && + cargo test --verbose --features "$FEATURES $TEST_FEATURES" && + cargo test --release --verbose --features "$FEATURES $TEST_FEATURES" && cargo doc --verbose --features "$FEATURES" diff --git a/Cargo.toml b/Cargo.toml index 8138fcbe..854c0b40 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,6 @@ [package] name = "indexmap" version = "1.1.0" -edition = "2018" authors = [ "bluss", "Josh Stone " @@ -35,11 +34,10 @@ features = ["serde-1"] bench = false [dependencies] -serde = { version = "1.0", optional = true, default-features = false } -hashbrown = "0.6.0" +serde = { version = "1.0", optional = true } [dev-dependencies] -itertools = "0.8.0" +itertools = "0.7.0" rand = "0.4" quickcheck = { version = "0.6", default-features = false } fnv = "1.0" @@ -84,4 +82,4 @@ required-features = [ "force_std" ] [[bench]] name = "faststring" -required-features = [ "force_std" ] \ No newline at end of file +required-features = [ "force_std" ] diff --git a/benches/bench.rs b/benches/bench.rs index 8910ffd9..ae1a4dac 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -1,5 +1,7 @@ #![feature(test)] extern crate test; +extern crate rand; +extern crate fnv; #[macro_use] extern crate lazy_static; @@ -11,6 +13,8 @@ type FnvBuilder = BuildHasherDefault; use test::Bencher; use test::black_box; +extern crate indexmap; + use indexmap::IndexMap; use std::collections::HashMap; diff --git a/benches/faststring.rs b/benches/faststring.rs index 5d7f21a8..65e78013 100644 --- a/benches/faststring.rs +++ b/benches/faststring.rs @@ -1,8 +1,12 @@ #![feature(test)] extern crate test; +extern crate rand; +extern crate lazy_static; use test::Bencher; +extern crate indexmap; + use indexmap::IndexMap; use std::collections::HashMap; diff --git a/build.rs b/build.rs index 964cbe27..320cb495 100644 --- a/build.rs +++ b/build.rs @@ -1,5 +1,9 @@ +extern crate autocfg; + fn main() { - let ac = autocfg::new(); - ac.emit_has_path("std"); - ac.emit_has_path("alloc"); -} \ No newline at end of file + //let ac = autocfg::new(); + //ac.emit_sysroot_crate("std"); + //ac.emit_sysroot_crate("alloc"); + autocfg::emit("std"); + //autocfg::emit("alloc"); +} diff --git a/src/lib.rs b/src/lib.rs index f94d1595..fc3e06ea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,7 +22,6 @@ #![cfg_attr(all(not(test), has_alloc, not(feature = "force_std")), no_std)] -#[cfg(test)] extern crate core; #[cfg(all(has_alloc, not(feature = "force_std")))] diff --git a/src/macros.rs b/src/macros.rs index 0186958b..553a3ae3 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -4,7 +4,6 @@ /// ## Example /// /// ``` -/// # extern crate std; /// /// #[macro_use] extern crate indexmap; /// # fn main() { @@ -45,7 +44,6 @@ macro_rules! indexmap { /// ## Example /// /// ``` -/// # extern crate std; /// #[macro_use] extern crate indexmap; /// # fn main() { /// diff --git a/src/map.rs b/src/map.rs index e7c77f6e..8c26fba1 100644 --- a/src/map.rs +++ b/src/map.rs @@ -1,7 +1,7 @@ //! `IndexMap` is a hash table where the iteration order of the key-value //! pairs is independent of the hash values of the keys. -pub use crate::mutable_keys::MutableKeys; +pub use mutable_keys::MutableKeys; use core::hash::Hash; use core::hash::BuildHasher; @@ -18,9 +18,9 @@ use alloc::vec::Vec; use alloc::boxed::Box; use alloc::vec; -use crate::util::{third, ptrdistance, enumerate}; -use crate::equivalent::Equivalent; -use crate::{ +use util::{third, ptrdistance, enumerate}; +use equivalent::Equivalent; +use { Bucket, HashValue, }; @@ -249,7 +249,7 @@ impl ShortHashProxy /// # Examples /// /// ``` -/// # extern crate std; +/// # extern crate indexmap; /// use indexmap::IndexMap; /// /// // count the frequency of each letter in a sentence. @@ -313,28 +313,28 @@ impl fmt::Debug for IndexMap S: BuildHasher, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_map().entries(self.iter()).finish()?; + try!(f.debug_map().entries(self.iter()).finish()); if cfg!(not(feature = "test_debug")) { return Ok(()); } - writeln!(f, "")?; + try!(writeln!(f, "")); for (i, index) in enumerate(&*self.core.indices) { - write!(f, "{}: {:?}", i, index)?; + try!(write!(f, "{}: {:?}", i, index)); if let Some(pos) = index.pos() { let hash = self.core.entries[pos].hash; let key = &self.core.entries[pos].key; let desire = desired_pos(self.core.mask, hash); - write!(f, ", desired={}, probe_distance={}, key={:?}", + try!(write!(f, ", desired={}, probe_distance={}, key={:?}", desire, probe_distance(self.core.mask, hash, i), - key)?; + key)); } - writeln!(f, "")?; + try!(writeln!(f, "")); } - writeln!(f, "cap={}, raw_cap={}, entries.cap={}", + try!(writeln!(f, "cap={}, raw_cap={}, entries.cap={}", self.capacity(), self.raw_capacity(), - self.core.entries.capacity())?; + self.core.entries.capacity())); Ok(()) } } @@ -1913,7 +1913,7 @@ impl Eq for IndexMap #[cfg(test)] mod tests { use super::*; - use crate::util::enumerate; + use util::enumerate; #[test] fn it_works() { diff --git a/src/serde.rs b/src/serde.rs index 4c78e989..eb54e01f 100644 --- a/src/serde.rs +++ b/src/serde.rs @@ -1,13 +1,15 @@ -use serde::ser::{Serialize, Serializer, SerializeMap, SerializeSeq}; -use serde::de::{Deserialize, Deserializer, Error, IntoDeserializer, MapAccess, SeqAccess, Visitor}; -use serde::de::value::{MapDeserializer, SeqDeserializer}; +extern crate serde; -use core::fmt::{self, Formatter}; -use core::hash::{BuildHasher, Hash}; -use core::marker::PhantomData; +use self::serde::ser::{Serialize, Serializer, SerializeMap, SerializeSeq}; +use self::serde::de::{Deserialize, Deserializer, Error, IntoDeserializer, MapAccess, SeqAccess, Visitor}; +use self::serde::de::value::{MapDeserializer, SeqDeserializer}; -use crate::IndexMap; +use std::fmt::{self, Formatter}; +use std::hash::{BuildHasher, Hash}; +use std::marker::PhantomData; + +use IndexMap; /// Requires crate feature `"serde-1"` impl Serialize for IndexMap @@ -18,9 +20,9 @@ impl Serialize for IndexMap fn serialize(&self, serializer: T) -> Result where T: Serializer { - let mut map_serializer = serializer.serialize_map(Some(self.len()))?; + let mut map_serializer = try!(serializer.serialize_map(Some(self.len()))); for (key, value) in self { - map_serializer.serialize_entry(key, value)?; + try!(map_serializer.serialize_entry(key, value)); } map_serializer.end() } @@ -44,7 +46,7 @@ impl<'de, K, V, S> Visitor<'de> for OrderMapVisitor { let mut values = IndexMap::with_capacity_and_hasher(map.size_hint().unwrap_or(0), S::default()); - while let Some((key, value)) = map.next_entry()? { + while let Some((key, value)) = try!(map.next_entry()) { values.insert(key, value); } @@ -79,7 +81,7 @@ impl<'de, K, V, S, E> IntoDeserializer<'de, E> for IndexMap } -use crate::IndexSet; +use IndexSet; /// Requires crate feature `"serde-1"` impl Serialize for IndexSet @@ -89,9 +91,9 @@ impl Serialize for IndexSet fn serialize(&self, serializer: Se) -> Result where Se: Serializer { - let mut set_serializer = serializer.serialize_seq(Some(self.len()))?; + let mut set_serializer = try!(serializer.serialize_seq(Some(self.len()))); for value in self { - set_serializer.serialize_element(value)?; + try!(set_serializer.serialize_element(value)); } set_serializer.end() } @@ -114,7 +116,7 @@ impl<'de, T, S> Visitor<'de> for OrderSetVisitor { let mut values = IndexSet::with_capacity_and_hasher(seq.size_hint().unwrap_or(0), S::default()); - while let Some(value) = seq.next_element()? { + while let Some(value) = try!(seq.next_element()) { values.insert(value); } diff --git a/src/set.rs b/src/set.rs index 6b4209af..97b6c95e 100644 --- a/src/set.rs +++ b/src/set.rs @@ -44,7 +44,7 @@ type Bucket = super::Bucket; /// # Examples /// /// ``` -/// # extern crate std; +/// # extern crate indexmap; /// use indexmap::IndexSet; /// /// // Collects which letters appear in a sentence. @@ -950,7 +950,7 @@ impl<'a, 'b, T, S1, S2> Sub<&'b IndexSet> for &'a IndexSet #[cfg(test)] mod tests { use super::*; - use crate::util::enumerate; + use util::enumerate; #[test] fn it_works() { diff --git a/tests/equivalent_trait.rs b/tests/equivalent_trait.rs index 18c861b3..8b79e20a 100644 --- a/tests/equivalent_trait.rs +++ b/tests/equivalent_trait.rs @@ -1,3 +1,4 @@ + #[macro_use] extern crate indexmap; use indexmap::Equivalent; diff --git a/tests/quick.rs b/tests/quick.rs index 95bddfe9..14f267cf 100644 --- a/tests/quick.rs +++ b/tests/quick.rs @@ -1,6 +1,11 @@ + +extern crate indexmap; +extern crate itertools; #[macro_use] extern crate quickcheck; +extern crate fnv; + use indexmap::IndexMap; use itertools::Itertools; @@ -332,7 +337,7 @@ impl Arbitrary for Alpha { }).collect()) } - fn shrink(&self) -> Box> { + fn shrink(&self) -> Box> { Box::new((**self).shrink().map(Alpha)) } } @@ -354,7 +359,7 @@ impl Arbitrary for Large> Large((0..len).map(|_| T::arbitrary(g)).collect()) } - fn shrink(&self) -> Box> { + fn shrink(&self) -> Box> { Box::new((**self).shrink().map(Large)) } } diff --git a/tests/serde.rs b/tests/serde.rs index 09edba61..dbb23573 100644 --- a/tests/serde.rs +++ b/tests/serde.rs @@ -2,6 +2,8 @@ #[macro_use] extern crate indexmap; +extern crate serde_test; +extern crate fnv; use serde_test::{Token, assert_tokens}; diff --git a/tests/tests.rs b/tests/tests.rs index e2c3ecc0..4a7f4db7 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1,5 +1,7 @@ + #[macro_use] extern crate indexmap; +extern crate itertools; #[test]