diff --git a/module/core/collection_tools/Cargo.toml b/module/core/collection_tools/Cargo.toml index 14edcdd31e..4331277b94 100644 --- a/module/core/collection_tools/Cargo.toml +++ b/module/core/collection_tools/Cargo.toml @@ -51,7 +51,7 @@ full = [ enabled = [] # Collection constructors, like `hmap!{ "key" => "val" }` -collection_constructors = [ "literally" ] +collection_constructors = [] # STD collection for no_std. collection_std = [] @@ -59,7 +59,6 @@ collection_std = [] [dependencies] ## external -literally = { version = "~0.1.3", optional = true, default-features = false } hashbrown = { version = "~0.14.3", optional = true, default-features = false, features = [ "default" ] } [dev-dependencies] diff --git a/module/core/collection_tools/Readme.md b/module/core/collection_tools/Readme.md index b0b93347b8..e1d1ba9706 100644 --- a/module/core/collection_tools/Readme.md +++ b/module/core/collection_tools/Readme.md @@ -14,20 +14,50 @@ This module encompasses a suite of meta-tools designed to enhance Rust's collect Consider the following example, which demonstrates the use of the `hmap!` macro to effortlessly create a `HashMap`: - ```rust -# #[ cfg( not( feature = "use_alloc" ) ) ] # #[ cfg( all( feature = "enabled", feature = "collection_constructors" ) ) ] # #[ cfg( any( feature = "use_alloc", not( feature = "no_std" ) ) ) ] # { - use collection_tools::*; let meta_map = hmap! { 3 => 13 }; -let mut std_map = std::collections::HashMap::new(); +let mut std_map = collection_tools::HashMap::new(); std_map.insert( 3, 13 ); assert_eq!( meta_map, std_map ); +# } +``` + +Note: Do not be afraid of `collection_tools::HashMap`. It is basically a reexport of `std`'s `HashMap`, unless you have enabled `use_alloc` feature. +Another example, this time, `bset!`, providing you a `BTreeSet`: + +```rust +# #[ cfg( all( feature = "enabled", feature = "collection_constructors" ) ) ] +# #[ cfg( any( feature = "use_alloc", not( feature = "no_std" ) ) ) ] +# { +use collection_tools::*; + +let meta_set = bset! { 3, 13 }; +let mut std_set = collection_tools::BTreeSet::new(); +std_set.insert( 13 ); +std_set.insert( 3 ); +assert_eq!( meta_set, std_set ); +# } +``` + +Another example with `list!`: + +```rust +# #[ cfg( all( feature = "enabled", feature = "collection_constructors" ) ) ] +# #[ cfg( any( feature = "use_alloc", not( feature = "no_std" ) ) ) ] +# { +use collection_tools::*; + +let meta_list : LinkedList< i32 > = list! { 3, 13 }; +let mut meta_list = collection_tools::LinkedList::new(); +meta_list.push_front( 13 ); +meta_list.push_front( 3 ); +assert_eq!( meta_list, meta_list ); # } ``` @@ -37,42 +67,47 @@ When implementing a `no_std` environment with the `use_alloc` feature in your Ru You can do - + ```rust -# #[ cfg( not( feature = "use_alloc" ) ) ] # #[ cfg( all( feature = "enabled", feature = "collection_std" ) ) ] # #[ cfg( any( feature = "use_alloc", not( feature = "no_std" ) ) ) ] # { +use collection_tools::HashSet; -use collection_tools::Vec; - -let mut map : Vec< i32 > = Vec::new(); -map.push( 1 ); -assert_eq!( map.first().unwrap().clone(), 1 ); - +let mut vec : HashSet< i32 > = HashSet::new(); +vec.insert( 1 ); +assert_eq!( vec.contains( &1 ), true ); # } ``` Instead of
-The code above will be expanded to this +Click to see ```rust #[ cfg( feature = "use_alloc" ) ] -extern crate alloc; -#[ cfg( feature = "use_alloc" ) ] -use alloc::vec::Vec; +use hashbrown::HashSet; // a `no_std` replacement for `HashSet` #[ cfg( not( feature = "no_std" ) ) ] -use std::vec::Vec; +use std::collections::HashSet; -let mut collection : Vec< i32 > = Vec::new(); -collection.push( 1 ); -assert_eq!( collection.first().unwrap().clone(), 1 ); +let mut vec : HashSet< i32 > = HashSet::new(); +vec.insert( 1 ); +assert_eq!( vec.contains( &1 ), true ); ```
+### Collections being used + +To support `no_std` environment as much as possible, we aim at using collections from `alloc` whenever its possible. + +If `use_alloc` feature is on, collections available only in `std` are replaced with their `no_std` counterparts. For now, the only replaced collections are `HashMap` and `HashSet` , taken from `hashbrown`. + +### MORE Examples + +If you are feeling confused about the syntax you should use for a macro, you can visit its documentation. It is saturated with different examples, so hopefully you'll not be stuck. + ### To add to your project ```sh diff --git a/module/core/collection_tools/examples/collection_tools_trivial.rs b/module/core/collection_tools/examples/collection_tools_trivial.rs index 71d45dd97e..b817a50c84 100644 --- a/module/core/collection_tools/examples/collection_tools_trivial.rs +++ b/module/core/collection_tools/examples/collection_tools_trivial.rs @@ -21,21 +21,21 @@ #[ cfg( not( all ( - not( feature = "use_alloc" ), +// not( feature = "use_alloc" ) ) ], all( feature = "enabled", feature = "collection_constructors" ), any( not( feature = "no_std" ), feature = "use_alloc" ) )))] fn main(){} -// zzz : qqq : rid off `#[ cfg( not( feature = "use_alloc" ) ) ]` -#[ cfg( not( feature = "use_alloc" ) ) ] +// zzz : aaa : rid off `#[ cfg( not( feature = "use_alloc" ) ) ]` -- Rid of by not relying on std +// #[ cfg( not( feature = "use_alloc" ) ) ] #[ cfg( all( feature = "enabled", feature = "collection_constructors" ) ) ] #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] fn main() { use collection_tools::*; let map = hmap! { 3 => 13 }; - let mut expected = std::collections::HashMap::new(); + let mut expected = collection_tools::HashMap::new(); expected.insert( 3, 13 ); assert_eq!( map, expected ); } diff --git a/module/core/collection_tools/src/constructors.rs b/module/core/collection_tools/src/constructors.rs new file mode 100644 index 0000000000..24c12b32d4 --- /dev/null +++ b/module/core/collection_tools/src/constructors.rs @@ -0,0 +1,629 @@ +/// Creates a `BTreeMap` from a list of key-value pairs. +/// +/// The `bmap` macro facilitates the convenient creation of a `BTreeMap` with initial elements. +/// Keys and values passed to the macro are automatically converted into the map's key and value types +/// using `.into()`, enabling the use of literals or values of different, but convertible types. +/// +/// Note: The `bmap` macro relies on the `.into()` method to convert each key and value into the target types +/// of the `BTreeMap`. This means that the keys and values must be compatible with the `Into< K >` and `Into< V >` traits +/// for the key type `K` and value type `V` used in the `BTreeMap`. +/// +/// # Syntax +/// +/// The macro can be called with a comma-separated list of key-value pairs. A trailing comma is optional. +/// +/// ```rust +/// # use collection_tools::{ BTreeMap, bmap }; +/// // BTreeMap of &str to i32 +/// let map1 : BTreeMap< &str, i32 > = bmap!( "one" => 1, "two" => 2, "three" => 3 ); +/// +/// // BTreeMap of String to String +/// let map2 : BTreeMap< String, String > = bmap!{ "name" => "value" }; +/// +/// // With trailing comma +/// let map3 : BTreeMap< i32, &str > = bmap!( 1 => "one", 2 => "two", 3 => "three", ); +/// ``` +/// +/// # Parameters +/// +/// - `$( $key:expr => $value:expr ),* $( , )?`: A comma-separated list of key-value pairs to insert into the `BTreeMap`. +/// Each key and value can be of any type that implements the `Into< K >` and `Into< V >` traits, where `K` and `V` are the +/// types stored in the `BTreeMap` as keys and values, respectively. +/// +/// # Returns +/// +/// Returns a `BTreeMap` containing all the specified key-value pairs. The map's capacity is +/// automatically determined based on the number of elements provided. +/// +/// # Example +/// +/// Basic usage with string slices and integer values: +/// +/// ```rust +/// # use collection_tools::{ BTreeMap, bmap }; +/// let map : BTreeMap< &str, i32 > = bmap!( "one" => 1, "two" => 2, "three" => 3 ); +/// assert_eq!( map.get( "one" ), Some( &1 ) ); +/// assert_eq!( map.get( "two" ), Some( &2 ) ); +/// assert_eq!( map.get( "three" ), Some( &3 ) ); +/// ``` +/// +/// # Example +/// +/// Using with different types that implement `Into< K >` and `Into< V >`: +/// +/// ```rust +/// # use collection_tools::{ BTreeMap, bmap }; +/// let months : BTreeMap< String, i32 > = bmap!( "January" => 1, "February" => 2, "March" => 3 ); +/// assert_eq!( months.get( &"January".to_string() ), Some( &1 ) ); +/// assert_eq!( months.get( &"February".to_string() ), Some( &2 ) ); +/// ``` +/// +/// # Example +/// +/// Creating a `BTreeMap` of integers to strings from literals: +/// +/// ```rust +/// # use collection_tools::{ BTreeMap, bmap }; +/// let numbers : BTreeMap< i32, String > = bmap!( 1 => "one", 2 => "two", 3 => "three" ); +/// assert_eq!( numbers.get( &1 ), Some( &"one".to_string() ) ); +/// assert_eq!( numbers.get( &2 ), Some( &"two".to_string() ) ); +/// assert_eq!( numbers.get( &3 ), Some( &"three".to_string() ) ); +/// ``` +/// +#[ macro_export( local_inner_macros ) ] +macro_rules! bmap +{ + ( + $( $key : expr => $value : expr ),* $( , )? + ) + => + {{ + let mut _map = collection_tools::BTreeMap::new(); + $( + let _ = _map.insert( $key.into(), $value.into() ); + )* + _map + }}; +} + +/// Creates a `BTreeSet` from a list of elements. +/// +/// The `bset` macro allows for convenient creation of a `BTreeSet` with initial elements. +/// Elements passed to the macro are automatically converted into the set's element type +/// using `.into()`, facilitating the use of literals or values of different, but convertible types. +/// +/// Note: The `bset` macro relies on the `.into()` method to convert each element into the target type +/// of the `BTreeSet`. This means that the elements must be compatible with the `Into` trait for the +/// type `T` used in the `BTreeSet`. +/// +/// # Syntax +/// +/// The macro can be called with a comma-separated list of elements. A trailing comma is optional. +/// +/// ```rust +/// # use collection_tools::{ BTreeSet, bset }; +/// // BTreeSet of &str +/// let set1 : BTreeSet< &str > = bset!( "a", "b", "c" ); +/// +/// // BTreeSet of String +/// let set2 : BTreeSet< String > = bset!{ "a".to_string(), "b", "c" }; +/// +/// // With trailing comma +/// let set3 : BTreeSet< i32 > = bset!( 1, 2, 3, ); +/// ``` +/// +/// # Parameters +/// +/// - `$( $key:expr ),* $( , )?`: A comma-separated list of elements to insert into the `BTreeSet`. +/// Each element can be of any type that implements the `Into` trait, where `T` is the +/// type stored in the `BTreeSet`. +/// +/// # Returns +/// +/// Returns a `BTreeSet` containing all the specified elements. The capacity of the set is +/// automatically determined based on the number of elements provided. +/// +/// # Example +/// +/// Basic usage with string slices: +/// +/// ```rust +/// # use collection_tools::{ BTreeSet, bset }; +/// let set : BTreeSet< &str > = bset!( "one", "two", "three" ); +/// assert!( set.contains( "one" ) ); +/// assert!( set.contains( "two" ) ); +/// assert!( set.contains( "three" ) ); +/// assert_eq!( set.len(), 3 ); +/// ``` +/// +/// # Example +/// +/// Using with different types that implement `Into`: +/// +/// ```rust +/// # use collection_tools::{ BTreeSet, bset }; +/// let numbers : BTreeSet< i32 > = bset!( 1, 2, 3 ); +/// assert!( numbers.contains( &1 ) ); +/// assert!( numbers.contains( &2 ) ); +/// assert!( numbers.contains( &3 ) ); +/// ``` +/// +/// # Example +/// +/// Creating a `BTreeSet` of `String` from string literals: +/// +/// ```rust +/// # use collection_tools::{ BTreeSet, bset }; +/// let s : BTreeSet< String > = bset!{ "value" }; +/// assert!( s.contains( "value" ) ); +/// ``` +/// +#[ macro_export( local_inner_macros ) ] +macro_rules! bset +{ + ( + $( $key : expr ),* $( , )? + ) + => + {{ + let mut _set = ::collection_tools::BTreeSet::new(); + $( + _set.insert( $key.into() ); + )* + _set + }}; +} + +/// Creates a `BinaryHeap` from a list of elements. +/// +/// The `heap` macro simplifies the creation of a `BinaryHeap` with initial elements. +/// Elements passed to the macro are automatically converted into the heap's element type +/// using `.into()`, allowing for the use of literals or values of different, but convertible types. +/// +/// Note: The `heap` macro utilizes the `.into()` method to convert each element into the target type +/// of the `BinaryHeap`. This means that the elements must be compatible with the `Into` trait for the +/// type `T` used in the `BinaryHeap`. +/// +/// # Syntax +/// +/// The macro can be called with a comma-separated list of elements. A trailing comma is optional. +/// +/// ```rust +/// # use collection_tools::{ BinaryHeap, heap }; +/// // BinaryHeap of i32 +/// let heap1 : BinaryHeap< i32 > = heap!( 3, 1, 4, 1, 5, 9 ); +/// +/// // BinaryHeap of String +/// let heap2 : BinaryHeap< String > = heap!{ "pear".to_string(), "apple", "banana" }; +/// +/// // With trailing comma +/// let heap3 : BinaryHeap< i32 > = heap!( 2, 7, 1, 8, ); +/// ``` +/// +/// # Parameters +/// +/// - `$( $key:expr ),* $( , )?`: A comma-separated list of elements to insert into the `BinaryHeap`. +/// Each element can be of any type that implements the `Into` trait, where `T` is the +/// type stored in the `BinaryHeap`. +/// +/// # Returns +/// +/// Returns a `BinaryHeap` containing all the specified elements. The capacity of the heap is +/// automatically determined based on the number of elements provided. +/// +/// # Example +/// +/// Basic usage with integers: +/// +/// ```rust +/// # use collection_tools::{ BinaryHeap, heap }; +/// let heap : BinaryHeap< i32 > = heap!( 5, 3, 7, 1 ); +/// assert_eq!( heap.peek(), Some( &7 ) ); // The largest value is at the top of the heap +/// ``` +/// +/// # Example +/// +/// Using with different types that implement `Into`: +/// +/// ```rust +/// # use collection_tools::{ BinaryHeap, heap }; +/// let chars : BinaryHeap< char > = heap!( 'a', 'b', 'c' ); +/// assert_eq!( chars.peek(), Some( &'c' ) ); // Characters are ordered by their ASCII value +/// ``` +/// +/// # Example +/// +/// Creating a `BinaryHeap` of `String` from string literals: +/// +/// ```rust +/// # use collection_tools::{ BinaryHeap, heap }; +/// let fruits : BinaryHeap< String > = heap!{ "cherry", "apple", "banana" }; +/// assert_eq!( fruits.peek(), Some( &"cherry".to_string() ) ); // The lexicographically largest value is at the top +/// ``` +/// +#[ macro_export( local_inner_macros ) ] +macro_rules! heap +{ + ( + $( $key : expr ),* $( , )? + ) + => + {{ + let mut _heap = collection_tools::BinaryHeap::new(); + $( + _heap.push( $key.into() ); + )* + _heap + }}; +} + +/// Creates a `HashMap` from a list of key-value pairs. +/// +/// The `hmap` macro allows for convenient creation of a `HashMap` with initial elements. +/// Keys and values passed to the macro are automatically converted into the map's key and value types +/// using `.into()`, enabling the use of literals or values of different, but convertible types. +/// +/// Note: The `hmap` macro relies on the `.into()` method to convert each key and value into the target types +/// of the `HashMap`. This means that the keys and values must be compatible with the `Into` and `Into` traits +/// for the key type `K` and value type `V` used in the `HashMap`. +/// +/// # Syntax +/// +/// The macro can be called with a comma-separated list of key-value pairs. A trailing comma is optional. +/// +/// ```rust +/// # use collection_tools::{ HashMap, hmap }; +/// // HashMap of &str to i32 +/// let map1 : HashMap< &str, i32 > = hmap!( "one" => 1, "two" => 2, "three" => 3 ); +/// +/// // HashMap of String to String +/// let map2 : HashMap< String, String > = hmap!{ "name".to_string() => "value".to_string(), "type" => "example" }; +/// +/// // With trailing comma +/// let map3 : HashMap< i32, &str > = hmap!( 1 => "one", 2 => "two", 3 => "three", ); +/// ``` +/// +/// # Parameters +/// +/// - `$( $key:expr => $value:expr ),* $( , )?`: A comma-separated list of key-value pairs to insert into the `HashMap`. +/// Each key and value can be of any type that implements the `Into` and `Into` traits, where `K` and `V` are the +/// types stored in the `HashMap` as keys and values, respectively. +/// +/// # Returns +/// +/// Returns a `HashMap` containing all the specified key-value pairs. The capacity of the map is +/// automatically determined based on the number of elements provided. +/// +/// # Example +/// +/// Basic usage with string slices and integer values: +/// +/// ```rust +/// # use collection_tools::{ HashMap, hmap }; +/// let map : HashMap< &str, i32 > = hmap!( "one" => 1, "two" => 2, "three" => 3 ); +/// assert_eq!( map.get( "one" ), Some( &1 ) ); +/// assert_eq!( map.get( "two" ), Some( &2 ) ); +/// assert_eq!( map.get( "three" ), Some( &3 ) ); +/// ``` +/// +/// # Example +/// +/// Using with different types that implement `Into` and `Into`: +/// +/// ```rust +/// # use collection_tools::{ HashMap, hmap }; +/// let items : HashMap< String, i32 > = hmap!( "pen" => 10, "book" => 45, "eraser" => 5 ); +/// assert_eq!( items.get( &"pen".to_string() ), Some(&10 ) ); +/// assert_eq!( items.get( &"book".to_string() ), Some(&45 ) ); +/// ``` +/// +/// # Example +/// +/// Creating a `HashMap` of integers to strings from literals: +/// +/// ```rust +/// # use collection_tools::{ HashMap, hmap }; +/// let pairs : HashMap< i32, String > = hmap!( 1 => "apple", 2 => "banana" ); +/// assert_eq!( pairs.get( &1 ), Some( &"apple".to_string() ) ); +/// assert_eq!( pairs.get( &2 ), Some( &"banana".to_string() ) ); +/// ``` +/// + +#[macro_export(local_inner_macros)] +macro_rules! hmap +{ + ( @single $( $x : tt )* ) => ( () ); + + ( + @count $( $rest : expr ),* + ) + => + ( + < [ () ] >::len( &[ $( hmap!( @single $rest ) ),* ] ) + ); + + ( + $( $key : expr => $value : expr ),* $( , )? + ) + => + {{ + let _cap = hmap!( @count $( $key ),* ); + let mut _map = collection_tools::HashMap::with_capacity( _cap ); + $( + let _ = _map.insert( $key.into(), $value.into() ); + )* + _map + }}; +} + +/// Creates a `HashSet` from a list of elements. +/// +/// The `hset` macro allows for convenient creation of a `HashSet` with initial elements. +/// Elements passed to the macro are automatically converted into the set's element type +/// using `.into()`, facilitating the use of literals or values of different, but convertible types. +/// +/// Note: The `hset` macro relies on the `.into()` method to convert each element into the target type +/// of the `HashSet`. This means that the elements must be compatible with the `Into< T >` trait for the +/// type `T` used in the `HashSet`. +/// +/// # Syntax +/// +/// The macro can be called with a comma-separated list of elements. A trailing comma is optional. +/// +/// ```rust +/// # use collection_tools::{ HashSet, hset }; +/// // HashSet of &str +/// let set1 : HashSet< &str > = hset!( "a", "b", "c" ); +/// +/// // HashSet of String +/// let set2 : HashSet< String > = hset!{ "a".to_string(), "b", "c" }; +/// +/// // With trailing comma +/// let set3 : HashSet< i32 > = hset!( 1, 2, 3, ); +/// ``` +/// +/// # Parameters +/// +/// - `$( $key:expr ),* $( , )?`: A comma-separated list of elements to insert into the `HashSet`. +/// Each element can be of any type that implements the `Into< T >` trait, where `T` is the +/// type stored in the `HashSet`. +/// +/// # Returns +/// +/// Returns a `HashSet` containing all the specified elements. The capacity of the set is +/// automatically determined based on the number of elements provided. +/// +/// # Example +/// +/// Basic usage with string slices: +/// +/// ```rust +/// # use collection_tools::{ HashSet, hset }; +/// let set : HashSet< &str > = hset!( "one", "two", "three" ); +/// assert!( set.contains( "one" ) ); +/// assert!( set.contains( "two" ) ); +/// assert!( set.contains( "three" ) ); +/// assert_eq!( set.len(), 3 ); +/// ``` +/// +/// # Example +/// +/// Using with different types that implement `Into< T >`: +/// +/// ```rust +/// # use collection_tools::{ HashSet, hset }; +/// let numbers : HashSet< i32 > = hset!( 1, 2, 3 ); +/// assert!( numbers.contains( &1 ) ); +/// assert!( numbers.contains( &2 ) ); +/// assert!( numbers.contains( &3 ) ); +/// ``` +/// +/// # Example +/// +/// Creating a `HashSet` of `String` from string literals: +/// +/// ```rust +/// # use collection_tools::{ HashSet, hset }; +/// let s : HashSet< String > = hset!{ "value" }; +/// assert_eq!( s.get( "value" ), Some( &"value".to_string() ) ); +/// ``` +/// +#[ macro_export( local_inner_macros ) ] +macro_rules! hset +{ + ( @single $( $x : tt )* ) => ( () ); + + ( + @count $( $rest : expr ),* + ) + => + ( + < [ () ] >::len( &[ $( hset!( @single $rest ) ),* ] ) + ); + + ( + $( $key : expr ),* $( , )? + ) + => + {{ + let _cap = hset!( @count $( $key ),* ); + let mut _set = collection_tools::HashSet::with_capacity( _cap ); + $( + let _ = _set.insert( $key.into() ); + )* + _set + }}; +} + +/// Creates a `LinkedList` from a list of elements. +/// +/// The `list` macro facilitates the creation of a `LinkedList` with initial elements. +/// Elements passed to the macro are automatically converted into the list's element type +/// using `.into()`, making it convenient to use literals or values of different, but convertible types. +/// +/// Note: The `list` macro leverages the `.into()` method to convert each element into the target type +/// of the `LinkedList`. Therefore, the elements must be compatible with the `Into` trait for the +/// type `T` used in the `LinkedList`. +/// +/// # Syntax +/// +/// The macro can be called with a comma-separated list of elements. A trailing comma is optional. +/// +/// ```rust +/// # use collection_tools::{ LinkedList, list }; +/// // LinkedList of i32 +/// let lst1 : LinkedList< i32 > = list!( 1, 2, 3, 4, 5 ); +/// +/// // LinkedList of String +/// let lst2 : LinkedList< String > = list!{ "hello".to_string(), "world", "rust" }; +/// +/// // With trailing comma +/// let lst3 : LinkedList< f64 > = list!( 1.1, 2.2, 3.3, ); +/// ``` +/// +/// # Parameters +/// +/// - `$( $key:expr ),* $( , )?`: A comma-separated list of elements to insert into the `LinkedList`. +/// Each element can be of any type that implements the `Into` trait, where `T` is the +/// type stored in the `LinkedList`. +/// +/// # Returns +/// +/// Returns a `LinkedList` containing all the specified elements. The capacity of the list is +/// dynamically adjusted based on the number of elements provided. +/// +/// # Example +/// +/// Basic usage with integers: +/// +/// ```rust +/// # use collection_tools::{ LinkedList, list }; +/// let lst: LinkedList< i32 > = list!( 1, 2, 3 ); +/// assert_eq!( lst.front(), Some( &1 ) ); // The first element is 1 +/// assert_eq!( lst.back(), Some( &3 ) ); // The last element is 3 +/// ``` +/// +/// # Example +/// +/// Using with different types that implement `Into`: +/// +/// ```rust +/// # use collection_tools::{ LinkedList, list }; +/// let chars : LinkedList< String > = list!( "a", "b", "c" ); +/// assert!( chars.contains( &"a".to_string() ) ); +/// assert!( chars.contains( &"b".to_string() ) ); +/// assert!( chars.contains( &"c".to_string() ) ); +/// ``` +/// +/// # Example +/// +/// Creating a `LinkedList` of `String` from string literals: +/// +/// ```rust +/// # use collection_tools::{ LinkedList, list }; +/// let fruits : LinkedList< String > = list!{ "apple", "banana", "cherry" }; +/// assert_eq!( fruits.front(), Some( &"apple".to_string() ) ); // The first element +/// assert_eq!( fruits.back(), Some( &"cherry".to_string() ) ); // The last element +/// ``` +/// +#[ macro_export( local_inner_macros ) ] +macro_rules! list +{ + ( + $( $key : expr ),* $( , )? + ) + => + {{ + let mut _lst = collection_tools::LinkedList::new(); + $( + _lst.push_back( $key.into() ); + )* + _lst + }}; +} + +/// Creates a `VecDeque` from a list of elements. +/// +/// The `vecd` macro allows for the convenient creation of a `VecDeque` with initial elements. +/// Elements passed to the macro are automatically converted into the deque's element type +/// using `.into()`, enabling the use of literals or values of different, but convertible types. +/// +/// Note: The `vecd` macro relies on the `.into()` method to convert each element into the target type +/// of the `VecDeque`. This means that the elements must be compatible with the `Into` trait for the +/// type `T` used in the `VecDeque`. +/// +/// # Syntax +/// +/// The macro can be called with a comma-separated list of elements. A trailing comma is optional. +/// +/// ```rust +/// # use collection_tools::{ VecDeque, vecd }; +/// // VecDeque of i32 +/// let vd1 : VecDeque< i32 > = vecd!( 1, 2, 3, 4, 5 ); +/// +/// // VecDeque of String +/// let vd2 : VecDeque< String > = vecd!{ "hello".to_string(), "world", "rust" }; +/// +/// // With trailing comma +/// let vd3 : VecDeque< f64 > = vecd!( 1.1, 2.2, 3.3, ); +/// ``` +/// +/// # Parameters +/// +/// - `$( $key:expr ),* $( , )?`: A comma-separated list of elements to insert into the `VecDeque`. +/// Each element can be of any type that implements the `Into< T >` trait, where `T` is the +/// type stored in the `VecDeque`. +/// +/// # Returns +/// +/// Returns a `VecDeque` containing all the specified elements. The capacity of the deque is +/// automatically determined based on the number of elements provided. +/// +/// # Example +/// +/// Basic usage with integers: +/// +/// ```rust +/// # use collection_tools::{ VecDeque, vecd }; +/// let vd : VecDeque< i32 > = vecd!( 1, 2, 3 ); +/// assert_eq!( vd.front(), Some( &1 ) ); // The first element is 1 +/// assert_eq!( vd.back(), Some( &3 ) ); // The last element is 3 +/// ``` +/// +/// # Example +/// +/// Using with different types that implement `Into< T >`: +/// +/// ```rust +/// # use collection_tools::{ VecDeque, vecd }; +/// let chars : VecDeque< char > = vecd!( 'a', 'b', 'c' ); +/// assert!( chars.contains( &'a' ) ); +/// assert!( chars.contains( &'b' ) ); +/// assert!( chars.contains( &'c' ) ); +/// ``` +/// +/// # Example +/// +/// Creating a `VecDeque` of `String` from string literals: +/// +/// ```rust +/// # use collection_tools::{ VecDeque, vecd }; +/// let fruits : VecDeque< String > = vecd!{ "apple", "banana", "cherry" }; +/// assert_eq!( fruits.front(), Some( &"apple".to_string() ) ); // The first element +/// assert_eq!( fruits.back(), Some( &"cherry".to_string() ) ); // The last element +/// ``` +/// +#[ macro_export( local_inner_macros ) ] +macro_rules! vecd +{ + ( + $( $key : expr ),* $( , )? + ) + => + { + collection_tools::VecDeque::from + ( + collection_tools::vec![ $( $key.into() ),* ] + ) + } +} diff --git a/module/core/collection_tools/src/lib.rs b/module/core/collection_tools/src/lib.rs index 1c13e0ded9..834304f7ca 100644 --- a/module/core/collection_tools/src/lib.rs +++ b/module/core/collection_tools/src/lib.rs @@ -9,9 +9,7 @@ pub mod dependency { - #[ cfg( feature = "collection_constructors" ) ] - pub use ::literally; - #[ cfg( all( feature = "collection_std", feature = "use_alloc" ) ) ] + #[ cfg( feature = "use_alloc" ) ] pub use ::hashbrown; } @@ -30,33 +28,24 @@ pub mod protected #[ allow( unused_imports ) ] pub use super::orphan::*; - #[ cfg( feature = "use_alloc" ) ] extern crate alloc; - #[ cfg( feature = "use_alloc" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use alloc::vec; - #[ cfg( feature = "use_alloc" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use alloc::vec::Vec; - #[ cfg( feature = "use_alloc" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use hashbrown::*; - #[ cfg( not( feature = "no_std" ) ) ] - #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use std::collections::*; - #[ cfg( not( feature = "no_std" ) ) ] + pub use alloc::collections::{ BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque }; + #[ cfg( feature = "use_alloc" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use std::vec; + pub use hashbrown::{ HashMap, HashSet }; #[ cfg( not( feature = "no_std" ) ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use std::vec::Vec; - + pub use std::collections::{ HashMap, HashSet }; } /// Parented namespace of the module. @@ -81,8 +70,13 @@ pub mod exposed #[ cfg( feature = "enabled" ) ] pub mod prelude { + #[ cfg( feature = "collection_constructors" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] - #[ cfg( feature = "collection_constructors" ) ] - pub use ::literally::*; + pub use super::constructors::*; } + +/// Macros to construct the collections. +/// Basically a tweaked version of `literally` crate but using `alloc` / `hashbrown` instead of `std` +#[ cfg( all( feature = "enabled", feature = "collection_constructors" ) ) ] +pub mod constructors; \ No newline at end of file diff --git a/module/core/collection_tools/tests/inc/constructor.rs b/module/core/collection_tools/tests/inc/constructor.rs index 09dae06337..b94b1842ae 100644 --- a/module/core/collection_tools/tests/inc/constructor.rs +++ b/module/core/collection_tools/tests/inc/constructor.rs @@ -3,41 +3,82 @@ use super::*; // -// #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] -// #[ test ] -// fn vec() -// { -// -// // test.case( "empty" ); -// let got : std::vec::Vec< i32 > = the_module::vec!{}; -// let exp: the_module::Vec< i32 > = std::vec::Vec::new(); -// assert_eq!( got, exp ); +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +#[ test ] +fn b_tree_map() +{ + + // test.case( "empty" ); + let got : the_module::BTreeMap< i32, i32 > = the_module::bmap!{}; + let exp : the_module::BTreeMap< i32, i32 > = the_module::BTreeMap::new(); + assert_eq!( got, exp ); + + // test.case( "single entry" ); + let got = the_module::bmap!{ 3 => 13 }; + let mut exp = the_module::BTreeMap::new(); + exp.insert(3, 13); + assert_eq!( got, exp ); + +} + // -// // test.case( "single entry" ); -// let got = the_module::vec!{ 3, 13 }; -// let mut exp = std::vec::Vec::new(); -// exp.push( 3 ); -// exp.push( 13 ); -// assert_eq!( got, exp ); + +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +#[ test ] +fn b_tree_set() +{ + + // test.case( "empty" ); + let got : the_module::BTreeSet< i32 > = the_module::bset!{}; + let exp : the_module::BTreeSet< i32 > = the_module::BTreeSet::new(); + assert_eq!( got, exp ); + + // test.case( "single entry" ); + let got = the_module::bset!{ 3, 13 }; + let mut exp = the_module::BTreeSet::new(); + exp.insert(3); + exp.insert(13); + assert_eq!( got, exp ); + +} + // -// } + +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +#[ test ] +fn binary_heap() +{ + + // test.case( "empty" ); + let got : the_module::BinaryHeap< i32 > = the_module::heap!{}; + let exp : the_module::BinaryHeap< i32 > = the_module::BinaryHeap::new(); + assert_eq!( got.into_vec(), exp.into_vec() ); + + // test.case( "single entry" ); + let got: the_module::BinaryHeap< i32 > = the_module::heap!{ 3, 13 }; + let mut exp = the_module::BinaryHeap::new(); + exp.push(3); + exp.push(13); + assert_eq!( got.into_sorted_vec(), exp.into_sorted_vec() ); + +} // -// #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] #[ test ] fn hash_map() { // test.case( "empty" ); - let got : std::collections::HashMap< i32, i32 > = the_module::hmap!{}; - let exp = std::collections::HashMap::new(); + let got : the_module::HashMap< i32, i32 > = the_module::hmap!{}; + let exp = the_module::HashMap::new(); assert_eq!( got, exp ); // test.case( "single entry" ); let got = the_module::hmap!{ 3 => 13 }; - let mut exp = std::collections::HashMap::new(); + let mut exp = the_module::HashMap::new(); exp.insert( 3, 13 ); assert_eq!( got, exp ); @@ -45,20 +86,83 @@ fn hash_map() // -// #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] #[ test ] fn hash_set() { // test.case( "empty" ); - let got : std::collections::HashSet< i32 > = the_module::hset!{}; - let exp = std::collections::HashSet::new(); + let got : the_module::HashSet< i32 > = the_module::hset!{}; + let exp = the_module::HashSet::new(); assert_eq!( got, exp ); // test.case( "single entry" ); let got = the_module::hset!{ 13 }; - let mut exp = std::collections::HashSet::new(); + let mut exp = the_module::HashSet::new(); exp.insert( 13 ); assert_eq!( got, exp ); -} \ No newline at end of file +} + +// + +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +#[ test ] +fn linked_list() +{ + + // test.case( "empty" ); + let got : the_module::LinkedList< i32 > = the_module::list!{}; + let exp = the_module::LinkedList::new(); + assert_eq!( got, exp ); + + // test.case( "single entry" ); + let got = the_module::list!{ 13, 15 }; + let mut exp = the_module::LinkedList::new(); + exp.push_front( 15 ); + exp.push_front( 13 ); + assert_eq!( got, exp ); + +} + +// + +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +#[ test ] +fn vec() +{ + + // test.case( "empty" ); + let got : the_module::Vec< i32 > = the_module::vec!{}; + let exp: the_module::Vec< i32 > = the_module::Vec::new(); + assert_eq!( got, exp ); + + // test.case( "single entry" ); + let got = the_module::vec!{ 3, 13 }; + let mut exp = the_module::Vec::new(); + exp.push( 3 ); + exp.push( 13 ); + assert_eq!( got, exp ); + +} + +// + +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +#[ test ] +fn vec_deque() +{ + + // test.case( "empty" ); + let got : the_module::VecDeque< i32 > = the_module::vecd!{}; + let exp: the_module::VecDeque< i32 > = the_module::VecDeque::new(); + assert_eq!( got, exp ); + + // test.case( "single entry" ); + let got = the_module::vecd!{ 3, 13 }; + let mut exp = the_module::VecDeque::new(); + exp.push_front( 13 ); + exp.push_front( 3 ); + assert_eq!( got, exp ); + +} diff --git a/module/core/collection_tools/tests/inc/reexport.rs b/module/core/collection_tools/tests/inc/reexport.rs index aa9e756c0d..000c6bc3fd 100644 --- a/module/core/collection_tools/tests/inc/reexport.rs +++ b/module/core/collection_tools/tests/inc/reexport.rs @@ -1,36 +1,105 @@ use super::*; +// + #[ test ] #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] -fn vec() +fn b_tree_map() { - let mut map : the_module::Vec< i32 > = the_module::Vec::new(); + let mut map : the_module::BTreeMap< i32, i32 > = the_module::BTreeMap::new(); + map.insert( 1, 2 ); + let exp = 2; + let got = *map.get( &1 ).unwrap(); + assert_eq!( exp, got ); +} + +// + +#[ test ] +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +fn b_tree_set() +{ + let mut map : the_module::BTreeSet< i32 > = the_module::BTreeSet::new(); + map.insert( 1 ); + assert_eq!( map.contains( &1 ), true ); + assert_eq!( map.contains( &2 ), false ); +} + +// + +#[ test ] +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +fn binary_heap() +{ + let mut map : the_module::BinaryHeap< i32 > = the_module::BinaryHeap::new(); map.push( 1 ); - map.push( 2 ); - let got = map.first().unwrap().clone(); - assert_eq!( got, 1 ); - let got = map.last().unwrap().clone(); - assert_eq!( got, 2 ); + let exp = Some(1).as_ref(); + let got = map.peek(); + assert_eq!( exp, got ); } +// + #[ test ] #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] -fn hashmap() +fn hash_map() { - use the_module::HashMap; - let mut map : HashMap< i32, i32 > = HashMap::new(); + let mut map : the_module::HashMap< i32, i32 > = the_module::HashMap::new(); map.insert( 1, 2 ); let exp = 2; let got = *map.get( &1 ).unwrap(); assert_eq!( exp, got ); } +// + #[ test ] #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] -fn hashset() +fn hash_set() { let mut map : the_module::HashSet< i32 > = the_module::HashSet::new(); map.insert( 1 ); assert_eq!( map.contains( &1 ), true ); assert_eq!( map.contains( &2 ), false ); } + +// + +#[ test ] +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +fn linked_list() +{ + let mut map : the_module::LinkedList< i32 > = the_module::LinkedList::new(); + map.push_back( 1 ); + assert_eq!( map.contains( &1 ), true ); + assert_eq!( map.contains( &2 ), false ); +} + +// + +#[ test ] +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +fn vec() +{ + + let mut map : the_module::Vec< i32 > = the_module::Vec::new(); + map.push( 1 ); + map.push( 2 ); + let got = map.first().unwrap().clone(); + assert_eq!( got, 1 ); + let got = map.last().unwrap().clone(); + assert_eq!( got, 2 ); + +} + +// + +#[ test ] +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +fn vec_deque() +{ + let mut map : the_module::VecDeque< i32 > = the_module::VecDeque::new(); + map.push_back( 1 ); + assert_eq!( map.contains( &1 ), true ); + assert_eq!( map.contains( &2 ), false ); +} diff --git a/module/core/collection_tools/tests/nostd/constructor.rs b/module/core/collection_tools/tests/nostd/constructor.rs index e4bca583ed..b94b1842ae 100644 --- a/module/core/collection_tools/tests/nostd/constructor.rs +++ b/module/core/collection_tools/tests/nostd/constructor.rs @@ -5,25 +5,66 @@ use super::*; #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] #[ test ] -fn vec() +fn b_tree_map() { // test.case( "empty" ); - let got : the_module::Vec< i32 > = the_module::vec!{}; - let exp: the_module::Vec< i32 > = the_module::Vec::new(); + let got : the_module::BTreeMap< i32, i32 > = the_module::bmap!{}; + let exp : the_module::BTreeMap< i32, i32 > = the_module::BTreeMap::new(); assert_eq!( got, exp ); // test.case( "single entry" ); - let got = the_module::vec!{ 3, 13 }; - let mut exp = the_module::Vec::new(); - exp.push( 3 ); - exp.push( 13 ); + let got = the_module::bmap!{ 3 => 13 }; + let mut exp = the_module::BTreeMap::new(); + exp.insert(3, 13); + assert_eq!( got, exp ); + +} + +// + +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +#[ test ] +fn b_tree_set() +{ + + // test.case( "empty" ); + let got : the_module::BTreeSet< i32 > = the_module::bset!{}; + let exp : the_module::BTreeSet< i32 > = the_module::BTreeSet::new(); + assert_eq!( got, exp ); + + // test.case( "single entry" ); + let got = the_module::bset!{ 3, 13 }; + let mut exp = the_module::BTreeSet::new(); + exp.insert(3); + exp.insert(13); assert_eq!( got, exp ); } // +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +#[ test ] +fn binary_heap() +{ + + // test.case( "empty" ); + let got : the_module::BinaryHeap< i32 > = the_module::heap!{}; + let exp : the_module::BinaryHeap< i32 > = the_module::BinaryHeap::new(); + assert_eq!( got.into_vec(), exp.into_vec() ); + + // test.case( "single entry" ); + let got: the_module::BinaryHeap< i32 > = the_module::heap!{ 3, 13 }; + let mut exp = the_module::BinaryHeap::new(); + exp.push(3); + exp.push(13); + assert_eq!( got.into_sorted_vec(), exp.into_sorted_vec() ); + +} + +// + #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] #[ test ] fn hash_map() @@ -61,4 +102,67 @@ fn hash_set() exp.insert( 13 ); assert_eq!( got, exp ); -} \ No newline at end of file +} + +// + +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +#[ test ] +fn linked_list() +{ + + // test.case( "empty" ); + let got : the_module::LinkedList< i32 > = the_module::list!{}; + let exp = the_module::LinkedList::new(); + assert_eq!( got, exp ); + + // test.case( "single entry" ); + let got = the_module::list!{ 13, 15 }; + let mut exp = the_module::LinkedList::new(); + exp.push_front( 15 ); + exp.push_front( 13 ); + assert_eq!( got, exp ); + +} + +// + +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +#[ test ] +fn vec() +{ + + // test.case( "empty" ); + let got : the_module::Vec< i32 > = the_module::vec!{}; + let exp: the_module::Vec< i32 > = the_module::Vec::new(); + assert_eq!( got, exp ); + + // test.case( "single entry" ); + let got = the_module::vec!{ 3, 13 }; + let mut exp = the_module::Vec::new(); + exp.push( 3 ); + exp.push( 13 ); + assert_eq!( got, exp ); + +} + +// + +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +#[ test ] +fn vec_deque() +{ + + // test.case( "empty" ); + let got : the_module::VecDeque< i32 > = the_module::vecd!{}; + let exp: the_module::VecDeque< i32 > = the_module::VecDeque::new(); + assert_eq!( got, exp ); + + // test.case( "single entry" ); + let got = the_module::vecd!{ 3, 13 }; + let mut exp = the_module::VecDeque::new(); + exp.push_front( 13 ); + exp.push_front( 3 ); + assert_eq!( got, exp ); + +} diff --git a/module/core/collection_tools/tests/nostd/mod.rs b/module/core/collection_tools/tests/nostd/mod.rs index 3583433b1a..c82bd04190 100644 --- a/module/core/collection_tools/tests/nostd/mod.rs +++ b/module/core/collection_tools/tests/nostd/mod.rs @@ -1,8 +1,8 @@ #[ allow( unused_imports ) ] use super::*; -// qqq : xxx : does not work for `use_alloc`, make it working -#[ cfg( not( feature = "use_alloc" ) ) ] +// aaa : xxx : does not work for `use_alloc`, make it working -- Made by switching from std collections to alloc / hashbrown +// #[ cfg( not( feature = "use_alloc" ) ) ] #[ cfg( any( feature = "collection_constructors" ) ) ] mod constructor; diff --git a/module/core/collection_tools/tests/nostd/reexport.rs b/module/core/collection_tools/tests/nostd/reexport.rs index 19e97abb40..000c6bc3fd 100644 --- a/module/core/collection_tools/tests/nostd/reexport.rs +++ b/module/core/collection_tools/tests/nostd/reexport.rs @@ -1,37 +1,105 @@ -#[ allow( unused_imports ) ] use super::*; +// + #[ test ] #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] -fn vec() +fn b_tree_map() { - let mut map : the_module::Vec< i32 > = the_module::Vec::new(); + let mut map : the_module::BTreeMap< i32, i32 > = the_module::BTreeMap::new(); + map.insert( 1, 2 ); + let exp = 2; + let got = *map.get( &1 ).unwrap(); + assert_eq!( exp, got ); +} + +// + +#[ test ] +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +fn b_tree_set() +{ + let mut map : the_module::BTreeSet< i32 > = the_module::BTreeSet::new(); + map.insert( 1 ); + assert_eq!( map.contains( &1 ), true ); + assert_eq!( map.contains( &2 ), false ); +} + +// + +#[ test ] +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +fn binary_heap() +{ + let mut map : the_module::BinaryHeap< i32 > = the_module::BinaryHeap::new(); map.push( 1 ); - map.push( 2 ); - let got = map.first().unwrap().clone(); - assert_eq!( got, 1 ); - let got = map.last().unwrap().clone(); - assert_eq!( got, 2 ); + let exp = Some(1).as_ref(); + let got = map.peek(); + assert_eq!( exp, got ); } +// + #[ test ] #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] -fn hashmap() +fn hash_map() { - use the_module::HashMap; - let mut map : HashMap< i32, i32 > = HashMap::new(); + let mut map : the_module::HashMap< i32, i32 > = the_module::HashMap::new(); map.insert( 1, 2 ); let exp = 2; let got = *map.get( &1 ).unwrap(); assert_eq!( exp, got ); } +// + #[ test ] #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] -fn hashset() +fn hash_set() { let mut map : the_module::HashSet< i32 > = the_module::HashSet::new(); map.insert( 1 ); assert_eq!( map.contains( &1 ), true ); assert_eq!( map.contains( &2 ), false ); } + +// + +#[ test ] +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +fn linked_list() +{ + let mut map : the_module::LinkedList< i32 > = the_module::LinkedList::new(); + map.push_back( 1 ); + assert_eq!( map.contains( &1 ), true ); + assert_eq!( map.contains( &2 ), false ); +} + +// + +#[ test ] +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +fn vec() +{ + + let mut map : the_module::Vec< i32 > = the_module::Vec::new(); + map.push( 1 ); + map.push( 2 ); + let got = map.first().unwrap().clone(); + assert_eq!( got, 1 ); + let got = map.last().unwrap().clone(); + assert_eq!( got, 2 ); + +} + +// + +#[ test ] +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +fn vec_deque() +{ + let mut map : the_module::VecDeque< i32 > = the_module::VecDeque::new(); + map.push_back( 1 ); + assert_eq!( map.contains( &1 ), true ); + assert_eq!( map.contains( &2 ), false ); +} diff --git a/module/core/collection_tools/tests/nostd_tests.rs b/module/core/collection_tools/tests/nostd_tests.rs index deff8c0af6..01523c2896 100644 --- a/module/core/collection_tools/tests/nostd_tests.rs +++ b/module/core/collection_tools/tests/nostd_tests.rs @@ -3,10 +3,10 @@ #[ allow( unused_imports ) ] use ::collection_tools as the_module; -// #[ allow( unused_imports ) ] -// use test_tools::exposed::*; +#[ allow( unused_imports ) ] +use test_tools::exposed::*; #[ path="../../../../module/step/meta/src/module/aggregating.rs" ] mod aggregating; mod nostd; -// xxx : enable \ No newline at end of file +// aaa : enable \ No newline at end of file diff --git a/module/core/collection_tools/tests/tests.rs b/module/core/collection_tools/tests/tests.rs index 103ec33039..00689894e0 100644 --- a/module/core/collection_tools/tests/tests.rs +++ b/module/core/collection_tools/tests/tests.rs @@ -7,5 +7,5 @@ use ::collection_tools as the_module; #[ path="../../../../module/step/meta/src/module/aggregating.rs" ] mod aggregating; -// mod inc; -// xxx +mod inc; +// aaa