1use super::{Nothing, PushedVal};
2
3
4trait IntoPo {
6 type Po;
7 fn into_po(self) -> Option<Self::Po>;
8}
9impl<T> IntoPo for Option<T> {
10 type Po = T;
11
12 #[inline]
13 fn into_po(self) -> Option<T> {
14 self
15 }
16}
17impl IntoPo for bool {
18 type Po = PushedVal;
19
20 #[inline]
21 fn into_po(self) -> Option<PushedVal> {
22 if self { None } else { Some(PushedVal) }
23 }
24}
25impl IntoPo for () {
26 type Po = Nothing;
27
28 #[inline]
29 fn into_po(self) -> Option<Self::Po> {
30 None
31 }
32}
33
34
35#[cfg(feature = "alloc")]
36macro_rules! do_impl {
37 (CanPush for $impl_for:ty, $t:ty, $po:ty; $($gen:tt)*) => {
38 impl<$($gen)*> $crate::base::CanPush<$t> for $impl_for {
39 type PushedOut = $po;
40 }
41 };
42 (Push for $impl_for:ty, $method:path, $t:ty, $po:ty; $($gen:tt)*) => {
43 do_impl!(CanPush for $impl_for, $t, $po; $($gen)*);
44 impl<$($gen)*> $crate::base::Push<$t> for $impl_for {
45 fn push(&mut self, val: $t) -> Option<Self::PushedOut> {
46 $crate::impls::IntoPo::into_po($method(self, val))
47 }
48 }
49 };
50 (keyval Push for $impl_for:ty, $method:path, $t:ty, $po:ty; $($gen:tt)*) => {
51 do_impl!(CanPush for $impl_for, $t, $po; $($gen)*);
52 impl<$($gen)*> $crate::base::Push<$t> for $impl_for {
53 fn push(&mut self, (key, val): $t) -> Option<Self::PushedOut> {
54 $crate::impls::IntoPo::into_po($method(self, key, val))
55 }
56 }
57 };
58 (PushSorted for $impl_for:ty, $method:path, $t:ty, $po:ty; $($gen:tt)*) => {
59 do_impl!(CanPush for $impl_for, $t, $po; $($gen)*);
60 impl<$($gen)*> $crate::sorted::PushSorted<$t> for $impl_for {
61 fn push_sorted(&mut self, val: $t) -> Option<Self::PushedOut> {
62 $crate::impls::IntoPo::into_po($method(self, val))
63 }
64 }
65 };
66 (keyval PushSorted for $impl_for:ty, $method:path, $t:ty, $po:ty; $($gen:tt)*) => {
67 do_impl!(CanPush for $impl_for, $t, $po; $($gen)*);
68 impl<$($gen)*> $crate::sorted::PushSorted<$t> for $impl_for {
69 fn push_sorted(&mut self, (key, val): $t) -> Option<Self::PushedOut> {
70 $crate::impls::IntoPo::into_po($method(self, key, val))
71 }
72 }
73 };
74 (PushBack for $impl_for:ty, $method:path, $t:ty, $po:ty; $($gen:tt)*) => {
75 do_impl!(Push for $impl_for, $method, $t, $po; $($gen)*);
76 impl<$($gen)*> $crate::ordered::PushBack<$t> for $impl_for { }
77 };
78 (keyval PushBack for $impl_for:ty, $method:path, $t:ty, $po:ty; $($gen:tt)*) => {
79 do_impl!(keyval Push for $impl_for, $method, $t, $po; $($gen)*);
80 impl<$($gen)*> $crate::ordered::PushBack<$t> for $impl_for { }
81 };
82 (PushFront for $impl_for:ty, $method:path, $t:ty, $po:ty; $($gen:tt)*) => {
83 impl<$($gen)*> $crate::ordered::PushFront<$t> for $impl_for {
84 fn push_front(&mut self, val: $t) -> Option<Self::PushedOut> {
85 $crate::impls::IntoPo::into_po($method(self, val))
86 }
87 }
88 };
89 (Insert for $impl_for:ty, $method:path, $t:ty, $po:ty; $($gen:tt)*) => {
90 impl<$($gen)*> $crate::ordered::Insert<$t> for $impl_for {
91 fn insert(&mut self, index: usize, val: $t) -> Option<Self::PushedOut> {
92 $crate::impls::IntoPo::into_po($method(self, index, val))
93 }
94 }
95 };
96 (Append for $impl_for:ty, $method:path; $($gen:tt)*) => {
97 impl<$($gen)*> $crate::append::Append for $impl_for {
98 fn append(&mut self, val: &mut Self) {
99 $method(self, val)
100 }
101 }
102 };
103 (AppendBack for $impl_for:ty, $method:path; $($gen:tt)*) => {
104 do_impl!(Append for $impl_for, $method; $($gen)*);
105 impl<$($gen)*> $crate::append::AppendBack for $impl_for {}
106 impl<$($gen)*> $crate::append::AppendFront for $impl_for {}
107 };
108}
109
110#[cfg_attr(feature = "cargo-clippy", allow(linkedlist))]
111cfg_if! {
113 if #[cfg(feature = "alloc")] {
114 cfg_if! {
115 if #[cfg(feature = "std")] {
116 use std::collections;
117 } else {
118 use alloc::{self as collections, String, Vec};
119 }
120 }
121 use self::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
122
123 do_impl!(Append for BTreeSet<T>, BTreeSet::append; T: Ord);
124 do_impl!(PushSorted for BTreeSet<T>, BTreeSet::insert, T, super::PushedVal; T: Ord);
125
126 do_impl!(Append for BinaryHeap<T>, BinaryHeap::append; T: Ord);
127 do_impl!(PushSorted for BinaryHeap<T>, BinaryHeap::push, T, super::Nothing; T: Ord);
128
129 do_impl!(Append for BTreeMap<K, V>, BTreeMap::append; K: Ord, V);
130 do_impl!(keyval PushSorted for BTreeMap<K, V>, BTreeMap::insert, (K, V), V; K: Ord, V);
131
132 do_impl!(AppendBack for LinkedList<T>, LinkedList::append; T);
133 do_impl!(PushBack for LinkedList<T>, LinkedList::push_back, T, super::Nothing; T);
134 do_impl!(PushFront for LinkedList<T>, LinkedList::push_front, T, super::Nothing; T);
135
136 do_impl!(AppendBack for String, string_append; );
137 do_impl!(PushBack for String, String::push, char, super::Nothing; );
138 do_impl!(PushBack for String, String::push_str, &'a str, super::Nothing; 'a);
139 do_impl!(Insert for String, String::insert, char, super::Nothing; );
140 do_impl!(Insert for String, String::insert_str, &'a str, super::Nothing; 'a);
141 fn string_append(lhs: &mut String, rhs: &mut String) {
142 lhs.push_str(rhs);
143 rhs.clear();
144 }
145
146 do_impl!(AppendBack for Vec<T>, Vec::append; T);
147 do_impl!(PushBack for Vec<T>, Vec::push, T, super::Nothing; T);
148 do_impl!(PushBack for Vec<u8>, push_utf8_char, char, super::Nothing; );
149 do_impl!(PushBack for Vec<u16>, push_utf16_char, char, super::Nothing; );
150 do_impl!(PushBack for Vec<u32>, push_utf32_char, char, super::Nothing; );
151 do_impl!(PushBack for Vec<T>,
152 Vec::extend_from_slice, &'a [T], super::Nothing; 'a, T: 'a + Clone);
153 do_impl!(Insert for Vec<T>, Vec::insert, T, super::Nothing; T);
154 do_impl!(Insert for Vec<u32>, insert_utf32_char, char, super::Nothing; );
155 fn push_utf8_char(lhs: &mut Vec<u8>, rhs: char) {
156 let mut buf = [0; 4];
157 Vec::extend_from_slice(lhs, rhs.encode_utf8(&mut buf).as_bytes())
158 }
159 fn push_utf16_char(lhs: &mut Vec<u16>, rhs: char) {
160 let mut buf = [0; 2];
161 Vec::extend_from_slice(lhs, rhs.encode_utf16(&mut buf))
162 }
163 fn push_utf32_char(lhs: &mut Vec<u32>, rhs: char) {
164 Vec::push(lhs, rhs as u32)
165 }
166 fn insert_utf32_char(lhs: &mut Vec<u32>, index: usize, rhs: char) {
167 Vec::insert(lhs, index, rhs as u32)
168 }
169
170 cfg_if! {
171 if #[cfg(feature = "nightly")] {
172 do_impl!(Insert for Vec<u8>, insert_utf8_char, char, super::Nothing; );
173 do_impl!(Insert for Vec<u16>, insert_utf16_char, char, super::Nothing; );
174 do_impl!(Insert for Vec<T>,
175 insert_slice, &'a [T], super::Nothing; 'a, T: 'a + Clone);
176 fn insert_utf8_char(lhs: &mut Vec<u8>, index: usize, rhs: char) {
177 let mut buf = [0; 4];
178 Vec::splice(lhs, index..index, rhs.encode_utf8(&mut buf).bytes());
179 }
180 fn insert_utf16_char(lhs: &mut Vec<u16>, index: usize, rhs: char) {
181 let mut buf = [0; 2];
182 Vec::splice(lhs, index..index, rhs.encode_utf16(&mut buf).iter().cloned());
183 }
184 fn insert_slice<T: Clone>(lhs: &mut Vec<T>, index: usize, rhs: &[T]) {
185 Vec::splice(lhs, index..index, rhs.iter().cloned());
186 }
187 }
188 }
189
190 do_impl!(AppendBack for VecDeque<T>, VecDeque::append; T);
191 do_impl!(PushBack for VecDeque<T>, VecDeque::push_back, T, super::Nothing; T);
192 do_impl!(PushFront for VecDeque<T>, VecDeque::push_front, T, super::Nothing; T);
193 do_impl!(Insert for VecDeque<T>, VecDeque::insert, T, super::Nothing; T);
194 }
195}
196
197cfg_if! {
198 if #[cfg(feature = "std")] {
199 use std::collections::{HashMap, HashSet};
200 use std::ffi::{OsStr, OsString};
201 use std::hash::Hash;
202
203 do_impl!(AppendBack for OsString, os_string_append; );
204 do_impl!(PushBack for OsString, OsString::push, &'a OsStr, super::Nothing; 'a);
205 do_impl!(PushBack for OsString, OsString::push, &'a str, super::Nothing; 'a);
206 fn os_string_append(lhs: &mut OsString, rhs: &mut OsString) {
207 lhs.push(&rhs);
208 rhs.clear();
209 }
210
211 do_impl!(keyval Push for HashMap<K, V>, HashMap::insert, (K, V), V; K: Hash + Eq, V);
212 do_impl!(Push for HashSet<T>, HashSet::insert, T, super::PushedVal; T: Hash + Eq);
213 }
214}