ark_std/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2
3#[cfg(not(feature = "std"))]
4#[doc(hidden)]
5extern crate alloc;
6
7#[cfg(not(feature = "std"))]
8pub use alloc::*;
9
10#[cfg(not(feature = "std"))]
11pub use core::*;
12
13#[cfg(not(feature = "std"))]
14pub mod fmt {
15    pub use alloc::fmt::*;
16    pub use core::fmt::*;
17}
18
19#[cfg(not(feature = "std"))]
20pub mod borrow {
21    pub use alloc::borrow::*;
22    pub use core::borrow::*;
23}
24
25#[cfg(not(feature = "std"))]
26pub mod slice {
27    pub use alloc::slice::*;
28    pub use core::slice::*;
29}
30
31#[cfg(not(feature = "std"))]
32pub mod str {
33    pub use alloc::str::*;
34    pub use core::str::*;
35}
36
37#[cfg(not(feature = "std"))]
38pub mod io;
39
40#[cfg(not(feature = "std"))]
41pub mod error;
42
43#[cfg(feature = "std")]
44#[doc(hidden)]
45pub use std::*;
46
47mod rand_helper;
48pub use rand_helper::*;
49
50pub mod perf_trace;
51
52pub mod iterable;
53
54pub use num_traits::{One, Zero};
55
56/// Returns the ceiling of the base-2 logarithm of `x`.
57///
58/// ```
59/// use ark_std::log2;
60///
61/// assert_eq!(log2(16), 4);
62/// assert_eq!(log2(17), 5);
63/// assert_eq!(log2(1), 0);
64/// assert_eq!(log2(0), 0);
65/// assert_eq!(log2(usize::MAX), (core::mem::size_of::<usize>() * 8) as u32);
66/// assert_eq!(log2(1 << 15), 15);
67/// assert_eq!(log2(2usize.pow(18)), 18);
68/// ```
69pub fn log2(x: usize) -> u32 {
70    if x == 0 {
71        0
72    } else if x.is_power_of_two() {
73        1usize.leading_zeros() - x.leading_zeros()
74    } else {
75        0usize.leading_zeros() - x.leading_zeros()
76    }
77}
78
79/// Creates parallel iterator over refs if `parallel` feature is enabled.
80/// Additionally, if the object being iterated implements
81/// `IndexedParallelIterator`, then one can specify a minimum size for
82/// iteration.
83#[macro_export]
84macro_rules! cfg_iter {
85    ($e: expr, $min_len: expr) => {{
86        #[cfg(feature = "parallel")]
87        let result = $e.par_iter().with_min_len($min_len);
88
89        #[cfg(not(feature = "parallel"))]
90        let result = $e.iter();
91
92        result
93    }};
94    ($e: expr) => {{
95        #[cfg(feature = "parallel")]
96        let result = $e.par_iter();
97
98        #[cfg(not(feature = "parallel"))]
99        let result = $e.iter();
100
101        result
102    }};
103}
104
105/// Creates parallel iterator over mut refs if `parallel` feature is enabled.
106/// Additionally, if the object being iterated implements
107/// `IndexedParallelIterator`, then one can specify a minimum size for
108/// iteration.
109#[macro_export]
110macro_rules! cfg_iter_mut {
111    ($e: expr, $min_len: expr) => {{
112        #[cfg(feature = "parallel")]
113        let result = $e.par_iter_mut().with_min_len($min_len);
114
115        #[cfg(not(feature = "parallel"))]
116        let result = $e.iter_mut();
117
118        result
119    }};
120    ($e: expr) => {{
121        #[cfg(feature = "parallel")]
122        let result = $e.par_iter_mut();
123
124        #[cfg(not(feature = "parallel"))]
125        let result = $e.iter_mut();
126
127        result
128    }};
129}
130
131/// Creates parallel iterator if `parallel` feature is enabled.
132/// Additionally, if the object being iterated implements
133/// `IndexedParallelIterator`, then one can specify a minimum size for
134/// iteration.
135#[macro_export]
136macro_rules! cfg_into_iter {
137    ($e: expr, $min_len: expr) => {{
138        #[cfg(feature = "parallel")]
139        let result = $e.into_par_iter().with_min_len($min_len);
140
141        #[cfg(not(feature = "parallel"))]
142        let result = $e.into_iter();
143
144        result
145    }};
146    ($e: expr) => {{
147        #[cfg(feature = "parallel")]
148        let result = $e.into_par_iter();
149
150        #[cfg(not(feature = "parallel"))]
151        let result = $e.into_iter();
152
153        result
154    }};
155}
156
157/// Returns an iterator over `chunk_size` elements of the slice at a
158/// time.
159#[macro_export]
160macro_rules! cfg_chunks {
161    ($e: expr, $size: expr) => {{
162        #[cfg(feature = "parallel")]
163        let result = $e.par_chunks($size);
164
165        #[cfg(not(feature = "parallel"))]
166        let result = $e.chunks($size);
167
168        result
169    }};
170}
171
172/// Returns an iterator over `chunk_size` mutable elements of the slice at a
173/// time.
174#[macro_export]
175macro_rules! cfg_chunks_mut {
176    ($e: expr, $size: expr) => {{
177        #[cfg(feature = "parallel")]
178        let result = $e.par_chunks_mut($size);
179
180        #[cfg(not(feature = "parallel"))]
181        let result = $e.chunks_mut($size);
182
183        result
184    }};
185}
186
187#[cfg(test)]
188mod test {
189    use super::*;
190    #[cfg(feature = "parallel")]
191    use rayon::prelude::*;
192
193    #[test]
194    fn test_cfg_macros() {
195        #[cfg(feature = "parallel")]
196        println!("In parallel mode");
197
198        let mut thing = crate::vec![1, 2, 3, 4, 5u64];
199        println!("Iterating");
200        cfg_iter!(&thing).for_each(|i| println!("{:?}", i));
201        println!("Iterating Mut");
202        cfg_iter_mut!(&mut thing).for_each(|i| *i += 1);
203        println!("Iterating By Value");
204        cfg_into_iter!(thing.clone()).for_each(|i| println!("{:?}", i));
205        println!("Chunks");
206        cfg_chunks!(&thing, 2).for_each(|chunk| println!("{:?}", chunk));
207        println!("Chunks Mut");
208        cfg_chunks_mut!(&mut thing, 2).for_each(|chunk| println!("{:?}", chunk));
209
210        println!("Iterating");
211        cfg_iter!(&thing, 3).for_each(|i| println!("{:?}", i));
212        println!("Iterating Mut");
213        cfg_iter_mut!(&mut thing, 3).for_each(|i| *i += 1);
214        println!("Iterating By Value");
215        cfg_into_iter!(thing, 3).for_each(|i| println!("{:?}", i));
216    }
217}