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