Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Constify the code generator #242

Draft
wants to merge 21 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
41e7857
phf_shared: Start constifying PhfBorrow impls
vbe0201 Oct 21, 2021
9bc0631
phf_shared: Make PhfHash usable in const context
vbe0201 Oct 21, 2021
d091ca1
phf_shared: Implement SipHasher13 to make hash a const fn
vbe0201 Oct 21, 2021
0376ed4
Bump all crate versions to 0.11.0
vbe0201 Oct 21, 2021
d1dd154
phf_generator: Constify most of the functionality
vbe0201 Oct 21, 2021
b759a56
Update html_root_urls for new versions
vbe0201 Oct 21, 2021
e69d5d7
phf_generator: Fix build with const-api feature
vbe0201 Oct 22, 2021
d744a73
phf_generator: Add RNG support for alphanumeric chars and fix gen_has…
vbe0201 Oct 22, 2021
c472035
phf_shared: std => core
vbe0201 Oct 22, 2021
55fcace
Exclude phf_codegen and phf_macros from const-api feature
vbe0201 Oct 22, 2021
bad9d6b
phf_macros: Repurpose as utility crate
vbe0201 Oct 22, 2021
20c7b27
phf: Turn macros into constant expressions
vbe0201 Oct 22, 2021
a263190
phf: Properly reference crate types in macros
vbe0201 Oct 22, 2021
43f883f
phf_generator: Implement const quicksort for buckets
vbe0201 Oct 22, 2021
69a0db7
phf: Fix build and most of the tests
vbe0201 Oct 23, 2021
f303e13
phf_macros: std => core
vbe0201 Oct 23, 2021
4c2d169
phf_macro_tests: Add more test cases
vbe0201 Oct 23, 2021
d4c3ae6
phf_shared: Clean up sip hasher implementation
vbe0201 Oct 23, 2021
4a2304a
phf_macros: Sort correctly and fix tests
vbe0201 Oct 23, 2021
c16e10e
phf: Fix doctest
vbe0201 Oct 23, 2021
2021fa0
phf: Make truly nested structures possible
vbe0201 Oct 23, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 5 additions & 2 deletions Cargo.toml
@@ -1,8 +1,11 @@
[workspace]
members = [
"phf",
"phf_codegen",
"phf_codegen/test",
# TODO: Re-enable when a possibility is found to build all of phf_codegen's
# dependencies *WITHOUT* the `const-api` cargo feature, but everything else
# either with or without, depending on feature opt-ins.
#"phf_codegen",
#"phf_codegen/test",
"phf_generator",
"phf_macros",
"phf_macros_tests",
Expand Down
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -15,6 +15,8 @@ a compiler note about how long it took.

MSRV (minimum supported rust version) is Rust 1.46.

TODO: Carify MSRV when building with const feature.

## Usage

PHF data structures can be constructed via either the procedural
Expand Down
13 changes: 5 additions & 8 deletions phf/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "phf"
authors = ["Steven Fackler <sfackler@gmail.com>"]
version = "0.10.0"
version = "0.11.0"
license = "MIT"
description = "Runtime support for perfect hash function data structures"
repository = "https://github.com/sfackler/rust-phf"
Expand All @@ -18,15 +18,12 @@ default = ["std"]
std = ["phf_shared/std"]
uncased = ["phf_shared/uncased"]
unicase = ["phf_shared/unicase"]
macros = [
"phf_macros",
"proc-macro-hack",
]
macros = ["phf_generator", "phf_macros"]

[dependencies]
proc-macro-hack = { version = "0.5.4", optional = true }
phf_macros = { version = "0.10.0", optional = true }
phf_shared = { version = "0.10.0", default-features = false }
phf_generator = { version = "0.11.0", features = ["const-api"], optional = true }
phf_macros = { version = "0.11.0", optional = true }
phf_shared = { version = "0.11.0", default-features = false, features = ["const-api"] }

[package.metadata.docs.rs]
features = ["macros"]
83 changes: 73 additions & 10 deletions phf/src/lib.rs
Expand Up @@ -36,7 +36,7 @@
//! ```rust
//! use phf::phf_map;
//!
//! #[derive(Clone)]
//! #[derive(Clone, Copy)]
//! pub enum Keyword {
//! Loop,
//! Continue,
Expand Down Expand Up @@ -71,13 +71,52 @@
//! [#183]: https://github.com/rust-phf/rust-phf/issues/183
//! [#196]: https://github.com/rust-phf/rust-phf/issues/196

#![doc(html_root_url = "https://docs.rs/phf/0.10")]
// XXX: Remove on stabilization.
#![allow(incomplete_features)]
#![feature(generic_const_exprs, const_trait_impl)]
#![doc(html_root_url = "https://docs.rs/phf/0.11")]
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]

#[cfg(feature = "std")]
extern crate std as core;

// Not part of the public API. Used by the macro facade.
#[cfg(feature = "macros")]
#[doc(hidden)]
pub extern crate phf_macros as __phf_macros;

#[cfg(feature = "macros")]
#[doc(hidden)]
pub const fn build_map<Key: 'static, Value: 'static, const N: usize>(
state: &'static ([(Key, Value); N], phf_generator::HashState<N>),
) -> Map<Key, Value>
where
[(); (N + phf_generator::DEFAULT_LAMBDA - 1) / phf_generator::DEFAULT_LAMBDA]: Sized,
{
Map {
key: state.1.key,
disps: &*state.1.disps,
entries: &state.0,
}
}

#[cfg(feature = "macros")]
#[doc(hidden)]
pub const fn build_ordered_map<Key: 'static, Value: 'static, const N: usize>(
state: &'static ([(Key, Value); N], phf_generator::HashState<N>),
) -> OrderedMap<Key, Value>
where
[(); (N + phf_generator::DEFAULT_LAMBDA - 1) / phf_generator::DEFAULT_LAMBDA]: Sized,
{
OrderedMap {
key: state.1.key,
disps: &*state.1.disps,
idxs: &*state.1.map,
entries: &state.0,
}
}

#[cfg(feature = "macros")]
/// Macro to create a `static` (compile-time) [`Map`].
///
Expand All @@ -97,15 +136,25 @@ extern crate std as core;
/// assert_eq!(MY_MAP["hello"], 1);
/// }
/// ```
#[proc_macro_hack::proc_macro_hack]
pub use phf_macros::phf_map;
#[macro_export]
macro_rules! phf_map {
($($key:expr => $value:expr),* $(,)*) => {
$crate::build_map(&$crate::__phf_macros::phf_map(&[$(($key, $value)),*]))
};
}

#[cfg(feature = "macros")]
/// Macro to create a `static` (compile-time) [`OrderedMap`].
///
/// Requires the `macros` feature. Same usage as [`phf_map`].
#[proc_macro_hack::proc_macro_hack]
pub use phf_macros::phf_ordered_map;
#[macro_export]
macro_rules! phf_ordered_map {
($($key:expr => $value:expr),* $(,)*) => {
$crate::build_ordered_map(
&$crate::__phf_macros::phf_ordered_map(&[$(($key, $value)),*]),
)
};
}

#[cfg(feature = "macros")]
/// Macro to create a `static` (compile-time) [`Set`].
Expand All @@ -126,15 +175,29 @@ pub use phf_macros::phf_ordered_map;
/// assert!(MY_SET.contains("hello world"));
/// }
/// ```
#[proc_macro_hack::proc_macro_hack]
pub use phf_macros::phf_set;
#[macro_export]
macro_rules! phf_set {
($($key:expr),* $(,)*) => {
$crate::Set {
map: $crate::build_map(&$crate::__phf_macros::phf_set(&[$($key),*])),
}
};
}

#[cfg(feature = "macros")]
/// Macro to create a `static` (compile-time) [`OrderedSet`].
///
/// Requires the `macros` feature. Same usage as [`phf_set`].
#[proc_macro_hack::proc_macro_hack]
pub use phf_macros::phf_ordered_set;
#[macro_export]
macro_rules! phf_ordered_set {
($($key:expr),* $(,)*) => {
$crate::OrderedSet {
map: $crate::build_ordered_map(
&$crate::__phf_macros::phf_ordered_set(&[$($key),*]),
),
}
};
}

#[doc(inline)]
pub use self::map::Map;
Expand Down
1 change: 1 addition & 0 deletions phf/src/map.rs
Expand Up @@ -13,6 +13,7 @@ use phf_shared::{self, HashKey, PhfBorrow, PhfHash};
/// The fields of this struct are public so that they may be initialized by the
/// `phf_map!` macro and code generation. They are subject to change at any
/// time and should never be accessed directly.
#[derive(Clone, Copy)]
pub struct Map<K: 'static, V: 'static> {
#[doc(hidden)]
pub key: HashKey,
Expand Down
1 change: 1 addition & 0 deletions phf/src/ordered_map.rs
Expand Up @@ -16,6 +16,7 @@ use phf_shared::{self, HashKey, PhfBorrow, PhfHash};
/// The fields of this struct are public so that they may be initialized by the
/// `phf_ordered_map!` macro and code generation. They are subject to change at
/// any time and should never be accessed directly.
#[derive(Clone, Copy)]
pub struct OrderedMap<K: 'static, V: 'static> {
#[doc(hidden)]
pub key: HashKey,
Expand Down
1 change: 1 addition & 0 deletions phf/src/ordered_set.rs
Expand Up @@ -15,6 +15,7 @@ use phf_shared::PhfBorrow;
/// The fields of this struct are public so that they may be initialized by the
/// `phf_ordered_set!` macro and code generation. They are subject to change at
/// any time and should never be accessed directly.
#[derive(Clone, Copy)]
pub struct OrderedSet<T: 'static> {
#[doc(hidden)]
pub map: OrderedMap<T, ()>,
Expand Down
1 change: 1 addition & 0 deletions phf/src/set.rs
Expand Up @@ -14,6 +14,7 @@ use crate::{map, Map};
/// The fields of this struct are public so that they may be initialized by the
/// `phf_set!` macro and code generation. They are subject to change at any
/// time and should never be accessed directly.
#[derive(Clone, Copy)]
pub struct Set<T: 'static> {
#[doc(hidden)]
pub map: Map<T, ()>,
Expand Down
6 changes: 3 additions & 3 deletions phf_codegen/Cargo.toml
@@ -1,13 +1,13 @@
[package]
name = "phf_codegen"
authors = ["Steven Fackler <sfackler@gmail.com>"]
version = "0.10.0"
version = "0.11.0"
license = "MIT"
description = "Codegen library for PHF types"
repository = "https://github.com/sfackler/rust-phf"
edition = "2018"
readme = "../README.md"

[dependencies]
phf_generator = "0.10.0"
phf_shared = "0.10.0"
phf_generator = "0.11.0"
phf_shared = "0.11.0"
2 changes: 1 addition & 1 deletion phf_codegen/src/lib.rs
Expand Up @@ -128,7 +128,7 @@
//! // ...
//! ```

#![doc(html_root_url = "https://docs.rs/phf_codegen/0.10")]
#![doc(html_root_url = "https://docs.rs/phf_codegen/0.11")]

use phf_shared::{FmtConst, PhfHash};
use std::collections::HashSet;
Expand Down
4 changes: 2 additions & 2 deletions phf_codegen/test/Cargo.toml
Expand Up @@ -6,11 +6,11 @@ build = "build.rs"
edition = "2018"

[dependencies]
phf = { version = "0.10.0", features = ["uncased", "unicase"] }
phf = { version = "0.11.0", features = ["uncased", "unicase"] }
uncased = { version = "0.9.6", default-features = false }
unicase = "2.4.0"

[build-dependencies]
phf_codegen = { version = "0.10.0", path = ".." }
phf_codegen = { version = "0.11.0", path = ".." }
unicase = "2.4.0"
uncased = { version = "0.9.6", default-features = false }
8 changes: 5 additions & 3 deletions phf_generator/Cargo.toml
@@ -1,15 +1,14 @@
[package]
name = "phf_generator"
authors = ["Steven Fackler <sfackler@gmail.com>"]
version = "0.10.0"
version = "0.11.0"
license = "MIT"
description = "PHF generation logic"
repository = "https://github.com/sfackler/rust-phf"
edition = "2018"

[dependencies]
rand = { version = "0.8", features = ["small_rng"] }
phf_shared = { version = "0.10.0", default-features = false }
phf_shared = { version = "0.11.0", default-features = false }
# for stable black_box()
criterion = { version = "=0.3.4", optional = true }

Expand All @@ -23,3 +22,6 @@ harness = false
[[bin]]
name = "gen_hash_test"
required-features = ["criterion"]

[features]
const-api = ["phf_shared/const-api"]
14 changes: 7 additions & 7 deletions phf_generator/src/bin/gen_hash_test.rs
@@ -1,16 +1,16 @@
use criterion::*;

use rand::distributions::Alphanumeric;
use rand::rngs::SmallRng;
use rand::{Rng, SeedableRng};

use phf_generator::generate_hash;
use phf_generator::{generate_hash, rng::Rng};

fn gen_vec(len: usize) -> Vec<String> {
let mut rng = SmallRng::seed_from_u64(0xAAAAAAAAAAAAAAAA).sample_iter(Alphanumeric);
let mut rng = Rng::new(0xAAAAAAAAAAAAAAAA);

(0..len)
.map(move |_| rng.by_ref().take(64).collect::<String>())
.map(move |_| {
let mut str = String::with_capacity(64);
(0..64).for_each(|_| str.push(rng.generate_alphanumeric()));
str
})
.collect()
}

Expand Down