From 64106c4d3d4ddba8c7bc2af75376e6d3d3d75601 Mon Sep 17 00:00:00 2001
From:
Date: Mon, 29 Jun 2015 20:16:15 +0000
Subject: Update documentation
---
lazy_static/index.html | 174 ++++++++++++++++++++++++++++++++++++
lazy_static/macro.lazy_static!.html | 154 +++++++++++++++++++++++++++++++
lazy_static/sidebar-items.js | 1 +
3 files changed, 329 insertions(+)
create mode 100644 lazy_static/index.html
create mode 100644 lazy_static/macro.lazy_static!.html
create mode 100644 lazy_static/sidebar-items.js
(limited to 'lazy_static')
diff --git a/lazy_static/index.html b/lazy_static/index.html
new file mode 100644
index 0000000..037359f
--- /dev/null
+++ b/lazy_static/index.html
@@ -0,0 +1,174 @@
+
+
+
+
+
+A macro for declaring lazily evaluated statics.
+
+
Using this macro, it is possible to have static
s that require code to be
+executed at runtime in order to be initialized.
+This includes anything requiring heap allocations, like vectors or hash maps,
+as well as anything that requires function calls to be computed.
+
+
+lazy_static! {
+ [pub] static ref NAME_1: TYPE_1 = EXPR_1;
+ [pub] static ref NAME_2: TYPE_2 = EXPR_2;
+ ...
+ [pub] static ref NAME_N: TYPE_N = EXPR_N;
+}
+
+
+
+
For a given static ref NAME: TYPE = EXPR;
, the macro generates a
+unique type that implements Deref<TYPE>
and stores it in a static with name NAME
.
+
+
On first deref, EXPR
gets evaluated and stored internally, such that all further derefs
+can return a reference to the same object.
+
+
Like regular static mut
s, this macro only works for types that fulfill the Sync
+trait.
+
+
+
Using the macro:
+
+#[macro_use]
+extern crate lazy_static;
+
+use std::collections::HashMap;
+
+lazy_static! {
+ static ref HASHMAP: HashMap<u32, &'static str> = {
+ let mut m = HashMap::new();
+ m.insert(0, "foo");
+ m.insert(1, "bar");
+ m.insert(2, "baz");
+ m
+ };
+ static ref COUNT: usize = HASHMAP.len();
+ static ref NUMBER: u32 = times_two(21);
+}
+
+fn times_two(n: u32) -> u32 { n * 2 }
+
+fn main() {
+ println!("The map has {} entries.", *COUNT);
+ println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());
+ println!("A expensive calculation on a static results in: {}.", *NUMBER);
+}
+
+
+
+
The Deref
implementation uses a hidden static mut
that is guarded by a atomic check
+using the sync::Once
abstraction. All lazily evaluated values are currently
+put in a heap allocated box, due to the Rust language currently not providing any way to
+define uninitialized static mut
values.
+
+
+
+
+
+macro_rules! lazy_static {
+ (static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
+ lazy_static!(PRIV static ref $N : $T = $e; $($t)*);
+ };
+ (pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
+ lazy_static!(PUB static ref $N : $T = $e; $($t)*);
+ };
+ ($VIS:ident static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
+ lazy_static!(MAKE TY $VIS $N);
+ impl ::std::ops::Deref for $N {
+ type Target = $T;
+ fn deref<'a>(&'a self) -> &'a $T {
+ #[inline(always)]
+ fn __static_ref_initialize() -> Box<$T> { Box::new($e) }
+
+ unsafe {
+ use std::sync::{Once, ONCE_INIT};
+ use std::mem::transmute;
+
+ #[inline(always)]
+ fn require_sync<T: Sync>(_: &T) { }
+
+ static mut DATA: *const $T = 0 as *const $T;
+ static mut ONCE: Once = ONCE_INIT;
+ ONCE.call_once(|| {
+ DATA = transmute::<Box<$T>, *const $T>(__static_ref_initialize());
+ });
+ let static_ref = &*DATA;
+ require_sync(static_ref);
+ static_ref
+ }
+ }
+ }
+ lazy_static!($($t)*);
+ };
+ (MAKE TY PUB $N:ident) => {
+ #[allow(missing_copy_implementations)]
+ #[allow(non_camel_case_types)]
+ #[allow(dead_code)]
+ pub struct $N {__private_field: ()}
+ pub static $N: $N = $N {__private_field: ()};
+ };
+ (MAKE TY PRIV $N:ident) => {
+ #[allow(missing_copy_implementations)]
+ #[allow(non_camel_case_types)]
+ #[allow(dead_code)]
+ struct $N {__private_field: ()}
+ static $N: $N = $N {__private_field: ()};
+ };
+ () => ()
+}
+
+
+