blink_alloc/
blink.rs

1//! Provides `Blink` allocator adaptor.
2
3use core::{
4    alloc::Layout,
5    convert::{identity, Infallible},
6    marker::PhantomData,
7    mem::{needs_drop, size_of, ManuallyDrop, MaybeUninit},
8    ptr::{self, NonNull},
9};
10
11#[cfg(feature = "alloc")]
12use allocator_api2::alloc::Global;
13
14use crate::{
15    api::BlinkAllocator,
16    cold,
17    drop_list::{DropItem, DropList},
18    in_place,
19};
20
21#[cfg(not(no_global_oom_handling))]
22use crate::ResultExt;
23
24#[cfg(feature = "alloc")]
25use crate::local::BlinkAlloc;
26
27#[cfg(not(no_global_oom_handling))]
28use crate::oom::{handle_alloc_error, size_overflow};
29
30type EmplaceType<T, E> = Result<T, ManuallyDrop<E>>;
31type EmplaceSlot<T, E> = MaybeUninit<EmplaceType<T, E>>;
32
33pub trait CoerceFromMut<'a, T: ?Sized> {
34    fn coerce(t: &'a mut T) -> Self;
35}
36
37impl<'a, T: ?Sized> CoerceFromMut<'a, T> for &'a mut T {
38    #[inline(always)]
39    fn coerce(t: &'a mut T) -> Self {
40        t
41    }
42}
43
44impl<'a, T: ?Sized> CoerceFromMut<'a, T> for &'a T {
45    #[inline(always)]
46    fn coerce(t: &'a mut T) -> Self {
47        t
48    }
49}
50
51/// Iterator extension trait for collecting iterators into blink allocator.
52///
53/// # Examples
54///
55/// ```
56/// # #[cfg(feature = "alloc")] fn main() {
57/// # use blink_alloc::{Blink, IteratorExt};
58/// let mut blink = Blink::new();
59/// let slice = (0..10).filter(|x| x % 3 != 0).collect_to_blink(&mut blink);
60/// assert_eq!(slice, [1, 2, 4, 5, 7, 8]);
61/// slice[0] = 10;
62/// assert_eq!(slice, [10, 2, 4, 5, 7, 8]);
63/// # }
64/// # #[cfg(not(feature = "alloc"))] fn main() {}
65/// ```
66///
67/// For non-static data with drop.
68///
69/// ```
70/// # #[cfg(feature = "alloc")] fn main() {
71/// # use blink_alloc::{Blink, IteratorExt};
72/// let mut blink = Blink::new();
73/// let slice = (0..10).filter(|x| x % 3 != 0).collect_to_blink_shared(&mut blink);
74/// assert_eq!(slice, [1, 2, 4, 5, 7, 8]);
75/// # }
76/// # #[cfg(not(feature = "alloc"))] fn main() {}
77/// ```
78///
79/// For non-static data and no drop.
80///
81/// ```
82/// # #[cfg(feature = "alloc")] fn main() {
83/// # use blink_alloc::{Blink, IteratorExt};
84/// let mut blink = Blink::new();
85/// let slice = (0..10).filter(|x| x % 3 != 0).collect_to_blink_no_drop(&mut blink);
86/// assert_eq!(slice, [1, 2, 4, 5, 7, 8]);
87/// slice[0] = 10;
88/// assert_eq!(slice, [10, 2, 4, 5, 7, 8]);
89/// # }
90/// # #[cfg(not(feature = "alloc"))] fn main() {}
91/// ```
92pub trait IteratorExt: Iterator {
93    /// Collect iterator into blink allocator and return slice reference.
94    #[cfg(not(no_global_oom_handling))]
95    #[inline(always)]
96    fn collect_to_blink<A: BlinkAllocator>(self, blink: &mut Blink<A>) -> &mut [Self::Item]
97    where
98        Self: Sized,
99        Self::Item: 'static,
100    {
101        blink.emplace().from_iter(self)
102    }
103
104    /// Collect iterator into blink allocator and return slice reference.
105    #[cfg(not(no_global_oom_handling))]
106    #[inline(always)]
107    fn collect_to_blink_shared<A: BlinkAllocator>(self, blink: &mut Blink<A>) -> &[Self::Item]
108    where
109        Self: Sized,
110    {
111        blink.emplace_shared().from_iter(self)
112    }
113
114    /// Collect iterator into blink allocator and return slice reference.
115    #[cfg(not(no_global_oom_handling))]
116    #[inline(always)]
117    fn collect_to_blink_no_drop<A: BlinkAllocator>(self, blink: &mut Blink<A>) -> &mut [Self::Item]
118    where
119        Self: Sized,
120    {
121        blink.emplace_no_drop().from_iter(self)
122    }
123
124    /// Attempts to collect iterator into blink allocator and return slice reference.
125    #[inline(always)]
126    #[allow(clippy::type_complexity)]
127    fn try_collect_to_blink<A: BlinkAllocator>(
128        self,
129        blink: &mut Blink<A>,
130    ) -> Result<&mut [Self::Item], (&mut [Self::Item], Option<Self::Item>)>
131    where
132        Self: Sized,
133        Self::Item: 'static,
134    {
135        blink.emplace().try_from_iter(self)
136    }
137
138    /// Attempts to collect iterator into blink allocator and return slice reference.
139    #[inline(always)]
140    #[allow(clippy::type_complexity)]
141    fn try_collect_to_blink_shared<A: BlinkAllocator>(
142        self,
143        blink: &mut Blink<A>,
144    ) -> Result<&[Self::Item], (&[Self::Item], Option<Self::Item>)>
145    where
146        Self: Sized,
147    {
148        blink.emplace_shared().try_from_iter(self)
149    }
150
151    /// Attempts to collect iterator into blink allocator and return slice reference.
152    #[inline(always)]
153    #[allow(clippy::type_complexity)]
154    fn try_collect_to_blink_no_drop<A: BlinkAllocator>(
155        self,
156        blink: &mut Blink<A>,
157    ) -> Result<&mut [Self::Item], (&mut [Self::Item], Option<Self::Item>)>
158    where
159        Self: Sized,
160    {
161        blink.emplace_no_drop().try_from_iter(self)
162    }
163}
164
165impl<I> IteratorExt for I where I: Iterator {}
166
167switch_alloc_default! {
168    /// An allocator adaptor for designed for blink allocator.
169    /// Provides user-friendly methods to emplace values into allocated memory.
170    /// Supports emplace existing, constructing value in allocated memory directly or indirectly.
171    /// And also emplacing items yield from iterator into contiguous memory and returning slice reference.
172    ///
173    /// [`Blink`] calls [`Drop::drop`] for emplaced values when reset or dropped.
174    /// This allows to use [`Blink`] instead of collections in some scenarios without needing to enable [`allocation_api`] feature.
175    ///
176    /// A blink-allocator adapter for user-friendly safe allocations
177    /// without use of collections.
178    ///
179    /// Provides an ability to emplace values into allocated memory,
180    /// baked by the associated blink-allocator instance.
181    /// And returns mutable reference to the value.
182    /// Values can be emplaced by move, by construction in allocated memory
183    /// (when compiler likes us), from iterators etc.
184    /// Most operations are provided in two flavors:
185    /// `try_` prefixed methods returns `Result` with allocation errors.
186    /// And non-prefixed methods calls [`handle_alloc_error`] method
187    /// (unless "alloc" feature is not enabled, in this case it panics).
188    /// Non-prefixed methods require "no_global_oom_handling" feature cfg is disabled.
189    ///
190    /// [`Blink`] can be reset by calling `reset` method.
191    /// It drops all emplaced values and resets associated allocator instance.
192    /// If allocator instance is shared, resetting it will have no effect.
193    ///
194    /// [`handle_alloc_error`]: alloc::alloc::handle_alloc_error
195    /// [`allocation_api`]: https://doc.rust-lang.org/beta/unstable-book/library-features/allocator-api.html
196    pub struct Blink<A = +BlinkAlloc<Global>> {
197        drop_list: DropList,
198        alloc: A,
199    }
200}
201
202// Safety: `Blink` is not auto-send because of `DropList`.
203// The `DropList` contains pointers to objects allocated from `Blink`.
204// If `Blink` is moved to another thread (or `&mut Blink`) then all returned pointers
205// to allocated objects were invalidated.
206unsafe impl<A> Send for Blink<A> where A: Send {}
207
208impl<A> Default for Blink<A>
209where
210    A: Default,
211{
212    fn default() -> Self {
213        Blink::new_in(Default::default())
214    }
215}
216
217#[cfg(feature = "alloc")]
218impl Blink<BlinkAlloc<Global>> {
219    /// Creates new blink instance with `BlinkAlloc` baked by `Global`
220    /// allocator.
221    ///
222    /// # Examples
223    ///
224    /// ```
225    /// use blink_alloc::Blink;
226    /// let mut blink = Blink::new();
227    ///
228    /// blink.put(42);
229    /// ```
230    #[inline(always)]
231    pub const fn new() -> Self {
232        Blink::new_in(BlinkAlloc::new())
233    }
234
235    /// Creates new blink instance with `BlinkAlloc` baked by `Global`
236    /// allocator.
237    /// `BlinkAlloc` receives starting chunk size.
238    ///
239    /// # Examples
240    ///
241    /// ```
242    /// use blink_alloc::Blink;
243    /// let mut blink = Blink::with_chunk_size(16);
244    ///
245    /// blink.put(42);
246    #[inline(always)]
247    pub const fn with_chunk_size(capacity: usize) -> Self {
248        Blink::new_in(BlinkAlloc::with_chunk_size(capacity))
249    }
250}
251
252impl<A> Blink<A> {
253    /// Creates new blink instance with provided allocator instance.
254    #[inline(always)]
255    pub const fn new_in(alloc: A) -> Self {
256        Blink {
257            drop_list: DropList::new(),
258            alloc,
259        }
260    }
261
262    /// Returns reference to allocator instance.
263    #[inline(always)]
264    pub fn allocator(&self) -> &A {
265        &self.alloc
266    }
267
268    /// Drops all allocated values.
269    ///
270    /// Prefer to use `reset` method if associated allocator instance supports it.
271    #[inline(always)]
272    pub fn drop_all(&mut self) {
273        self.drop_list.reset();
274    }
275}
276
277impl<A> Blink<A>
278where
279    A: BlinkAllocator,
280{
281    /// Drops all allocated values.
282    /// And resets associated allocator instance.
283    #[inline(always)]
284    pub fn reset(&mut self) {
285        self.drop_list.reset();
286        self.alloc.reset();
287    }
288
289    /// Allocates memory for a copy of the slice.
290    /// If allocation fails, returns `Err`.
291    /// Otherwise copies the slice into the allocated memory and returns
292    /// mutable reference to the copy.
293    #[inline]
294    unsafe fn _try_copy_slice<'a, T, E>(
295        &'a self,
296        slice: &[T],
297        alloc_err: impl FnOnce(Layout) -> E,
298    ) -> Result<&'a mut [T], E>
299    where
300        T: Copy,
301    {
302        let layout = Layout::for_value(slice);
303        let Ok(ptr) = self.alloc.allocate(layout) else {
304            return Err(alloc_err(layout));
305        };
306
307        let ptr = ptr.as_ptr().cast();
308        core::ptr::copy_nonoverlapping(slice.as_ptr(), ptr, slice.len());
309        Ok(core::slice::from_raw_parts_mut(ptr, slice.len()))
310    }
311
312    unsafe fn _try_emplace_drop<'a, T, I, G: 'a, E>(
313        &'a self,
314        init: I,
315        f: impl FnOnce(&mut EmplaceSlot<T, G>, I),
316        err: impl FnOnce(G) -> E,
317        alloc_err: impl FnOnce(I, Layout) -> E,
318    ) -> Result<&'a mut T, E> {
319        let layout = Layout::new::<DropItem<Result<T, ManuallyDrop<E>>>>();
320
321        let Ok(ptr) = self.alloc.allocate(layout) else {
322            return Err(alloc_err(init, layout));
323        };
324
325        // Safety: `item_ptr` is a valid pointer to allocated memory for type `DropItem<T>`.
326        let item = unsafe { DropItem::init_value(ptr.cast(), init, f) };
327
328        if item.value.is_ok() {
329            match self.drop_list.add(item) {
330                Ok(value) => return Ok(value),
331                _ => unreachable!(),
332            }
333        }
334
335        match &mut item.value {
336            Err(g) => {
337                let err = err(unsafe { ManuallyDrop::take(g) });
338                // Give memory back.
339                self.alloc.deallocate(ptr.cast(), layout);
340                Err(err)
341            }
342            _ => unreachable!(),
343        }
344    }
345
346    unsafe fn _try_emplace_no_drop<'a, T, I, G: 'a, E>(
347        &self,
348        init: I,
349        f: impl FnOnce(&mut EmplaceSlot<T, G>, I),
350        err: impl FnOnce(G) -> E,
351        alloc_err: impl FnOnce(I, Layout) -> E,
352    ) -> Result<&'a mut T, E> {
353        let layout = Layout::new::<T>();
354        let Ok(ptr) = self.alloc.allocate(layout) else {
355            return Err(alloc_err(init, layout));
356        };
357
358        // Safety: `ptr` is a valid pointer to allocated memory.
359        // Allocated with this `T`'s layout.
360        // Duration of the allocation is until next call to [`BlinkAlloc::reset`].
361
362        let uninit = &mut *ptr.as_ptr().cast();
363        f(uninit, init);
364
365        match uninit.assume_init_mut() {
366            Ok(value) => Ok(value),
367            Err(g) => {
368                let err = err(unsafe { ManuallyDrop::take(g) });
369                // Give memory back.
370                self.alloc.deallocate(ptr.cast(), layout);
371                Err(err)
372            }
373        }
374    }
375
376    /// Allocates memory for a value and emplaces value into the memory
377    /// using init value and provided closure.
378    /// If allocation fails, returns `Err(init)`.
379    /// Otherwise calls closure consuming `init`
380    /// and initializes memory with closure result.
381    #[inline(always)]
382    unsafe fn _try_emplace<'a, T, I, G: 'a, E>(
383        &'a self,
384        init: I,
385        f: impl FnOnce(&mut EmplaceSlot<T, G>, I),
386        no_drop: bool,
387        err: impl FnOnce(G) -> E,
388        alloc_err: impl FnOnce(I, Layout) -> E,
389    ) -> Result<&'a mut T, E> {
390        if !needs_drop::<T>() || no_drop {
391            self._try_emplace_no_drop(init, f, err, alloc_err)
392        } else {
393            self._try_emplace_drop(init, f, err, alloc_err)
394        }
395    }
396
397    unsafe fn _try_emplace_drop_from_iter<'a, T: 'a, I, E>(
398        &'a self,
399        mut iter: I,
400        err: impl FnOnce(&'a mut [T], Option<T>, Option<Layout>) -> E,
401    ) -> Result<&'a mut [T], E>
402    where
403        I: Iterator<Item = T>,
404    {
405        if size_of::<T>() == 0 {
406            let item_layout = Layout::new::<DropItem<[T; 0]>>();
407            let Ok(ptr) = self.alloc.allocate(item_layout) else {
408                return Err(err(&mut [], None, Some(item_layout)));
409            };
410            // Drain elements from iterator.
411            // Stop at `usize::MAX`.
412            // Drop exactly this number of elements on reset.
413            let count = saturating_drain_iter(iter);
414            let (item, slice) = DropItem::init_slice(ptr.cast(), count);
415            self.drop_list.add(item);
416            return Ok(slice);
417        }
418
419        struct Guard<'a, T: 'a, A: BlinkAllocator> {
420            ptr: Option<NonNull<DropItem<[T; 0]>>>,
421            count: usize,
422            cap: usize,
423            layout: Layout,
424            alloc: &'a A,
425            drop_list: &'a DropList,
426        }
427
428        impl<'a, T, A> Drop for Guard<'a, T, A>
429        where
430            A: BlinkAllocator,
431        {
432            #[inline(always)]
433            fn drop(&mut self) {
434                self.flush();
435            }
436        }
437
438        impl<'a, T, A> Guard<'a, T, A>
439        where
440            A: BlinkAllocator,
441        {
442            #[inline(always)]
443            fn flush(&mut self) -> &'a mut [T] {
444                match self.ptr.take() {
445                    Some(ptr) if self.count != 0 => {
446                        // if self.count < self.cap {
447                        //     // shrink the allocation to the actual size.
448                        //     // `BlinkAllocator` guarantees that this will not fail
449                        //     // be a no-op.
450
451                        //     let item_layout = Layout::new::<DropItem<[T; 0]>>();
452
453                        //     let (new_layout, _) = Layout::array::<T>(self.count)
454                        //         .and_then(|array| item_layout.extend(array))
455                        //         .expect("Smaller than actual allocation");
456
457                        //     // Safety:
458                        //     // Shrinking the allocation to the actual used size.
459                        //     let new_ptr =
460                        //         unsafe { self.alloc.shrink(ptr.cast(), self.layout, new_layout) }
461                        //             .expect("BlinkAllocator guarantees this will succeed");
462
463                        //     ptr = new_ptr.cast();
464                        // }
465
466                        // Safety: `item` was properly initialized.
467                        let (item, slice) = unsafe { DropItem::init_slice(ptr, self.count) };
468                        unsafe {
469                            self.drop_list.add(item);
470                        }
471                        slice
472                    }
473                    Some(ptr) => unsafe {
474                        self.alloc.deallocate(ptr.cast(), self.layout);
475                        &mut []
476                    },
477                    None => &mut [],
478                }
479            }
480
481            #[inline(always)]
482            fn fill(
483                &mut self,
484                size_hint: usize,
485                one_more_elem: &mut Option<T>,
486                iter: &mut impl Iterator<Item = T>,
487            ) -> Result<(), Option<Layout>> {
488                let Ok(array_layout) = Layout::array::<T>(size_hint) else {
489                    return Err(None);
490                };
491
492                let item_layout = Layout::new::<DropItem<[T; 0]>>();
493                let Ok((full_layout, array_offset)) = item_layout.extend(array_layout) else {
494                    return Err(None);
495                };
496
497                debug_assert_eq!(array_offset, size_of::<DropItem<[T; 0]>>());
498
499                let res = match self.ptr {
500                    None => self.alloc.allocate(full_layout),
501                    Some(ptr) => unsafe { self.alloc.grow(ptr.cast(), self.layout, full_layout) },
502                };
503
504                let Ok(ptr) = res else {
505                    return Err(Some(full_layout));
506                };
507                self.layout = full_layout;
508
509                let item_ptr = ptr.cast();
510                self.ptr = Some(item_ptr);
511
512                let len = ptr.len();
513                if len > full_layout.size() {
514                    self.cap = (len - size_of::<DropItem<[T; 0]>>()) / size_of::<T>()
515                } else {
516                    debug_assert_eq!(len, full_layout.size());
517                    self.cap = size_hint;
518                };
519
520                let array_ptr = unsafe { item_ptr.as_ptr().add(1).cast::<T>() };
521
522                if let Some(one_more_elem) = one_more_elem.take() {
523                    debug_assert!(self.count < self.cap);
524
525                    // Safety: `array_ptr` is a valid pointer to allocated memory for type `[T; hint]`.
526                    // And `hint` is larger than `self.count`
527                    unsafe {
528                        ptr::write(array_ptr.add(self.count), one_more_elem);
529                    }
530                    self.count += 1;
531                }
532
533                for idx in self.count..self.cap {
534                    if Layout::new::<Option<T>>() == Layout::new::<T>() {
535                        // Putting elements directly into the array.
536
537                        let elem = unsafe {
538                            in_place(array_ptr.add(idx).cast(), &mut *iter, Iterator::next)
539                        };
540
541                        if elem.is_none() {
542                            break;
543                        }
544                    } else {
545                        match iter.next() {
546                            None => break,
547                            Some(elem) => unsafe { ptr::write(array_ptr.add(idx), elem) },
548                        }
549                    }
550                    self.count = idx + 1;
551                }
552
553                Ok(())
554            }
555        }
556
557        let mut guard = Guard {
558            ptr: None,
559            count: 0,
560            cap: 0,
561            layout: Layout::new::<()>(),
562            alloc: &self.alloc,
563            drop_list: &self.drop_list,
564        };
565
566        let (lower, _) = iter.size_hint();
567
568        if lower != 0 {
569            if let Err(layout) = guard.fill(lower.max(FASTER_START), &mut None, &mut iter) {
570                return Err(err(guard.flush(), None, layout));
571            }
572        }
573
574        let mut one_more = iter.next();
575        if one_more.is_none() {
576            return Ok(guard.flush());
577        };
578        cold();
579
580        loop {
581            let (lower, upper) = iter.size_hint();
582            let Some(size_hint) = size_hint_and_one(lower, upper, guard.count.max(FASTER_START)) else {
583                return Err(err(guard.flush(), one_more, None));
584            };
585
586            if let Err(layout) = guard.fill(size_hint, &mut one_more, &mut iter) {
587                return Err(err(guard.flush(), one_more, layout));
588            }
589
590            one_more = iter.next();
591            if one_more.is_none() {
592                return Ok(guard.flush());
593            };
594        }
595    }
596
597    unsafe fn _try_emplace_no_drop_from_iter<'a, T: 'a, I, E>(
598        &'a self,
599        mut iter: I,
600        err: impl FnOnce(&'a mut [T], Option<T>, Option<Layout>) -> E,
601    ) -> Result<&'a mut [T], E>
602    where
603        I: Iterator<Item = T>,
604    {
605        if size_of::<T>() == 0 {
606            // Drain elements from iterator.
607            // Stop at `usize::MAX`.
608            // Drop exactly this number of elements on reset.
609            let count = saturating_drain_iter(iter);
610            let ptr = NonNull::<T>::dangling();
611            let slice = core::slice::from_raw_parts_mut(ptr.as_ptr(), count);
612            return Ok(slice);
613        }
614
615        struct Guard<'a, T: 'a, A: BlinkAllocator> {
616            ptr: Option<NonNull<T>>,
617            count: usize,
618            cap: usize,
619            layout: Layout,
620            alloc: &'a A,
621        }
622
623        impl<'a, T, A> Guard<'a, T, A>
624        where
625            A: BlinkAllocator,
626        {
627            #[inline(always)]
628            fn flush(&mut self) -> &'a mut [T] {
629                match self.ptr.take() {
630                    Some(ptr) if self.count != 0 => {
631                        // if self.count < self.cap {
632                        //     // shrink the allocation to the actual size.
633                        //     // `BlinkAllocator` guarantees that this will not fail
634                        //     // be a no-op.
635
636                        //     let new_layout = Layout::array::<T>(self.count)
637                        //         .expect("Smaller than actual allocation");
638
639                        //     // Safety:
640                        //     // Shrinking the allocation to the actual used size.
641                        //     let new_ptr =
642                        //         unsafe { self.alloc.shrink(ptr.cast(), self.layout, new_layout) }
643                        //             .expect("BlinkAllocator guarantees this will succeed");
644
645                        //     ptr = new_ptr.cast();
646                        // }
647
648                        // Safety: reallocated for slice of size `self.count`
649                        unsafe { &mut *core::slice::from_raw_parts_mut(ptr.as_ptr(), self.count) }
650                    }
651                    Some(ptr) => {
652                        unsafe { self.alloc.deallocate(ptr.cast(), self.layout) };
653                        &mut []
654                    }
655                    None => &mut [],
656                }
657            }
658
659            #[inline(always)]
660            fn fill(
661                &mut self,
662                size_hint: usize,
663                one_more_elem: &mut Option<T>,
664                iter: &mut impl Iterator<Item = T>,
665            ) -> Result<(), Option<Layout>> {
666                let Ok(full_layout) = Layout::array::<T>(size_hint) else {
667                    return Err(None);
668                };
669
670                let res = match self.ptr {
671                    None => self.alloc.allocate(full_layout),
672                    Some(ptr) => unsafe { self.alloc.grow(ptr.cast(), self.layout, full_layout) },
673                };
674
675                let Ok(ptr) = res else {
676                    return Err(Some(full_layout));
677                };
678
679                self.layout = full_layout;
680                self.ptr = Some(ptr.cast());
681
682                let len = ptr.len();
683                if len > full_layout.size() {
684                    self.cap = len / size_of::<T>()
685                } else {
686                    debug_assert_eq!(len, full_layout.size());
687                    self.cap = size_hint;
688                };
689
690                let array_ptr = ptr.as_ptr().cast::<T>();
691
692                if let Some(one_more_elem) = one_more_elem.take() {
693                    debug_assert!(self.count < self.cap);
694
695                    // Safety: `array_ptr` is a valid pointer to allocated memory for type `[T; hint]`.
696                    // And `hint` is larger than `self.count`
697                    unsafe {
698                        ptr::write(array_ptr.add(self.count), one_more_elem);
699                    }
700                    self.count += 1;
701                }
702
703                for idx in self.count..size_hint {
704                    if Layout::new::<Option<T>>() == Layout::new::<T>() {
705                        // Putting elements directly into the array.
706                        let elem = unsafe {
707                            in_place(array_ptr.add(idx).cast(), &mut *iter, Iterator::next)
708                        };
709                        if elem.is_none() {
710                            break;
711                        }
712                    } else {
713                        match iter.next() {
714                            None => break,
715                            Some(elem) => unsafe { ptr::write(array_ptr.add(idx), elem) },
716                        }
717                    }
718                    self.count = idx + 1;
719                }
720
721                Ok(())
722            }
723        }
724
725        let mut guard = Guard {
726            ptr: None,
727            count: 0,
728            cap: 0,
729            layout: Layout::new::<T>(),
730            alloc: &self.alloc,
731        };
732
733        let (lower, _) = iter.size_hint();
734
735        if lower != 0 {
736            if let Err(layout) = guard.fill(lower.max(FASTER_START), &mut None, &mut iter) {
737                return Err(err(guard.flush(), None, layout));
738            }
739        }
740
741        let mut one_more = iter.next();
742        if one_more.is_none() {
743            return Ok(guard.flush());
744        };
745        cold();
746
747        loop {
748            let (lower, upper) = iter.size_hint();
749            let Some(size_hint) = size_hint_and_one(lower, upper, guard.count.max(FASTER_START)) else {
750                return Err(err(guard.flush(), one_more, None));
751            };
752
753            if let Err(layout) = guard.fill(size_hint, &mut one_more, &mut iter) {
754                return Err(err(guard.flush(), one_more, layout));
755            }
756
757            one_more = iter.next();
758            if one_more.is_none() {
759                return Ok(guard.flush());
760            };
761        }
762    }
763
764    /// Allocates memory for a value and emplaces value into the memory
765    /// using init value and provided closure.
766    /// If allocation fails, returns `Err(init)`.
767    /// Otherwise calls closure consuming `init`
768    /// and initializes memory with closure result.
769    #[inline(always)]
770    unsafe fn _try_emplace_from_iter<'a, T: 'a, I, E>(
771        &'a self,
772        iter: I,
773        no_drop: bool,
774        err: impl FnOnce(&'a mut [T], Option<T>, Option<Layout>) -> E,
775    ) -> Result<&mut [T], E>
776    where
777        I: IntoIterator<Item = T>,
778    {
779        if !needs_drop::<T>() || no_drop {
780            self._try_emplace_no_drop_from_iter(iter.into_iter(), err)
781        } else {
782            self._try_emplace_drop_from_iter(iter.into_iter(), err)
783        }
784    }
785}
786
787/// Provides interface for emplacing values.
788/// Created by [`Blink::emplace`], [`Blink::emplace_no_drop`]
789/// and [`Blink::emplace_unchecked`].
790pub struct Emplace<'a, A, T, R = &'a mut T, S = &'a mut [T]> {
791    blink: &'a Blink<A>,
792    no_drop: bool,
793    marker: PhantomData<fn(T) -> (R, S)>,
794}
795
796impl<'a, A, T, R, S> Emplace<'a, A, T, R, S>
797where
798    A: BlinkAllocator,
799    T: 'a,
800    R: CoerceFromMut<'a, T>,
801    S: CoerceFromMut<'a, [T]>,
802{
803    /// Allocates memory for a value and moves `value` into the memory.
804    /// If allocation fails, returns `Err(value)`.
805    /// On success returns reference to the emplaced value.
806    #[inline(always)]
807    pub fn try_value(&self, value: T) -> Result<R, T> {
808        unsafe {
809            self.blink._try_emplace(
810                value,
811                |slot, value| {
812                    slot.write(Ok::<_, ManuallyDrop<Infallible>>(value));
813                },
814                self.no_drop,
815                |never| match never {},
816                |init, _| init,
817            )
818        }
819        .map(R::coerce)
820    }
821
822    /// Allocates memory for a value and moves `value` into the memory.
823    /// Returns reference to the emplaced value.
824    /// If allocation fails, diverges.
825    #[cfg(not(no_global_oom_handling))]
826    #[inline(always)]
827    pub fn value(&self, value: T) -> R {
828        R::coerce(
829            unsafe {
830                self.blink._try_emplace(
831                    value,
832                    |slot, value| {
833                        slot.write(Ok::<_, ManuallyDrop<Infallible>>(value));
834                    },
835                    self.no_drop,
836                    identity,
837                    |_, layout| handle_alloc_error(layout),
838                )
839            }
840            .safe_ok(),
841        )
842    }
843
844    /// Allocates memory for a value.
845    /// On success invokes closure and initialize the value.
846    /// Returns reference to the value.
847    /// If allocation fails, returns error with closure.
848    #[inline(always)]
849    pub fn try_with<F>(&self, f: F) -> Result<R, F>
850    where
851        F: FnOnce() -> T,
852    {
853        unsafe {
854            self.blink._try_emplace(
855                f,
856                |slot, f| {
857                    slot.write(Ok::<_, ManuallyDrop<Infallible>>(f()));
858                },
859                self.no_drop,
860                never,
861                |f, _| f,
862            )
863        }
864        .map(R::coerce)
865    }
866
867    /// Allocates memory for a value.
868    /// On success invokes closure and initialize the value.
869    /// Returns reference to the value.
870    /// If allocation fails, diverges.
871    #[cfg(not(no_global_oom_handling))]
872    #[inline(always)]
873    pub fn with<F>(&self, f: F) -> R
874    where
875        F: FnOnce() -> T,
876    {
877        R::coerce(
878            unsafe {
879                self.blink._try_emplace(
880                    f,
881                    |slot, f| {
882                        slot.write(Ok::<_, ManuallyDrop<Infallible>>(f()));
883                    },
884                    self.no_drop,
885                    never,
886                    |_, layout| handle_alloc_error(layout),
887                )
888            }
889            .safe_ok(),
890        )
891    }
892    /// Allocates memory for a value.
893    /// If allocation fails, returns error with closure.
894    /// On success invokes closure and initialize the value.
895    /// If closure fails, returns the error.
896    /// Returns reference to the value.
897    #[inline(always)]
898    pub fn try_with_fallible<F, E>(&self, f: F) -> Result<R, Result<E, F>>
899    where
900        F: FnOnce() -> Result<T, E>,
901        E: 'a,
902    {
903        unsafe {
904            self.blink._try_emplace(
905                f,
906                |slot, f| {
907                    slot.write(f().map_err(ManuallyDrop::new));
908                },
909                self.no_drop,
910                |err| Ok(err),
911                |f, _| Err(f),
912            )
913        }
914        .map(R::coerce)
915    }
916
917    /// Allocates memory for a value.
918    /// If allocation fails, returns error with closure.
919    /// On success invokes closure and initialize the value.
920    /// If closure fails, returns the error.
921    /// Returns reference to the value.
922    #[cfg(not(no_global_oom_handling))]
923    #[inline(always)]
924    pub fn with_fallible<F, E>(&self, f: F) -> Result<R, E>
925    where
926        F: FnOnce() -> Result<T, E>,
927        E: 'a,
928    {
929        unsafe {
930            self.blink._try_emplace(
931                f,
932                |slot, f| {
933                    slot.write(f().map_err(ManuallyDrop::new));
934                },
935                self.no_drop,
936                identity,
937                |_, layout| handle_alloc_error(layout),
938            )
939        }
940        .map(R::coerce)
941    }
942
943    /// Allocates memory for an array and initializes it with
944    /// values from iterator.
945    /// Uses iterator hints to allocate memory.
946    /// If iterator yields more values than allocated array can hold,
947    /// grows allocation and moves next values to extended array.
948    /// Repeats until iterator is exhausted.
949    /// Works best on iterators that report accurate upper size hint.
950    /// Grows allocated memory potentially reducing number of allocations
951    /// and copies.
952    /// If allocation fails, returns slice of values emplaced so far.
953    /// And one element that was taken from iterator and not emplaced.
954    #[inline(always)]
955    pub fn try_from_iter<I>(&self, iter: I) -> Result<S, (S, Option<T>)>
956    where
957        I: IntoIterator<Item = T>,
958    {
959        unsafe {
960            self.blink
961                ._try_emplace_from_iter(iter, self.no_drop, |slice: &'a mut [T], value, _| {
962                    (S::coerce(slice), value)
963                })
964        }
965        .map(S::coerce)
966    }
967
968    /// Allocates memory for an array and initializes it with
969    /// values from iterator.
970    /// Uses iterator hints to allocate memory.
971    /// If iterator yields more values than allocated array can hold,
972    /// grows allocation and moves next values to extended array.
973    /// Repeats until iterator is exhausted.
974    /// Works best on iterators that report accurate upper size hint.
975    /// Grows allocated memory potentially reducing number of allocations
976    /// and copies.
977    /// If allocation fails, diverges.
978    /// Values already emplaced will be dropped.
979    /// One last value that was taken from iterator and not emplaced
980    /// is dropped before this method returns.
981    #[cfg(not(no_global_oom_handling))]
982    #[inline(always)]
983    pub fn from_iter<I>(&self, iter: I) -> S
984    where
985        I: Iterator<Item = T>,
986    {
987        S::coerce(
988            unsafe {
989                self.blink
990                    ._try_emplace_from_iter(iter, self.no_drop, |_, _, layout| match layout {
991                        Some(layout) => handle_alloc_error(layout),
992                        None => size_overflow(),
993                    })
994            }
995            .safe_ok(),
996        )
997    }
998}
999
1000impl<A> Blink<A>
1001where
1002    A: BlinkAllocator,
1003{
1004    /// Puts value into this `Blink` instance.
1005    /// Returns reference to the value.
1006    ///
1007    /// Effectively extends lifetime of the value
1008    /// from local scope to the reset scope.
1009    ///
1010    /// For more flexible value placement see
1011    /// [`Blink::emplace`], [`Blink::emplace_no_drop`] and
1012    /// [`Blink::emplace_unchecked`].
1013    ///
1014    /// # Example
1015    ///
1016    /// ```
1017    /// # #[cfg(feature = "alloc")] fn main() {
1018    /// # use blink_alloc::Blink;
1019    /// let mut blink = Blink::new();
1020    /// let foo = blink.put(42);
1021    /// assert_eq!(*foo, 42);
1022    /// *foo = 24;
1023    /// blink.reset();
1024    /// // assert_eq!(*foo, 24); // Cannot compile. `foo` does not outlive reset.
1025    /// # }
1026    /// # #[cfg(not(feature = "alloc"))] fn main() {}
1027    /// ```
1028    #[cfg(not(no_global_oom_handling))]
1029    #[inline(always)]
1030    #[allow(clippy::mut_from_ref)]
1031    pub fn put<T: 'static>(&self, value: T) -> &mut T {
1032        unsafe {
1033            self._try_emplace(
1034                value,
1035                |slot, value| {
1036                    slot.write(Ok::<_, ManuallyDrop<Infallible>>(value));
1037                },
1038                false,
1039                identity,
1040                |_, layout| handle_alloc_error(layout),
1041            )
1042        }
1043        .safe_ok()
1044    }
1045
1046    /// Puts value into this `Blink` instance.
1047    /// Returns reference to the value.
1048    ///
1049    /// The value will not be dropped when `Blink` is reset.
1050    ///
1051    /// Effectively extends lifetime of the value
1052    /// from local scope to the reset scope.
1053    ///
1054    /// For more flexible value placement see
1055    /// [`Blink::emplace`], [`Blink::emplace_no_drop`] and
1056    /// [`Blink::emplace_unchecked`].
1057    ///
1058    /// # Example
1059    ///
1060    /// ```
1061    /// # #[cfg(feature = "alloc")] fn main() {
1062    /// # use blink_alloc::Blink;
1063    /// let mut blink = Blink::new();
1064    /// let foo = blink.put(42);
1065    /// assert_eq!(*foo, 42);
1066    /// *foo = 24;
1067    /// blink.reset();
1068    /// // assert_eq!(*foo, 24); // Cannot compile. `foo` does not outlive reset.
1069    /// # }
1070    /// # #[cfg(not(feature = "alloc"))] fn main() {}
1071    /// ```
1072    #[cfg(not(no_global_oom_handling))]
1073    #[inline(always)]
1074    #[allow(clippy::mut_from_ref)]
1075    pub fn put_no_drop<T>(&self, value: T) -> &mut T {
1076        unsafe {
1077            self._try_emplace(
1078                value,
1079                |slot, value| {
1080                    slot.write(Ok::<_, ManuallyDrop<Infallible>>(value));
1081                },
1082                true,
1083                identity,
1084                |_, layout| handle_alloc_error(layout),
1085            )
1086        }
1087        .safe_ok()
1088    }
1089
1090    /// Allocates memory for a value.
1091    /// Returns some reference to the uninitialized value.
1092    /// If allocation fails, returns none.
1093    #[inline(always)]
1094    pub fn try_uninit<T>(&self) -> Option<&mut MaybeUninit<T>> {
1095        let layout = Layout::new::<T>();
1096        let ptr = self.alloc.allocate(layout).ok()?;
1097
1098        // Safety:
1099        // - `ptr` is valid for `layout`.
1100        // - `MaybeUninit` is always initialized.
1101        Some(unsafe { &mut *ptr.as_ptr().cast() })
1102    }
1103
1104    /// Allocates memory for a value.
1105    /// Returns reference to the uninitialized value.
1106    #[cfg(not(no_global_oom_handling))]
1107    #[inline(always)]
1108    #[allow(clippy::mut_from_ref)]
1109    pub fn uninit<T>(&self) -> &mut MaybeUninit<T> {
1110        let layout = Layout::new::<T>();
1111        let ptr = self
1112            .alloc
1113            .allocate(layout)
1114            .unwrap_or_else(|_| handle_alloc_error(layout));
1115
1116        // Safety:
1117        // - `ptr` is valid for `layout`.
1118        // - `MaybeUninit` is always initialized.
1119        unsafe { &mut *ptr.as_ptr().cast() }
1120    }
1121
1122    /// Copies the slice to the allocated memory
1123    /// and returns reference to the new slice.
1124    #[cfg(not(no_global_oom_handling))]
1125    #[inline(always)]
1126    #[allow(clippy::mut_from_ref)]
1127    pub fn copy_slice<T>(&self, slice: &[T]) -> &mut [T]
1128    where
1129        T: Copy,
1130    {
1131        let result = unsafe { self._try_copy_slice(slice, handle_alloc_error) };
1132        match result {
1133            Ok(slice) => slice,
1134            Err(never) => never,
1135        }
1136    }
1137
1138    /// Allocates memory for a copy of the slice.
1139    /// Copies the slice to the allocated memory
1140    /// and returns reference to the new slice.
1141    /// If allocation fails, returns `None`.
1142    #[inline(always)]
1143    pub fn try_copy_slice<T>(&self, slice: &[T]) -> Option<&mut [T]>
1144    where
1145        T: Copy,
1146    {
1147        unsafe { self._try_copy_slice(slice, |_| ()) }.ok()
1148    }
1149
1150    /// Copies the slice to the allocated memory
1151    /// and returns reference to the new slice.
1152    #[cfg(not(no_global_oom_handling))]
1153    #[inline(always)]
1154    #[allow(clippy::mut_from_ref)]
1155    pub fn copy_str(&self, string: &str) -> &mut str {
1156        let result = unsafe { self._try_copy_slice(string.as_bytes(), handle_alloc_error) };
1157        match result {
1158            Ok(slice) => unsafe { core::str::from_utf8_unchecked_mut(slice) },
1159            Err(never) => never,
1160        }
1161    }
1162
1163    /// Allocates memory for a copy of the slice.
1164    /// Copies the slice to the allocated memory
1165    /// and returns reference to the new slice.
1166    /// If allocation fails, returns `None`.
1167    #[inline(always)]
1168    pub fn try_copy_str(&self, string: &str) -> Option<&mut str> {
1169        unsafe { self._try_copy_slice(string.as_bytes(), |_| ()) }
1170            .ok()
1171            .map(|bytes| unsafe { core::str::from_utf8_unchecked_mut(bytes) })
1172    }
1173
1174    /// Returns an `Emplace` adaptor that can emplace values into
1175    /// the blink allocator.
1176    ///
1177    /// This version requires the value type to be `'static`.
1178    /// To use with non-static types consider using one of the following:
1179    ///
1180    /// * [`Blink::emplace_no_drop`]
1181    ///   Causes emplaced value to not be dropped on reset.
1182    ///   Avoiding potential unsoundness in `Drop` implementation.
1183    /// * [`Blink::emplace_shared`]
1184    ///   Returns shared reference to emplaced values.
1185    /// * [`Blink::emplace_unchecked`]
1186    ///   Unsafe version of `emplace`.
1187    ///   User must guarantee that the value won't have access to references
1188    ///   allocated by the blink allocator later.
1189    ///
1190    /// # Example
1191    ///
1192    /// ```
1193    /// # #[cfg(feature = "alloc")] fn main() {
1194    /// # use blink_alloc::Blink;
1195    /// let mut blink = Blink::new();
1196    /// let foo = blink.put(42);
1197    /// assert_eq!(*foo, 42);
1198    /// *foo = 24;
1199    /// blink.reset();
1200    /// // assert_eq!(*foo, 24); // Cannot compile. `foo` does not outlive reset.
1201    /// # }
1202    /// # #[cfg(not(feature = "alloc"))] fn main() {}
1203    /// ```
1204    #[inline(always)]
1205    pub fn emplace<T: 'static>(&self) -> Emplace<A, T> {
1206        Emplace {
1207            blink: self,
1208            no_drop: false,
1209            marker: PhantomData,
1210        }
1211    }
1212
1213    /// Returns an `Emplace` adaptor that can emplace values into
1214    /// the blink allocator.
1215    ///
1216    /// This version causes emplaced value to be not-dropped on reset.
1217    /// To drop returned value on reset, consider one of the following:
1218    ///
1219    /// * [`Blink::emplace`]
1220    ///   Requires the value type to be `'static`.
1221    /// * [`Blink::emplace_shared`]
1222    ///   Returns shared reference to emplaced values.
1223    /// * [`Blink::emplace_unchecked`]
1224    ///   Unsafe version of `emplace`.
1225    ///   User must guarantee that the value won't have access to references
1226    ///   allocated by the blink allocator later.
1227    ///
1228    /// # Example
1229    ///
1230    /// ```
1231    /// # #[cfg(feature = "alloc")] fn main() {
1232    /// # use blink_alloc::Blink;
1233    /// struct Foo<'a>(&'a String);
1234    ///
1235    /// impl Drop for Foo<'_> {
1236    ///     fn drop(&mut self) {
1237    ///         println!("{}", self.0);
1238    ///     }
1239    /// }
1240    ///
1241    /// let mut blink = Blink::new();
1242    /// let s = "Hello".to_owned();
1243    /// let foo = blink.emplace_no_drop().value(Foo(&s));
1244    /// assert_eq!(foo.0, "Hello");
1245    /// let world = blink.put("World".to_owned());
1246    /// // Would be unsound if `foo` could be dropped.
1247    /// foo.0 = world;
1248    /// blink.reset();
1249    /// // assert_eq!(foo.0, "Universe"); // Cannot compile. `foo` does not outlive reset.
1250    /// # }
1251    /// # #[cfg(not(feature = "alloc"))] fn main() {}
1252    /// ```
1253    #[inline(always)]
1254    pub fn emplace_no_drop<T>(&self) -> Emplace<A, T> {
1255        Emplace {
1256            blink: self,
1257            no_drop: true,
1258            marker: PhantomData,
1259        }
1260    }
1261
1262    /// Returns an `Emplace` adaptor that can emplace values into
1263    /// the blink allocator.
1264    ///
1265    /// This version returns shared references to emplaced values.
1266    /// Lifts the `'static` requirement.
1267    /// Still allows emplaced values to be dropped on reset.
1268    ///
1269    /// To drop returned value on reset, consider one of the following:
1270    ///
1271    /// * [`Blink::emplace`]
1272    ///   Requires the value type to be `'static`.
1273    /// * [`Blink::emplace_no_drop`]
1274    ///   Causes emplaced value to not be dropped on reset.
1275    ///   Avoiding potential unsoundness in `Drop` implementation.
1276    /// * [`Blink::emplace_unchecked`]
1277    ///   Unsafe version of `emplace`.
1278    ///   User must guarantee that the value won't have access to references
1279    ///   allocated by the blink allocator later.
1280    ///
1281    ///
1282    /// ```
1283    /// # #[cfg(feature = "alloc")] fn main() {
1284    /// # use blink_alloc::Blink;
1285    /// struct Foo<'a>(&'a String);
1286    ///
1287    /// impl Drop for Foo<'_> {
1288    ///     fn drop(&mut self) {
1289    ///         println!("{}", self.0);
1290    ///     }
1291    /// }
1292    ///
1293    /// let mut blink = Blink::new();
1294    /// let s = "Hello".to_owned();
1295    /// let foo = blink.emplace_no_drop().value(Foo(&s));
1296    /// assert_eq!(foo.0, "Hello");
1297    /// let world = blink.put("World".to_owned());
1298    /// // Would be unsound if `foo` was mutable.
1299    /// // foo.0 = world;
1300    /// blink.reset();
1301    /// // assert_eq!(foo.0, "Universe"); // Cannot compile. `foo` does not outlive reset.
1302    /// # }
1303    /// # #[cfg(not(feature = "alloc"))] fn main() {}
1304    /// ```
1305    #[inline(always)]
1306    pub fn emplace_shared<T>(&self) -> Emplace<A, T, &T, &[T]> {
1307        Emplace {
1308            blink: self,
1309            no_drop: true,
1310            marker: PhantomData,
1311        }
1312    }
1313
1314    /// Returns an `Emplace` adaptor that can emplace values into
1315    /// the blink allocator.
1316    ///
1317    /// This is unsafe version of [`Blink::emplace`].
1318    /// User must guarantee that values won't attempt to access
1319    /// memory allocated by the blink allocator later in their [`Drop::drop`]
1320    /// For safe code consider using one of the following:
1321    ///
1322    /// * [`Blink::emplace`]
1323    ///   Requires the value type to be `'static`.
1324    /// * [`Blink::emplace_no_drop`]
1325    ///   Causes emplaced value to not be dropped on reset.
1326    ///   Avoiding potential unsoundness in `Drop` implementation.
1327    /// * [`Blink::emplace_shared`]
1328    ///   Returns shared reference to emplaced values.
1329    ///
1330    /// # Safety
1331    ///
1332    /// Avoid incorrect usage. See below.
1333    ///
1334    /// # Incorrect usage example
1335    ///
1336    /// Other emplace methods are safe as they guarantee following case
1337    /// is impossible.
1338    ///
1339    /// ```no_run
1340    /// # #[cfg(feature = "alloc")] fn main() {
1341    /// # use blink_alloc::Blink;
1342    /// struct Foo<'a>(&'a String);
1343    ///
1344    /// impl Drop for Foo<'_> {
1345    ///     fn drop(&mut self) {
1346    ///         println!("{}", self.0);
1347    ///     }
1348    /// }
1349    ///
1350    /// let mut blink = Blink::new();
1351    /// let s = "Hello".to_owned();
1352    /// let foo = blink.emplace_no_drop().value(Foo(&s));
1353    /// assert_eq!(foo.0, "Hello");
1354    /// let world = blink.put("World".to_owned());
1355    /// // Unsound since `foo` would access `world` in `Drop`
1356    /// // and `world` is dropped earlier.
1357    /// foo.0 = world;
1358    /// blink.reset();
1359    /// // assert_eq!(foo.0, "Universe"); // Cannot compile. `foo` does not outlive reset.
1360    /// # }
1361    /// # #[cfg(not(feature = "alloc"))] fn main() {}
1362    /// ```
1363    #[inline(always)]
1364    pub unsafe fn emplace_unchecked<T>(&self) -> Emplace<A, T> {
1365        Emplace {
1366            blink: self,
1367            no_drop: false,
1368            marker: PhantomData,
1369        }
1370    }
1371}
1372
1373/// Wrapper for [`Blink`] that implements [`Send`].
1374///
1375/// Normally it is impossible to send [`Blink`] to another thread
1376/// due to the fact that it will drop non-sendable types on reset.
1377///
1378/// This wrapper resets [`Blink`] on construction and thus safe to send.
1379///
1380/// # Example
1381///
1382/// ```
1383/// # #[cfg(feature = "alloc")] fn main() {
1384/// # use blink_alloc::{SendBlink, Blink};
1385/// let mut blink = Blink::new();
1386/// let rc = std::rc::Rc::new(42);
1387/// let rc = blink.put(rc);
1388/// assert_eq!(**rc, 42);
1389/// let send_blink = SendBlink::new(blink);
1390///
1391/// std::thread::scope(move |_| {
1392///     let mut blink = send_blink.into_inner();
1393///     blink.put(42);
1394/// });
1395/// # }
1396/// # #[cfg(not(feature = "alloc"))] fn main() {}
1397/// ````
1398pub struct SendBlink<A> {
1399    blink: Blink<A>,
1400}
1401
1402impl<A> SendBlink<A>
1403where
1404    A: BlinkAllocator,
1405{
1406    /// Creates new [`SendBlink`] from [`Blink`].
1407    /// Resets the blink allocator to avoid dropping non-sendable types on other threads.
1408    #[inline(always)]
1409    pub fn new(mut blink: Blink<A>) -> Self {
1410        blink.reset();
1411        SendBlink { blink }
1412    }
1413
1414    /// Returns inner [`Blink`] value.
1415    #[inline(always)]
1416    pub fn into_inner(self) -> Blink<A> {
1417        self.blink
1418    }
1419}
1420
1421#[inline(always)]
1422fn never<T>(never: Infallible) -> T {
1423    match never {}
1424}
1425
1426const FASTER_START: usize = 8;
1427
1428#[inline]
1429fn size_hint_and_one(lower: usize, upper: Option<usize>, count: usize) -> Option<usize> {
1430    // Upper bound is limited by current size.
1431    // Constant for faster start.
1432    let upper = upper.map_or(count, |upper| upper.min(count));
1433    let size_hint = lower.max(upper);
1434
1435    // Add one more element to size hint.
1436    let Some(size_hint) = size_hint.checked_add(1) else {
1437        return None;
1438    };
1439
1440    // Sum with current count.
1441    count.checked_add(size_hint)
1442}
1443
1444#[inline]
1445fn saturating_drain_iter<T>(mut iter: impl Iterator<Item = T>) -> usize {
1446    let mut drained = 0;
1447    loop {
1448        let (lower, _) = iter.size_hint();
1449        if lower == 0 {
1450            match iter.next() {
1451                None => return drained,
1452                Some(_) => drained += 1,
1453            }
1454            continue;
1455        }
1456        // Don't drink too much.
1457        let lower = lower.min(usize::MAX - drained);
1458        match iter.nth(lower - 1) {
1459            None => {
1460                // This bastard lied about lower bound.
1461                // No idea how many elements were actually drained.
1462                return drained;
1463            }
1464            Some(_) => {
1465                drained += lower;
1466            }
1467        }
1468        if drained == usize::MAX {
1469            // Enough is enough.
1470            return usize::MAX;
1471        }
1472    }
1473}
1474
1475#[test]
1476fn test_iter_drain() {
1477    assert_eq!(5, saturating_drain_iter(0..5));
1478    assert_eq!(usize::MAX, saturating_drain_iter(0..usize::MAX));
1479    assert_eq!(usize::MAX, saturating_drain_iter(core::iter::repeat(1)));
1480}