1 #![allow(unused_variables)]
2 #![allow(missing_docs)]
6 /// A slice-backed vector-like data structure.
8 /// This is a very similar concept to `ArrayVec`, but instead
9 /// of the backing memory being an owned array, the backing
10 /// memory is a unique-borrowed slice. You can thus create
11 /// one of these structures "around" some slice that you're
12 /// working with to make it easier to manipulate.
14 /// * Has a fixed capacity (the initial slice size).
15 /// * Has a variable length.
16 pub struct SliceVec
<'s
, T
> {
21 impl<'s
, T
> Default
for SliceVec
<'s
, T
> {
24 fn default() -> Self {
25 Self { data: &mut [], len: 0 }
29 impl<'s
, T
> Deref
for SliceVec
<'s
, T
> {
33 fn deref(&self) -> &Self::Target
{
34 &self.data
[..self.len
]
38 impl<'s
, T
> DerefMut
for SliceVec
<'s
, T
> {
41 fn deref_mut(&mut self) -> &mut Self::Target
{
42 &mut self.data
[..self.len
]
46 impl<'s
, T
, I
> Index
<I
> for SliceVec
<'s
, T
>
50 type Output
= <I
as SliceIndex
<[T
]>>::Output
;
53 fn index(&self, index
: I
) -> &Self::Output
{
58 impl<'s
, T
, I
> IndexMut
<I
> for SliceVec
<'s
, T
>
64 fn index_mut(&mut self, index
: I
) -> &mut Self::Output
{
65 &mut self.deref_mut()[index
]
69 impl<'s
, T
> SliceVec
<'s
, T
> {
71 pub fn append(&mut self, other
: &mut Self)
75 for item
in other
.drain(..) {
80 /// A `*mut` pointer to the backing slice.
84 /// This pointer has provenance over the _entire_ backing slice.
87 pub fn as_mut_ptr(&mut self) -> *mut T
{
88 self.data
.as_mut_ptr()
91 /// Performs a `deref_mut`, into unique slice form.
94 pub fn as_mut_slice(&mut self) -> &mut [T
] {
98 /// A `*const` pointer to the backing slice.
102 /// This pointer has provenance over the _entire_ backing slice.
105 pub fn as_ptr(&self) -> *const T
{
109 /// Performs a `deref`, into shared slice form.
112 pub fn as_slice(&self) -> &[T
] {
116 /// The capacity of the `SliceVec`.
118 /// This the length of the initial backing slice.
121 pub fn capacity(&self) -> usize {
125 /// Truncates the `SliceVec` down to length 0.
127 pub fn clear(&mut self)
134 /// Creates a draining iterator that removes the specified range in the vector
135 /// and yields the removed items.
138 /// * If the start is greater than the end
139 /// * If the end is past the edge of the vec.
143 /// # use tinyvec::*;
144 /// let mut arr = [6, 7, 8];
145 /// let mut sv = SliceVec::from(&mut arr);
146 /// let drained_values: ArrayVec<[i32; 4]> = sv.drain(1..).collect();
147 /// assert_eq!(sv.as_slice(), &[6][..]);
148 /// assert_eq!(drained_values.as_slice(), &[7, 8][..]);
151 /// assert_eq!(sv.as_slice(), &[]);
154 pub fn drain
<'p
, R
: RangeBounds
<usize>>(
155 &'p
mut self, range
: R
,
156 ) -> SliceVecDrain
<'p
, 's
, T
>
160 use core
::ops
::Bound
;
161 let start
= match range
.start_bound() {
162 Bound
::Included(x
) => *x
,
163 Bound
::Excluded(x
) => x
.saturating_add(1),
164 Bound
::Unbounded
=> 0,
166 let end
= match range
.end_bound() {
167 Bound
::Included(x
) => x
.saturating_add(1),
168 Bound
::Excluded(x
) => *x
,
169 Bound
::Unbounded
=> self.len
,
173 "SliceVec::drain> Illegal range, {} to {}",
179 "SliceVec::drain> Range ends at {} but length is only {}!",
192 pub fn extend_from_slice(&mut self, sli
: &[T
])
200 let new_len
= self.len
+ sli
.len();
201 if new_len
> self.capacity() {
203 "SliceVec::extend_from_slice> total length {} exceeds capacity {}",
209 let target
= &mut self.data
[self.len
..new_len
];
210 target
.clone_from_slice(sli
);
211 self.set_len(new_len
);
214 /// Fill the vector until its capacity has been reached.
216 /// Successively fills unused space in the spare slice of the vector with
217 /// elements from the iterator. It then returns the remaining iterator
218 /// without exhausting it. This also allows appending the head of an
219 /// infinite iterator.
221 /// This is an alternative to `Extend::extend` method for cases where the
222 /// length of the iterator can not be checked. Since this vector can not
223 /// reallocate to increase its capacity, it is unclear what to do with
224 /// remaining elements in the iterator and the iterator itself. The
225 /// interface also provides no way to communicate this to the caller.
228 /// * If the `next` method of the provided iterator panics.
233 /// # use tinyvec::*;
234 /// let mut arr = [7, 7, 7, 7];
235 /// let mut sv = SliceVec::from_slice_len(&mut arr, 0);
236 /// let mut to_inf = sv.fill(0..);
237 /// assert_eq!(&sv[..], [0, 1, 2, 3]);
238 /// assert_eq!(to_inf.next(), Some(4));
241 pub fn fill
<I
: IntoIterator
<Item
= T
>>(&mut self, iter
: I
) -> I
::IntoIter
{
242 let mut iter
= iter
.into_iter();
243 for element
in iter
.by_ref().take(self.capacity() - self.len()) {
249 /// Wraps up a slice and uses the given length as the initial length.
251 /// If you want to simply use the full slice, use `from` instead.
255 /// * The length specified must be less than or equal to the capacity of the
259 #[allow(clippy::match_wild_err_arm)]
260 pub fn from_slice_len(data
: &'s
mut [T
], len
: usize) -> Self {
261 assert
!(len
<= data
.len());
265 /// Inserts an item at the position given, moving all following elements +1
269 /// * If `index` > `len`
270 /// * If the capacity is exhausted
274 /// # use tinyvec::*;
275 /// let mut arr = [1, 2, 3, 0, 0];
276 /// let mut sv = SliceVec::from_slice_len(&mut arr, 3);
278 /// assert_eq!(sv.as_slice(), &[1, 4, 2, 3]);
280 /// assert_eq!(sv.as_slice(), &[1, 4, 2, 3, 5]);
283 pub fn insert(&mut self, index
: usize, item
: T
) {
284 if index
> self.len
{
285 panic
!("SliceVec::insert> index {} is out of bounds {}", index
, self.len
);
288 // Try to push the element.
290 // And move it into its place.
291 self.as_mut_slice()[index
..].rotate_right(1);
294 /// Checks if the length is 0.
297 pub fn is_empty(&self) -> bool
{
301 /// The length of the `SliceVec` (in elements).
304 pub fn len(&self) -> usize {
308 /// Remove and return the last element of the vec, if there is one.
311 /// * If the vec is empty you get `None`.
315 /// # use tinyvec::*;
316 /// let mut arr = [1, 2];
317 /// let mut sv = SliceVec::from(&mut arr);
318 /// assert_eq!(sv.pop(), Some(2));
319 /// assert_eq!(sv.pop(), Some(1));
320 /// assert_eq!(sv.pop(), None);
323 pub fn pop(&mut self) -> Option
<T
>
329 let out
= take(&mut self.data
[self.len
]);
336 /// Place an element onto the end of the vec.
339 /// * If the length of the vec would overflow the capacity.
343 /// # use tinyvec::*;
344 /// let mut arr = [0, 0];
345 /// let mut sv = SliceVec::from_slice_len(&mut arr, 0);
346 /// assert_eq!(&sv[..], []);
348 /// assert_eq!(&sv[..], [1]);
350 /// assert_eq!(&sv[..], [1, 2]);
351 /// // sv.push(3); this would overflow the ArrayVec and panic!
354 pub fn push(&mut self, val
: T
) {
355 if self.len
< self.capacity() {
356 self.data
[self.len
] = val
;
359 panic
!("SliceVec::push> capacity overflow")
363 /// Removes the item at `index`, shifting all others down by one index.
365 /// Returns the removed element.
369 /// * If the index is out of bounds.
374 /// # use tinyvec::*;
375 /// let mut arr = [1, 2, 3];
376 /// let mut sv = SliceVec::from(&mut arr);
377 /// assert_eq!(sv.remove(1), 2);
378 /// assert_eq!(&sv[..], [1, 3]);
381 pub fn remove(&mut self, index
: usize) -> T
385 let targets
: &mut [T
] = &mut self.deref_mut()[index
..];
386 let item
= take(&mut targets
[0]);
387 targets
.rotate_left(1);
392 /// As [`resize_with`](SliceVec::resize_with)
393 /// and it clones the value as the closure.
398 /// # use tinyvec::*;
400 /// let mut arr = ["hello", "", "", "", ""];
401 /// let mut sv = SliceVec::from_slice_len(&mut arr, 1);
402 /// sv.resize(3, "world");
403 /// assert_eq!(&sv[..], ["hello", "world", "world"]);
406 /// let mut arr = ['a', 'b', 'c', 'd'];
407 /// let mut sv = SliceVec::from(&mut arr);
408 /// sv.resize(2, 'z');
409 /// assert_eq!(&sv[..], ['a', 'b']);
412 pub fn resize(&mut self, new_len
: usize, new_val
: T
)
416 self.resize_with(new_len
, || new_val
.clone())
419 /// Resize the vec to the new length.
421 /// * If it needs to be longer, it's filled with repeated calls to the
422 /// provided function.
423 /// * If it needs to be shorter, it's truncated.
424 /// * If the type needs to drop the truncated slots are filled with calls to
425 /// the provided function.
430 /// # use tinyvec::*;
431 /// let mut arr = [1, 2, 3, 7, 7, 7, 7];
432 /// let mut sv = SliceVec::from_slice_len(&mut arr, 3);
433 /// sv.resize_with(5, Default::default);
434 /// assert_eq!(&sv[..], [1, 2, 3, 0, 0]);
436 /// let mut arr = [0, 0, 0, 0];
437 /// let mut sv = SliceVec::from_slice_len(&mut arr, 0);
439 /// sv.resize_with(4, || {
443 /// assert_eq!(&sv[..], [2, 4, 8, 16]);
446 pub fn resize_with
<F
: FnMut() -> T
>(&mut self, new_len
: usize, mut f
: F
) {
447 match new_len
.checked_sub(self.len
) {
449 if needs_drop
::<T
>() {
450 while self.len() > new_len
{
452 self.data
[self.len
] = f();
458 Some(new_elements
) => {
459 for _
in 0..new_elements
{
466 /// Walk the vec and keep only the elements that pass the predicate given.
471 /// # use tinyvec::*;
473 /// let mut arr = [1, 1, 2, 3, 3, 4];
474 /// let mut sv = SliceVec::from(&mut arr);
475 /// sv.retain(|&x| x % 2 == 0);
476 /// assert_eq!(&sv[..], [2, 4]);
479 pub fn retain
<F
: FnMut(&T
) -> bool
>(&mut self, mut acceptable
: F
)
483 // Drop guard to contain exactly the remaining elements when the test
485 struct JoinOnDrop
<'vec
, Item
> {
486 items
: &'vec
mut [Item
],
488 // Start of tail relative to `done_end`.
492 impl<Item
> Drop
for JoinOnDrop
<'_
, Item
> {
494 self.items
[self.done_end
..].rotate_left(self.tail_start
);
498 let mut rest
= JoinOnDrop { items: self.data, done_end: 0, tail_start: 0 }
;
500 for idx
in 0..self.len
{
501 // Loop start invariant: idx = rest.done_end + rest.tail_start
502 if !acceptable(&rest
.items
[idx
]) {
503 let _
= take(&mut rest
.items
[idx
]);
505 rest
.tail_start
+= 1;
507 rest
.items
.swap(rest
.done_end
, idx
);
513 /// Forces the length of the vector to `new_len`.
516 /// * If `new_len` is greater than the vec's capacity.
519 /// * This is a fully safe operation! The inactive memory already counts as
520 /// "initialized" by Rust's rules.
521 /// * Other than "the memory is initialized" there are no other guarantees
522 /// regarding what you find in the inactive portion of the vec.
524 pub fn set_len(&mut self, new_len
: usize) {
525 if new_len
> self.capacity() {
526 // Note(Lokathor): Technically we don't have to panic here, and we could
527 // just let some other call later on trigger a panic on accident when the
528 // length is wrong. However, it's a lot easier to catch bugs when things
529 // are more "fail-fast".
531 "SliceVec::set_len> new length {} exceeds capacity {}",
540 /// Splits the collection at the point given.
542 /// * `[0, at)` stays in this vec (and this vec is now full).
543 /// * `[at, len)` ends up in the new vec (with any spare capacity).
546 /// * if `at` > `self.len()`
551 /// # use tinyvec::*;
552 /// let mut arr = [1, 2, 3];
553 /// let mut sv = SliceVec::from(&mut arr);
554 /// let sv2 = sv.split_off(1);
555 /// assert_eq!(&sv[..], [1]);
556 /// assert_eq!(&sv2[..], [2, 3]);
559 pub fn split_off
<'a
>(&'a
mut self, at
: usize) -> SliceVec
<'s
, T
> {
560 let mut new
= Self::default();
561 let backing
: &'s
mut [T
] = replace(&mut self.data
, &mut []);
562 let (me
, other
) = backing
.split_at_mut(at
);
563 new
.len
= self.len
- at
;
570 /// Remove an element, swapping the end of the vec into its place.
573 /// * If the index is out of bounds.
577 /// # use tinyvec::*;
578 /// let mut arr = ["foo", "bar", "quack", "zap"];
579 /// let mut sv = SliceVec::from(&mut arr);
581 /// assert_eq!(sv.swap_remove(1), "bar");
582 /// assert_eq!(&sv[..], ["foo", "zap", "quack"]);
584 /// assert_eq!(sv.swap_remove(0), "foo");
585 /// assert_eq!(&sv[..], ["quack", "zap"]);
588 pub fn swap_remove(&mut self, index
: usize) -> T
594 "SliceVec::swap_remove> index {} is out of bounds {}",
598 if index
== self.len
- 1 {
601 let i
= self.pop().unwrap();
602 replace(&mut self[index
], i
)
606 /// Reduces the vec's length to the given value.
608 /// If the vec is already shorter than the input, nothing happens.
610 pub fn truncate(&mut self, new_len
: usize)
614 if needs_drop
::<T
>() {
615 while self.len
> new_len
{
619 self.len
= self.len
.min(new_len
);
623 /// Wraps a slice, using the given length as the starting length.
625 /// If you want to use the whole length of the slice, you can just use the
630 /// If the given length is greater than the length of the slice you get
633 pub fn try_from_slice_len(data
: &'s
mut [T
], len
: usize) -> Option
<Self> {
634 if len
<= data
.len() {
635 Some(Self { data, len }
)
642 #[cfg(feature = "grab_spare_slice")]
643 impl<'s
, T
> SliceVec
<'s
, T
> {
644 /// Obtain the shared slice of the array _after_ the active memory.
648 /// # use tinyvec::*;
649 /// let mut arr = [0; 4];
650 /// let mut sv = SliceVec::from_slice_len(&mut arr, 0);
651 /// assert_eq!(sv.grab_spare_slice().len(), 4);
656 /// assert_eq!(sv.grab_spare_slice().len(), 0);
659 pub fn grab_spare_slice(&self) -> &[T
] {
660 &self.data
[self.len
..]
663 /// Obtain the mutable slice of the array _after_ the active memory.
667 /// # use tinyvec::*;
668 /// let mut arr = [0; 4];
669 /// let mut sv = SliceVec::from_slice_len(&mut arr, 0);
670 /// assert_eq!(sv.grab_spare_slice_mut().len(), 4);
673 /// assert_eq!(sv.grab_spare_slice_mut().len(), 2);
676 pub fn grab_spare_slice_mut(&mut self) -> &mut [T
] {
677 &mut self.data
[self.len
..]
681 impl<'s
, T
> From
<&'s
mut [T
]> for SliceVec
<'s
, T
> {
682 /// Uses the full slice as the initial length.
685 /// # use tinyvec::*;
686 /// let mut arr = [0_i32; 2];
687 /// let mut sv = SliceVec::from(&mut arr[..]);
689 fn from(data
: &'s
mut [T
]) -> Self {
690 let len
= data
.len();
695 impl<'s
, T
, A
> From
<&'s
mut A
> for SliceVec
<'s
, T
>
699 /// Calls `AsRef::as_mut` then uses the full slice as the initial length.
702 /// # use tinyvec::*;
703 /// let mut arr = [0, 0];
704 /// let mut sv = SliceVec::from(&mut arr);
706 fn from(a
: &'s
mut A
) -> Self {
707 let data
= a
.as_mut();
708 let len
= data
.len();
713 /// Draining iterator for [`SliceVec`]
715 /// See [`SliceVec::drain`](SliceVec::drain)
716 pub struct SliceVecDrain
<'p
, 's
, T
: Default
> {
717 parent
: &'p
mut SliceVec
<'s
, T
>,
722 impl<'p
, 's
, T
: Default
> Iterator
for SliceVecDrain
<'p
, 's
, T
> {
725 fn next(&mut self) -> Option
<Self::Item
> {
726 if self.target_index
!= self.target_end
{
727 let out
= take(&mut self.parent
[self.target_index
]);
728 self.target_index
+= 1;
735 impl<'p
, 's
, T
: Default
> FusedIterator
for SliceVecDrain
<'p
, 's
, T
> {}
736 impl<'p
, 's
, T
: Default
> Drop
for SliceVecDrain
<'p
, 's
, T
> {
739 // Changed because it was moving `self`, it's also more clear and the std
742 // Implementation very similar to [`SliceVec::remove`](SliceVec::remove)
743 let count
= self.target_end
- self.target_start
;
744 let targets
: &mut [T
] = &mut self.parent
.deref_mut()[self.target_start
..];
745 targets
.rotate_left(count
);
746 self.parent
.len
-= count
;
750 impl<'s
, T
> AsMut
<[T
]> for SliceVec
<'s
, T
> {
753 fn as_mut(&mut self) -> &mut [T
] {
758 impl<'s
, T
> AsRef
<[T
]> for SliceVec
<'s
, T
> {
761 fn as_ref(&self) -> &[T
] {
766 impl<'s
, T
> Borrow
<[T
]> for SliceVec
<'s
, T
> {
769 fn borrow(&self) -> &[T
] {
774 impl<'s
, T
> BorrowMut
<[T
]> for SliceVec
<'s
, T
> {
777 fn borrow_mut(&mut self) -> &mut [T
] {
782 impl<'s
, T
> Extend
<T
> for SliceVec
<'s
, T
> {
784 fn extend
<I
: IntoIterator
<Item
= T
>>(&mut self, iter
: I
) {
791 impl<'s
, T
> IntoIterator
for SliceVec
<'s
, T
> {
792 type Item
= &'s
mut T
;
793 type IntoIter
= core
::slice
::IterMut
<'s
, T
>;
796 fn into_iter(self) -> Self::IntoIter
{
801 impl<'s
, T
> PartialEq
for SliceVec
<'s
, T
>
807 fn eq(&self, other
: &Self) -> bool
{
808 self.as_slice().eq(other
.as_slice())
811 impl<'s
, T
> Eq
for SliceVec
<'s
, T
> where T
: Eq {}
813 impl<'s
, T
> PartialOrd
for SliceVec
<'s
, T
>
819 fn partial_cmp(&self, other
: &Self) -> Option
<core
::cmp
::Ordering
> {
820 self.as_slice().partial_cmp(other
.as_slice())
823 impl<'s
, T
> Ord
for SliceVec
<'s
, T
>
829 fn cmp(&self, other
: &Self) -> core
::cmp
::Ordering
{
830 self.as_slice().cmp(other
.as_slice())
834 impl<'s
, T
> PartialEq
<&[T
]> for SliceVec
<'s
, T
>
840 fn eq(&self, other
: &&[T
]) -> bool
{
841 self.as_slice().eq(*other
)
845 impl<'s
, T
> Hash
for SliceVec
<'s
, T
>
850 fn hash
<H
: Hasher
>(&self, state
: &mut H
) {
851 self.as_slice().hash(state
)
855 #[cfg(feature = "experimental_write_impl")]
856 impl<'s
> core
::fmt
::Write
for SliceVec
<'s
, u8> {
857 fn write_str(&mut self, s
: &str) -> core
::fmt
::Result
{
858 let my_len
= self.len();
859 let str_len
= s
.as_bytes().len();
860 if my_len
+ str_len
<= self.capacity() {
861 let remainder
= &mut self.data
[my_len
..];
862 let target
= &mut remainder
[..str_len
];
863 target
.copy_from_slice(s
.as_bytes());
866 Err(core
::fmt
::Error
)
871 // // // // // // // //
873 // // // // // // // //
875 impl<'s
, T
> Binary
for SliceVec
<'s
, T
>
879 #[allow(clippy::missing_inline_in_public_items)]
880 fn fmt(&self, f
: &mut Formatter
) -> core
::fmt
::Result
{
885 for (i
, elem
) in self.iter().enumerate() {
887 write
!(f
, ",{}", if f
.alternate() { "\n " }
else { " " }
)?
;
889 Binary
::fmt(elem
, f
)?
;
898 impl<'s
, T
> Debug
for SliceVec
<'s
, T
>
902 #[allow(clippy::missing_inline_in_public_items)]
903 fn fmt(&self, f
: &mut Formatter
) -> core
::fmt
::Result
{
908 for (i
, elem
) in self.iter().enumerate() {
910 write
!(f
, ",{}", if f
.alternate() { "\n " }
else { " " }
)?
;
912 Debug
::fmt(elem
, f
)?
;
921 impl<'s
, T
> Display
for SliceVec
<'s
, T
>
925 #[allow(clippy::missing_inline_in_public_items)]
926 fn fmt(&self, f
: &mut Formatter
) -> core
::fmt
::Result
{
931 for (i
, elem
) in self.iter().enumerate() {
933 write
!(f
, ",{}", if f
.alternate() { "\n " }
else { " " }
)?
;
935 Display
::fmt(elem
, f
)?
;
944 impl<'s
, T
> LowerExp
for SliceVec
<'s
, T
>
948 #[allow(clippy::missing_inline_in_public_items)]
949 fn fmt(&self, f
: &mut Formatter
) -> core
::fmt
::Result
{
954 for (i
, elem
) in self.iter().enumerate() {
956 write
!(f
, ",{}", if f
.alternate() { "\n " }
else { " " }
)?
;
958 LowerExp
::fmt(elem
, f
)?
;
967 impl<'s
, T
> LowerHex
for SliceVec
<'s
, T
>
971 #[allow(clippy::missing_inline_in_public_items)]
972 fn fmt(&self, f
: &mut Formatter
) -> core
::fmt
::Result
{
977 for (i
, elem
) in self.iter().enumerate() {
979 write
!(f
, ",{}", if f
.alternate() { "\n " }
else { " " }
)?
;
981 LowerHex
::fmt(elem
, f
)?
;
990 impl<'s
, T
> Octal
for SliceVec
<'s
, T
>
994 #[allow(clippy::missing_inline_in_public_items)]
995 fn fmt(&self, f
: &mut Formatter
) -> core
::fmt
::Result
{
1000 for (i
, elem
) in self.iter().enumerate() {
1002 write
!(f
, ",{}", if f
.alternate() { "\n " }
else { " " }
)?
;
1004 Octal
::fmt(elem
, f
)?
;
1013 impl<'s
, T
> Pointer
for SliceVec
<'s
, T
>
1017 #[allow(clippy::missing_inline_in_public_items)]
1018 fn fmt(&self, f
: &mut Formatter
) -> core
::fmt
::Result
{
1023 for (i
, elem
) in self.iter().enumerate() {
1025 write
!(f
, ",{}", if f
.alternate() { "\n " }
else { " " }
)?
;
1027 Pointer
::fmt(elem
, f
)?
;
1036 impl<'s
, T
> UpperExp
for SliceVec
<'s
, T
>
1040 #[allow(clippy::missing_inline_in_public_items)]
1041 fn fmt(&self, f
: &mut Formatter
) -> core
::fmt
::Result
{
1046 for (i
, elem
) in self.iter().enumerate() {
1048 write
!(f
, ",{}", if f
.alternate() { "\n " }
else { " " }
)?
;
1050 UpperExp
::fmt(elem
, f
)?
;
1059 impl<'s
, T
> UpperHex
for SliceVec
<'s
, T
>
1063 #[allow(clippy::missing_inline_in_public_items)]
1064 fn fmt(&self, f
: &mut Formatter
) -> core
::fmt
::Result
{
1069 for (i
, elem
) in self.iter().enumerate() {
1071 write
!(f
, ",{}", if f
.alternate() { "\n " }
else { " " }
)?
;
1073 UpperHex
::fmt(elem
, f
)?
;