1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use AHashSet;
use HashSet;
use Hash;
/// 🔁 Removes duplicate elements from a mutable vector using the standard [`HashSet`] (SipHash).
///
/// # Type Parameters
/// - `T`: The type of elements in the vector. Must implement [`Eq`], [`Hash`], and [`Clone`].
///
/// # Arguments
/// - `values`: A mutable reference to the vector to deduplicate.
///
/// # Returns
/// This function returns no value. It modifies the input vector in-place by retaining only the
/// **first occurrence** of each unique item.
///
/// # Behavior
/// - Duplicates are identified using `Eq` + `Hash`.
/// - The **first** occurrence of each item is kept; subsequent duplicates are removed.
/// - Preserves the **original order** of retained elements.
/// - Empty vectors are left unchanged.
/// - Works with primitives, strings, enums, and any type that implements `Eq`, `Hash`, and `Clone`.
///
/// # Performance
/// - Uses [`std::collections::HashSet`] (SipHash), secure and collision-resistant.
/// - Slower than [`AHashSet`] on large datasets, but safer for untrusted input.
///
/// # Examples
///
/// ### 🔢 Remove duplicate integers
/// ```
/// use pencil_box::array::uniq::uniq;
///
/// let mut nums = vec![1, 2, 2, 3, 1];
/// uniq(&mut nums);
/// assert_eq!(nums, vec![1, 2, 3]);
/// ```
///
/// ### 🔤 Remove duplicate strings
/// ```
/// let mut words = vec!["hi".to_string(), "hi".to_string(), "there".to_string()];
/// uniq(&mut words);
/// assert_eq!(words, vec!["hi", "there"]);
/// ```
///
/// ### 🧱 Works with enums or custom types (if they implement `Eq`, `Hash`, `Clone`)
/// ```
/// #[derive(Hash, Eq, PartialEq, Clone, Debug)]
/// enum Fruit { Apple, Banana, Apple }
///
/// let mut fruits = vec![Fruit::Apple, Fruit::Banana, Fruit::Apple];
/// uniq(&mut fruits);
/// assert_eq!(fruits.len(), 2);
/// ```
/// ⚡ Removes duplicate elements from a mutable vector using [`AHashSet`] for faster hashing.
///
/// # Type Parameters
/// - `T`: The type of elements in the vector. Must implement [`Eq`], [`Hash`], and [`Clone`].
///
/// # Arguments
/// - `values`: A mutable reference to the vector to deduplicate.
///
/// # Returns
/// This function returns no value. It modifies the input vector in-place by retaining only the
/// **first occurrence** of each unique item.
///
/// # Behavior
/// - Identical to [`uniq`], but uses a faster hash implementation (`AHashSet`).
/// - Retains the first instance, removes subsequent duplicates.
/// - Preserves input order of retained items.
///
/// # Performance
/// - Uses [`ahash::AHashSet`], a fast, non-cryptographic hashing algorithm.
/// - ⚠️ Not resistant to hash collision attacks — do **not** use with untrusted input.
/// - Excellent for large vectors in performance-critical paths.
///
/// # Examples
///
/// ### 🚀 Deduplicate large vectors efficiently
/// ```
/// use pencil_box::array::uniq::uniq_performant;
///
/// let mut data = (0..1_000_000).chain(0..500_000).collect::<Vec<_>>();
/// uniq_performant(&mut data);
/// assert_eq!(data.len(), 1_000_000);
/// ```
///
/// ### 💡 Identical logic to `uniq`
/// ```
/// let mut input = vec![1, 1, 2, 3];
/// uniq_performant(&mut input);
/// assert_eq!(input, vec![1, 2, 3]);
/// ```
///
/// ### 📭 No-op on empty vector
/// ```
/// let mut empty: Vec<i32> = vec![];
/// uniq_performant(&mut empty);
/// assert!(empty.is_empty());
/// ```