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