Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use ::core::ops::Range;
- ::cfg_if::cfg_if! {
- if #[cfg(target_endian = "big")]
- {
- #[repr(C)]
- #[derive(Clone, Copy)]
- struct HeapString {
- capacity: usize,
- length: usize,
- ptr: *mut u8,
- }
- const DISCRIMINANT_INDEX: usize = 0;
- const BYTES_RANGE: Range<usize> =
- 1 .. INLINE_BUFFER_LEN
- ;
- }
- else if #[cfg(target_endian = "little")]
- {
- #[repr(C)]
- #[derive(Clone, Copy)]
- struct HeapString {
- ptr: *mut u8,
- length: usize,
- capacity: usize,
- }
- const DISCRIMINANT_INDEX: usize =
- INLINE_BUFFER_LEN - 1
- ;
- const BYTES_RANGE: Range<usize> =
- 0 .. DISCRIMINANT_INDEX
- ;
- }
- else
- {
- compile_error!("Unreachable!");
- }
- }
- impl HeapString {
- #[inline]
- pub
- fn as_bytes (self: &'_ Self)
- -> &'_ [u8]
- {
- unsafe {
- ::core::slice::from_raw_parts(self.ptr, self.length)
- }
- }
- }
- const INLINE_BUFFER_LEN: usize =
- ::core::mem::size_of::<HeapString>()
- ;
- type Buffer = [u8; INLINE_BUFFER_LEN];
- #[repr(C)]
- pub
- union SmallString {
- heap_string: HeapString,
- buffer: Buffer,
- }
- enum SmallStringView<'a> {
- HeapString(&'a HeapString),
- Buffer(&'a Buffer),
- }
- enum SmallStringViewMut<'a> {
- HeapString(&'a mut HeapString),
- Buffer(&'a mut Buffer),
- }
- impl SmallString {
- #[inline]
- fn is_inline (self: &'_ Self)
- -> bool
- {
- unsafe {
- self.buffer[DISCRIMINANT_INDEX] == 1
- }
- }
- #[inline]
- fn view (self: &'_ Self)
- -> SmallStringView<'_>
- {
- use SmallStringView::*;
- unsafe {
- if self.is_inline() {
- Buffer(&self.buffer)
- } else {
- HeapString(&self.heap_string)
- }
- }
- }
- #[inline]
- fn view_mut (self: &'_ mut Self)
- -> SmallStringViewMut<'_>
- {
- use SmallStringViewMut::*;
- unsafe {
- if self.is_inline() {
- Buffer(&mut self.buffer)
- } else {
- HeapString(&mut self.heap_string)
- }
- }
- }
- #[inline]
- pub
- fn as_bytes (self: &'_ Self)
- -> &'_ [u8]
- {
- use SmallStringView::*;
- match self.view() {
- | Buffer(buffer) => {
- &buffer[BYTES_RANGE]
- },
- | HeapString(heap_string) => {
- heap_string.as_bytes()
- }
- }
- }
- }
- impl ::core::ops::Deref for SmallString {
- type Target = str;
- #[inline]
- fn deref (self: &'_ Self)
- -> &'_ Self::Target
- {
- unsafe { ::core::str::from_utf8_unchecked(
- self.as_bytes()
- )}
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement