Skip to content

Commit 38ae018

Browse files
committed
FEAT: Support building without libstd
1 parent 18c9016 commit 38ae018

File tree

8 files changed

+107
-3
lines changed

8 files changed

+107
-3
lines changed

.travis.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@ matrix:
2020
- rust: nightly
2121
env:
2222
- FEATURES='test_low_transition_point'
23+
- name: "no_std"
24+
rust: stable
25+
env: TARGET=thumbv6m-none-eabi
26+
before_script:
27+
- rustup target add $TARGET
28+
- set -ex
29+
script:
30+
- cargo build -vv --target=$TARGET
31+
- cargo build -v -p test-nostd --target=$TARGET
2332
branches:
2433
only:
2534
- master

Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,13 @@ indexmap.
2424
keywords = ["hashmap"]
2525
categories = ["data-structures"]
2626

27+
build = "build.rs"
28+
2729
[lib]
2830
bench = false
2931

32+
[build-dependencies]
33+
autocfg = "0.1.6"
3034
[dependencies]
3135
serde = { version = "1.0", optional = true }
3236
rayon = { version = "1.0", optional = true }
@@ -56,3 +60,6 @@ tag-name = "{{version}}"
5660

5761
[package.metadata.docs.rs]
5862
features = ["serde-1", "rayon"]
63+
64+
[workspace]
65+
members = ["test-nostd"]

build.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
extern crate autocfg;
2+
3+
fn main() {
4+
let ac = autocfg::new();
5+
ac.emit_sysroot_crate("std");
6+
ac.emit_sysroot_crate("alloc");
7+
}

src/lib.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
21
#![deny(unsafe_code)]
32
#![doc(html_root_url = "https://docs.rs/indexmap/1/")]
3+
#![cfg_attr(not(has_std), no_std)]
44

55
//! [`IndexMap`] is a hash table where the iteration order of the key-value
66
//! pairs is independent of the hash values of the keys.
@@ -21,6 +21,25 @@
2121
//! upgrade policy, where in a later 1.x version, we will raise the minimum
2222
//! required Rust version.
2323
24+
#[cfg(not(has_std))]
25+
#[macro_use(vec)]
26+
extern crate alloc;
27+
28+
#[cfg(not(has_std))]
29+
pub(crate) mod std {
30+
pub use core::*;
31+
pub mod alloc {
32+
pub use ::alloc::*;
33+
}
34+
pub mod collections {
35+
pub use ::alloc::collections::*;
36+
}
37+
pub use ::alloc::vec as vec;
38+
}
39+
40+
#[cfg(not(has_std))]
41+
use std::vec::Vec;
42+
2443
#[macro_use]
2544
mod macros;
2645
#[cfg(feature = "serde-1")]

src/map.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
//! `IndexMap` is a hash table where the iteration order of the key-value
22
//! pairs is independent of the hash values of the keys.
33
4+
#[cfg(not(has_std))]
5+
use alloc::boxed::Box;
6+
#[cfg(not(has_std))]
7+
use std::vec::Vec;
8+
49
pub use mutable_keys::MutableKeys;
510

611
#[cfg(feature = "rayon")]
@@ -10,9 +15,11 @@ use std::hash::Hash;
1015
use std::hash::BuildHasher;
1116
use std::hash::Hasher;
1217
use std::iter::FromIterator;
13-
use std::collections::hash_map::RandomState;
1418
use std::ops::RangeFull;
1519

20+
#[cfg(has_std)]
21+
use std::collections::hash_map::RandomState;
22+
1623
use std::cmp::{max, Ordering};
1724
use std::fmt;
1825
use std::mem::{replace};
@@ -264,10 +271,17 @@ impl<Sz> ShortHashProxy<Sz>
264271
/// assert_eq!(letters.get(&'y'), None);
265272
/// ```
266273
#[derive(Clone)]
274+
#[cfg(has_std)]
267275
pub struct IndexMap<K, V, S = RandomState> {
268276
core: OrderMapCore<K, V>,
269277
hash_builder: S,
270278
}
279+
#[derive(Clone)]
280+
#[cfg(not(has_std))]
281+
pub struct IndexMap<K, V, S> {
282+
core: OrderMapCore<K, V>,
283+
hash_builder: S,
284+
}
271285

272286
// core of the map that does not depend on S
273287
#[derive(Clone)]
@@ -379,6 +393,7 @@ macro_rules! probe_loop {
379393
}
380394
}
381395

396+
#[cfg(has_std)]
382397
impl<K, V> IndexMap<K, V> {
383398
/// Create a new map. (Does not allocate.)
384399
pub fn new() -> Self {

src/set.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@
33
#[cfg(feature = "rayon")]
44
pub use ::rayon::set as rayon;
55

6-
use std::cmp::Ordering;
6+
#[cfg(not(has_std))]
7+
use std::vec::Vec;
8+
9+
#[cfg(has_std)]
710
use std::collections::hash_map::RandomState;
11+
12+
use std::cmp::Ordering;
813
use std::fmt;
914
use std::iter::{FromIterator, Chain};
1015
use std::hash::{Hash, BuildHasher};
@@ -59,9 +64,15 @@ type Bucket<T> = super::Bucket<T, ()>;
5964
/// assert!(!letters.contains(&'y'));
6065
/// ```
6166
#[derive(Clone)]
67+
#[cfg(has_std)]
6268
pub struct IndexSet<T, S = RandomState> {
6369
map: IndexMap<T, (), S>,
6470
}
71+
#[cfg(not(has_std))]
72+
#[derive(Clone)]
73+
pub struct IndexSet<T, S> {
74+
map: IndexMap<T, (), S>,
75+
}
6576

6677
impl<T, S> Entries for IndexSet<T, S> {
6778
type Entry = Bucket<T>;
@@ -99,6 +110,7 @@ impl<T, S> fmt::Debug for IndexSet<T, S>
99110
}
100111
}
101112

113+
#[cfg(has_std)]
102114
impl<T> IndexSet<T> {
103115
/// Create a new set. (Does not allocate.)
104116
pub fn new() -> Self {

test-nostd/Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "test-nostd"
3+
version = "0.1.0"
4+
authors = ["bluss"]
5+
publish = false
6+
7+
[dependencies]
8+
indexmap = { path = ".." }
9+
# no-std compatible hasher
10+
ahash = "0.2"
11+
12+
[dev-dependencies]

test-nostd/src/lib.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#![no_std]
2+
3+
extern crate indexmap;
4+
extern crate ahash;
5+
6+
use indexmap::IndexMap;
7+
use indexmap::IndexSet;
8+
type Map<K, V> = IndexMap<K, V, ahash::ABuildHasher>;
9+
type Set<T> = IndexSet<T, ahash::ABuildHasher>;
10+
11+
use core::iter::FromIterator;
12+
13+
pub fn test_compile() {
14+
let mut map = Map::default();
15+
map.insert(1, 1);
16+
map.insert(2, 4);
17+
for (_, _) in map.iter() { }
18+
19+
let _map2 = Map::from_iter(Some((1, 1)));
20+
21+
let mut set = Set::default();
22+
set.insert("a");
23+
}

0 commit comments

Comments
 (0)