1use itertools::Itertools;
2use std::{cell::Cell, mem::DropGuard};
3
4use macros::EnumAsGetters;
5
6pub mod dedup;
7pub mod hash_cons;
8pub use dedup::*;
9pub use hash_cons::*;
10
11pub static TAB_INCR: &str = " ";
12
13pub fn pretty_display_list<T>(
23 t_to_string: impl Fn(T) -> String,
24 it: impl IntoIterator<Item = T>,
25) -> String {
26 let mut elems = it
27 .into_iter()
28 .map(t_to_string)
29 .map(|x| format!(" {},\n", x))
30 .peekable();
31 if elems.peek().is_none() {
32 "[]".to_owned()
33 } else {
34 format!("[\n{}]", elems.format(""))
35 }
36}
37
38#[macro_export]
40macro_rules! impl_from_enum {
41 ($enum:ident::$variant:ident($ty:ty)) => {
42 impl From<$ty> for $enum {
43 fn from(x: $ty) -> Self {
44 $enum::$variant(x)
45 }
46 }
47 impl TryFrom<$enum> for $ty {
48 type Error = ();
49 fn try_from(e: $enum) -> Result<Self, Self::Error> {
50 match e {
51 $enum::$variant(x) => Ok(x),
52 _ => Err(()),
53 }
54 }
55 }
56 };
57}
58
59pub fn repeat_except_first<T: Clone>(x: T) -> impl Iterator<Item = Option<T>> {
61 [None].into_iter().chain(std::iter::repeat(Some(x)))
62}
63
64#[derive(Debug, EnumAsGetters)]
66pub enum CycleDetector<T> {
67 Unprocessed,
69 Processing,
72 Cyclic,
74 Processed(T),
76}
77
78impl<T> CycleDetector<T> {
79 pub fn start_processing(&mut self) -> bool {
82 match self {
83 CycleDetector::Unprocessed => {
84 *self = CycleDetector::Processing;
85 true
86 }
87 CycleDetector::Processing => {
88 *self = CycleDetector::Cyclic;
89 false
90 }
91 CycleDetector::Cyclic | CycleDetector::Processed(_) => false,
92 }
93 }
94
95 pub fn done_processing(&mut self, x: T) {
96 *self = CycleDetector::Processed(x)
97 }
98}
99
100impl<T> Default for CycleDetector<T> {
101 fn default() -> Self {
102 CycleDetector::Unprocessed
103 }
104}
105
106pub use dfs_with_path::DfsWithPath;
107pub mod dfs_with_path {
108 use petgraph::visit::{GraphRef, IntoNeighbors, VisitMap, Visitable};
109
110 enum DfsPathAction<N> {
111 PopPath,
112 Explore(N),
113 }
114
115 pub struct DfsWithPath<N, VM> {
117 stack: Vec<DfsPathAction<N>>,
118 discovered: VM,
119 pub path: Vec<N>,
120 }
121
122 impl<N, VM> DfsWithPath<N, VM>
123 where
124 N: Copy + PartialEq,
125 VM: VisitMap<N>,
126 {
127 pub fn new<G>(graph: G, start: N) -> Self
128 where
129 G: GraphRef + Visitable<NodeId = N, Map = VM>,
130 {
131 Self {
132 stack: vec![DfsPathAction::Explore(start)],
133 discovered: graph.visit_map(),
134 path: Vec::new(),
135 }
136 }
137
138 pub fn next<G>(&mut self, graph: G) -> Option<N>
139 where
140 G: IntoNeighbors<NodeId = N>,
141 {
142 while let Some(action) = self.stack.pop() {
143 match action {
144 DfsPathAction::Explore(node) => {
145 if self.discovered.visit(node) {
146 self.path.push(node);
147 self.stack.push(DfsPathAction::PopPath);
148 self.stack.extend(
149 graph
150 .neighbors(node)
151 .filter(|node| !self.discovered.is_visited(node))
152 .map(DfsPathAction::Explore),
153 );
154 return Some(node);
155 }
156 }
157 DfsPathAction::PopPath => {
158 self.path.pop();
159 }
160 }
161 }
162 None
163 }
164 }
165}
166
167pub mod type_map {
168 use rustc_hash::FxHashMap;
169 use std::{
170 any::{Any, TypeId},
171 marker::PhantomData,
172 };
173
174 pub trait Mappable: Any + Send + Sync {}
175 impl<T> Mappable for T where T: Any + Send + Sync {}
176
177 pub trait Mapper {
178 type Value<T: Mappable>: Mappable;
179 }
180
181 pub struct TypeMap<M> {
184 data: FxHashMap<TypeId, Box<dyn Mappable>>,
185 phantom: PhantomData<M>,
186 }
187
188 impl<M: Mapper> TypeMap<M> {
189 pub fn get<T: Mappable>(&self) -> Option<&M::Value<T>> {
190 self.data
191 .get(&TypeId::of::<T>())
192 .map(|val: &Box<dyn Mappable>| &**val)
194 .and_then(|val: &dyn Mappable| (val as &dyn Any).downcast_ref())
195 }
196
197 pub fn get_mut<T: Mappable>(&mut self) -> Option<&mut M::Value<T>> {
198 self.data
199 .get_mut(&TypeId::of::<T>())
200 .map(|val: &mut Box<dyn Mappable>| &mut **val)
202 .and_then(|val: &mut dyn Mappable| (val as &mut dyn Any).downcast_mut())
203 }
204
205 pub fn insert<T: Mappable>(&mut self, val: M::Value<T>) -> Option<Box<M::Value<T>>> {
206 self.data
207 .insert(TypeId::of::<T>(), Box::new(val))
208 .and_then(|val: Box<dyn Mappable>| (val as Box<dyn Any>).downcast().ok())
209 }
210
211 pub fn or_insert_with<T: Mappable>(
212 &mut self,
213 f: impl FnOnce() -> M::Value<T>,
214 ) -> &mut M::Value<T> {
215 if self.get::<T>().is_none() {
216 self.insert(f());
217 }
218 self.get_mut::<T>().unwrap()
219 }
220 pub fn or_default<T: Mappable>(&mut self) -> &mut M::Value<T>
221 where
222 M::Value<T>: Default,
223 {
224 self.or_insert_with(Default::default)
225 }
226 }
227
228 impl<M> Default for TypeMap<M> {
229 fn default() -> Self {
230 Self {
231 data: Default::default(),
232 phantom: Default::default(),
233 }
234 }
235 }
236}
237
238pub mod hash_by_addr {
239 use serde::{Deserialize, Serialize};
240 use std::{
241 hash::{Hash, Hasher},
242 ops::Deref,
243 };
244
245 #[derive(Debug, Clone, Serialize, Deserialize)]
248 pub struct HashByAddr<T>(pub T);
249
250 impl<T: Deref> HashByAddr<T> {
251 fn addr(&self) -> *const T::Target {
252 self.0.deref()
253 }
254 }
255
256 impl<T: Eq + Deref> Eq for HashByAddr<T> {}
257
258 impl<T: PartialEq + Deref> PartialEq for HashByAddr<T> {
259 fn eq(&self, other: &Self) -> bool {
260 std::ptr::addr_eq(self.addr(), other.addr())
261 }
262 }
263
264 impl<T: Hash + Deref> Hash for HashByAddr<T> {
265 fn hash<H: Hasher>(&self, state: &mut H) {
266 self.addr().hash(state);
267 }
268 }
269}
270
271pub mod serialize_map_to_array {
272 use core::{fmt, marker::PhantomData};
273 use std::{
274 collections::hash_map::RandomState,
275 hash::{BuildHasher, Hash},
276 };
277
278 use indexmap::IndexMap as SeqHashMap;
279 use serde::{
280 Deserialize, Deserializer, Serialize,
281 de::{SeqAccess, Visitor},
282 ser::Serializer,
283 };
284 use serde_state::{DeserializeState, SerializeState};
285
286 #[derive(Serialize, Deserialize, SerializeState, DeserializeState)]
287 struct KeyValue<K, V> {
288 key: K,
289 value: V,
290 }
291
292 pub struct SeqHashMapToArray<K, V, U = RandomState>(PhantomData<(K, V, U)>);
294
295 impl<K, V, U> SeqHashMapToArray<K, V, U> {
296 pub fn serialize<S>(map: &SeqHashMap<K, V, U>, serializer: S) -> Result<S::Ok, S::Error>
298 where
299 K: Serialize,
300 V: Serialize,
301 S: Serializer,
302 {
303 serializer.collect_seq(map.into_iter().map(|(key, value)| KeyValue { key, value }))
304 }
305 pub fn serialize_state<S, State: ?Sized>(
306 map: &SeqHashMap<K, V, U>,
307 state: &State,
308 serializer: S,
309 ) -> Result<S::Ok, S::Error>
310 where
311 K: SerializeState<State>,
312 V: SerializeState<State>,
313 S: Serializer,
314 {
315 serializer.collect_seq(
316 map.into_iter().map(|(key, value)| {
317 serde_state::WithState::new(KeyValue { key, value }, state)
318 }),
319 )
320 }
321
322 pub fn deserialize<'de, D>(deserializer: D) -> Result<SeqHashMap<K, V, U>, D::Error>
324 where
325 K: Deserialize<'de> + Eq + Hash,
326 V: Deserialize<'de>,
327 U: BuildHasher + Default,
328 D: Deserializer<'de>,
329 {
330 struct SeqHashMapToArrayVisitor<K, V, U>(PhantomData<(K, V, U)>);
331
332 impl<'de, K, V, U> Visitor<'de> for SeqHashMapToArrayVisitor<K, V, U>
333 where
334 K: Deserialize<'de> + Eq + Hash,
335 V: Deserialize<'de>,
336 U: BuildHasher + Default,
337 {
338 type Value = SeqHashMap<K, V, U>;
339
340 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
341 formatter.write_str("a list of key-value objects")
342 }
343
344 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
345 let mut map = SeqHashMap::<K, V, U>::default();
346 while let Some(entry) = seq.next_element::<KeyValue<K, V>>()? {
347 map.insert(entry.key, entry.value);
348 }
349 Ok(map)
350 }
351 }
352 let map =
353 deserializer.deserialize_seq(SeqHashMapToArrayVisitor::<K, V, U>(PhantomData))?;
354 Ok(map)
355 }
356 pub fn deserialize_state<'de, D, State: ?Sized>(
358 state: &State,
359 deserializer: D,
360 ) -> Result<SeqHashMap<K, V, U>, D::Error>
361 where
362 K: DeserializeState<'de, State> + Eq + Hash,
363 V: DeserializeState<'de, State>,
364 U: BuildHasher + Default,
365 D: Deserializer<'de>,
366 {
367 struct SeqHashMapToArrayVisitor<'a, State: ?Sized, K, V, U>(
368 &'a State,
369 PhantomData<(K, V, U)>,
370 );
371
372 impl<'de, State: ?Sized, K, V, U> Visitor<'de> for SeqHashMapToArrayVisitor<'_, State, K, V, U>
373 where
374 K: DeserializeState<'de, State> + Eq + Hash,
375 V: DeserializeState<'de, State>,
376 U: BuildHasher + Default,
377 {
378 type Value = SeqHashMap<K, V, U>;
379
380 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
381 formatter.write_str("a list of key-value objects")
382 }
383
384 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
385 let mut map = SeqHashMap::default();
386 let seed =
387 serde_state::__private::wrap_deserialize_seed::<KeyValue<K, V>, _>(self.0);
388 while let Some(entry) = seq.next_element_seed(seed)? {
389 map.insert(entry.key, entry.value);
390 }
391 Ok(map)
392 }
393 }
394 let map = deserializer
395 .deserialize_seq(SeqHashMapToArrayVisitor::<_, K, V, U>(state, PhantomData))?;
396 Ok(map)
397 }
398 }
399}
400
401const RED_ZONE: usize = 100 * 1024; const STACK_PER_RECURSION: usize = 1024 * 1024; const MAX_STACK_DEPTH: usize = 1024;
412
413thread_local! {
414 static STACK_DEPTH: Cell<usize> = const { Cell::new(0) };
415}
416
417#[inline]
420#[track_caller]
421pub fn ensure_sufficient_stack<R>(f: impl FnOnce() -> R) -> R {
422 match try_ensure_sufficient_stack(f) {
423 Ok(value) => value,
424 Err(_) => panic!("stack depth limit exceeded"),
425 }
426}
427
428#[derive(Debug)]
429pub struct StackDepthLimitExceeded;
430
431#[inline]
433pub fn try_ensure_sufficient_stack<R>(f: impl FnOnce() -> R) -> Result<R, StackDepthLimitExceeded> {
434 let depth = STACK_DEPTH.get();
435 if depth >= MAX_STACK_DEPTH {
436 return Err(StackDepthLimitExceeded);
437 }
438 STACK_DEPTH.set(depth + 1);
439 let _guard = DropGuard::new((), |()| STACK_DEPTH.set(depth));
441 Ok(stacker::maybe_grow(RED_ZONE, STACK_PER_RECURSION, f))
442}
443
444pub fn arg_values<'a, T: AsRef<str>>(
447 args: &'a [T],
448 needle: &'a str,
449) -> impl Iterator<Item = &'a str> {
450 struct ArgFilter<'a, T> {
451 args: std::slice::Iter<'a, T>,
452 needle: &'a str,
453 }
454 impl<'a, T: AsRef<str>> Iterator for ArgFilter<'a, T> {
455 type Item = &'a str;
456 fn next(&mut self) -> Option<Self::Item> {
457 while let Some(arg) = self.args.next() {
458 let mut split_arg = arg.as_ref().splitn(2, '=');
459 if split_arg.next() == Some(self.needle) {
460 return match split_arg.next() {
461 arg @ Some(_) => arg,
463 None => self.args.next().map(|x| x.as_ref()),
465 };
466 }
467 }
468 None
469 }
470 }
471 ArgFilter {
472 args: args.iter(),
473 needle,
474 }
475}
476
477pub fn arg_value<'a, T: AsRef<str>>(args: &'a [T], needle: &'a str) -> Option<&'a str> {
478 arg_values(args, needle).next()
479}
480
481#[test]
482fn catch_stack_overflow() {
483 fn recurse(depth: usize) -> Result<(), StackDepthLimitExceeded> {
484 try_ensure_sufficient_stack(|| {
485 if depth > 0 {
486 recurse(depth - 1)
487 } else {
488 Ok(())
489 }
490 })?
491 }
492
493 assert!(recurse(1024).is_err());
494 assert_eq!(try_ensure_sufficient_stack(|| 42).unwrap(), 42);
495}