More documentation tweaks to clarify and explain
This commit is contained in:
parent
764038fe6e
commit
2d5be08822
|
@ -14,7 +14,7 @@ What this means is that in an ``AnyMap`` you may store zero or one values for ev
|
||||||
|
|
||||||
This library uses a fair bit of unsafe code for several reasons:
|
This library uses a fair bit of unsafe code for several reasons:
|
||||||
|
|
||||||
- To support Any and CloneAny, unsafe code is required (because of how the `downcast` methods are defined in `impl dyn Any` rather than being trait methods; I think this is kind of a historical detail of the structure of `std::any::Any`); if you wanted to ditch `Clone` support this unsafety could be removed.
|
- To support `CloneAny`, unsafe code is required (because the downcast methods are defined on `dyn Any` rather than being trait methods); if you wanted to ditch `Clone` support this unsafety could be removed.
|
||||||
|
|
||||||
- In the interests of performance, skipping various checks that are unnecessary because of the invariants of the data structure (no need to check the type ID when it’s been statically ensured by being used as the hash map key).
|
- In the interests of performance, skipping various checks that are unnecessary because of the invariants of the data structure (no need to check the type ID when it’s been statically ensured by being used as the hash map key).
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ This library uses a fair bit of unsafe code for several reasons:
|
||||||
|
|
||||||
It’s not possible to remove all unsafety from this library without also removing some of the functionality. Still, at the cost of the `CloneAny` functionality and the raw interface, you can definitely remove all unsafe code. Here’s how you could do it:
|
It’s not possible to remove all unsafety from this library without also removing some of the functionality. Still, at the cost of the `CloneAny` functionality and the raw interface, you can definitely remove all unsafe code. Here’s how you could do it:
|
||||||
|
|
||||||
- Remove the genericness of it all;
|
- Remove the genericness of it all (choose `dyn Any`, `dyn Any + Send` or `dyn Any + Send + Sync` and stick with it);
|
||||||
- Merge `anymap::raw` into the normal interface, flattening it;
|
- Merge `anymap::raw` into the normal interface, flattening it;
|
||||||
- Change things like `.map(|any| unsafe { any.downcast_unchecked() })` to `.and_then(|any| any.downcast())` (performance cost: one extra superfluous type ID comparison, indirect).
|
- Change things like `.map(|any| unsafe { any.downcast_unchecked() })` to `.and_then(|any| any.downcast())` (performance cost: one extra superfluous type ID comparison, indirect).
|
||||||
|
|
||||||
|
|
29
src/lib.rs
29
src/lib.rs
|
@ -1,4 +1,6 @@
|
||||||
//! This crate provides the `AnyMap` type, a safe and convenient store for one value of each type.
|
//! This crate provides a safe and convenient store for one value of each type.
|
||||||
|
//!
|
||||||
|
//! Your starting point is [`Map`]. It has an example.
|
||||||
|
|
||||||
#![warn(missing_docs, unused_results)]
|
#![warn(missing_docs, unused_results)]
|
||||||
|
|
||||||
|
@ -95,12 +97,27 @@ pub mod raw;
|
||||||
/// The type parameter `A` allows you to use a different value type; normally you will want it to
|
/// The type parameter `A` allows you to use a different value type; normally you will want it to
|
||||||
/// be `std::any::Any`, but there are other choices:
|
/// be `std::any::Any`, but there are other choices:
|
||||||
///
|
///
|
||||||
/// - If you want the entire map to be cloneable, use `CloneAny` instead of `Any`.
|
/// - If you want the entire map to be cloneable, use `CloneAny` instead of `Any`; with that, you
|
||||||
/// - You can add on `+ Send` or `+ Send + Sync` (e.g. `Map<dyn Any + Send>`) to add those bounds.
|
/// can only add types that implement `Clone` to the map.
|
||||||
|
/// - You can add on `+ Send` or `+ Send + Sync` (e.g. `Map<dyn Any + Send>`) to add those auto
|
||||||
|
/// traits.
|
||||||
|
///
|
||||||
|
/// Cumulatively, there are thus six forms of map:
|
||||||
|
///
|
||||||
|
/// - <code>[Map]<dyn [std::any::Any]></code>, also spelled [`AnyMap`] for convenience.
|
||||||
|
/// - <code>[Map]<dyn [std::any::Any] + Send></code>
|
||||||
|
/// - <code>[Map]<dyn [std::any::Any] + Send + Sync></code>
|
||||||
|
/// - <code>[Map]<dyn [CloneAny]></code>
|
||||||
|
/// - <code>[Map]<dyn [CloneAny] + Send></code>
|
||||||
|
/// - <code>[Map]<dyn [CloneAny] + Send + Sync></code>
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
///
|
||||||
|
/// (Here using the [`AnyMap`] convenience alias; the first line could use
|
||||||
|
/// <code>[anymap::Map][Map]::<[std::any::Any]>::new()</code> instead if desired.)
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use anymap::AnyMap;
|
/// let mut data = anymap::AnyMap::new();
|
||||||
/// let mut data = AnyMap::new();
|
|
||||||
/// assert_eq!(data.get(), None::<&i32>);
|
/// assert_eq!(data.get(), None::<&i32>);
|
||||||
/// data.insert(42i32);
|
/// data.insert(42i32);
|
||||||
/// assert_eq!(data.get(), Some(&42i32));
|
/// assert_eq!(data.get(), Some(&42i32));
|
||||||
|
@ -135,7 +152,7 @@ impl<A: ?Sized + UncheckedAnyExt> Clone for Map<A> where Box<A>: Clone {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The most common type of `Map`: just using `Any`.
|
/// The most common type of `Map`: just using `Any`; <code>[Map]<dyn [Any]></code>.
|
||||||
///
|
///
|
||||||
/// Why is this a separate type alias rather than a default value for `Map<A>`? `Map::new()`
|
/// Why is this a separate type alias rather than a default value for `Map<A>`? `Map::new()`
|
||||||
/// doesn’t seem to be happy to infer that it should go with the default value.
|
/// doesn’t seem to be happy to infer that it should go with the default value.
|
||||||
|
|
Loading…
Reference in a new issue