Advertisement
Guest User

Untitled

a guest
Sep 19th, 2019
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.80 KB | None | 0 0
  1. use ::core::ops::Range;
  2.  
  3. ::cfg_if::cfg_if! {
  4. if #[cfg(target_endian = "big")]
  5. {
  6. #[repr(C)]
  7. #[derive(Clone, Copy)]
  8. struct HeapString {
  9. capacity: usize,
  10. length: usize,
  11. ptr: *mut u8,
  12. }
  13.  
  14. const DISCRIMINANT_INDEX: usize = 0;
  15.  
  16. const BYTES_RANGE: Range<usize> =
  17. 1 .. INLINE_BUFFER_LEN
  18. ;
  19. }
  20. else if #[cfg(target_endian = "little")]
  21. {
  22. #[repr(C)]
  23. #[derive(Clone, Copy)]
  24. struct HeapString {
  25. ptr: *mut u8,
  26. length: usize,
  27. capacity: usize,
  28. }
  29.  
  30. const DISCRIMINANT_INDEX: usize =
  31. INLINE_BUFFER_LEN - 1
  32. ;
  33.  
  34. const BYTES_RANGE: Range<usize> =
  35. 0 .. DISCRIMINANT_INDEX
  36. ;
  37. }
  38. else
  39. {
  40. compile_error!("Unreachable!");
  41. }
  42. }
  43.  
  44. impl HeapString {
  45. #[inline]
  46. pub
  47. fn as_bytes (self: &'_ Self)
  48. -> &'_ [u8]
  49. {
  50. unsafe {
  51. ::core::slice::from_raw_parts(self.ptr, self.length)
  52. }
  53. }
  54. }
  55.  
  56. const INLINE_BUFFER_LEN: usize =
  57. ::core::mem::size_of::<HeapString>()
  58. ;
  59.  
  60. type Buffer = [u8; INLINE_BUFFER_LEN];
  61.  
  62. #[repr(C)]
  63. pub
  64. union SmallString {
  65. heap_string: HeapString,
  66. buffer: Buffer,
  67. }
  68.  
  69. enum SmallStringView<'a> {
  70. HeapString(&'a HeapString),
  71. Buffer(&'a Buffer),
  72. }
  73.  
  74. enum SmallStringViewMut<'a> {
  75. HeapString(&'a mut HeapString),
  76. Buffer(&'a mut Buffer),
  77. }
  78.  
  79. impl SmallString {
  80. #[inline]
  81. fn is_inline (self: &'_ Self)
  82. -> bool
  83. {
  84. unsafe {
  85. self.buffer[DISCRIMINANT_INDEX] == 1
  86. }
  87. }
  88.  
  89. #[inline]
  90. fn view (self: &'_ Self)
  91. -> SmallStringView<'_>
  92. {
  93. use SmallStringView::*;
  94. unsafe {
  95. if self.is_inline() {
  96. Buffer(&self.buffer)
  97. } else {
  98. HeapString(&self.heap_string)
  99. }
  100. }
  101. }
  102.  
  103. #[inline]
  104. fn view_mut (self: &'_ mut Self)
  105. -> SmallStringViewMut<'_>
  106. {
  107. use SmallStringViewMut::*;
  108. unsafe {
  109. if self.is_inline() {
  110. Buffer(&mut self.buffer)
  111. } else {
  112. HeapString(&mut self.heap_string)
  113. }
  114. }
  115. }
  116.  
  117. #[inline]
  118. pub
  119. fn as_bytes (self: &'_ Self)
  120. -> &'_ [u8]
  121. {
  122. use SmallStringView::*;
  123. match self.view() {
  124. | Buffer(buffer) => {
  125. &buffer[BYTES_RANGE]
  126. },
  127. | HeapString(heap_string) => {
  128. heap_string.as_bytes()
  129. }
  130. }
  131. }
  132. }
  133.  
  134. impl ::core::ops::Deref for SmallString {
  135. type Target = str;
  136.  
  137. #[inline]
  138. fn deref (self: &'_ Self)
  139. -> &'_ Self::Target
  140. {
  141. unsafe { ::core::str::from_utf8_unchecked(
  142. self.as_bytes()
  143. )}
  144. }
  145. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement